From 8def1d1aa128f68efcd950bf6a0fde2e52fc3272 Mon Sep 17 00:00:00 2001 From: Stephen Oresanya Date: Tue, 1 Jul 2025 12:55:20 +0100 Subject: [PATCH 1/3] Fix #1042: Add explicit config setup to authorization unit tests - Added explicit config setup for initial authorization tests - Added explicit config setup for remaining authorization unit tests Signed-off-by: Stephen Oresanya --- .../functional_blocks/test_authorization.cpp | 96 +++++++++++++++---- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp b/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp index 0202d0fa7..d2697434f 100644 --- a/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp +++ b/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp @@ -346,20 +346,30 @@ TEST_F(AuthorizationTest, is_auth_cache_ctrlr_enabled) { this->authorization = std::make_unique(context); EXPECT_FALSE(authorization->is_auth_cache_ctrlr_enabled()); } - TEST_F(AuthorizationTest, authorize_req_websocket_disconnected) { - // Try to do an authorize request when the websocket is disconnected. + // Test: Authorize request should return Unknown when WebSocket is offline + // Setup: Explicitly disable all local authorization options + this->set_local_pre_authorize(this->device_model, false); + this->set_local_authorize_offline(this->device_model, false); + + // Simulate offline WebSocket connection ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(false)); + const AuthorizeResponse response = authorization->authorize_req(get_id_token(), std::nullopt, std::nullopt); EXPECT_EQ(response.idTokenInfo.status, AuthorizationStatusEnum::Unknown); } TEST_F(AuthorizationTest, authorize_req_wrong_future_message_type) { - // Try to do an authorize request with the websocket connected. The dispatch_call_async returns - // a wrong message type. + // Test: Response should be Unknown if dispatch_call_async returns wrong message type + // Setup: Disable local auth and simulate online WebSocket + this->set_local_pre_authorize(this->device_model, false); + this->set_local_authorize_offline(this->device_model, false); + ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); + ocpp::EnhancedMessage enhanced_message; enhanced_message.messageType = MessageType::GetDisplayMessages; + EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)) .WillOnce(Return(std::async(std::launch::deferred, [enhanced_message]() { return enhanced_message; }))); @@ -368,8 +378,13 @@ TEST_F(AuthorizationTest, authorize_req_wrong_future_message_type) { } TEST_F(AuthorizationTest, authorize_req_accepted) { - // Try to do an authorize request, which is accepted. + // Test: Authorize request returns Accepted when WebSocket is online and dispatcher responds positively + // Setup: Disable local auth, simulate online WebSocket, and mock Accepted response + this->set_local_pre_authorize(this->device_model, false); + this->set_local_authorize_offline(this->device_model, false); + ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); + EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() { return create_example_authorize_response(AuthorizeCertificateStatusEnum::Accepted, AuthorizationStatusEnum::Accepted); @@ -380,12 +395,18 @@ TEST_F(AuthorizationTest, authorize_req_accepted) { } TEST_F(AuthorizationTest, authorize_req_exception) { - // Try to do an authorize request, during which which an exception is thrown. + // Test: An exception in AuthorizationStatusEnum deserialization leads to Unknown response + // Setup: Disable local auth, simulate online WebSocket, and mock invalid status value + this->set_local_pre_authorize(this->device_model, false); + this->set_local_authorize_offline(this->device_model, false); + ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); + EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() { - // Create authorize response with a wrong enum value, which will throw. - return create_example_authorize_response(AuthorizeCertificateStatusEnum::Accepted, - static_cast(INT32_MAX)); + return create_example_authorize_response( + AuthorizeCertificateStatusEnum::Accepted, + static_cast(INT32_MAX) // invalid value triggers exception + ); }))); const AuthorizeResponse response = authorization->authorize_req(get_id_token(), std::nullopt, std::nullopt); @@ -393,13 +414,17 @@ TEST_F(AuthorizationTest, authorize_req_exception) { } TEST_F(AuthorizationTest, authorize_req_exception2) { - // Try to do an authorization request, an exception is thrown for the authorize response. + // Test: An exception in AuthorizeCertificateStatusEnum deserialization leads to Unknown response + // Setup: Disable local auth, simulate online WebSocket, and mock invalid certificate status + this->set_local_pre_authorize(this->device_model, false); + this->set_local_authorize_offline(this->device_model, false); + ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); + EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() { - // Create authorize response with a from enum value for the authorize certificute status, which will - // cause an exception to be thrown. - return create_example_authorize_response(static_cast(INT32_MAX), - AuthorizationStatusEnum::Accepted); + return create_example_authorize_response( + static_cast(INT32_MAX), // invalid cert status + AuthorizationStatusEnum::Accepted); }))); const AuthorizeResponse response = authorization->authorize_req(get_id_token(), std::nullopt, std::nullopt); @@ -517,6 +542,11 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_accepted) { // Local auth list is enabled. this->set_local_auth_list_ctrlr_enabled(this->device_model, true); + // Explicit config setup for test isolation + set_local_pre_authorize(false); + set_local_authorize_offline(false); + ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); + IdTokenInfo id_token_info_result; id_token_info_result.status = AuthorizationStatusEnum::Accepted; @@ -540,6 +570,11 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_no_remo // Disable remote authorization. this->disable_remote_authorization(this->device_model, true); + // Explicit config setup for test isolation + set_local_pre_authorize(false); + set_local_authorize_offline(false); + ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); + IdTokenInfo id_token_info_result; id_token_info_result.status = AuthorizationStatusEnum::Invalid; @@ -555,14 +590,19 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_no_remo } TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_websocket_disconnected) { - // Validate token with the local auth list: unknown the websocket is not connected and token info + // Validate token with the local auth list: unknown because the websocket is not connected and token info // status is not accepted. Set AuthCtrlr::Enabled to true this->set_auth_ctrlr_enabled(this->device_model, true); // Local auth list is enabled. this->set_local_auth_list_ctrlr_enabled(this->device_model, true); // Remote authorization is enabled. this->disable_remote_authorization(this->device_model, false); - // But the websocket is disconnected so it is not possible to authorize the request. + + // Explicit config setup for test isolation + set_local_pre_authorize(false); + set_local_authorize_offline(false); + + // WebSocket is disconnected for this test case EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(false)); IdTokenInfo id_token_info_result; @@ -587,7 +627,12 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_connectivity_ma this->set_local_auth_list_ctrlr_enabled(this->device_model, true); // Remote authorization is enabled. this->disable_remote_authorization(this->device_model, false); - // But the websocket is connected so it is possible to authorize the request. + + // Explicit config setup for test isolation + set_local_pre_authorize(false); + set_local_authorize_offline(false); + + // WebSocket is connected EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true)); // Authorize request returns 'Accepted'. EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() { @@ -658,6 +703,10 @@ TEST_F( // And offline contract validation is not allowed. this->set_allow_contract_validation_offline(this->device_model, true); this->set_local_authorize_offline(this->device_model, false); + + // Explicit config setup for test isolation + set_local_pre_authorize(false); + ON_CALL(this->evse_security, verify_certificate(_, DEFAULT_LEAF_CERT_TYPE)) .WillByDefault(Return(ocpp::CertificateValidationResult::Valid)); @@ -681,6 +730,10 @@ TEST_F( this->set_allow_contract_validation_offline(this->device_model, true); this->set_local_authorize_offline(this->device_model, true); this->set_local_auth_list_ctrlr_enabled(this->device_model, true); + + // Explicit config setup for test isolation + set_local_pre_authorize(false); + ON_CALL(this->evse_security, verify_certificate(_, DEFAULT_LEAF_CERT_TYPE)) .WillByDefault(Return(ocpp::CertificateValidationResult::Valid)); @@ -707,6 +760,10 @@ TEST_F(AuthorizationTest, // And offline contract validation is not allowed. this->set_allow_contract_validation_offline(this->device_model, true); this->set_local_authorize_offline(this->device_model, false); + + // Explicit config setup for test isolation + set_local_pre_authorize(false); + std::vector types({ocpp::LeafCertificateType::MO, ocpp::LeafCertificateType::V2G}); ON_CALL(this->evse_security, verify_certificate(_, types)) .WillByDefault(Return(ocpp::CertificateValidationResult::Expired)); @@ -1024,6 +1081,11 @@ TEST_F(AuthorizationTest, validate_token_auth_cache_lifetime_expired) { this->set_auth_cache_lifetime(this->device_model, 5000); // Allow remote authorization this->disable_remote_authorization(this->device_model, false); + + // Explicit config setup for test isolation + set_local_pre_authorize(false); + set_local_authorize_offline(false); + // The websocket is connected. EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true)); From 8f38c2daca81d0a9b2c5cbf627c7677bc805f011 Mon Sep 17 00:00:00 2001 From: Stephen Oresanya Date: Mon, 11 Aug 2025 14:13:12 +0100 Subject: [PATCH 2/3] fix(tests): update set_local_pre_authorize and set_local_authorize_offline calls to match new signature Signed-off-by: Stephen Oresanya --- .../functional_blocks/test_authorization.cpp | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp b/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp index d2697434f..889081084 100644 --- a/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp +++ b/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp @@ -543,8 +543,8 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_accepted) { this->set_local_auth_list_ctrlr_enabled(this->device_model, true); // Explicit config setup for test isolation - set_local_pre_authorize(false); - set_local_authorize_offline(false); + set_local_pre_authorize(this->device_model, false); + set_local_authorize_offline(this->device_model, false); ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); IdTokenInfo id_token_info_result; @@ -571,8 +571,8 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_no_remo this->disable_remote_authorization(this->device_model, true); // Explicit config setup for test isolation - set_local_pre_authorize(false); - set_local_authorize_offline(false); + set_local_pre_authorize(this->device_model, false); + set_local_authorize_offline(this->device_model, false); ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true)); IdTokenInfo id_token_info_result; @@ -599,12 +599,13 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_websock this->disable_remote_authorization(this->device_model, false); // Explicit config setup for test isolation - set_local_pre_authorize(false); - set_local_authorize_offline(false); + set_local_pre_authorize(this->device_model, false); + set_local_authorize_offline(this->device_model, false); // WebSocket is disconnected for this test case EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(false)); + IdTokenInfo id_token_info_result; id_token_info_result.status = AuthorizationStatusEnum::Invalid; @@ -705,9 +706,10 @@ TEST_F( this->set_local_authorize_offline(this->device_model, false); // Explicit config setup for test isolation - set_local_pre_authorize(false); + set_local_pre_authorize(this->device_model, false); ON_CALL(this->evse_security, verify_certificate(_, DEFAULT_LEAF_CERT_TYPE)) + .WillByDefault(Return(ocpp::CertificateValidationResult::Valid)); IdToken id_token; @@ -732,9 +734,10 @@ TEST_F( this->set_local_auth_list_ctrlr_enabled(this->device_model, true); // Explicit config setup for test isolation - set_local_pre_authorize(false); + set_local_pre_authorize(this->device_model, false); ON_CALL(this->evse_security, verify_certificate(_, DEFAULT_LEAF_CERT_TYPE)) + .WillByDefault(Return(ocpp::CertificateValidationResult::Valid)); IdTokenInfo id_token_info_result; @@ -762,7 +765,7 @@ TEST_F(AuthorizationTest, this->set_local_authorize_offline(this->device_model, false); // Explicit config setup for test isolation - set_local_pre_authorize(false); + set_local_pre_authorize(this->device_model, false); std::vector types({ocpp::LeafCertificateType::MO, ocpp::LeafCertificateType::V2G}); ON_CALL(this->evse_security, verify_certificate(_, types)) @@ -1083,8 +1086,9 @@ TEST_F(AuthorizationTest, validate_token_auth_cache_lifetime_expired) { this->disable_remote_authorization(this->device_model, false); // Explicit config setup for test isolation - set_local_pre_authorize(false); - set_local_authorize_offline(false); + set_local_pre_authorize(this->device_model, false); + set_local_authorize_offline(this->device_model, false); + // The websocket is connected. EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true)); From af6de95f2dae6244ba7fb792faddd375d2468ffe Mon Sep 17 00:00:00 2001 From: Stephen Oresanya Date: Mon, 11 Aug 2025 14:19:26 +0100 Subject: [PATCH 3/3] Fix #1042: Pass device_model to set_local_* calls in authorization tests Ensures calls match function definitions by including the device_model argument. Also reformatted with clang-format for CI compliance. Signed-off-by: Stephen Oresanya --- tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp b/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp index 889081084..b0c502280 100644 --- a/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp +++ b/tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp @@ -605,7 +605,6 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_websock // WebSocket is disconnected for this test case EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(false)); - IdTokenInfo id_token_info_result; id_token_info_result.status = AuthorizationStatusEnum::Invalid; @@ -630,8 +629,8 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_connectivity_ma this->disable_remote_authorization(this->device_model, false); // Explicit config setup for test isolation - set_local_pre_authorize(false); - set_local_authorize_offline(false); + set_local_pre_authorize(this->device_model, false); + set_local_authorize_offline(this->device_model, false); // WebSocket is connected EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true)); @@ -1089,7 +1088,6 @@ TEST_F(AuthorizationTest, validate_token_auth_cache_lifetime_expired) { set_local_pre_authorize(this->device_model, false); set_local_authorize_offline(this->device_model, false); - // The websocket is connected. EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true));