-
Notifications
You must be signed in to change notification settings - Fork 303
CASSCPP-15: Add support for Cassandra 4.1.x and 5.0 releases to CI #592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,6 +62,7 @@ docs | |
| .#* | ||
| #* | ||
| .clang_complete | ||
| .idea | ||
|
|
||
| # OSX | ||
| .DS_Store | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1488,19 +1488,58 @@ CCM::Bridge::generate_create_updateconf_command(CassVersion cassandra_version) { | |
| updateconf_command.push_back("enable_user_defined_functions:true"); | ||
| } | ||
|
|
||
| // Create Cassandra version specific updated (C* 3.0+) | ||
| if (cassandra_version >= "3.0.0") { | ||
| updateconf_command.push_back("enable_scripted_user_defined_functions:true"); | ||
|
Comment on lines
1488
to
-1493
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't seem to be in option in Cassandra 5.0+ but as far as I can tell we don't actually used scripted UDFs anyways so we can just delete it
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's still defined, it's just been renamed because of the conversion that happened with C* 4.1 (the reason we have to do all this translation. The reference is here. You should be able to keep this in and just let the for loop calling translate_config_for_version() below take care of this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you look at https://apache.googlesource.com/cassandra/+/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java, you'll see enable_scripted_user_defined_functions was actually removed in 5.0+. But like I said we don't use JS UDFs anyways so we don't need it in the first place (of course if I'm wrong do lmk) |
||
| } | ||
|
|
||
| if (cassandra_version >= "4.0.0" && !is_dse()) { | ||
| updateconf_command.push_back("enable_materialized_views:true"); | ||
| updateconf_command.push_back("enable_user_defined_functions:true"); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Boy, there are a lot of hard-coded cassandra.yaml configs that get updated here for very obsolete C* versions. I see fixed config settings for pre-2.0 C*... yikes. Those can all be deleted, or at least the ones for anything before C* 4.0 can be (assuming we're using OSS C* as our minimum here as discussed in another comment). Specifically I'm thinking all of these can be removed and these can just be made part of the default.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol alright will do
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will put this on hold until we decide exactly which versions we want to keep testing against |
||
|
|
||
| for (size_t i = 0; i < updateconf_command.size(); ++i) { | ||
| updateconf_command[i] = translate_config_for_version(updateconf_command[i], cassandra_version); | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Semi-nit: this forces us to loop through the array twice, once when creating it and again to update everything. Maybe just create a helper function which calls
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did that at first but because there's no nested functions and I didn't see lambdas used much in many other areas of the codebase (i.e. so no clean closures or currying) I just stuck with this way because I didn't like having to pass all the context into the translation function at every call. It's not performance sensitive nor is it a lot of elements so it's fine in this context. If we wanted pure performance there's plenty more we could do here beyond solving O(2N) 🙂 |
||
| return updateconf_command; | ||
| } | ||
|
|
||
| std::string CCM::Bridge::translate_config_for_version(const std::string& key_value, | ||
| CassVersion cassandra_version) { | ||
| if (cassandra_version < "4.1.0") { | ||
| return key_value; | ||
| } | ||
|
|
||
| std::size_t separator = key_value.find(':'); | ||
| if (separator == std::string::npos) { | ||
| return key_value; | ||
| } | ||
|
|
||
| std::string key = key_value.substr(0, separator); | ||
| std::string value = key_value.substr(separator + 1); | ||
|
|
||
| if (key.find('.') != std::string::npos) { | ||
| return key_value; | ||
| } | ||
|
|
||
| static const char* SUFFIXES[][2] = { | ||
| { "_in_ms", "ms" }, | ||
| { "_in_mb", "MiB" }, | ||
| { "_mb_per_sec", "MiB/s" } | ||
| }; | ||
|
|
||
| for (const auto& i : SUFFIXES) { | ||
| std::string suffix = i[0]; | ||
| if (key.size() >= suffix.size() && | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed there was are Which I still could if you think it's cleaner to be honest. |
||
| key.compare(key.size() - suffix.size(), suffix.size(), suffix) == 0) { | ||
| return key.substr(0, key.size() - suffix.size()) + ":" + value + i[1]; | ||
| } | ||
| } | ||
|
|
||
| std::string enable_prefix = "enable_"; | ||
| if (key.compare(0, enable_prefix.size(), enable_prefix) == 0) { | ||
| return key.substr(enable_prefix.size()) + "_enabled:" + value; | ||
| } | ||
|
|
||
| return key_value; | ||
| } | ||
|
|
||
| std::string CCM::Bridge::generate_dse_workloads(std::vector<DseWorkload> workloads) { | ||
| std::string dse_workloads; | ||
| for (std::vector<DseWorkload>::iterator iterator = workloads.begin(); iterator != workloads.end(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -947,6 +947,22 @@ class Bridge { | |
| */ | ||
| std::vector<std::string> generate_create_updateconf_command(CassVersion cassandra_version); | ||
|
|
||
| /** | ||
| * Translate a cassandra.yaml "key:value" update pair to the format Cassandra 4.1 | ||
| * introduced (ignoring nested keys) | ||
| * | ||
| * Transformations include: | ||
| * - "_in_*"/"_*_per_sec" suffix -> appending "*[/s]" to the value | ||
| * - "enable_" prefix -> "_enabled" suffix | ||
| * | ||
| * @param key_value Original "key:value" pair | ||
| * @param cassandra_version Cassandra version being used | ||
| * @return The pair translated if renamed and cassandra_version >= 4.1.0; | ||
| * otherwise key_value unchanged | ||
| */ | ||
| std::string translate_config_for_version(const std::string& key_value, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally this would just be a static free-floating function in the
so I just kept it like this for consistency 🤷 |
||
| CassVersion cassandra_version); | ||
|
|
||
| /** | ||
| * Generate the command separated list for have a single or multiple | ||
| * workloads for the CCM setworkload command | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -155,8 +155,13 @@ CASSANDRA_INTEGRATION_TEST_F(SchemaMetadataTest, VirtualMetadata) { | |
| ASSERT_TRUE(table_meta); | ||
| EXPECT_TRUE(table_meta.is_virtual()); | ||
|
|
||
| // Cassandra 4.1 added a `sstables` column and changed `task_id`'s type; | ||
| // later 5.0.x patches add more columns to this table, so for future compatibility, | ||
| // column count is a floor, not an exact match, from 4.1 onward | ||
| bool is_4_1_or_later = server_version_ >= "4.1.0"; | ||
|
|
||
| // Verify virtual table's metadata | ||
| EXPECT_EQ(cass_table_meta_column_count(table_meta.get()), 8u); | ||
| EXPECT_GE(cass_table_meta_column_count(table_meta.get()), is_4_1_or_later ? 9u : 8u); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it was 10 columns for 5.x iirc? Either way I didn't find it very productive to essentially just map every cassandra version to the number of columns for a table for just a single test 🤷
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we have three different answers (one for 5.0.x, one for 4.1.x and one for anything earlier) it might make sense to bump this to a helper function which returns the expected value... I think that was done for one of the other drivers (although I can't find it right now). If it's just a choice between 8 or 9 then yeah, I don't think a helper function is really necessary here; this code seems pretty clear as it stands.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought of this but wasn't sure if it was worth adding conditional test cases for each version because that could arguably be a slippery slope in terms of maintainability. If you think it's worth it for the sake of completeness then I could still do so, your call here |
||
| EXPECT_EQ(cass_table_meta_index_count(table_meta.get()), 0u); | ||
| EXPECT_EQ(cass_table_meta_materialized_view_count(table_meta.get()), 0u); | ||
|
|
||
|
|
@@ -178,7 +183,8 @@ CASSANDRA_INTEGRATION_TEST_F(SchemaMetadataTest, VirtualMetadata) { | |
|
|
||
| column_meta = cass_table_meta_column_by_name(table_meta.get(), "task_id"); | ||
| ASSERT_TRUE(column_meta); | ||
| EXPECT_EQ(cass_data_type_type(cass_column_meta_data_type(column_meta)), CASS_VALUE_TYPE_UUID); | ||
| EXPECT_EQ(cass_data_type_type(cass_column_meta_data_type(column_meta)), | ||
| is_4_1_or_later ? CASS_VALUE_TYPE_TIMEUUID : CASS_VALUE_TYPE_UUID); | ||
|
|
||
| column_meta = cass_table_meta_column_by_name(table_meta.get(), "kind"); | ||
| ASSERT_TRUE(column_meta); | ||
|
|
@@ -195,4 +201,10 @@ CASSANDRA_INTEGRATION_TEST_F(SchemaMetadataTest, VirtualMetadata) { | |
| column_meta = cass_table_meta_column_by_name(table_meta.get(), "unit"); | ||
| ASSERT_TRUE(column_meta); | ||
| EXPECT_EQ(cass_data_type_type(cass_column_meta_data_type(column_meta)), CASS_VALUE_TYPE_TEXT); | ||
|
|
||
| if (is_4_1_or_later) { | ||
| column_meta = cass_table_meta_column_by_name(table_meta.get(), "sstables"); | ||
| ASSERT_TRUE(column_meta); | ||
| EXPECT_EQ(cass_data_type_type(cass_column_meta_data_type(column_meta)), CASS_VALUE_TYPE_INT); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure which exact versions we want to test so I just left them all here for now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We normally aim to support platforms (operating systems, JDK versions, Python runtimes etc.) that aren't EOL at time of release. That policy doesn't apply directly to the underlying Cassandra version but in practice we basically do the same. So Java currently supports C* 4.0 and up (since everything older is EOL) and my plan was to do the same here.
DSE certainly complicates that story. I haven't done a look recently to see where we stand on supported DSE versions but I think DSE 5.1, 6.8 and prolly 6.9 is likely adequate. Would be nice if we could get HCD 1.0 in there as well... did you do any testing with that?