diff --git a/Jenkinsfile b/Jenkinsfile index 8ad772ffc..4b9fc80e9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -129,13 +129,26 @@ CCM_CASSANDRA_VERSION=${DSE_FIXED_VERSION} # maintain for backwards compatibilit CCM_VERSION=${DSE_FIXED_VERSION} CCM_SERVER_TYPE=dse DSE_VERSION=${DSE_FIXED_VERSION} -CCM_IS_DSE=true +CCM_DISTRIBUTION=dse +CASSANDRA_VERSION=${DSE_FIXED_VERSION} CCM_BRANCH=${DSE_FIXED_VERSION} DSE_BRANCH=${DSE_FIXED_VERSION} JDK=1.8 ENVIRONMENT_EOF ''' } + + if (env.SERVER_VERSION.split('-')[0] == 'hcd') { + env.HCD_FIXED_VERSION = env.SERVER_VERSION.split('-')[1] + sh label: 'Update environment for HCD', script: '''#!/bin/bash -le + cat >> ${HOME}/environment.txt << ENVIRONMENT_EOF +CCM_PATH=${HOME}/ccm +CCM_CASSANDRA_VERSION=${HCD_FIXED_VERSION} # maintain for backwards compatibility +CASSANDRA_VERSION=${HCD_FIXED_VERSION} +CCM_DISTRIBUTION=hcd +ENVIRONMENT_EOF + ''' + } if (env.SERVER_VERSION == env.SERVER_VERSION_SNI && env.DOTNET_VERSION != 'mono') { sh label: 'Update environment for SNI proxy tests', script: '''#!/bin/bash -le @@ -432,13 +445,13 @@ pipeline { axes { axis { name 'SERVER_VERSION' - values '3.0', // latest 3.0.x Apache Cassandra� - '3.11', // latest 3.11.x Apache Cassandra� - '4.0', // latest 4.0.x Apache Cassandra� - '5.0-beta1', // Development Apache Cassandra� + values '3.11', // latest 3.11.x Apache Cassandra� + '4.1', // latest 4.x Apache Cassandra� + '5.0', // Development Apache Cassandra� 'dse-5.1.35', // latest 5.1.x DataStax Enterprise - 'dse-6.7.17', // latest 6.7.x DataStax Enterprise - 'dse-6.8.30' // 6.8 current DataStax Enterprise + 'dse-6.8.30', // latest 6.7.x DataStax Enterprise + 'dse-6.9.3', // latest DataStax Enterprise + 'hcd-1.0.0' // Hyper-Converged Database } axis { name 'DOTNET_VERSION' @@ -449,11 +462,11 @@ pipeline { exclude { axis { name 'DOTNET_VERSION' - values 'mono', 'net8' + values 'mono' } axis { name 'SERVER_VERSION' - values '3.0', '5.0-beta1', 'dse-5.1.35', 'dse-6.8.30' + values '3.11', '4.1', 'dse-5.1.35', 'dse-6.8.30' } } exclude { @@ -463,7 +476,7 @@ pipeline { } axis { name 'SERVER_VERSION' - values 'dse-6.7.17', '3.11' + values '3.11', '5.0', 'dse-6.9.3', 'hcd-1.0.0' } } } diff --git a/Jenkinsfile.scheduled b/Jenkinsfile.scheduled index 32c3d582c..581bd4f49 100644 --- a/Jenkinsfile.scheduled +++ b/Jenkinsfile.scheduled @@ -128,13 +128,26 @@ CCM_CASSANDRA_VERSION=${DSE_FIXED_VERSION} # maintain for backwards compatibilit CCM_VERSION=${DSE_FIXED_VERSION} CCM_SERVER_TYPE=dse DSE_VERSION=${DSE_FIXED_VERSION} -CCM_IS_DSE=true +CCM_DISTRIBUTION=dse +CASSANDRA_VERSION=${DSE_FIXED_VERSION} CCM_BRANCH=${DSE_FIXED_VERSION} DSE_BRANCH=${DSE_FIXED_VERSION} JDK=1.8 ENVIRONMENT_EOF ''' } + + if (env.SERVER_VERSION.split('-')[0] == 'hcd') { + env.HCD_FIXED_VERSION = env.SERVER_VERSION.split('-')[1] + sh label: 'Update environment for HCD', script: '''#!/bin/bash -le + cat >> ${HOME}/environment.txt << ENVIRONMENT_EOF +CCM_PATH=${HOME}/ccm +CCM_CASSANDRA_VERSION=${HCD_FIXED_VERSION} # maintain for backwards compatibility +CASSANDRA_VERSION=${HCD_FIXED_VERSION} +CCM_DISTRIBUTION=hcd +ENVIRONMENT_EOF + ''' + } if (env.SERVER_VERSION == env.SERVER_VERSION_SNI && env.DOTNET_VERSION != 'mono') { sh label: 'Update environment for SNI proxy tests', script: '''#!/bin/bash -le @@ -465,12 +478,15 @@ pipeline { '2.2', // Legacy Apache Cassandra� '3.0', // Previous Apache Cassandra� '3.11', // latest 3.11.x Apache Cassandra� - '4.0', // latest 4.0.x Apache Cassandra� - '5.0-beta1', // Development Apache Cassandra� + '4.0', // Previous 4.0.x Apache Cassandra� + '4.1', // Latest 4.1.x Apache Cassandra� + '5.0', // Development Apache Cassandra� 'dse-5.1.35', // Legacy DataStax Enterprise 'dse-6.0.18', // Previous DataStax Enterprise - 'dse-6.7.17', // Current DataStax Enterprise - 'dse-6.8.30' // Current DataStax Enterprise + 'dse-6.7.17', // Previous DataStax Enterprise + 'dse-6.8.30', // Previous DataStax Enterprise + 'dse-6.9.3', // Latest DataStax Enterprise + 'hcd-1.0.0' // Hyper-Converged Database } axis { name 'DOTNET_VERSION' @@ -495,7 +511,7 @@ pipeline { } axis { name 'SERVER_VERSION' - values '2.1', '2.2', '3.0', '5.0-beta1', 'dse-5.1.35', 'dse-6.0.18' + values '2.1', '2.2', '3.0', '5.0', 'dse-5.1.35', 'dse-6.0.18' } } exclude { @@ -593,8 +609,9 @@ pipeline { values '2.1', // Legacy Apache Cassandra� '2.2', // Legacy Apache Cassandra� '3.11', // latest 3.11.x Apache Cassandra� - '4.0' // latest 4.0.x Apache Cassandra� - '5.0-beta1' // Development Apache Cassandra� + '4.0', // latest 4.0.x Apache Cassandra� + '4.1', // latest 4.1.x Apache Cassandra� + '5.0' // Development Apache Cassandra� } axis { name 'DOTNET_VERSION' @@ -629,7 +646,7 @@ pipeline { } axis { name 'SERVER_VERSION' - values '2.1', '2.2', '5.0-beta1' + values '2.1', '2.2', '5.0' } } } @@ -707,13 +724,17 @@ pipeline { name 'SERVER_VERSION' values '2.1', // Legacy Apache Cassandra� '2.2', // Legacy Apache Cassandra� + '3.0', // Previous Apache Cassandra� '3.11', // latest 3.11.x Apache Cassandra� - '4.0', // latest 4.0.x Apache Cassandra� - '5.0-beta1', // latest 4.0.x Apache Cassandra� + '4.0', // Previous 4.0.x Apache Cassandra� + '4.1', // Latest 4.1.x Apache Cassandra� + '5.0', // Development Apache Cassandra� 'dse-5.1.35', // Legacy DataStax Enterprise 'dse-6.0.18', // Previous DataStax Enterprise - 'dse-6.7.17', // Current DataStax Enterprise - 'dse-6.8.30' // Current DataStax Enterprise + 'dse-6.7.17', // Previous DataStax Enterprise + 'dse-6.8.30', // Previous DataStax Enterprise + 'dse-6.9.3', // Latest DataStax Enterprise + 'hcd-1.0.0' // Hyper-Converged Database } axis { name 'DOTNET_VERSION' @@ -728,7 +749,7 @@ pipeline { } axis { name 'SERVER_VERSION' - values '2.1', '2.2', 'dse-6.0.18', 'dse-5.1.35', '5.0-beta1' + values '2.1', '2.2', 'dse-6.0.18', 'dse-5.1.35', '5.0' } } exclude { @@ -817,8 +838,9 @@ pipeline { values '2.1', // Legacy Apache Cassandra� '2.2', // Legacy Apache Cassandra� '3.11', // latest 3.11.x Apache Cassandra� - '4.0' // latest 4.0.x Apache Cassandra� - '5.0-beta1' // Development Apache Cassandra� + '4.0', // latest 4.0.x Apache Cassandra� + '4.1', // latest 4.1.x Apache Cassandra� + '5.0' // Development Apache Cassandra� } axis { name 'DOTNET_VERSION' @@ -833,7 +855,7 @@ pipeline { } axis { name 'SERVER_VERSION' - values '2.1', '5.0-beta1' + values '2.1', '5.0' } } exclude { diff --git a/src/Cassandra.IntegrationTests/Core/PagingTests.cs b/src/Cassandra.IntegrationTests/Core/PagingTests.cs index f62108e29..2bdf05a8e 100644 --- a/src/Cassandra.IntegrationTests/Core/PagingTests.cs +++ b/src/Cassandra.IntegrationTests/Core/PagingTests.cs @@ -126,7 +126,7 @@ public void Should_PagingOnBoundStatement_When_ReceivedNumberOfRowsIsOne() } [Test] - [TestCassandraVersion(4, 0)] + [TestBothServersVersion(4, 0, 6, 0)] public void Should_PagingOnBoundStatement_When_NewResultMetadataIsSet() { if (Session.Cluster.Metadata.ControlConnection.Serializer.CurrentProtocolVersion < ProtocolVersion.V5) diff --git a/src/Cassandra.IntegrationTests/Core/ParameterizedStatementsTests.cs b/src/Cassandra.IntegrationTests/Core/ParameterizedStatementsTests.cs index b3d8c586d..665c43e1b 100644 --- a/src/Cassandra.IntegrationTests/Core/ParameterizedStatementsTests.cs +++ b/src/Cassandra.IntegrationTests/Core/ParameterizedStatementsTests.cs @@ -50,7 +50,9 @@ protected override string[] SetupQueries } }; - if (TestClusterManager.CheckCassandraVersion(false, new Version(4, 0), Comparison.LessThan)) + // COMPACT STORAGE is not supported by DSE 6.0 / C* 4.0. + if (TestClusterManager.CheckCassandraVersion(true, new Version(4, 0), Comparison.LessThan) || + (TestClusterManager.IsDse && TestClusterManager.CheckDseVersion(new Version(6, 0), Comparison.LessThan))) { setupQueries.Add($"CREATE TABLE {TableCompactStorage} (key blob PRIMARY KEY, bar int, baz uuid)" + $" WITH COMPACT STORAGE"); @@ -517,7 +519,7 @@ public void SimpleStatement_Dictionary_Parameters_CaseInsensitivity_ExcessOfPara } [Test] - [TestCassandraVersion(4, 0)] + [TestBothServersVersion(4, 0, 6, 0)] public void SimpleStatement_With_Keyspace_Defined_On_Protocol_Greater_Than_4() { if (Session.Cluster.Metadata.ControlConnection.Serializer.CurrentProtocolVersion < ProtocolVersion.V5) @@ -535,7 +537,7 @@ public void SimpleStatement_With_Keyspace_Defined_On_Protocol_Greater_Than_4() } [Test] - [TestCassandraVersion(4, 0, Comparison.LessThan)] + [TestBothServersVersion(4, 0, 5,1, Comparison.LessThan)] public void SimpleStatement_With_Keyspace_Defined_On_Lower_Protocol_Versions() { // It should fail as the keyspace from the session will be used @@ -547,9 +549,11 @@ public void SimpleStatement_With_Keyspace_Defined_On_Lower_Protocol_Versions() [TestCassandraVersion(3, 11)] public void SimpleStatement_With_No_Compact_Enabled_Should_Reveal_Non_Schema_Columns() { - if (TestClusterManager.CheckCassandraVersion(false, new Version(4, 0), Comparison.GreaterThanOrEqualsTo)) + if (TestClusterManager.CheckCassandraVersion(true, new Version(4, 0), Comparison.GreaterThanOrEqualsTo) || + (TestClusterManager.IsDse && TestClusterManager.CheckDseVersion(new Version(6, 0), Comparison.GreaterThanOrEqualsTo)) || + TestClusterManager.IsHcd) { - Assert.Ignore("COMPACT STORAGE is only supported by C* versions prior to 4.0"); + Assert.Ignore("COMPACT STORAGE is not supported by DSE 6.0 / C* 4.0"); return; } @@ -568,9 +572,11 @@ public void SimpleStatement_With_No_Compact_Enabled_Should_Reveal_Non_Schema_Col [TestCassandraVersion(3, 11)] public void SimpleStatement_With_No_Compact_Disabled_Should_Not_Reveal_Non_Schema_Columns() { - if (TestClusterManager.CheckCassandraVersion(false, new Version(4, 0), Comparison.GreaterThanOrEqualsTo)) + if (TestClusterManager.CheckCassandraVersion(true, new Version(4, 0), Comparison.GreaterThanOrEqualsTo) || + (TestClusterManager.IsDse && TestClusterManager.CheckDseVersion(new Version(6, 0), Comparison.GreaterThanOrEqualsTo)) || + TestClusterManager.IsHcd) { - Assert.Ignore("COMPACT STORAGE is only supported by C* versions prior to 4.0"); + Assert.Ignore("COMPACT STORAGE is not supported by DSE 6.0 / C* 4.0"); return; } diff --git a/src/Cassandra.IntegrationTests/Core/PreparedStatementsTests.cs b/src/Cassandra.IntegrationTests/Core/PreparedStatementsTests.cs index 659ecf4da..ae4762c7f 100644 --- a/src/Cassandra.IntegrationTests/Core/PreparedStatementsTests.cs +++ b/src/Cassandra.IntegrationTests/Core/PreparedStatementsTests.cs @@ -825,7 +825,7 @@ public void Bound_TinyInt_Tests() [TestCase(true)] [TestCase(false)] - [TestCassandraVersion(4, 0)] + [TestBothServersVersion(4,0,5,1)] public void Session_Prepare_With_Keyspace_Defined_On_Protocol_Greater_Than_4(bool usePayload) { if (Session.Cluster.Metadata.ControlConnection.Serializer.CurrentProtocolVersion < ProtocolVersion.V5) @@ -858,7 +858,7 @@ public void Session_Prepare_With_Keyspace_Defined_On_Protocol_Greater_Than_4(boo [TestCase(true)] [TestCase(false)] - [TestCassandraVersion(4, 0)] + [TestBothServersVersion(4,0,5,1)] public async Task Session_PrepareAsync_With_Keyspace_Defined_On_Protocol_Greater_Than_4(bool usePayload) { if (Session.Cluster.Metadata.ControlConnection.Serializer.CurrentProtocolVersion < ProtocolVersion.V5) @@ -891,14 +891,14 @@ await TestHelper.TimesLimit(async () => } [Test] - [TestCassandraVersion(4, 0)] + [TestBothServersVersion(4,0,5,1)] public void Session_Prepare_With_Keyspace_Defined_On_Protocol_V4() { TestKeyspaceInPrepareNotSupported(true); } [Test] - [TestCassandraVersion(4, 0, Comparison.LessThan)] + [TestBothServersVersion(4, 0, 5,1, Comparison.LessThan)] public void Session_Prepare_With_Keyspace_Defined_On_Previuos_Cassandra_Versions() { TestKeyspaceInPrepareNotSupported(false); @@ -1085,7 +1085,7 @@ public void Batch_PreparedStatements_NotSupportedInC1_2() } [Test] - [TestCassandraVersion(4, 0)] + [TestBothServersVersion(4,0,5,1)] public void BatchStatement_With_Keyspace_Defined_On_Protocol_Greater_Than_4() { using (var cluster = ClusterBuilder().AddContactPoint(TestClusterManager.InitialContactPoint).Build()) @@ -1111,7 +1111,7 @@ public void BatchStatement_With_Keyspace_Defined_On_Protocol_Greater_Than_4() } [Test] - [TestCassandraVersion(4, 0, Comparison.LessThan)] + [TestBothServersVersion(4, 0, 5,1, Comparison.LessThan)] public void BatchStatement_With_Keyspace_Defined_On_Lower_Protocol_Versions() { using (var cluster = ClusterBuilder().AddContactPoint(TestClusterManager.InitialContactPoint).Build()) diff --git a/src/Cassandra.IntegrationTests/Core/SchemaMetadataTests.cs b/src/Cassandra.IntegrationTests/Core/SchemaMetadataTests.cs index 35b1f6e8f..89accff5f 100644 --- a/src/Cassandra.IntegrationTests/Core/SchemaMetadataTests.cs +++ b/src/Cassandra.IntegrationTests/Core/SchemaMetadataTests.cs @@ -34,11 +34,8 @@ public SchemaMetadataTests() : base(() => { string[] cassandraYaml = null; - if (TestClusterManager.CheckCassandraVersion(true, new Version(5, 0), Comparison.GreaterThanOrEqualsTo)) - { - cassandraYaml = new[] { "materialized_views_enabled: true" }; - } - else if (TestClusterManager.CheckCassandraVersion(true, new Version(4, 0), Comparison.GreaterThanOrEqualsTo)) + if (TestClusterManager.CheckCassandraVersion(true, new Version(4, 0), Comparison.GreaterThanOrEqualsTo) || + TestClusterManager.IsHcd) { cassandraYaml = new[] { "enable_materialized_views: true" }; } @@ -664,11 +661,13 @@ public void RaiseErrorOnInvalidMultipleSecondaryIndexTest(bool metadataSync) [Test, TestCase(true), TestCase(false), TestCassandraVersion(3, 0)] public void ColumnClusteringOrderReversedTest(bool metadataSync) { - if (TestClusterManager.CheckCassandraVersion(false, new Version(4, 0), Comparison.GreaterThanOrEqualsTo)) + if (TestClusterManager.CheckCassandraVersion(true, new Version(4, 0), Comparison.GreaterThanOrEqualsTo) || + (TestClusterManager.IsDse && TestClusterManager.CheckDseVersion(new Version(6, 0), Comparison.GreaterThanOrEqualsTo))) { - Assert.Ignore("Compact table test designed for C* 3.0"); + Assert.Ignore("COMPACT STORAGE is not supported by DSE 6.0 / C* 4.0"); return; } + var keyspaceName = TestUtils.GetUniqueKeyspaceName(); var tableName = TestUtils.GetUniqueTableName().ToLower(); var cluster = GetNewTemporaryCluster(builder => builder.WithMetadataSyncOptions(new MetadataSyncOptions().SetMetadataSyncEnabled(metadataSync))); diff --git a/src/Cassandra.IntegrationTests/Core/TypeSerializersTests.cs b/src/Cassandra.IntegrationTests/Core/TypeSerializersTests.cs index a003c13fb..2210b101a 100644 --- a/src/Cassandra.IntegrationTests/Core/TypeSerializersTests.cs +++ b/src/Cassandra.IntegrationTests/Core/TypeSerializersTests.cs @@ -235,7 +235,7 @@ public void Should_Use_Custom_TypeSerializers() } } - [Test, TestCassandraVersion(4, 0, Comparison.LessThan)] + [Test, TestBothServersVersion(4, 0, 5,1, Comparison.LessThan)] public void DynamicCompositeTypeTest() { string uniqueTableName = TestUtils.GetUniqueTableName(); @@ -371,7 +371,7 @@ private static IEnumerable VectorTestCaseData() }; } - [Test, TestBothServersVersion(5, 0, 6, 9), TestCaseSource(nameof(VectorTestCaseData))] + [Test, TestCassandraVersion(5, 0), TestCaseSource(nameof(VectorTestCaseData))] public void VectorSimpleStatementTest(string cqlSubType, Func elementGeneratorFn, Action assertFn) { SetupVectorUdtSchema(); @@ -392,7 +392,7 @@ public void VectorSimpleStatementTest(string cqlSubType, Func elementGener vectorSimpleStmtTestFn((i, v) => new SimpleStatement(new Dictionary { { "idx", i }, { "vec", v } }, $"INSERT INTO {tableName} (i, j) VALUES (:idx, :vec)")); } - [Test, TestBothServersVersion(5, 0, 6, 9), TestCaseSource(nameof(VectorTestCaseData))] + [Test, TestCassandraVersion(5, 0), TestCaseSource(nameof(VectorTestCaseData))] public void VectorSimpleStatementTestComplex(string cqlSubType, Func elementGeneratorFn, Action assertFn) { SetupVectorUdtSchema(); @@ -429,7 +429,7 @@ public void VectorSimpleStatementTestComplex(string cqlSubType, Func eleme $"INSERT INTO {tableNameComplex} (i, k, l) VALUES (:idx, :vec, :vecc)")); } - [Test, TestBothServersVersion(5, 0, 6, 9), TestCaseSource(nameof(VectorTestCaseData))] + [Test, TestCassandraVersion(5, 0), TestCaseSource(nameof(VectorTestCaseData))] public void VectorPreparedStatementTest(string cqlSubType, Func elementGeneratorFn, Action assertFn) { SetupVectorUdtSchema(); @@ -453,7 +453,7 @@ public void VectorPreparedStatementTest(string cqlSubType, Func elementGen vectorPreparedStmtTestFn($"INSERT INTO {tableName} (i, j) VALUES (:idx, :vec)", (i, v, ps) => ps.Bind(new { idx = i, vec = v })); } - [Test, TestBothServersVersion(5, 0, 6, 9), TestCaseSource(nameof(VectorTestCaseData))] + [Test, TestCassandraVersion(5, 0), TestCaseSource(nameof(VectorTestCaseData))] public void VectorPreparedStatementTestComplex(string cqlSubType, Func elementGeneratorFn, Action assertFn) { SetupVectorUdtSchema(); @@ -498,7 +498,7 @@ public void VectorPreparedStatementTestComplex(string cqlSubType, Func ele )); } - [Test, TestBothServersVersion(5, 0, 6, 9), TestCaseSource(nameof(VectorTestCaseData))] + [Test, TestCassandraVersion(5, 0), TestCaseSource(nameof(VectorTestCaseData))] public void VectorTestCollectionConversion(string cqlSubType, Func elementGeneratorFn, Action assertFn) { SetupVectorUdtSchema(); @@ -534,7 +534,7 @@ public void VectorTestCollectionConversion(string cqlSubType, Func element vectorPreparedStmtTestFn($"INSERT INTO {tableName} (i, j) VALUES (:idx, :vec)", (i, v, ps) => ps.Bind(new { idx = i, vec = v })); } - [Test, TestBothServersVersion(5, 0, 6, 9), TestCaseSource(nameof(VectorTestCaseData))] + [Test, TestCassandraVersion(5, 0), TestCaseSource(nameof(VectorTestCaseData))] public void VectorTestCollectionConversionComplex(string cqlSubType, Func elementGeneratorFn, Action assertFn) { SetupVectorUdtSchema(); @@ -596,6 +596,34 @@ public void VectorTestCollectionConversionComplex(string cqlSubType, Func )); } + [Test] + [TestDseVersion(6, 9)] + public void VectorFloatTest() + { + var tableName = TestUtils.GetUniqueTableName(); + Session.Execute($"CREATE TABLE {tableName} (i int PRIMARY KEY, j vector)"); + + var vector = new CqlVector(1.1f, 2.2f, 3.3f); + + // Simple insert and select + Session.Execute(new SimpleStatement($"INSERT INTO {tableName} (i, j) VALUES (1, ?)", vector)); + var rs = Session.Execute($"SELECT * FROM {tableName} WHERE i = 1"); + AssertSimpleVectorTest(vector, rs, Assert.AreEqual); + + // Prepared insert and select + var ps = Session.Prepare($"INSERT INTO {tableName} (i, j) VALUES (?, ?)"); + Session.Execute(ps.Bind(2, vector)); + rs = Session.Execute($"SELECT * FROM {tableName} WHERE i = 2"); + AssertSimpleVectorTest(vector, rs, Assert.AreEqual); + + // throw when length is not 3 + Assert.Throws(() => + { + var shortVector = new CqlVector(1.1f, 2.2f); + Session.Execute(new SimpleStatement($"INSERT INTO {tableName} (i, j) VALUES (3, ?)", shortVector)); + }); + } + private void AssertSimpleVectorTest(CqlVector expected, RowSet rs, Action assertFn) { var rowList = rs.ToList(); diff --git a/src/Cassandra.IntegrationTests/Core/UdfTests.cs b/src/Cassandra.IntegrationTests/Core/UdfTests.cs index c14cb094b..3dc772933 100644 --- a/src/Cassandra.IntegrationTests/Core/UdfTests.cs +++ b/src/Cassandra.IntegrationTests/Core/UdfTests.cs @@ -50,13 +50,14 @@ public void TestFixtureSetup() { return; } - _testCluster = TestClusterManager.GetTestCluster(1, 0, false, DefaultMaxClusterCreateRetries, false, false); - var cassandraYaml = "enable_user_defined_functions: true"; - if (TestClusterManager.CheckCassandraVersion(true, Version.Parse("5.0"), Comparison.GreaterThanOrEqualsTo)) + + if (TestClusterManager.IsHcd) { - cassandraYaml = "user_defined_functions_enabled: true"; + Assert.Ignore("Skipping UDF tests on HCD due to DSP-24606. See CSHARP-1020."); + return; } - _testCluster.UpdateConfig(cassandraYaml); + _testCluster = TestClusterManager.GetTestCluster(1, 0, false, DefaultMaxClusterCreateRetries, false, false); + _testCluster.UpdateConfig("enable_user_defined_functions:true"); _testCluster.Start(1); using (var cluster = ClusterBuilder().AddContactPoint(_testCluster.InitialContactPoint).Build()) { @@ -159,7 +160,7 @@ public void GetFunction_Should_Retrieve_Metadata_Of_Cql_Function_Without_Paramet Assert.AreEqual(false, func.CalledOnNullInput); Assert.False(func.Monotonic); Assert.False(func.Deterministic); - Assert.AreEqual(func.MonotonicOn, new string[0]); + Assert.AreEqual(new string[0], func.MonotonicOn); } [Test, TestCase(true), TestCase(false), TestCassandraVersion(2, 2)] diff --git a/src/Cassandra.IntegrationTests/Linq/LinqRealClusterTests.cs b/src/Cassandra.IntegrationTests/Linq/LinqRealClusterTests.cs index 7348d1a2d..264202b7a 100644 --- a/src/Cassandra.IntegrationTests/Linq/LinqRealClusterTests.cs +++ b/src/Cassandra.IntegrationTests/Linq/LinqRealClusterTests.cs @@ -407,7 +407,7 @@ public void CreateTable_With_Vectors() Assert.Throws(() => table.Create()); } - [Test, TestBothServersVersion(5, 0, 6, 9)] + [Test, TestCassandraVersion(5, 0)] [TestCase(true)] [TestCase(false)] public void LinqWhere_WithVectors(bool withMapConfig) diff --git a/src/Cassandra.IntegrationTests/TestBase/TestDseVersion.cs b/src/Cassandra.IntegrationTests/TestBase/TestCassandraVersion.cs similarity index 76% rename from src/Cassandra.IntegrationTests/TestBase/TestDseVersion.cs rename to src/Cassandra.IntegrationTests/TestBase/TestCassandraVersion.cs index b5303b433..46db8b158 100644 --- a/src/Cassandra.IntegrationTests/TestBase/TestDseVersion.cs +++ b/src/Cassandra.IntegrationTests/TestBase/TestCassandraVersion.cs @@ -24,7 +24,7 @@ namespace Cassandra.IntegrationTests.TestBase /// /// An attribute that filters the test to execute according to the current DSE version. /// - public class TestDseVersion : NUnitAttribute, IApplyToTest + public class TestCassandraVersion : NUnitAttribute, IApplyToTest { public int Major { get; set; } @@ -37,35 +37,35 @@ public class TestDseVersion : NUnitAttribute, IApplyToTest private bool IsOssRequired { get; set; } /// - /// Creates an instance of an attribute that filters the test to execute according to the current DSE version + /// Creates an instance of an attribute that filters the test to execute according to the current Cassandra version /// being used. /// /// Major version /// Minor version /// - /// Determines if the DSE version required should be "greater or equals to" = 1, + /// Determines if the Cassandra version required should be "greater or equals to" = 1, /// "equals to" = 0, "less than or equal to " = -1 /// /// Whether OSS C* is required. - public TestDseVersion(int major, int minor, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) + public TestCassandraVersion(int major, int minor, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) : this(major, minor, 0, comparison, isOssRequired) { } /// - /// Creates an instance of an attribute that filters the test to execute according to the current DSE version + /// Creates an instance of an attribute that filters the test to execute according to the current Cassandra version /// being used. /// /// Major version /// Minor version /// Build version /// - /// Determines if the DSE version required should be "greater or equals to" = 1, + /// Determines if the Cassandra version required should be "greater or equals to" = 1, /// "equals to" = 0, "less than or equal to " = -1 /// /// Whether OSS C* is required. - public TestDseVersion(int major, int minor, int build, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) + public TestCassandraVersion(int major, int minor, int build, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) { Major = major; Minor = minor; @@ -73,34 +73,25 @@ public TestDseVersion(int major, int minor, int build, Comparison comparison = C Comparison = comparison; IsOssRequired = isOssRequired; } - - /// - /// Gets the DSE version that should be used to compare against the running version. - /// - protected virtual Version GetExpectedServerVersion() - { - return new Version(Major, Minor, Build); - } - + protected virtual bool IsDseRequired() { - return true; + return false; } public void ApplyToTest(NUnit.Framework.Internal.Test test) { - var expectedVersion = GetExpectedServerVersion(); - if (!Applies(out var msg)) + if (!Applies(out string msg)) { test.RunState = RunState.Ignored; var message = msg; test.Properties.Set("_SKIPREASON", message); } } - + public bool Applies(out string msg) { - var expectedVersion = GetExpectedServerVersion(); + var expectedVersion = new Version(Major, Minor, Build); return TestDseVersion.VersionMatch(expectedVersion, IsDseRequired(), IsOssRequired, Comparison, out msg); } @@ -109,7 +100,7 @@ public static bool VersionMatch(Version expectedVersion, bool requiresDse, bool if (TestClusterManager.IsDse && requiresOss) { message = string.Format("Test designed to run with OSS {0} v{1} (executing DSE {2})", - TestDseVersion.GetComparisonText(comparison), + TestCassandraVersion.GetComparisonText(comparison), expectedVersion, TestClusterManager.DseVersion); return false; @@ -117,16 +108,24 @@ public static bool VersionMatch(Version expectedVersion, bool requiresDse, bool if (!TestClusterManager.IsDse && requiresDse) { - message = $"Test designed to run with DSE {TestDseVersion.GetComparisonText(comparison)} " + - $"v{expectedVersion} (executing OSS {TestClusterManager.CassandraVersion})"; + message = $"Test designed to run with DSE {TestCassandraVersion.GetComparisonText(comparison)} " + + $"v{expectedVersion} (executing {TestClusterManager.CassandraVersion})"; return false; } - var executingVersion = TestClusterManager.IsDse ? TestClusterManager.DseVersion : TestClusterManager.CassandraVersion; - if (!TestDseVersion.VersionMatch(expectedVersion, executingVersion, comparison)) + var executingVersion = requiresDse ? TestClusterManager.DseVersion : TestClusterManager.CassandraVersion; + if (!TestCassandraVersion.VersionMatch(expectedVersion, executingVersion, comparison)) { - message = - $"Test designed to run with DSE {TestDseVersion.GetComparisonText(comparison)} v{expectedVersion} (executing {executingVersion})"; + if (requiresDse) + { + message = + $"Test designed to run with DSE {TestCassandraVersion.GetComparisonText(comparison)} v{expectedVersion} (executing {executingVersion})"; + } + else + { + message = + $"Test designed to run with Cassandra {TestCassandraVersion.GetComparisonText(comparison)} v{expectedVersion} (executing {executingVersion})"; + } return false; } @@ -136,7 +135,7 @@ public static bool VersionMatch(Version expectedVersion, bool requiresDse, bool public static bool VersionMatch(Version expectedVersion, bool requiresDse, bool requiresOss, Comparison comparison) { - return TestDseVersion.VersionMatch(expectedVersion, requiresDse, requiresOss, comparison, out _); + return TestCassandraVersion.VersionMatch(expectedVersion, requiresDse, requiresOss, comparison, out _); } public static bool VersionMatch(Version expectedVersion, Version executingVersion, Comparison comparison) @@ -201,27 +200,19 @@ private static string GetComparisonText(Comparison comparison) /// /// An attribute that filters the test to execute according to the current Cassandra version of the DSE version. /// - public class TestCassandraVersion : TestDseVersion + public class TestDseVersion : TestCassandraVersion { - protected override Version GetExpectedServerVersion() - { - var version = new Version(Major, Minor, Build); - return TestClusterManager.IsDse - ? TestClusterManager.GetDseVersionFromCassandraVersion(version) - : version; - } - protected override bool IsDseRequired() { - return false; + return true; } - public TestCassandraVersion( + public TestDseVersion( int major, int minor, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) : base(major, minor, comparison, isOssRequired) { } - public TestCassandraVersion(int major, int minor, int build, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) : base(major, minor, build, comparison, isOssRequired) + public TestDseVersion(int major, int minor, int build, Comparison comparison = Comparison.GreaterThanOrEqualsTo, bool isOssRequired = false) : base(major, minor, build, comparison, isOssRequired) { } } diff --git a/src/Cassandra.IntegrationTests/TestClusterManagement/CcmBridge.cs b/src/Cassandra.IntegrationTests/TestClusterManagement/CcmBridge.cs index dde5d86fa..446659267 100644 --- a/src/Cassandra.IntegrationTests/TestClusterManagement/CcmBridge.cs +++ b/src/Cassandra.IntegrationTests/TestClusterManagement/CcmBridge.cs @@ -17,7 +17,9 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net.Sockets; +using System.Text.RegularExpressions; using System.Threading; using Cassandra.IntegrationTests.TestBase; using Cassandra.Tests; @@ -71,6 +73,11 @@ public void Create(bool useSsl) ExecuteCcm(string.Format( "create {0} --dse -v {1} {2}", Name, Version, sslParams)); } + else if(TestClusterManager.CurrentBackendType == TestClusterManager.BackendType.Hcd) + { + ExecuteCcm(string.Format( + "create {0} --hcd -v {1} {2}", Name, Version, sslParams)); + } else { ExecuteCcm(string.Format( @@ -266,6 +273,9 @@ public ProcessOutput BootstrapNode(int n, string dc, bool start = true) if (TestClusterManager.IsDse) { cmd += " --dse"; + }else if (TestClusterManager.CurrentBackendType == TestClusterManager.BackendType.Hcd) + { + cmd += " --hcd"; } var output = ExecuteCcm(string.Format(cmd, n, IpPrefix, n, 7000 + 100 * n, dc != null ? "-d " + dc : null)); @@ -294,10 +304,9 @@ public void UpdateConfig(params string[] configs) { return; } - foreach (var c in configs) - { - ExecuteCcm(string.Format("updateconf \"{0}\"", c)); - } + FixYaml(configs); + var joinedConfigs = string.Join(" ", configs.Select(s => $"\"{s}\"")); + ExecuteCcm($"updateconf {joinedConfigs}"); } public void UpdateDseConfig(params string[] configs) @@ -311,12 +320,55 @@ public void UpdateDseConfig(params string[] configs) { return; } - foreach (var c in configs) + FixYaml(configs); + var joinedConfigs = string.Join(" ", configs.Select(s => $"\"{s}\"")); + ExecuteCcm($"updatedseconf {joinedConfigs}"); + } + + public void UpdateConfig(int nodeId, params string[] yamlChanges) + { + if (yamlChanges == null) return; + FixYaml(yamlChanges); + var joinedChanges = string.Join(" ", yamlChanges.Select(s => $"\"{s}\"")); + ExecuteCcm($"node{nodeId} updateconf {joinedChanges}"); + } + + private static void FixYaml(string[] yamlToFix) + { + // in-place fix + if (TestClusterManager.CheckCassandraVersion(false, System.Version.Parse("4.1"), Comparison.GreaterThanOrEqualsTo)) { - ExecuteCcm(string.Format("updatedseconf \"{0}\"", c)); + // Fix the yaml options that turned obsolete since 4.1.0 + for (int i = 0; i < yamlToFix.Length; i++) + { + string line = yamlToFix[i]; + var keyValueParts = line.Split(':'); + + var key = keyValueParts[0]; + var value = keyValueParts[1]; + + var matchMs = Regex.Match(key, @"^(\w+)_in_ms$"); + if (matchMs.Success) + { + yamlToFix[i] = $"{matchMs.Groups[1].Value}:{value}ms"; + } + + var matchKb = Regex.Match(key, @"^(\w+)_in_kb$"); + if (matchKb.Success) + { + yamlToFix[i] = $"{matchKb.Groups[1].Value}:{value}KiB"; + } + + var matchEnable = Regex.Match(key, @"enable_(\w+)$"); + if (matchEnable.Success) + { + yamlToFix[i] = $"{matchEnable.Groups[1].Value}_enabled:{value}"; + } + } } } - + + public void SetNodeWorkloads(int nodeId, string[] workloads) { if (!TestClusterManager.IsDse) diff --git a/src/Cassandra.IntegrationTests/TestClusterManagement/CcmCluster.cs b/src/Cassandra.IntegrationTests/TestClusterManagement/CcmCluster.cs index 087e60ef4..b15e095c5 100644 --- a/src/Cassandra.IntegrationTests/TestClusterManagement/CcmCluster.cs +++ b/src/Cassandra.IntegrationTests/TestClusterManagement/CcmCluster.cs @@ -214,23 +214,17 @@ public void BootstrapNode(int nodeIdToStart, string dataCenterName, bool start = public void UpdateDseConfig(params string[] yamlChanges) { - if (yamlChanges == null) return; - var joinedChanges = string.Join(" ", yamlChanges.Select(s => $"\"{s}\"")); - _ccm.ExecuteCcm($"updatedseconf {joinedChanges}"); + _ccm.UpdateDseConfig(yamlChanges); } public void UpdateConfig(params string[] yamlChanges) { - if (yamlChanges == null) return; - var joinedChanges = string.Join(" ", yamlChanges.Select(s => $"\"{s}\"")); - _ccm.ExecuteCcm($"updateconf {joinedChanges}"); + _ccm.UpdateConfig(yamlChanges); } public void UpdateConfig(int nodeId, params string[] yamlChanges) { - if (yamlChanges == null) return; - var joinedChanges = string.Join(" ", yamlChanges.Select(s => $"\"{s}\"")); - _ccm.ExecuteCcm($"node{nodeId} updateconf {joinedChanges}"); + _ccm.UpdateConfig(nodeId, yamlChanges); } } } diff --git a/src/Cassandra.IntegrationTests/TestClusterManagement/TestClusterManager.cs b/src/Cassandra.IntegrationTests/TestClusterManagement/TestClusterManager.cs index 662a3cfdd..08502d525 100644 --- a/src/Cassandra.IntegrationTests/TestClusterManagement/TestClusterManager.cs +++ b/src/Cassandra.IntegrationTests/TestClusterManagement/TestClusterManager.cs @@ -28,22 +28,18 @@ public static class TestClusterManager { public const string DefaultKeyspaceName = "test_cluster_keyspace"; private static ICcmProcessExecuter _executor; - + private static readonly Version Version2Dot0 = new Version(2, 0); private static readonly Version Version2Dot1 = new Version(2, 1); - private static readonly Version Version2Dot2 = new Version(2, 2); private static readonly Version Version3Dot0 = new Version(3, 0); - private static readonly Version Version3Dot1 = new Version(3, 1); private static readonly Version Version3Dot11 = new Version(3, 11); - private static readonly Version Version3Dot12 = new Version(3, 12); private static readonly Version Version4Dot0 = new Version(4, 0); - private static readonly Version Version4Dot6 = new Version(4, 6); private static readonly Version Version4Dot7 = new Version(4, 7); - private static readonly Version Version4Dot8 = new Version(4, 8); private static readonly Version Version5Dot0 = new Version(5, 0); private static readonly Version Version5Dot1 = new Version(5, 1); private static readonly Version Version6Dot0 = new Version(6, 0); - private static readonly Version Version6Dot7 = new Version(6, 7); + private static readonly Version Version6Dot9 = new Version(6, 9); + private static readonly Version Version6Dot10 = new Version(6, 10); /// /// Gets the Cassandra version used for this test run @@ -70,7 +66,7 @@ public static Version CassandraVersion // C* 3.0 return Version3Dot0; } - if (dseVersion < Version6Dot0) + if (dseVersion < Version6Dot10) { // C* 3.11 return Version3Dot11; @@ -78,7 +74,10 @@ public static Version CassandraVersion // C* 4.0 return Version4Dot0; } - + if (IsHcd) + { + return Version4Dot0; + } return new Version(TestClusterManager.CassandraVersionString.Split('-')[0]); } } @@ -99,6 +98,40 @@ public static string DsePath get { return Environment.GetEnvironmentVariable("DSE_PATH"); } } + public enum BackendType + { + Hcd, + Dse, + Cassandra + } + + /// + /// "hcd", "dse", or "cassandra" (default), based on CCM_DISTRIBUTION + /// if there's env var DSE_VERSION, ignore CCM_DISTRIBUTION + /// + public static BackendType CurrentBackendType + { + get + { + if ( Environment.GetEnvironmentVariable("DSE_VERSION") != null ) + { + return BackendType.Dse; + } + string distribution = Environment.GetEnvironmentVariable("CCM_DISTRIBUTION") ?? "cassandra"; + switch (distribution) + { + case "hcd": + return BackendType.Hcd; + case "dse": + return BackendType.Dse; + case "cassandra": + return BackendType.Cassandra; + default: + throw new TestInfrastructureException("Unknown CCM_DISTRIBUTION value: " + distribution); + } + } + } + public static string InitialContactPoint { get { return IpPrefix + "1"; } @@ -106,22 +139,55 @@ public static string InitialContactPoint public static string DseVersionString { - get { return Environment.GetEnvironmentVariable("DSE_VERSION") ?? "6.7.7"; } + get + { + if (!IsDse) + { + throw new TestInfrastructureException("DSE_VERSION is only available when using DSE backend"); + } + if (Environment.GetEnvironmentVariable("DSE_VERSION") != null) + { + return Environment.GetEnvironmentVariable("DSE_VERSION"); + } + return Environment.GetEnvironmentVariable("CASSANDRA_VERSION") ?? "6.7.7"; + } } + /// + /// Use DSE_VERSION if it's set, otherwise use CASSANDRA_VERSION + /// public static string CassandraVersionString { - get { return Environment.GetEnvironmentVariable("CASSANDRA_VERSION") ?? "3.11.2"; } + get + { + if (Environment.GetEnvironmentVariable("DSE_VERSION") != null) + { + return Environment.GetEnvironmentVariable("DSE_VERSION"); + } + return Environment.GetEnvironmentVariable("CASSANDRA_VERSION") ?? "3.11.2"; + } } public static bool IsDse { - get { return Environment.GetEnvironmentVariable("DSE_VERSION") != null; } + get { return CurrentBackendType == BackendType.Dse; } + } + + public static bool IsHcd + { + get { return CurrentBackendType == BackendType.Hcd; } } public static Version DseVersion { - get { return IsDse ? new Version(DseVersionString.Split('-')[0]) : TestClusterManager.GetDseVersionFromCassandraVersion(new Version(CassandraVersionString.Split('-')[0])); } + get + { + if (!IsDse) + { + throw new TestInfrastructureException("DseVersion is only available when using DSE backend"); + } + return new Version(DseVersionString.Split('-')[0]); + } } public static bool CcmUseWsl => bool.Parse(Environment.GetEnvironmentVariable("CCM_USE_WSL") ?? "false"); @@ -161,15 +227,14 @@ public static bool CheckDseVersion(Version version, Comparison comparison) public static bool CheckCassandraVersion(bool requiresOss, Version version, Comparison comparison) { - if (requiresOss && TestClusterManager.IsDse) + if (requiresOss && TestClusterManager.CurrentBackendType != BackendType.Cassandra) { return false; } - var runningVersion = TestClusterManager.IsDse ? TestClusterManager.DseVersion : TestClusterManager.CassandraVersion; - var expectedVersion = TestClusterManager.IsDse ? TestClusterManager.GetDseVersionFromCassandraVersion(version) : version; - - return TestDseVersion.VersionMatch(expectedVersion, runningVersion, comparison); + var runningVersion = TestClusterManager.CassandraVersion; + var expectedVersion = version; + return TestCassandraVersion.VersionMatch(expectedVersion, runningVersion, comparison); } /// @@ -208,33 +273,7 @@ public static ICcmProcessExecuter Executor return TestClusterManager._executor; } } - - public static Version GetDseVersionFromCassandraVersion(Version cassandraVersion) - { - if (cassandraVersion < Version2Dot1) - { - // C* 2.0 => DSE 4.6 - return Version4Dot6; - } - if (cassandraVersion < Version2Dot2) - { - // C* 2.1 => DSE 4.8 - return Version4Dot8; - } - if (cassandraVersion < Version3Dot1) - { - // C* 3.0 => DSE 5.0 - return Version5Dot0; - } - if (cassandraVersion < Version3Dot12) - { - // C* 3.11 => DSE 5.1 - return Version5Dot1; - } - // DSE 6.0 - return Version6Dot0; - } - + private static ITestCluster CreateNewNoRetry(int nodeLength, TestClusterOptions options, bool startCluster) { TryRemove();