Skip to content

Commit 08e90f6

Browse files
driftxPiotr Kołaczkowski
andauthored
CNDB-16043: Add more tests for mixed version SAI queries (#2325)
Extends IndexQuerySupport framework with new test scenarios mixing row-aware and non-row-aware index versions. In the added scenarios, rows are first inserted and flushed into AA indexes, then the node(s) are upgraded to a row-aware index SAI version and finally more rows are inserted and flushed. Then existing workloads are executed against those mixed version indexes. Compaction of mixed version indexes is also tested. This commit does not add new test queries nor new datamodels, but only reuses the existing tests we had that were executed against a single version at a time. Co-authored-by: Piotr Kołaczkowski <pkolaczk@datastax.com>
1 parent c00cfa8 commit 08e90f6

File tree

49 files changed

+1651
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1651
-2
lines changed

test/distributed/org/apache/cassandra/distributed/test/sai/datamodels/MultiNodeExecutor.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
package org.apache.cassandra.distributed.test.sai.datamodels;
2020

2121
import java.util.ArrayList;
22+
import java.util.HashSet;
2223
import java.util.Iterator;
2324
import java.util.List;
25+
import java.util.Set;
26+
import java.util.stream.Collectors;
2427

2528
import org.apache.cassandra.db.Keyspace;
2629
import org.apache.cassandra.distributed.Cluster;
2730
import org.apache.cassandra.distributed.api.ConsistencyLevel;
2831
import org.apache.cassandra.distributed.test.sai.SAIUtil;
2932
import org.apache.cassandra.distributed.util.ColumnTypeUtil;
33+
import org.apache.cassandra.index.sai.SAITester;
3034
import org.apache.cassandra.index.sai.cql.datamodels.DataModel;
35+
import org.apache.cassandra.index.sai.disk.format.Version;
3136

3237
public class MultiNodeExecutor implements DataModel.Executor
3338
{
@@ -56,6 +61,15 @@ public void compact(String keyspace, String table)
5661
cluster.forEach(node -> node.forceCompact(keyspace, table));
5762
}
5863

64+
@Override
65+
public void setCurrentVersion(Version version)
66+
{
67+
// need to pass version as String, because Version is not serializable and cannot be easily made to be so
68+
String versionName = version.toString();
69+
cluster.forEach(node ->
70+
node.runOnInstance(() -> org.apache.cassandra.index.sai.SAIUtil.setCurrentVersion(Version.parse(versionName))));
71+
}
72+
5973
@Override
6074
public void disableCompaction(String keyspace, String table)
6175
{
@@ -98,4 +112,22 @@ public long getCounter()
98112
{
99113
return MultiNodeQueryTester.Counter.get();
100114
}
115+
116+
@Override
117+
public Set<Version> getSSTableIndexVersions(String keyspace, String indexedTable)
118+
{
119+
// Need to pass version as String, because Version is not serializable
120+
var versions = new HashSet<String>();
121+
cluster.forEach(node ->
122+
versions.addAll(
123+
node.callsOnInstance(() ->
124+
SAITester.getSSTableIndexVersions(keyspace, indexedTable)
125+
.stream()
126+
.map(Version::toString)
127+
.collect(Collectors.toSet())
128+
).call()
129+
)
130+
);
131+
return versions.stream().map(Version::parse).collect(Collectors.toSet());
132+
}
101133
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright DataStax, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.cassandra.distributed.test.sai.datamodels;
18+
19+
import org.apache.cassandra.index.sai.cql.datamodels.IndexQuerySupport;
20+
import org.junit.Test;
21+
22+
public class QueryCellDeletionsUpgradeTest extends MultiNodeQueryTester
23+
{
24+
@Test
25+
public void testCellDeletionsAfterUpgrade() throws Throwable
26+
{
27+
IndexQuerySupport.cellDeletionsAfterUpgrade(executor, dataModel.get(), sets);
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright DataStax, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.cassandra.distributed.test.sai.datamodels;
18+
19+
import org.apache.cassandra.index.sai.cql.datamodels.IndexQuerySupport;
20+
import org.junit.Test;
21+
22+
public class QueryRowDeletionsUpgradeTest extends MultiNodeQueryTester
23+
{
24+
@Test
25+
public void testRowDeletionsAfterUpgrade() throws Throwable
26+
{
27+
IndexQuerySupport.rowDeletionsAfterUpgrade(executor, dataModel.get(), sets);
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright DataStax, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.cassandra.distributed.test.sai.datamodels;
18+
19+
import org.apache.cassandra.index.sai.cql.datamodels.IndexQuerySupport;
20+
import org.junit.Test;
21+
22+
public class QueryTimeToLiveUpgradeTest extends MultiNodeQueryTester
23+
{
24+
@Test
25+
public void testTimeToLiveAfterUpgrade() throws Throwable
26+
{
27+
IndexQuerySupport.timeToLiveAfterUpgrade(executor, dataModel.get(), sets);
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright DataStax, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.cassandra.distributed.test.sai.datamodels;
18+
19+
import org.apache.cassandra.index.sai.cql.datamodels.IndexQuerySupport;
20+
import org.junit.Test;
21+
22+
public class QueryWriteLifecycleUpgradeTest extends MultiNodeQueryTester
23+
{
24+
@Test
25+
public void testWriteLifecycleAfterUpgrade() throws Throwable
26+
{
27+
IndexQuerySupport.writeLifecycleAfterUpgrade(executor, dataModel.get(), sets);
28+
}
29+
}

test/unit/org/apache/cassandra/index/sai/SAITester.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,36 @@ protected void verifySAIVersionInUse(Version expectedVersion, String keyspace, S
454454
}
455455
}
456456

457+
/**
458+
* Returns the set containing all SAI index versions found among all sstable indexes of the given table.
459+
* Memtable indexes are not included.
460+
*/
461+
public static Set<Version> getSSTableIndexVersions(String keyspace, String table)
462+
{
463+
ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore(table);
464+
var group = StorageAttachedIndexGroup.getIndexGroup(cfs);
465+
if (group == null) // no indexes present on the table
466+
return Set.of();
467+
468+
Set<IndexContext> indexContexts = group.getIndexes()
469+
.stream()
470+
.map(StorageAttachedIndex::getIndexContext)
471+
.collect(Collectors.toSet());
472+
473+
var versions = new HashSet<Version>();
474+
for (var sstable : cfs.getLiveSSTables())
475+
{
476+
var indexDescriptor = group.descriptorFor(sstable);
477+
if (indexDescriptor != null)
478+
{
479+
versions.add(indexDescriptor.perSSTableComponents().version());
480+
for (IndexContext indexContext : indexContexts)
481+
versions.add(indexDescriptor.perIndexComponents(indexContext).version());
482+
}
483+
}
484+
return versions;
485+
}
486+
457487
protected static void assertFailureReason(ReadFailureException e, RequestFailureReason reason)
458488
{
459489
int expected = reason.codeForNativeProtocol();

test/unit/org/apache/cassandra/index/sai/cql/datamodels/DataModel.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.google.common.collect.Sets;
3232

3333
import org.apache.cassandra.cql3.CQL3Type;
34+
import org.apache.cassandra.index.sai.disk.format.Version;
3435
import org.apache.cassandra.utils.Pair;
3536

3637
public interface DataModel
@@ -155,6 +156,10 @@ public interface DataModel
155156

156157
void insertRows(Executor tester) throws Throwable;
157158

159+
void insertRowsPartA(Executor tester) throws Throwable;
160+
161+
void insertRowsPartB(Executor tester) throws Throwable;
162+
158163
void insertRowsWithTTL(Executor tester) throws Throwable;
159164

160165
void updateCells(Executor tester) throws Throwable;
@@ -167,6 +172,9 @@ public interface DataModel
167172

168173
List<Object> executeNonIndexed(Executor tester, String query, int fetchSize, Object... values) throws Throwable;
169174

175+
/** Returns the set of all SAI index versions in use by the model for the on-disk indexes */
176+
Set<Version> getSSTableIndexVersions(Executor tester) throws Throwable;
177+
170178
public class BaseDataModel implements DataModel
171179
{
172180
final List<Pair<String, String>> columns;
@@ -272,6 +280,27 @@ public void insertRows(Executor tester) throws Throwable
272280
}
273281
}
274282

283+
@Override
284+
public void insertRowsPartA(Executor tester) throws Throwable
285+
{
286+
insertRowsRange(tester, 0, keys.size() / 2);
287+
}
288+
289+
@Override
290+
public void insertRowsPartB(Executor tester) throws Throwable
291+
{
292+
insertRowsRange(tester, keys.size() / 2, keys.size());
293+
}
294+
295+
private void insertRowsRange(Executor tester, int startIndex, int endIndex) throws Throwable
296+
{
297+
String template = "INSERT INTO %%s (%s, %s) VALUES (%s, %s)";
298+
for (int i = startIndex; i < endIndex; i++)
299+
{
300+
executeLocal(tester, String.format(template, primaryKey, columnNames, keys.get(i), rows.get(i)));
301+
}
302+
}
303+
275304
public void insertRowsWithTTL(Executor tester) throws Throwable
276305
{
277306
String template = "INSERT INTO %%s (%s, %s) VALUES (%s, %s)%s";
@@ -341,6 +370,12 @@ public List<Object> executeNonIndexed(Executor tester, String query, int fetchSi
341370
return tester.executeRemote(formatNonIndexedQuery(query), fetchSize, values);
342371
}
343372

373+
@Override
374+
public Set<Version> getSSTableIndexVersions(Executor tester) throws Throwable
375+
{
376+
return tester.getSSTableIndexVersions(KEYSPACE, indexedTable);
377+
}
378+
344379
protected Set<Integer> deletable()
345380
{
346381
return Sets.newHashSet(3, 7, 9, 12);
@@ -614,6 +649,8 @@ public static interface Executor
614649

615650
void compact(String keyspace, String table);
616651

652+
void setCurrentVersion(Version version);
653+
617654
void disableCompaction(String keyspace, String table);
618655

619656
void waitForTableIndexesQueryable(String keyspace, String table);
@@ -625,5 +662,11 @@ public static interface Executor
625662
void counterReset();
626663

627664
long getCounter();
665+
666+
/**
667+
* Returns the set of all SAI index versions in use by the specified table for the on-disk indexes.
668+
* Memtable indexes are not included.
669+
*/
670+
Set<Version> getSSTableIndexVersions(String keyspace, String indexedTable);
628671
}
629672
}

0 commit comments

Comments
 (0)