Files
scylladb/test/alternator
Nadav Har'El f292d3d679 alternator: make schema modifications in CreateTable atomic
The Alternator CreateTable operation currently performs several schema-
changing operations separately - one by one: It creates a keyspace,
a table in that keyspace and possibly also multiple views, and it sets
tags on the table. A consequence of this is that concurrent CreateTable
and DeleteTable operations (for example) can result in unexpected errors
or inconsistent states - for example CreateTable wants to create the
table in the keyspace it just created, but a concurrent DeleteTable
deleted it. We have two issues about this problem (#6391 and #9868)
and three tests (test_table.py::test_concurrent_create_and_delete_table)
reproducing it.

In this patch we fix these problems by switching to the modern Scylla
schema-changing API: Instead of doing several schema-changing
operations one by one, we create a vector of schema mutation performing
all these operations - and then perform all these mutations together.

When the experimental Raft-based schema modifications is enabled, this
completely solves the races, and the tests begin to pass. However, if
the experimental Raft mode is not enabled, these tests continue to fail
because there is still no locking while applying the different schema
mutations (not even on a single node). So I put a special fixture
"fails_without_raft" on these tests - which means that the tests
xfail if run without raft, and expected to pass when run on Raft.

Indeed, after this patch
test/alternator/run --raft test_table.py::test_concurrent_create_and_delete_table

shows three passing tests (they also pass if we drastically improve the
number of iterations), while
test/alternator/run test_table.py::test_concurrent_create_and_delete_table

shows three xfailing tests.

All other Alternator tests pass as before with this patch, verifying
that the handling of new tables, new views, tags, and CDC log tables,
all happen correctly even after this patch.

A note about the implementation: Before this patch, the CreateTable code
used high-level functions like prepare_new_column_family_announcement().
These high-level functions become unusable if we write multiple schema
operations to one list of mutations, because for example this function
validates that the keyspace had already been created - when it hasn't
and that's the whole point. So instead we had to use lower-level
function like add_table_or_view_to_schema_mutation() and
before_create_column_family(). However, despite being lower level,
these functions were public so I think it's reasonable to use them,
and we probably have no other alternative.

Fixes #6391
Fixes #9868

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
2022-02-18 09:03:52 +02:00
..

Tests for Alternator that should also pass, identically, against DynamoDB.

Tests use the boto3 library for AWS API, and the pytest frameworks (both are available from Linux distributions, or with "pip install").

To run all tests against the local installation of Alternator on http://localhost:8000, just run pytest.

Some additional pytest options:

  • To run all tests in a single file, do pytest test_table.py.
  • To run a single specific test, do pytest test_table.py::test_create_table_unsupported_names.
  • Additional useful pytest options, especially useful for debugging tests:
    • -v: show the names of each individual test running instead of just dots.
    • -s: show the full output of running tests (by default, pytest captures the test's output and only displays it if a test fails)

Add the --aws option to test against AWS instead of the local installation. For example - pytest --aws test_item.py or pytest --aws.

If you plan to run tests against AWS and not just a local Scylla installation, the files ~/.aws/credentials should be configured with your AWS key:

[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

and ~/.aws/config with the default region to use in the test:

[default]
region = us-east-1

HTTPS support

In order to run tests with HTTPS, run pytest with --https parameter. Note that the Scylla cluster needs to be provided with alternator_https_port configuration option in order to initialize a HTTPS server. Moreover, running an instance of a HTTPS server requires a certificate. Here's how to easily generate a key and a self-signed certificate, which is sufficient to run --https tests:

openssl genrsa 2048 > scylla.key
openssl req -new -x509 -nodes -sha256 -days 365 -key scylla.key -out scylla.crt

If this pair is put into conf/ directory, it will be enough to allow the alternator HTTPS server to think it's been authorized and properly certified. Still, boto3 library issues warnings that the certificate used for communication is self-signed, and thus should not be trusted. For the sake of running local tests this warning is explicitly ignored.

Authorization

By default, boto3 prepares a properly signed Authorization header with every request. In order to confirm the authorization, the server recomputes the signature by using user credentials (user-provided username + a secret key known by the server), and then checks if it matches the signature from the header. Early alternator code did not verify signatures at all, which is also allowed by the protocol. A partial implementation of the authorization verification can be allowed by providing a Scylla configuration parameter:

  alternator_enforce_authorization: true

The implementation is currently coupled with Scylla's system_auth.roles table, which means that an additional step needs to be performed when setting up Scylla as the test environment. Tests will use the following credentials: Username: alternator Secret key: secret_pass

With CQLSH, it can be achieved by executing this snipped:

cqlsh -x "INSERT INTO system_auth.roles (role, salted_hash) VALUES ('alternator', 'secret_pass')"

Most tests expect the authorization to succeed, so they will pass even with alternator_enforce_authorization turned off. However, test cases from test_authorization.py may require this option to be turned on, so it's advised.