// Catch2 tests for Compression Error Handler // Migrated from GTest: error_handler_test.cpp #include #include #include #include #include using namespace yams; using namespace yams::compression; namespace { struct ErrorHandlerFixture { ErrorHandlerFixture() { config_ = ErrorHandlingConfig{}; config_.maxRetryAttempts = 3; config_.retryDelay = std::chrono::milliseconds{100}; config_.maxRetryDelay = std::chrono::milliseconds{5000}; config_.enableIntegrityValidation = true; handler_ = std::make_unique(config_); } ~ErrorHandlerFixture() { handler_.reset(); } ErrorHandlingConfig config_; std::unique_ptr handler_; }; } // namespace TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - BasicErrorHandling", "[compression][error_handler][catch2]") { CompressionError error; error.code = ErrorCode::CompressionError; error.severity = ErrorSeverity::Error; error.recommendedStrategy = RecoveryStrategy::Retry; error.algorithm = CompressionAlgorithm::Zstandard; error.operation = "compress"; error.details = "Test compression error"; error.dataSize = 1024; error.compressionLevel = 5; error.timestamp = std::chrono::system_clock::now(); error.attemptNumber = 1; int retryCount = 0; auto retryFunc = [&retryCount]() -> Result { retryCount++; if (retryCount < 3) { return Error{ErrorCode::CompressionError, "Still failing"}; } CompressionResult result; result.algorithm = CompressionAlgorithm::Zstandard; result.level = 5; result.originalSize = 1024; result.compressedSize = 512; result.duration = std::chrono::milliseconds{1}; return result; }; auto result = handler_->handleError(error, retryFunc); CHECK(result.success); CHECK(retryCount == 3); } TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - MaxRetriesExhausted", "[compression][error_handler][catch2]") { CompressionError error; error.code = ErrorCode::CompressionError; error.severity = ErrorSeverity::Error; error.recommendedStrategy = RecoveryStrategy::Retry; error.algorithm = CompressionAlgorithm::LZMA; error.attemptNumber = 1; auto retryFunc = []() -> Result { return Error{ErrorCode::CompressionError, "Always fails"}; }; auto result = handler_->handleError(error, retryFunc); CHECK_FALSE(result.success); // strategyUsed reflects the strategy that was actually executed, not a fallback CHECK(result.strategyUsed == RecoveryStrategy::Retry); } TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - CriticalErrorHandling", "[compression][error_handler][catch2]") { CompressionError error; error.code = ErrorCode::InternalError; error.severity = ErrorSeverity::Critical; error.recommendedStrategy = RecoveryStrategy::None; error.algorithm = CompressionAlgorithm::Zstandard; auto retryFunc = []() -> Result { return Error{ErrorCode::InternalError, "Critical error"}; }; auto result = handler_->handleError(error, retryFunc); CHECK_FALSE(result.success); CHECK(result.strategyUsed == RecoveryStrategy::None); } TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - DegradedModeActivation", "[compression][error_handler][catch2]") { CHECK_FALSE(handler_->isInDegradedMode()); handler_->setDegradedMode(true); CHECK(handler_->isInDegradedMode()); handler_->setDegradedMode(false); CHECK_FALSE(handler_->isInDegradedMode()); } TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - ErrorStatistics", "[compression][error_handler][catch2]") { // Record some errors for (int i = 0; i < 5; i++) { CompressionError error; error.code = ErrorCode::CompressionError; error.severity = ErrorSeverity::Error; error.recommendedStrategy = RecoveryStrategy::Retry; error.algorithm = CompressionAlgorithm::Zstandard; error.attemptNumber = 1; auto retryFunc = []() -> Result { CompressionResult result; result.algorithm = CompressionAlgorithm::Zstandard; return result; }; (void)handler_->handleError(error, retryFunc); } // getErrorStats returns std::unordered_map auto stats = handler_->getErrorStats(); // All 5 iterations used CompressionError, so should have count of 5 CHECK(stats[ErrorCode::CompressionError] >= 5); } TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - ErrorCallbacks", "[compression][error_handler][catch2]") { bool callbackInvoked = false; ErrorCode capturedCode = ErrorCode::Success; handler_->registerErrorCallback([&](const CompressionError& error) { callbackInvoked = true; capturedCode = error.code; }); CompressionError error; error.code = ErrorCode::CompressionError; error.severity = ErrorSeverity::Error; error.recommendedStrategy = RecoveryStrategy::None; auto retryFunc = []() -> Result { return Error{ErrorCode::CompressionError, "Test error"}; }; (void)handler_->handleError(error, retryFunc); CHECK(callbackInvoked); CHECK(capturedCode == ErrorCode::CompressionError); } // Note: RecoveryStrategySelection test removed - selectRecoveryStrategy is not part of public API TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - ResetStatistics", "[compression][error_handler][catch2]") { // Record an error CompressionError error; error.code = ErrorCode::CompressionError; error.severity = ErrorSeverity::Error; auto retryFunc = []() -> Result { return Error{ErrorCode::CompressionError, "Test"}; }; (void)handler_->handleError(error, retryFunc); auto stats = handler_->getErrorStats(); CHECK(stats.size() > 0); handler_->resetStats(); stats = handler_->getErrorStats(); CHECK(stats.empty()); } TEST_CASE_METHOD(ErrorHandlerFixture, "CompressionErrorHandler - ConfigurationUpdate", "[compression][error_handler][catch2]") { ErrorHandlingConfig newConfig; newConfig.maxRetryAttempts = 5; newConfig.retryDelay = std::chrono::milliseconds{200}; newConfig.maxRetryDelay = std::chrono::milliseconds{10000}; newConfig.enableIntegrityValidation = false; handler_->updateConfig(newConfig); const auto& currentConfig = handler_->config(); CHECK(currentConfig.maxRetryAttempts == 5); CHECK(currentConfig.retryDelay.count() == 200); CHECK_FALSE(currentConfig.enableIntegrityValidation); } // Note: DiagnosticsOutput test removed - getDiagnostics is not part of public API // Note: ErrorScopeRAII test removed - ErrorScope class not available (use CompressionErrorScope)