From 973254595821cc38157a925f4eb63073722e2f99 Mon Sep 17 00:00:00 2001 From: Nadav Har'El Date: Tue, 3 Jun 2025 11:00:19 +0300 Subject: [PATCH 1/2] test/alternator: fall back to legal-looking access key id When the Alternator tests run against Scylla, they figure out (using CQL) the correct username and password needed to connect. When it can't, we fell back to some silly pair 'unknown_user', 'unknown_secret', assuming that the server won't check it anyway. It turns out that if we want to run tests against new version of DynamoDB Local (Amazon's local mock of DynamoDB), it indeed doesn't authentication, but starting in DynamoDB Local 2.0, it does check that the access key ID (the username) itself is valid, and considers "unknown_user" to be invalid because it contains an underscore - AWS_ACCESS_KEY_ID must only contains letters and numbers. See https://repost.aws/articles/ARc4hEkF9CRgOrw8kSMe6CwQ/ for Amazon's explanation for this change in DynamoDB Local 2. The trivial fix is to remove the underscore from the silly username. After this patch, Alternator tests can connect to DynamoDB Local. They still can't complete correctly - this will be fixed in the next patch. Refs #7775 Signed-off-by: Nadav Har'El --- test/alternator/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/alternator/conftest.py b/test/alternator/conftest.py index f5a169efee..64b17807f3 100644 --- a/test/alternator/conftest.py +++ b/test/alternator/conftest.py @@ -107,7 +107,7 @@ def get_valid_alternator_role(): pass # If we couldn't find a valid role, let's hope that # alternator-enforce-authorization is not enabled so anything will work - return ('unknown_user', 'unknown_secret') + return ('unknownuser', 'unknownsecret') return _get_valid_alternator_role From e32559758a4b592d29a1ed58d832c0e66b5be446 Mon Sep 17 00:00:00 2001 From: Nadav Har'El Date: Tue, 3 Jun 2025 12:16:51 +0300 Subject: [PATCH 2/2] test/alternator: any response from healthcheck means server is alive In the Alternator tests we check (in dynamodb_test_connect()) after every test that the server is still alive, so we can blaim the test that just ran if it crashes the server. We check the server's health using a simple GET response, which works on both DynamoDB and Alternator, e.g., ``` $ curl http://dynamodb.us-east-2.amazonaws.com/ healthy: dynamodb.us-east-2.amazonaws.com ``` However, it turns out that new versions of DynamoDB Local - Amazon's local mock of DynamoDB, for some reason insists that all requests - including this health check - must be signed, so our unsigned health request is rejected with error 400, saying the request must be signed. So the current code which insists that the response have error code 200, fails and the test incorrectly things that DynamoDB Local crashed during the test. The fix is trivial: Just don't check that the error code is 200. Any HTTP response from the server means it is still alive! If the server is not alive, we will get an exception, not any HTTP response, and this will lead the code to the "server has crashed" case. Refs #7775 Signed-off-by: Nadav Har'El --- test/alternator/conftest.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/alternator/conftest.py b/test/alternator/conftest.py index 64b17807f3..fed1b88fec 100644 --- a/test/alternator/conftest.py +++ b/test/alternator/conftest.py @@ -204,7 +204,12 @@ def dynamodb_test_connection(dynamodb, request, optional_rest_api): # URL is the fastest one. url = dynamodb.meta.client._endpoint.host response = requests.get(url, verify=False) - assert response.ok + # We don't check response: In Alternator and DynamoDB, we expect + # response.ok (200), but in recent versions of DynamoDB Local we can + # get error code 400 because it only allows signed health requests + # and gives an invalid signature error on an unsigned get(). + # In any case, any HTTP response (as opposed to exception in get()) + # means that the server is still alive. except: dynamodb_test_connection.scylla_crashed = True pytest.fail(f'Scylla appears to have crashed in test {request.node.parent.name}::{request.node.name}')