Unify CQLTester#waitForIndex and SAITester#waitForIndexQueryable

patch by Andrés de la Peña; reviewed by Caleb Rackliffe for CASSANDRA-18521
This commit is contained in:
Andrés de la Peña 2023-05-11 15:01:00 +01:00 committed by Caleb Rackliffe
parent 631ae36ca5
commit 01aeb616be
39 changed files with 392 additions and 313 deletions

View File

@ -292,7 +292,7 @@ public abstract class ParseUtils
* @param value The string to un-double quote.
* @return The un-double quoted string.
*/
static String unDoubleQuote(String value)
public static String unDoubleQuote(String value)
{
return unquote(value, '"');
}
@ -482,7 +482,7 @@ public abstract class ParseUtils
* @return {@code true} if the given string is surrounded by the quote character, and {@code
* false} otherwise.
*/
private static boolean isQuoted(String value, char quoteChar)
public static boolean isQuoted(String value, char quoteChar)
{
return value != null
&& value.length() > 1

View File

@ -51,7 +51,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
@ -103,6 +103,7 @@ import org.apache.cassandra.config.DataStorageSpec;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.cql3.functions.FunctionName;
import org.apache.cassandra.cql3.functions.types.ParseUtils;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Directories;
import org.apache.cassandra.db.Keyspace;
@ -137,6 +138,7 @@ import org.apache.cassandra.dht.Murmur3Partitioner;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.index.Index;
import org.apache.cassandra.index.SecondaryIndexManager;
import org.apache.cassandra.io.filesystem.ListenableFileSystem;
import org.apache.cassandra.io.util.File;
@ -177,7 +179,6 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_DRIVE
import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_REUSE_PREPARED;
import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_ROW_CACHE_SIZE;
import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_USE_PREPARED;
import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@ -205,6 +206,7 @@ public abstract class CQLTester
public static final String DATA_CENTER = ServerTestUtils.DATA_CENTER;
public static final String DATA_CENTER_REMOTE = ServerTestUtils.DATA_CENTER_REMOTE;
public static final String RACK1 = ServerTestUtils.RACK1;
protected static final int ASSERTION_TIMEOUT_SECONDS = 15;
private static org.apache.cassandra.transport.Server server;
private static JMXConnectorServer jmxServer;
@ -1143,122 +1145,229 @@ public abstract class CQLTester
protected void dropTable(String query)
{
dropFormattedTable(String.format(query, KEYSPACE + "." + currentTable()));
dropTable(KEYSPACE, query);
}
protected void dropFormattedTable(String formattedQuery)
protected void dropTable(String keyspace, String query)
{
dropFormattedTable(String.format(query, keyspace + "." + currentTable()));
}
private void dropFormattedTable(String formattedQuery)
{
logger.info(formattedQuery);
schemaChange(formattedQuery);
}
/**
* Creates a secondary index, waiting for it to become queryable.
*
* @param query the index creation query
* @return the name of the created index
*/
protected String createIndex(String query)
{
return createIndex(KEYSPACE, query);
}
/**
* Creates a secondary index, waiting for it to become queryable.
*
* @param keyspace the keyspace the created index should belong to
* @param query the index creation query
* @return the name of the created index
*/
protected String createIndex(String keyspace, String query)
{
String formattedQuery = formatQuery(keyspace, query);
return createFormattedIndex(formattedQuery);
Pair<String, String> qualifiedIndexName = createFormattedIndex(keyspace, formattedQuery);
waitForIndexQueryable(qualifiedIndexName.left, qualifiedIndexName.right);
return qualifiedIndexName.right;
}
protected String createFormattedIndex(String formattedQuery)
/**
* Creates a secondary index without waiting for it to become queryable.
*
* @param query the index creation query
* @return the name of the created index
*/
protected String createIndexAsync(String query)
{
return createIndexAsync(KEYSPACE, query);
}
/**
* Creates a secondary index without waiting for it to become queryable.
*
* @param keyspace the keyspace the created index should belong to
* @param query the index creation query
* @return the name of the created index
*/
protected String createIndexAsync(String keyspace, String query)
{
String formattedQuery = formatQuery(keyspace, query);
return createFormattedIndex(keyspace, formattedQuery).right;
}
private Pair<String, String> createFormattedIndex(String keyspace, String formattedQuery)
{
logger.info(formattedQuery);
String indexName = getCreateIndexName(formattedQuery);
Pair<String, String> qualifiedIndexName = getCreateIndexName(keyspace, formattedQuery);
schemaChange(formattedQuery);
return indexName;
return qualifiedIndexName;
}
protected static String getCreateIndexName(String formattedQuery)
protected static Pair<String, String> getCreateIndexName(String keyspace, String formattedQuery)
{
Matcher matcher = CREATE_INDEX_PATTERN.matcher(formattedQuery);
if (!matcher.find())
throw new IllegalArgumentException("Expected valid create index query but found: " + formattedQuery);
String parsedKeyspace = matcher.group(5);
if (!Strings.isNullOrEmpty(parsedKeyspace))
keyspace = parsedKeyspace;
String index = matcher.group(2);
if (!Strings.isNullOrEmpty(index))
return index;
String keyspace = matcher.group(5);
if (Strings.isNullOrEmpty(keyspace))
throw new IllegalArgumentException("Keyspace name should be specified: " + formattedQuery);
String table = matcher.group(7);
if (Strings.isNullOrEmpty(table))
throw new IllegalArgumentException("Table name should be specified: " + formattedQuery);
String column = matcher.group(9);
String baseName = Strings.isNullOrEmpty(column)
? IndexMetadata.generateDefaultIndexName(table)
: IndexMetadata.generateDefaultIndexName(table, new ColumnIdentifier(column, true));
KeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspace);
return ks.findAvailableIndexName(baseName);
}
/**
* Index creation is asynchronous, this method searches in the system table IndexInfo
* for the specified index and returns true if it finds it, which indicates the
* index was built. If we haven't found it after 5 seconds we give-up.
*/
protected boolean waitForIndex(String keyspace, String table, String index) throws Throwable
{
long start = currentTimeMillis();
boolean indexCreated = false;
while (!indexCreated)
if (Strings.isNullOrEmpty(index))
{
Object[][] results = getRows(execute("select index_name from system.\"IndexInfo\" where table_name = ?", keyspace));
for(int i = 0; i < results.length; i++)
{
if (index.equals(results[i][0]))
{
indexCreated = true;
break;
}
}
String table = matcher.group(7);
if (Strings.isNullOrEmpty(table))
throw new IllegalArgumentException("Table name should be specified: " + formattedQuery);
if (currentTimeMillis() - start > 5000)
break;
String column = matcher.group(9);
Thread.sleep(10);
String baseName = Strings.isNullOrEmpty(column)
? IndexMetadata.generateDefaultIndexName(table)
: IndexMetadata.generateDefaultIndexName(table, new ColumnIdentifier(column, true));
KeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspace);
assertNotNull(ks);
index = ks.findAvailableIndexName(baseName);
}
return indexCreated;
index = ParseUtils.isQuoted(index, '\"')
? ParseUtils.unDoubleQuote(index)
: index.toLowerCase();
return Pair.create(keyspace, index);
}
public void waitForTableIndexesQueryable()
{
waitForTableIndexesQueryable(currentTable());
}
public void waitForTableIndexesQueryable(String table)
{
waitForTableIndexesQueryable(KEYSPACE, table);
}
/**
* Index creation is asynchronous, this method waits until the specified index hasn't any building task running.
* <p>
* This method differs from {@link #waitForIndex(String, String, String)} in that it doesn't require the index to be
* fully nor successfully built, so it can be used to wait for failing index builds.
* Index creation is asynchronous. This method waits until all the indexes in the specified table are queryable.
*
* @param keyspace the table keyspace name
* @param table the table name
*/
public void waitForTableIndexesQueryable(String keyspace, String table)
{
waitForAssert(() -> Assertions.assertThat(getNotQueryableIndexes(keyspace, table)).isEmpty(), 60, TimeUnit.SECONDS);
}
public void waitForIndexQueryable(String index)
{
waitForIndexQueryable(KEYSPACE, index);
}
/**
* Index creation is asynchronous. This method waits until the specified index is queryable.
*
* @param keyspace the index keyspace name
* @param indexName the index name
* @return {@code true} if the index build tasks have finished in 5 seconds, {@code false} otherwise
* @param index the index name
*/
protected boolean waitForIndexBuilds(String keyspace, String indexName) throws InterruptedException
public void waitForIndexQueryable(String keyspace, String index)
{
long start = currentTimeMillis();
SecondaryIndexManager indexManager = getCurrentColumnFamilyStore(keyspace).indexManager;
waitForAssert(() -> assertTrue(isIndexQueryable(keyspace, index)), 60, TimeUnit.SECONDS);
}
while (true)
protected void waitForIndexBuilds(String index)
{
waitForIndexBuilds(KEYSPACE, index);
}
/**
* Index creation is asynchronous. This method waits until the specified index hasn't any building task running.
* <p>
* This method differs from {@link #waitForIndexQueryable(String, String)} in that it doesn't require the
* index to be fully nor successfully built, so it can be used to wait for failing index builds.
*
* @param keyspace the index keyspace name
* @param index the index name
*/
protected void waitForIndexBuilds(String keyspace, String index)
{
waitForAssert(() -> assertFalse(isIndexBuilding(keyspace, index)), 60, TimeUnit.SECONDS);
}
/**
* @return the names of the indexes in the current table that are not queryable
*/
protected Set<String> getNotQueryableIndexes()
{
return getNotQueryableIndexes(KEYSPACE, currentTable());
}
/**
* @param keyspace the table keyspace name
* @param table the table name
* @return the names of the indexes in the specified table that are not queryable
*/
protected Set<String> getNotQueryableIndexes(String keyspace, String table)
{
SecondaryIndexManager sim = Keyspace.open(keyspace).getColumnFamilyStore(table).indexManager;
return sim.listIndexes()
.stream()
.filter(index -> !sim.isIndexQueryable(index))
.map(index -> index.getIndexMetadata().name)
.collect(Collectors.toSet());
}
protected boolean isIndexBuilding(String keyspace, String indexName)
{
SecondaryIndexManager manager = getIndexManager(keyspace, indexName);
assertNotNull(manager);
return manager.isIndexBuilding(indexName);
}
protected boolean isIndexQueryable(String keyspace, String indexName)
{
SecondaryIndexManager manager = getIndexManager(keyspace, indexName);
assertNotNull(manager);
Index index = manager.getIndexByName(indexName);
return manager.isIndexQueryable(index);
}
@Nullable
protected SecondaryIndexManager getIndexManager(String keyspace, String indexName)
{
for (ColumnFamilyStore cfs : Keyspace.open(keyspace).getColumnFamilyStores())
{
if (!indexManager.isIndexBuilding(indexName))
{
return true;
}
else if (currentTimeMillis() - start > 5000)
{
return false;
}
else
{
Thread.sleep(10);
}
Index index = cfs.indexManager.getIndexByName(indexName);
if (index != null)
return cfs.indexManager;
}
return null;
}
protected void waitForAssert(Runnable runnableAssert, long timeout, TimeUnit unit)
{
Awaitility.await().dontCatchUncaughtExceptions().atMost(timeout, unit).untilAsserted(runnableAssert::run);
}
protected void waitForAssert(Runnable assertion)
{
waitForAssert(assertion, ASSERTION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
protected void createIndexMayThrow(String query) throws Throwable

View File

@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
import org.apache.cassandra.utils.Pair;
import org.assertj.core.api.Assertions;
public class CQLTesterTest extends CQLTester
{
@Test
public void testGetCreateIndexName()
{
schemaChange("CREATE KEYSPACE k WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}");
schemaChange("CREATE KEYSPACE k2 WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}");
String table = createTable("CREATE TABLE %s (k int PRIMARY KEY, c int)");
// standard index with explicit name
testGetCreateIndexName("k", "idx", "CREATE INDEX idx ON k.t (c)");
testGetCreateIndexName(KEYSPACE, "idx", "CREATE INDEX idx ON t (c)");
testGetCreateIndexName(KEYSPACE, "idx", "CREATE INDEX idx ON %s (c)");
// custom index with explicit name
testGetCreateIndexName("k", "idx", "CREATE CUSTOM INDEX idx ON k.t (c) USING 'class'");
testGetCreateIndexName(KEYSPACE, "idx", "CREATE CUSTOM INDEX idx ON t (c) USING 'class'");
testGetCreateIndexName(KEYSPACE, "idx", "CREATE CUSTOM INDEX idx ON %s (c) USING 'class'");
// with an unqouted case-sensitive index name
testGetCreateIndexName("k", "idx", "CREATE INDEX iDx ON k.t (c)");
testGetCreateIndexName(KEYSPACE, "idx", "CREATE INDEX iDx ON t (c)");
testGetCreateIndexName(KEYSPACE, "idx", "CREATE INDEX iDx ON %s (c)");
// with a quoted case-sensitive index name
testGetCreateIndexName("k", "iDx", "CREATE INDEX \"iDx\" ON k.t (c)");
testGetCreateIndexName(KEYSPACE, "iDx", "CREATE INDEX \"iDx\" ON t (c)");
testGetCreateIndexName(KEYSPACE, "iDx", "CREATE INDEX \"iDx\" ON %s (c)");
// standard index with autogenerated name
testGetCreateIndexName("k", "t_c_idx", "CREATE INDEX ON k.t (c)");
testGetCreateIndexName(KEYSPACE, "t_c_idx", "CREATE INDEX ON t (c)");
testGetCreateIndexName(KEYSPACE, table + "_c_idx", "CREATE INDEX ON %s (c)");
// custom index with autogenerated name
testGetCreateIndexName("k", "t_c_idx", "CREATE CUSTOM INDEX ON k.t (c) USING 'class'");
testGetCreateIndexName(KEYSPACE, "t_c_idx", "CREATE CUSTOM INDEX ON t (c) USING 'class'");
testGetCreateIndexName(KEYSPACE, table + "_c_idx", "CREATE CUSTOM INDEX ON %s (c) USING 'class'");
// with a not-default working keyspace
testGetCreateIndexName("k", "t_c_idx", "k2", "CREATE INDEX ON k.t (c)");
testGetCreateIndexName("k2", "t_c_idx", "k2", "CREATE INDEX ON t (c)");
testGetCreateIndexName("k2", table + "_c_idx", "k2", "CREATE INDEX ON %s (c)");
}
private void testGetCreateIndexName(String expectedKeyspaceName, String expectedIndexName, String query)
{
testGetCreateIndexName(expectedKeyspaceName, expectedIndexName, KEYSPACE, query);
}
private void testGetCreateIndexName(String expectedKeyspaceName, String expectedIndexName, String keyspace, String query)
{
Pair<String, String> name = getCreateIndexName(keyspace, formatQuery(keyspace, query));
Assertions.assertThat(name.left).isEqualTo(expectedKeyspaceName);
Assertions.assertThat(name.right).isEqualTo(expectedIndexName);
}
}

View File

@ -127,13 +127,13 @@ public class KeyCacheCqlTest extends CQLTester
@Override
protected String createIndex(String query)
{
return createFormattedIndex(formatQuery(KEYSPACE_PER_TEST, query));
return createIndex(KEYSPACE_PER_TEST, query);
}
@Override
protected void dropTable(String query)
{
dropFormattedTable(String.format(query, KEYSPACE_PER_TEST + "." + currentTable()));
dropTable(KEYSPACE_PER_TEST, query);
}
@Test

View File

@ -256,7 +256,7 @@ public class SecondaryIndexOnMapEntriesTest extends CQLTester
assertRows(execute(query, params));
}
private void createSimpleTableAndIndex() throws Throwable
private void createSimpleTableAndIndex()
{
createTable("CREATE TABLE %s (k TEXT PRIMARY KEY, v MAP<TEXT, INT>)");
createIndex("CREATE INDEX ON %s(ENTRIES(v))");

View File

@ -107,8 +107,8 @@ public class SecondaryIndexTest extends CQLTester
format("DROP INDEX %s.%s", KEYSPACE, indexName));
createTable("CREATE TABLE %s (a int primary key, b int);");
createIndex("CREATE INDEX " + indexName + " ON %s(b);");
createIndex("CREATE INDEX IF NOT EXISTS " + indexName + " ON %s(b);");
createIndexAsync("CREATE INDEX " + indexName + " ON %s(b);");
createIndexAsync("CREATE INDEX IF NOT EXISTS " + indexName + " ON %s(b);");
assertInvalidMessage(format("Index '%s' already exists",
removeQuotes(indexName.toLowerCase(Locale.US))),
@ -117,7 +117,7 @@ public class SecondaryIndexTest extends CQLTester
// IF NOT EXISTS should apply in cases where the new index differs from an existing one in name only
String otherIndexName = "index_" + nanoTime();
assertEquals(1, getCurrentColumnFamilyStore().metadata().indexes.size());
createIndex("CREATE INDEX IF NOT EXISTS " + otherIndexName + " ON %s(b)");
createIndexAsync("CREATE INDEX IF NOT EXISTS " + otherIndexName + " ON %s(b)");
assertEquals(1, getCurrentColumnFamilyStore().metadata().indexes.size());
assertInvalidMessage(format("Index %s is a duplicate of existing index %s",
removeQuotes(otherIndexName.toLowerCase(Locale.US)),
@ -254,7 +254,7 @@ public class SecondaryIndexTest extends CQLTester
@Test
public void testIndexOnComposite() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (blog_id int, timestamp int, author text, content text, PRIMARY KEY (blog_id, timestamp))");
createTable("CREATE TABLE %s (blog_id int, timestamp int, author text, content text, PRIMARY KEY (blog_id, timestamp))");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 0, 0, "bob", "1st post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 0, 1, "tom", "2nd post");
@ -264,8 +264,6 @@ public class SecondaryIndexTest extends CQLTester
createIndex("CREATE INDEX authoridx ON %s (author)");
assertTrue(waitForIndex(keyspace(), tableName, "authoridx"));
beforeAndAfterFlush(() -> {
assertRows(execute("SELECT blog_id, timestamp FROM %s WHERE author = 'bob'"),
row(1, 0),
@ -618,14 +616,13 @@ public class SecondaryIndexTest extends CQLTester
@Test
public void testCanQuerySecondaryIndex() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (k int PRIMARY KEY, v int,)");
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int,)");
execute("ALTER TABLE %s WITH CACHING = { 'keys': 'ALL', 'rows_per_partition': 'ALL' }");
execute("INSERT INTO %s (k,v) VALUES (0,0)");
execute("INSERT INTO %s (k,v) VALUES (1,1)");
createIndex("CREATE INDEX testindex on %s (v)");
assertTrue(waitForIndex(keyspace(), tableName, "testindex"));
assertRows(execute("SELECT k FROM %s WHERE v = 0"), row(0));
cleanupCache();
@ -1040,7 +1037,7 @@ public class SecondaryIndexTest extends CQLTester
for (int j = 0; j < 10; j++)
execute("INSERT INTO %s (pk, ck, value) VALUES (?, ?, ?)", i, j, i + j);
createIndex("CREATE CUSTOM INDEX testIndex ON %s (value) USING '" + IndexBlockingOnInitialization.class.getName() + "'");
createIndexAsync("CREATE CUSTOM INDEX testIndex ON %s (value) USING '" + IndexBlockingOnInitialization.class.getName() + "'");
try
{
execute("SELECT value FROM %s WHERE value = 2");
@ -1060,9 +1057,8 @@ public class SecondaryIndexTest extends CQLTester
public void testReadOnlyIndex() throws Throwable
{
// On successful initialization both reads and writes go through
String tableName = createTable("CREATE TABLE %s (pk int, ck int, value int, PRIMARY KEY (pk, ck))");
createTable("CREATE TABLE %s (pk int, ck int, value int, PRIMARY KEY (pk, ck))");
String indexName = createIndex("CREATE CUSTOM INDEX ON %s (value) USING '" + ReadOnlyOnFailureIndex.class.getName() + "'");
assertTrue(waitForIndex(keyspace(), tableName, indexName));
execute("SELECT value FROM %s WHERE value = 1");
execute("INSERT INTO %s (pk, ck, value) VALUES (?, ?, ?)", 1, 1, 1);
ReadOnlyOnFailureIndex index = (ReadOnlyOnFailureIndex) getCurrentColumnFamilyStore().indexManager.getIndexByName(indexName);
@ -1078,9 +1074,9 @@ public class SecondaryIndexTest extends CQLTester
// On bad initial build writes are not forwarded to the index
ReadOnlyOnFailureIndex.failInit = true;
indexName = createIndex("CREATE CUSTOM INDEX ON %s (value) USING '" + ReadOnlyOnFailureIndex.class.getName() + "'");
indexName = createIndexAsync("CREATE CUSTOM INDEX ON %s (value) USING '" + ReadOnlyOnFailureIndex.class.getName() + "'");
index = (ReadOnlyOnFailureIndex) getCurrentColumnFamilyStore().indexManager.getIndexByName(indexName);
assertTrue(waitForIndexBuilds(keyspace(), indexName));
waitForIndexBuilds(indexName);
assertInvalidThrow(IndexNotAvailableException.class, "SELECT value FROM %s WHERE value = 1");
execute("INSERT INTO %s (pk, ck, value) VALUES (?, ?, ?)", 1, 1, 1);
assertEquals(0, index.rowsInserted.size());
@ -1099,9 +1095,8 @@ public class SecondaryIndexTest extends CQLTester
public void testWriteOnlyIndex() throws Throwable
{
// On successful initialization both reads and writes go through
String tableName = createTable("CREATE TABLE %s (pk int, ck int, value int, PRIMARY KEY (pk, ck))");
createTable("CREATE TABLE %s (pk int, ck int, value int, PRIMARY KEY (pk, ck))");
String indexName = createIndex("CREATE CUSTOM INDEX ON %s (value) USING '" + WriteOnlyOnFailureIndex.class.getName() + "'");
assertTrue(waitForIndex(keyspace(), tableName, indexName));
execute("SELECT value FROM %s WHERE value = 1");
execute("INSERT INTO %s (pk, ck, value) VALUES (?, ?, ?)", 1, 1, 1);
WriteOnlyOnFailureIndex index = (WriteOnlyOnFailureIndex) getCurrentColumnFamilyStore().indexManager.getIndexByName(indexName);
@ -1117,9 +1112,9 @@ public class SecondaryIndexTest extends CQLTester
// On bad initial build writes are forwarded to the index
WriteOnlyOnFailureIndex.failInit = true;
indexName = createIndex("CREATE CUSTOM INDEX ON %s (value) USING '" + WriteOnlyOnFailureIndex.class.getName() + "'");
indexName = createIndexAsync("CREATE CUSTOM INDEX ON %s (value) USING '" + WriteOnlyOnFailureIndex.class.getName() + "'");
index = (WriteOnlyOnFailureIndex) getCurrentColumnFamilyStore().indexManager.getIndexByName(indexName);
assertTrue(waitForIndexBuilds(keyspace(), indexName));
waitForIndexBuilds(indexName);
execute("INSERT INTO %s (pk, ck, value) VALUES (?, ?, ?)", 1, 1, 1);
assertEquals(1, index.rowsInserted.size());
assertInvalidThrow(IndexNotAvailableException.class, "SELECT value FROM %s WHERE value = 1");
@ -1449,7 +1444,7 @@ public class SecondaryIndexTest extends CQLTester
public void testIndexOnFrozenUDT() throws Throwable
{
String type = createType("CREATE TYPE %s (a int)");
String tableName = createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<" + type + ">)");
createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<" + type + ">)");
Object udt1 = userType("a", 1);
Object udt2 = userType("a", 2);
@ -1459,7 +1454,6 @@ public class SecondaryIndexTest extends CQLTester
execute("INSERT INTO %s (k, v) VALUES (?, ?)", 1, udt2);
execute("INSERT INTO %s (k, v) VALUES (?, ?)", 1, udt1);
assertTrue(waitForIndex(keyspace(), tableName, indexName));
assertRows(execute("SELECT * FROM %s WHERE v = ?", udt1), row(1, udt1), row(0, udt1));
assertEmpty(execute("SELECT * FROM %s WHERE v = ?", udt2));
@ -1478,7 +1472,7 @@ public class SecondaryIndexTest extends CQLTester
public void testIndexOnFrozenCollectionOfUDT() throws Throwable
{
String type = createType("CREATE TYPE %s (a int)");
String tableName = createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<set<frozen<" + type + ">>>)");
createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<set<frozen<" + type + ">>>)");
Object udt1 = userType("a", 1);
Object udt2 = userType("a", 2);
@ -1489,7 +1483,6 @@ public class SecondaryIndexTest extends CQLTester
String indexName = createIndex("CREATE INDEX ON %s (full(v))");
execute("INSERT INTO %s (k, v) VALUES (?, ?)", 2, set(udt2));
assertTrue(waitForIndex(keyspace(), tableName, indexName));
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE v CONTAINS ?", udt1);
@ -1511,7 +1504,7 @@ public class SecondaryIndexTest extends CQLTester
public void testIndexOnNonFrozenCollectionOfFrozenUDT() throws Throwable
{
String type = createType("CREATE TYPE %s (a int)");
String tableName = createTable("CREATE TABLE %s (k int PRIMARY KEY, v set<frozen<" + type + ">>)");
createTable("CREATE TABLE %s (k int PRIMARY KEY, v set<frozen<" + type + ">>)");
Object udt1 = userType("a", 1);
Object udt2 = userType("a", 2);
@ -1525,7 +1518,6 @@ public class SecondaryIndexTest extends CQLTester
execute("INSERT INTO %s (k, v) VALUES (?, ?)", 2, set(udt2));
execute("UPDATE %s SET v = v + ? WHERE k = ?", set(udt2), 1);
assertTrue(waitForIndex(keyspace(), tableName, indexName));
assertRows(execute("SELECT * FROM %s WHERE v CONTAINS ?", udt1), row(1, set(udt1, udt2)));
assertRows(execute("SELECT * FROM %s WHERE v CONTAINS ?", udt2), row(1, set(udt1, udt2)), row(2, set(udt2)));

View File

@ -466,8 +466,6 @@ public class InsertUpdateIfConditionTest extends CQLTester
// create and confirm
createIndex("CREATE INDEX IF NOT EXISTS myindex ON %s (value1)");
assertTrue(waitForIndex(KEYSPACE, tableName, "myindex"));
// unsuccessful create since it's already there
execute("CREATE INDEX IF NOT EXISTS myindex ON %s (value1)");

View File

@ -94,7 +94,7 @@ public class GuardrailTablesTest extends ThresholdTester
@Override
protected void dropTable(String tableName)
{
dropFormattedTable(format("DROP TABLE %s.%s", KEYSPACE_PER_TEST, tableName));
super.dropTable(format("DROP TABLE %s.%s", KEYSPACE_PER_TEST, tableName));
}
private String assertCreateTableValid() throws Throwable

View File

@ -57,22 +57,20 @@ public class SecondaryIndexManagerTest extends CQLTester
}
@Test
public void creatingIndexMarksTheIndexAsBuilt() throws Throwable
public void creatingIndexMarksTheIndexAsBuilt()
{
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String indexName = createIndex("CREATE INDEX ON %s(c)");
waitForIndex(KEYSPACE, tableName, indexName);
assertMarkedAsBuilt(indexName);
}
@Test
public void rebuilOrRecoveringIndexMarksTheIndexAsBuilt() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String indexName = createIndex("CREATE INDEX ON %s(c)");
waitForIndex(KEYSPACE, tableName, indexName);
assertMarkedAsBuilt(indexName);
assertTrue(tryRebuild(indexName, false));
@ -82,10 +80,9 @@ public class SecondaryIndexManagerTest extends CQLTester
@Test
public void recreatingIndexMarksTheIndexAsBuilt() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String indexName = createIndex("CREATE INDEX ON %s(c)");
waitForIndex(KEYSPACE, tableName, indexName);
assertMarkedAsBuilt(indexName);
// drop the index and verify that it has been removed from the built indexes table
@ -94,17 +91,15 @@ public class SecondaryIndexManagerTest extends CQLTester
// create the index again and verify that it's added to the built indexes table
createIndex(String.format("CREATE INDEX %s ON %%s(c)", indexName));
waitForIndex(KEYSPACE, tableName, indexName);
assertMarkedAsBuilt(indexName);
}
@Test
public void addingSSTablesMarksTheIndexAsBuilt() throws Throwable
public void addingSSTablesMarksTheIndexAsBuilt()
{
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String indexName = createIndex("CREATE INDEX ON %s(c)");
waitForIndex(KEYSPACE, tableName, indexName);
assertMarkedAsBuilt(indexName);
ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
@ -123,10 +118,10 @@ public class SecondaryIndexManagerTest extends CQLTester
{
// create an index which blocks on creation
TestingIndex.blockCreate();
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(b) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(b) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(b) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(b) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
// try to rebuild/recover the index before the index creation task has finished
assertFalse(tryRebuild(defaultIndexName, false));
@ -138,9 +133,9 @@ public class SecondaryIndexManagerTest extends CQLTester
// check that the index is marked as built when the creation finishes
TestingIndex.unblockCreate();
waitForIndex(KEYSPACE, tableName, defaultIndexName);
waitForIndex(KEYSPACE, tableName, readOnlyIndexName);
waitForIndex(KEYSPACE, tableName, writeOnlyIndexName);
waitForIndexQueryable(defaultIndexName);
waitForIndexQueryable(readOnlyIndexName);
waitForIndexQueryable(writeOnlyIndexName);
assertMarkedAsBuilt(defaultIndexName);
assertMarkedAsBuilt(readOnlyIndexName);
assertMarkedAsBuilt(writeOnlyIndexName);
@ -157,16 +152,13 @@ public class SecondaryIndexManagerTest extends CQLTester
@Test
public void cannotRebuildOrRecoverWhileAnotherRebuildIsInProgress() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(b) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(b) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
final AtomicBoolean error = new AtomicBoolean();
// wait for index initialization and verify it's built:
waitForIndex(KEYSPACE, tableName, defaultIndexName);
waitForIndex(KEYSPACE, tableName, readOnlyIndexName);
waitForIndex(KEYSPACE, tableName, writeOnlyIndexName);
// verify it's built after initialization:
assertMarkedAsBuilt(defaultIndexName);
assertMarkedAsBuilt(readOnlyIndexName);
assertMarkedAsBuilt(writeOnlyIndexName);
@ -214,12 +206,11 @@ public class SecondaryIndexManagerTest extends CQLTester
@Test
public void cannotRebuildWhileAnSSTableBuildIsInProgress() throws Throwable
{
final String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
final String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
final AtomicBoolean error = new AtomicBoolean();
// wait for index initialization and verify it's built:
waitForIndex(KEYSPACE, tableName, indexName);
// verify it's built after initialization:
assertMarkedAsBuilt(indexName);
// add sstables in another thread, but make it block:
@ -260,12 +251,11 @@ public class SecondaryIndexManagerTest extends CQLTester
@Test
public void addingSSTableWhileRebuildIsInProgress() throws Throwable
{
final String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
final String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
final AtomicBoolean error = new AtomicBoolean();
// wait for index initialization and verify it's built:
waitForIndex(KEYSPACE, tableName, indexName);
// verify it's built after initialization:
assertMarkedAsBuilt(indexName);
// rebuild the index in another thread, but make it block:
@ -308,12 +298,11 @@ public class SecondaryIndexManagerTest extends CQLTester
@Test
public void addingSSTableWithBuildFailureWhileRebuildIsInProgress() throws Throwable
{
final String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
final String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
final AtomicBoolean error = new AtomicBoolean();
// wait for index initialization and verify it's built:
waitForIndex(KEYSPACE, tableName, indexName);
// verify it's built after initialization:
assertMarkedAsBuilt(indexName);
// rebuild the index in another thread, but make it block:
@ -362,11 +351,10 @@ public class SecondaryIndexManagerTest extends CQLTester
}
@Test
public void rebuildWithFailure() throws Throwable
public void rebuildWithFailure()
{
final String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
final String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
waitForIndex(KEYSPACE, tableName, indexName);
// Rebuild the index with failure and verify it is not marked as built
TestingIndex.shouldFailBuild = true;
@ -384,13 +372,13 @@ public class SecondaryIndexManagerTest extends CQLTester
}
@Test
public void initializingIndexNotQueryableButMaybeWritable() throws Throwable
public void initializingIndexNotQueryableButMaybeWritable()
{
TestingIndex.blockCreate();
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
// the index shouldn't be queryable while the initialization hasn't finished
assertFalse(isQueryable(defaultIndexName));
@ -402,9 +390,9 @@ public class SecondaryIndexManagerTest extends CQLTester
// the index should be queryable once the initialization has finished
TestingIndex.unblockCreate();
waitForIndex(KEYSPACE, tableName, defaultIndexName);
waitForIndex(KEYSPACE, tableName, readOnlyIndexName);
waitForIndex(KEYSPACE, tableName, writeOnlyIndexName);
waitForIndexQueryable(defaultIndexName);
waitForIndexQueryable(readOnlyIndexName);
waitForIndexQueryable(writeOnlyIndexName);
assertTrue(isQueryable(defaultIndexName));
assertTrue(isQueryable(readOnlyIndexName));
assertTrue(isQueryable(writeOnlyIndexName));
@ -414,13 +402,13 @@ public class SecondaryIndexManagerTest extends CQLTester
}
@Test
public void initializingIndexNotQueryableButMaybeNotWritableAfterPartialRebuild() throws Throwable
public void initializingIndexNotQueryableButMaybeNotWritableAfterPartialRebuild()
{
TestingIndex.blockCreate();
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
// the index should never be queryable while the initialization hasn't finished
assertFalse(isQueryable(defaultIndexName));
@ -463,7 +451,7 @@ public class SecondaryIndexManagerTest extends CQLTester
// the index should be queryable once the initialization has finished
TestingIndex.unblockCreate();
waitForIndex(KEYSPACE, tableName, defaultIndexName);
waitForIndexQueryable(defaultIndexName);
assertTrue(isQueryable(defaultIndexName));
assertTrue(isQueryable(readOnlyIndexName));
assertTrue(isQueryable(writeOnlyIndexName));
@ -477,12 +465,12 @@ public class SecondaryIndexManagerTest extends CQLTester
{
TestingIndex.shouldFailCreate = true;
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
assertTrue(waitForIndexBuilds(KEYSPACE, defaultIndexName));
assertTrue(waitForIndexBuilds(KEYSPACE, readOnlyIndexName));
assertTrue(waitForIndexBuilds(KEYSPACE, writeOnlyIndexName));
String defaultIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
waitForIndexBuilds(defaultIndexName);
waitForIndexBuilds(readOnlyIndexName);
waitForIndexBuilds(writeOnlyIndexName);
tryRebuild(defaultIndexName, true);
tryRebuild(readOnlyIndexName, true);
@ -501,16 +489,16 @@ public class SecondaryIndexManagerTest extends CQLTester
}
@Test
public void indexWithFailedInitializationDoesNotChangeQueryabilityNorWritabilityAfterPartialRebuild() throws Throwable
public void indexWithFailedInitializationDoesNotChangeQueryabilityNorWritabilityAfterPartialRebuild()
{
TestingIndex.shouldFailCreate = true;
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String defaultIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
assertTrue(waitForIndexBuilds(KEYSPACE, defaultIndexName));
assertTrue(waitForIndexBuilds(KEYSPACE, readOnlyIndexName));
assertTrue(waitForIndexBuilds(KEYSPACE, writeOnlyIndexName));
String defaultIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String readOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", ReadOnlyOnFailureIndex.class.getName()));
String writeOnlyIndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", WriteOnlyOnFailureIndex.class.getName()));
waitForIndexBuilds(defaultIndexName);
waitForIndexBuilds(readOnlyIndexName);
waitForIndexBuilds(writeOnlyIndexName);
TestingIndex.shouldFailCreate = false;
// the index should never be queryable, but it could be writable after the failed initialization
@ -524,9 +512,9 @@ public class SecondaryIndexManagerTest extends CQLTester
// a successful partial build doesn't set the index as queryable nor writable
ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
cfs.indexManager.handleNotification(new SSTableAddedNotification(cfs.getLiveSSTables(), null), this);
assertTrue(waitForIndexBuilds(KEYSPACE, defaultIndexName));
assertTrue(waitForIndexBuilds(KEYSPACE, readOnlyIndexName));
assertTrue(waitForIndexBuilds(KEYSPACE, writeOnlyIndexName));
waitForIndexBuilds(defaultIndexName);
waitForIndexBuilds(readOnlyIndexName);
waitForIndexBuilds(writeOnlyIndexName);
assertFalse(isQueryable(defaultIndexName));
assertFalse(isQueryable(readOnlyIndexName));
assertFalse(isQueryable(writeOnlyIndexName));
@ -556,7 +544,7 @@ public class SecondaryIndexManagerTest extends CQLTester
TestingIndex.failedCreateThrowable = throwable;
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
String indexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
tryRebuild(indexName, true);
fail("Should have failed!");
}
@ -573,7 +561,7 @@ public class SecondaryIndexManagerTest extends CQLTester
}
@Test
public void handleJVMStablityOnFailedRebuild() throws Throwable
public void handleJVMStablityOnFailedRebuild()
{
handleJVMStablityOnFailedRebuild(new SocketException("Should not fail"), false);
handleJVMStablityOnFailedRebuild(new FileNotFoundException("Should not fail"), false);
@ -582,11 +570,10 @@ public class SecondaryIndexManagerTest extends CQLTester
handleJVMStablityOnFailedRebuild(new RuntimeException("Should not fail"), false);
}
private void handleJVMStablityOnFailedRebuild(Throwable throwable, boolean shouldKillJVM) throws Throwable
private void handleJVMStablityOnFailedRebuild(Throwable throwable, boolean shouldKillJVM)
{
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
String indexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c) USING '%s'", TestingIndex.class.getName()));
waitForIndex(KEYSPACE, tableName, indexName);
KillerForTests killerForTests = new KillerForTests();
JVMStabilityInspector.Killer originalKiller = JVMStabilityInspector.replaceKiller(killerForTests);

View File

@ -50,7 +50,6 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@ -426,7 +425,7 @@ public class CassandraIndexTest extends CQLTester
Object[] row2 = row("k0", "c1");
Object[] row3 = row("k1", "c0");
Object[] row4 = row("k1", "c1");
String tableName = createTable("CREATE TABLE %s (k text, c text, PRIMARY KEY(k, c))");
createTable("CREATE TABLE %s (k text, c text, PRIMARY KEY(k, c))");
createIndex("CREATE INDEX no_regulars_idx ON %s(c)");
execute("INSERT INTO %s (k, c) VALUES (?, ?)", row1);
@ -440,7 +439,6 @@ public class CassandraIndexTest extends CQLTester
dropIndex("DROP INDEX %s.no_regulars_idx");
createIndex("CREATE INDEX no_regulars_idx ON %s(c)");
assertTrue(waitForIndex(keyspace(), tableName, "no_regulars_idx"));
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE c = ?", "c0"), row1, row3);
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE c = ?", "c1"), row2, row4);
@ -572,16 +570,15 @@ public class CassandraIndexTest extends CQLTester
.untilAsserted(() -> assertRows(execute(selectBuiltIndexesQuery), row("system", "PaxosUncommittedIndex", null)));
String indexName = "build_remove_test_idx";
String tableName = createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
createIndex(String.format("CREATE INDEX %s ON %%s(c)", indexName));
waitForIndex(KEYSPACE, tableName, indexName);
// check that there are no other rows in the built indexes table
assertRows(execute(selectBuiltIndexesQuery), row(KEYSPACE, indexName, null), row("system", "PaxosUncommittedIndex", null));
// rebuild the index and verify the built status table
getCurrentColumnFamilyStore().rebuildSecondaryIndex(indexName);
waitForIndex(KEYSPACE, tableName, indexName);
waitForIndexQueryable(indexName);
// check that there are no other rows in the built indexes table
assertRows(execute(selectBuiltIndexesQuery), row(KEYSPACE, indexName, null), row("system", "PaxosUncommittedIndex", null));

View File

@ -97,7 +97,6 @@ import org.apache.cassandra.service.snapshot.TableSnapshot;
import org.apache.cassandra.utils.JVMStabilityInspector;
import org.apache.cassandra.utils.Throwables;
import org.apache.lucene.codecs.CodecUtil;
import org.awaitility.Awaitility;
import static org.apache.cassandra.inject.ActionBuilder.newActionBuilder;
import static org.apache.cassandra.inject.Expression.quote;
@ -119,8 +118,6 @@ public abstract class SAITester extends CQLTester
protected static final ColumnIdentifier V1_COLUMN_IDENTIFIER = ColumnIdentifier.getInterned("v1", true);
protected static final int ASSERTION_TIMEOUT_SECONDS = 15;
protected static final Injections.Counter indexBuildCounter = Injections.newCounter("IndexBuildCounter")
.add(newInvokePoint().onClass(CompactionManager.class)
.onMethod("submitIndexBuild",
@ -273,7 +270,7 @@ public abstract class SAITester extends CQLTester
cfs.indexManager.executePreJoinTasksBlocking(true);
if (wait)
{
waitForIndexQueryable();
waitForTableIndexesQueryable();
}
}
@ -297,38 +294,12 @@ public abstract class SAITester extends CQLTester
}
}
protected void waitForAssert(Runnable runnableAssert, long timeout, TimeUnit unit)
{
Awaitility.await().dontCatchUncaughtExceptions().atMost(timeout, unit).untilAsserted(runnableAssert::run);
}
protected void waitForAssert(Runnable assertion)
{
waitForAssert(assertion, ASSERTION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
protected boolean indexNeedsFullRebuild(String index)
{
ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
return cfs.indexManager.needsFullRebuild(index);
}
protected boolean isIndexQueryable()
{
return isIndexQueryable(KEYSPACE, currentTable());
}
protected boolean isIndexQueryable(String keyspace, String table)
{
ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore(table);
for (Index index : cfs.indexManager.listIndexes())
{
if (!cfs.indexManager.isIndexQueryable(index))
return false;
}
return true;
}
protected void verifyInitialIndexFailed(String indexName)
{
// Verify that the initial index build fails...
@ -388,16 +359,6 @@ public abstract class SAITester extends CQLTester
return metricValue;
}
public void waitForIndexQueryable()
{
waitForIndexQueryable(KEYSPACE, currentTable());
}
public void waitForIndexQueryable(String keyspace, String table)
{
waitForAssert(() -> assertTrue(isIndexQueryable(keyspace, table)), 60, TimeUnit.SECONDS);
}
public void waitForCompactions()
{
waitForAssert(() -> assertFalse(CompactionManager.instance.isCompacting(ColumnFamilyStore.all(), ssTableReader -> true)), 10, TimeUnit.SECONDS);

View File

@ -38,7 +38,6 @@ public class AllowFilteringTest extends SAITester
createTable("CREATE TABLE %s (k1 int, k2 int, c1 int, c2 int, c3 int, v1 int, " +
"PRIMARY KEY ((k1, k2), c1, c2, c3))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(c1) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// with only index restrictions
test("SELECT * FROM %s WHERE c1=0", false);
@ -83,7 +82,6 @@ public class AllowFilteringTest extends SAITester
createTable("CREATE TABLE %s (k1 int, k2 int, c1 int, c2 int, c3 int, c4 int, v1 int, " +
"PRIMARY KEY ((k1, k2), c1, c2, c3, c4))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(c3) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// with only index restrictions
test("SELECT * FROM %s WHERE c3=0", false);
@ -129,7 +127,6 @@ public class AllowFilteringTest extends SAITester
"PRIMARY KEY ((k1, k2), c1, c2, c3, c4))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(c2) USING '%s'", StorageAttachedIndex.class.getName()));
createIndex(format("CREATE CUSTOM INDEX ON %%s(c4) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// with only index restrictions
test("SELECT * FROM %s WHERE c2=0 AND c4=0", false);
@ -175,7 +172,6 @@ public class AllowFilteringTest extends SAITester
{
createTable("CREATE TABLE %s (k1 int, k2 int, c1 int, c2 int, v1 int, v2 int, PRIMARY KEY ((k1, k2), c1, c2))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// with only index restrictions
test("SELECT * FROM %s WHERE v1=0", false);
@ -219,7 +215,6 @@ public class AllowFilteringTest extends SAITester
"PRIMARY KEY ((k1, k2), c1, c2))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
createIndex(format("CREATE CUSTOM INDEX ON %%s(v2) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// with only index restrictions
test("SELECT * FROM %s WHERE v1=0 AND v2=0", false);
@ -268,7 +263,6 @@ public class AllowFilteringTest extends SAITester
createIndex(format("CREATE CUSTOM INDEX ON %%s(c4) USING '%s'", StorageAttachedIndex.class.getName()));
createIndex(format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
createIndex(format("CREATE CUSTOM INDEX ON %%s(v2) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// with only index restrictions
test("SELECT * FROM %s WHERE c2=0 AND c4=0 AND v1=0 AND v2=0", false);

View File

@ -169,14 +169,22 @@ class BaseDataModel
public void createIndexes(Executor tester) throws Throwable
{
String template = "CREATE CUSTOM INDEX ndi_%s_index_%s ON %%s (%s) USING 'StorageAttachedIndex'";
createIndexes(tester, columns);
}
protected void createIndexes(Executor tester, List<Pair<String, String>> columns) throws Throwable
{
String indexNameTemplate = "sai_%s_index_%s";
String createIndexTemplate = "CREATE CUSTOM INDEX %s ON %%s (%s) USING 'StorageAttachedIndex'";
for (Pair<String, String> column : columns)
{
if (!skipColumns.contains(column.left))
String columnName = column.left;
if (!skipColumns.contains(columnName))
{
executeLocalIndexed(tester, String.format(template, column.left, indexedTable, column.left));
tester.waitForIndexQueryable(KEYSPACE, indexedTable);
String indexName = String.format(indexNameTemplate, columnName, indexedTable);
executeLocalIndexed(tester, String.format(createIndexTemplate, indexName, columnName));
tester.waitForIndexQueryable(KEYSPACE, indexName);
}
}
}
@ -294,16 +302,7 @@ class BaseDataModel
public void createIndexes(Executor tester) throws Throwable
{
super.createIndexes(tester);
String template = "CREATE CUSTOM INDEX ndi_%s_index_%s ON %%s (%s) USING 'StorageAttachedIndex'";
for (Pair<String, String> column : keyColumns)
{
if (!skipColumns.contains(column.left))
{
executeLocalIndexed(tester, String.format(template, column.left, indexedTable, column.left));
tester.waitForIndexQueryable(KEYSPACE, indexedTable);
}
}
createIndexes(tester, keyColumns);
}
@Override
@ -383,7 +382,7 @@ class BaseDataModel
{
void createTable(String statement);
void waitForIndexQueryable(String keyspace, String table);
void waitForIndexQueryable(String keyspace, String index);
void executeLocal(String query, Object...values) throws Throwable;

View File

@ -32,7 +32,6 @@ public class BooleanTypeTest extends SAITester
createTable("CREATE TABLE %s (id text PRIMARY KEY, val boolean)");
createIndex("CREATE CUSTOM INDEX ON %s(val) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
execute("INSERT INTO %s (id, val) VALUES ('0', false)");
execute("INSERT INTO %s (id, val) VALUES ('1', true)");

View File

@ -178,7 +178,6 @@ public class CollectionIndexingTest extends SAITester
{
createTable("CREATE TABLE %s (pk int primary key, value map<int, text>)");
createIndex(createIndex);
waitForIndexQueryable();
execute("INSERT INTO %s (pk, value) VALUES (?, ?)", 1, new HashMap<Integer, String>() {{
put(1, "v1");
put(2, "v2");
@ -194,7 +193,6 @@ public class CollectionIndexingTest extends SAITester
{
createTable("CREATE TABLE %s (pk int primary key, value frozen<map<int, text>>)");
createIndex(createIndex);
waitForIndexQueryable();
execute("INSERT INTO %s (pk, value) VALUES (?, ?)", 1, new HashMap<Integer, String>() {{
put(1, "v1");
put(2, "v2");
@ -210,7 +208,6 @@ public class CollectionIndexingTest extends SAITester
{
createTable("CREATE TABLE %s (pk int primary key, value frozen<list<int>>)");
createIndex(createIndex);
waitForIndexQueryable();
execute("INSERT INTO %s (pk, value) VALUES (?, ?)", 1, Arrays.asList(1, 2, 3));
execute("INSERT INTO %s (pk, value) VALUES (?, ?)", 2, Arrays.asList(1, 2, 3));
execute("INSERT INTO %s (pk, value) VALUES (?, ?)", 3, Arrays.asList(4, 5, 6));

View File

@ -37,8 +37,6 @@ public class DecimalLargeValueTest extends SAITester
createIndex("CREATE CUSTOM INDEX ON %s(dec) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
disableCompaction();
}

View File

@ -40,7 +40,6 @@ public class DuplicateRowIDTest extends SAITester
{
createTable("CREATE TABLE %s (id1 TEXT PRIMARY KEY, v1 INT)");
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
for (int i = 0; i < 2048; ++i)
{

View File

@ -41,7 +41,6 @@ public class MixedIndexImplementationsTest extends SAITester
String ossIndex = createIndex("CREATE INDEX ON %s(v1)");
String ndiIndex = createIndex(
String.format("CREATE CUSTOM INDEX ON %%s(v2) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// drop non-storage-attached index when a SAI index exists
dropIndex("DROP INDEX %s." + ossIndex);
@ -68,8 +67,6 @@ public class MixedIndexImplementationsTest extends SAITester
execute(insert, 2, 1, 0);
execute(insert, 3, 1, 1);
waitForIndexQueryable();
String ossSelect = "SELECT * FROM %s WHERE v1 = ?";
assertRowsIgnoringOrder(execute(ossSelect, 0), new Object[][]{{0, 0, 0}, {1, 0, 1}});
assertRowsIgnoringOrder(execute(ossSelect, 1), new Object[][]{{2, 1, 0}, {3, 1, 1}});
@ -99,7 +96,6 @@ public class MixedIndexImplementationsTest extends SAITester
createIndex(String.format("CREATE CUSTOM INDEX ON %%s(c3) USING '%s'", StorageAttachedIndex.class.getName()));
createIndex(String.format("CREATE CUSTOM INDEX ON %%s(r1) USING '%s'", StorageAttachedIndex.class.getName()));
createIndex(String.format("CREATE CUSTOM INDEX ON %%s(r2) USING '%s'", StorageAttachedIndex.class.getName()));
waitForIndexQueryable();
// without using the not-SAI index
testAllowFiltering("SELECT * FROM %s", false);

View File

@ -46,8 +46,6 @@ public class MultipleColumnIndexTest extends SAITester
createIndex("CREATE CUSTOM INDEX ON %s(values(text_map)) USING 'StorageAttachedIndex'");
createIndex("CREATE CUSTOM INDEX ON %s(entries(text_map)) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
execute("INSERT INTO %s(id, text_map) values (1, {'k1':'v1', 'k2':'v2'})");
execute("INSERT INTO %s(id, text_map) values (2, {'k1':'v1', 'k3':'v3'})");
execute("INSERT INTO %s(id, text_map) values (3, {'k4':'v4', 'k5':'v5'})");

View File

@ -43,9 +43,9 @@ public class SingleNodeExecutor implements BaseDataModel.Executor
}
@Override
public void waitForIndexQueryable(String keyspace, String table)
public void waitForIndexQueryable(String keyspace, String index)
{
tester.waitForIndexQueryable(keyspace, table);
tester.waitForIndexQueryable(keyspace, index);
}
@Override

View File

@ -70,6 +70,7 @@ import org.apache.cassandra.schema.IndexMetadata;
import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.utils.Throwables;
import org.assertj.core.api.Assertions;
import org.mockito.Mockito;
import static java.util.Collections.singletonList;
@ -257,7 +258,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
createIndex("CREATE CUSTOM INDEX IF NOT EXISTS ON %s(val) USING 'StorageAttachedIndex' ");
createIndex("CREATE CUSTOM INDEX IF NOT EXISTS ON %s(val) USING 'StorageAttachedIndex' ");
createIndexAsync("CREATE CUSTOM INDEX IF NOT EXISTS ON %s(val) USING 'StorageAttachedIndex' ");
assertEquals(1, saiCreationCounter.get());
}
@ -334,7 +335,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
flush();
executeNet("CREATE CUSTOM INDEX index_1 ON %s(v1) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
waitForTableIndexesQueryable();
// same name
assertThatThrownBy(() -> executeNet("CREATE CUSTOM INDEX index_1 ON %s(v1) USING 'StorageAttachedIndex'"))
@ -365,7 +366,6 @@ public class StorageAttachedIndexDDLTest extends SAITester
execute("INSERT INTO %s (id1, v1) VALUES ('" + i + "', '0')");
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
ResultSet rows = executeNet("SELECT id1 FROM %s WHERE v1='0'");
assertEquals(rowCount, rows.all().size());
@ -384,7 +384,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
// Create the index, but do not allow the initial index build to begin:
Injections.inject(delayInitializationTask);
createIndex("CREATE CUSTOM INDEX ON %s(val) USING 'StorageAttachedIndex'");
createIndexAsync("CREATE CUSTOM INDEX ON %s(val) USING 'StorageAttachedIndex'");
// Flush the Memtable's contents, which will feed data to the index as the SSTable is written:
flush();
@ -392,7 +392,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
// Allow the initialization task, which builds the index, to continue:
delayInitializationTask.countDown();
waitForIndexQueryable();
waitForTableIndexesQueryable();
ResultSet rows = executeNet("SELECT id FROM %s WHERE val = 'Camel'");
assertEquals(1, rows.all().size());
@ -410,7 +410,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
execute("INSERT INTO %s (id1, v1) VALUES ('" + i + "', '0')");
Injections.inject(forceFlushPause);
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1"));
assertThatThrownBy(() -> executeNet("SELECT id1 FROM %s WHERE v1='0'")).isInstanceOf(ReadFailureException.class);
}
@ -427,7 +427,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
flush();
Injections.inject(failSAIInitialializaion);
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForAssert(() -> assertEquals(1, indexBuildCounter.get()));
waitForCompactions();
@ -478,7 +478,6 @@ public class StorageAttachedIndexDDLTest extends SAITester
verifyNoIndexFiles();
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
verifyIndexFiles(literalIndexContext, 2);
ResultSet rows = executeNet("SELECT id1 FROM %s WHERE v1='0'");
assertEquals(2, rows.all().size());
@ -501,7 +500,6 @@ public class StorageAttachedIndexDDLTest extends SAITester
verifyNoIndexFiles();
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
verifyIndexFiles(literalIndexContext, 2);
ResultSet rows = executeNet("SELECT id1 FROM %s WHERE v1='0'");
assertEquals(2, rows.all().size());
@ -571,9 +569,9 @@ public class StorageAttachedIndexDDLTest extends SAITester
if (concurrentTruncate)
{
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1"));
truncate(true);
waitForIndexQueryable();
waitForTableIndexesQueryable();
}
else
{
@ -721,7 +719,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
try
{
// Create a new index, which will actuate a build compaction and fail, but leave the node running...
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
IndexContext literalIndexContext = createIndexContext(createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
// two index builders running in different compaction threads because of parallelised index initial build
waitForAssert(() -> assertEquals(2, indexBuildCounter.get()));
waitForCompactionsFinished();
@ -729,7 +727,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
// Only token/primary key files for the first SSTable in the compaction task should exist, while column-specific files are blown away:
verifyIndexFiles(literalIndexContext, 2, 0, 0);
assertFalse(isIndexQueryable());
Assertions.assertThat(getNotQueryableIndexes()).isNotEmpty();
assertZeroSegmentBuilderUsage();
}
@ -757,7 +755,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
try
{
// Create a new index, which will actuate a build compaction and fail, but leave the node running...
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1"));
// two index builders running in different compaction threads because of parallelised index initial build
waitForAssert(() -> assertEquals(2, indexBuildCounter.get()));
waitForAssert(() -> assertEquals(0, getCompactionTasks()));
@ -765,7 +763,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
// SSTable-level token/offset file(s) should be removed, while column-specific files never existed:
verifyNoIndexFiles();
assertFalse(isIndexQueryable());
Assertions.assertThat(getNotQueryableIndexes()).isNotEmpty();
assertZeroSegmentBuilderUsage();
}
@ -857,7 +855,6 @@ public class StorageAttachedIndexDDLTest extends SAITester
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
populateData.run();
verifySSTableIndexes(IndexMetadata.generateDefaultIndexName(currentTable(), V1_COLUMN_IDENTIFIER), 2, 0);
@ -895,7 +892,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
.build();
Injections.inject(delayIndexBuilderCompletion);
String indexName = createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
String indexName = createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForAssert(() -> assertEquals(1, delayIndexBuilderCompletion.getCount()));
dropIndex("DROP INDEX %s." + indexName);
@ -911,7 +908,6 @@ public class StorageAttachedIndexDDLTest extends SAITester
// create index again, it should succeed
indexName = createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
verifySSTableIndexes(indexName, 1);
ResultSet rows = executeNet("SELECT id1 FROM %s WHERE v1='0'");
@ -940,7 +936,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
Injections.inject(delayIndexBuilderCompletion);
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
IndexContext literalIndexContext = createIndexContext(createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForAssert(() -> assertTrue(getCompactionTasks() > 0), 1000, TimeUnit.MILLISECONDS);
@ -963,7 +959,7 @@ public class StorageAttachedIndexDDLTest extends SAITester
// initial index builder should have stopped abruptly resulting in the index not being queryable
verifyInitialIndexFailed(literalIndexContext.getIndexName());
assertFalse(isIndexQueryable());
Assertions.assertThat(getNotQueryableIndexes()).isNotEmpty();
ColumnFamilyStore cfs = Keyspace.open(KEYSPACE).getColumnFamilyStore(currentTable());
for (Index i : cfs.indexManager.listIndexes())

View File

@ -97,7 +97,6 @@ public abstract class IndexingTypeSupport extends SAITester
{
for (String index : dataset.decorateIndexColumn("value"))
createIndex(String.format("CREATE CUSTOM INDEX ON %%s(%s) USING 'StorageAttachedIndex'", index));
waitForIndexQueryable();
}
insertData(this, allRows, scenario);
@ -115,7 +114,6 @@ public abstract class IndexingTypeSupport extends SAITester
flush();
for (String index : dataset.decorateIndexColumn("value"))
createIndex(String.format("CREATE CUSTOM INDEX ON %%s(%s) USING 'StorageAttachedIndex'", index));
waitForIndexQueryable();
break;
}

View File

@ -47,6 +47,7 @@ import org.apache.cassandra.inject.Injection;
import org.apache.cassandra.inject.Injections;
import org.apache.cassandra.inject.InvokePointBuilder;
import org.apache.cassandra.schema.Schema;
import org.assertj.core.api.Assertions;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -241,7 +242,7 @@ public class NodeStartupTest extends SAITester
{
populator.populate(this);
assertTrue(isIndexQueryable());
Assertions.assertThat(getNotQueryableIndexes()).isEmpty();
assertTrue(isGroupIndexComplete());
assertTrue(isColumnIndexComplete());
Assert.assertEquals(expectedDocuments, execute("SELECT * FROM %s WHERE v1 = '0'").size());
@ -252,7 +253,7 @@ public class NodeStartupTest extends SAITester
simulateNodeRestart();
assertTrue(isIndexQueryable());
Assertions.assertThat(getNotQueryableIndexes()).isEmpty();
assertTrue(isGroupIndexComplete());
assertTrue(isColumnIndexComplete());
Assert.assertEquals(expectedDocuments, execute("SELECT * FROM %s WHERE v1 = '0'").size());

View File

@ -63,8 +63,6 @@ public class SelectiveIntersectionTest extends SAITester
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v2"));
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v3"));
waitForIndexQueryable();
for (int i = 0; i < 100; ++i)
{
execute("INSERT INTO %s(pk,v1,v2,v3) VALUES (?, ?, ?, ?)", i, Integer.toString(i), Integer.toString(i / 20), Integer.toString(i % 10));

View File

@ -73,7 +73,6 @@ public class SingleNodeQueryFailureTest extends SAITester
createTable(CREATE_TABLE_TEMPLATE);
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
execute("INSERT INTO %s (id, v1) VALUES ('1', '0')");
flush();

View File

@ -121,7 +121,6 @@ public class CompactionTest extends SAITester
{
createTable(CREATE_TABLE_TEMPLATE);
String v1IndexName = createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
int num = 10;
for (int i = 0; i < num; i++)
@ -249,7 +248,6 @@ public class CompactionTest extends SAITester
// build indexes on SSTables that will be compacted soon
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
// continue in-progress compaction
compactionLatch.countDown();

View File

@ -41,7 +41,6 @@ public class DiskSpaceTest extends SAITester
// create index, disk space should include index components
String indexName = createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
long indexSize = indexDiskSpaceUse();
long sstableSizeWithIndex = totalDiskSpaceUsed();

View File

@ -50,7 +50,6 @@ public class DropTableTest extends SAITester
{
createTable(CREATE_TABLE_TEMPLATE);
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
int rows = 100;
for (int j = 0; j < rows; j++)

View File

@ -110,7 +110,7 @@ public class FailureTest extends SAITester
Injection ssTableContextCreationFailure = newFailureOnEntry("context_failure_on_creation", SSTableContext.class, "<init>", RuntimeException.class);
Injections.inject(ssTableContextCreationFailure);
String v1IndexName = createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
String v1IndexName = createIndexAsync(String.format(CREATE_INDEX_TEMPLATE, "v1"));
// Verify that the initial index build fails...
verifyInitialIndexFailed(v1IndexName);

View File

@ -46,7 +46,6 @@ public class GroupComponentsTest extends SAITester
{
createTable("CREATE TABLE %s (pk int primary key, value text)");
createIndex("CREATE CUSTOM INDEX ON %s(value) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
execute("INSERT INTO %s (pk) VALUES (1)");
flush();
@ -72,7 +71,6 @@ public class GroupComponentsTest extends SAITester
{
createTable("CREATE TABLE %s (pk int primary key, value text)");
createIndex("CREATE CUSTOM INDEX ON %s(value) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
execute("INSERT INTO %s (pk) VALUES (1)");
flush();
@ -94,7 +92,6 @@ public class GroupComponentsTest extends SAITester
{
createTable("CREATE TABLE %s (pk int primary key, value text)");
IndexContext indexContext = createIndexContext(createIndex("CREATE CUSTOM INDEX ON %s(value) USING 'StorageAttachedIndex'"), UTF8Type.instance);
waitForIndexQueryable();
execute("INSERT INTO %s (pk, value) VALUES (1, '1')");
flush();

View File

@ -30,8 +30,7 @@ import org.apache.cassandra.index.sai.StorageAttachedIndex;
import org.apache.cassandra.inject.Injection;
import org.apache.cassandra.inject.Injections;
import org.apache.cassandra.inject.InvokePointBuilder;
import static org.junit.Assert.assertFalse;
import org.assertj.core.api.Assertions;
public class NodeRestartTest extends SAITester
{
@ -65,7 +64,7 @@ public class NodeRestartTest extends SAITester
// We should have completed no actual SSTable validations:
assertValidationCount(0, 0);
assertFalse(isIndexQueryable());
Assertions.assertThat(getNotQueryableIndexes()).isNotEmpty();
}
// We don't allow the node to actually join the ring before a valid index is ready to accept queries.
@ -113,7 +112,6 @@ public class NodeRestartTest extends SAITester
flush();
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
verifyIndexFiles(literalIndexContext, 1);
assertNumRows(1, "SELECT * FROM %%s WHERE v1 = '0'");
assertValidationCount(0, 0);
@ -124,7 +122,7 @@ public class NodeRestartTest extends SAITester
assertNumRows(1, "SELECT * FROM %%s WHERE v1 = '0'");
waitForIndexQueryable();
waitForTableIndexesQueryable();
// index components are included after restart
verifyIndexComponentsIncludedInSSTable();
@ -172,7 +170,6 @@ public class NodeRestartTest extends SAITester
flush();
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
verifyIndexFiles(literalIndexContext, 1);
assertNumRows(1, "SELECT * FROM %%s WHERE v1 = '0'");
assertValidationCount(0, 0);

View File

@ -52,7 +52,6 @@ public class SnapshotTest extends SAITester
// Insert some initial data and create the index over it
execute("INSERT INTO %s (id1, v1) VALUES ('0', '0');");
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
flush();
verifyIndexFiles(literalIndexContext, 1, 1, 1);
// Note: This test will fail here if it is run on its own because the per-index validation
@ -130,7 +129,6 @@ public class SnapshotTest extends SAITester
// create index
IndexContext literalIndexContext = createIndexContext(createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1")), UTF8Type.instance);
waitForIndexQueryable();
verifyIndexFiles(literalIndexContext, 2);
assertValidationCount(0, 0);

View File

@ -83,7 +83,6 @@ public class QueryMetricsTest extends AbstractMetricsTest
createTable(String.format(CREATE_TABLE_TEMPLATE, keyspace, table));
createIndex(String.format(CREATE_INDEX_TEMPLATE, index, keyspace, table, "v1"));
waitForIndexQueryable(keyspace, table);
execute("INSERT INTO " + keyspace + '.' + table + " (id1, v1, v2) VALUES ('0', 0, '0')");

View File

@ -169,7 +169,6 @@ public abstract class SegmentFlushingFailureTester extends SAITester
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
String table2 = createTable(CREATE_TABLE_TEMPLATE);
createIndex(String.format(CREATE_INDEX_TEMPLATE, "v1"));
waitForIndexQueryable();
assertEquals(expectedBytesLimit(), getSegmentBufferSpaceLimit());
assertEquals("Segment buffer memory tracker should start at zero!", 0L, getSegmentBufferUsedBytes());

View File

@ -48,7 +48,6 @@ public class StateMetricsTest extends AbstractMetricsTest
createTable(String.format(CREATE_TABLE_TEMPLATE, keyspace, table));
createIndex(String.format(CREATE_INDEX_TEMPLATE, index, keyspace, table, "v1"));
waitForIndexQueryable(keyspace, table);
execute("INSERT INTO " + keyspace + '.' + table + " (id1, v1, v2) VALUES ('0', 0, '0')");
@ -73,9 +72,8 @@ public class StateMetricsTest extends AbstractMetricsTest
String keyspace = createKeyspace(CREATE_KEYSPACE_TEMPLATE);
createTable(String.format(CREATE_TABLE_TEMPLATE, keyspace, table));
createIndex(String.format(CREATE_INDEX_TEMPLATE, index+"_v1", keyspace, table, "v1"));
createIndex(String.format(CREATE_INDEX_TEMPLATE, index+"_v2", keyspace, table, "v2"));
waitForIndexQueryable(keyspace, table);
createIndex(String.format(CREATE_INDEX_TEMPLATE, index + "_v1", keyspace, table, "v1"));
createIndex(String.format(CREATE_INDEX_TEMPLATE, index + "_v2", keyspace, table, "v2"));
execute("INSERT INTO " + keyspace + '.' + table + " (id1, v1, v2) VALUES ('0', 0, '0')");
execute("INSERT INTO " + keyspace + '.' + table + " (id1, v1, v2) VALUES ('1', 1, '1')");

View File

@ -78,7 +78,7 @@ public class OperationTest
private static final String KS_NAME = "sai";
private static final String CF_NAME = "test_cf";
private static final String CLUSTERING_CF_NAME = "clustering_test_cf";
private static final String STATIC_CF_NAME = "static_ndi_test_cf";
private static final String STATIC_CF_NAME = "static_sai_test_cf";
private static ColumnFamilyStore BACKEND;
private static ColumnFamilyStore CLUSTERING_BACKEND;

View File

@ -73,14 +73,14 @@ public class IndexesSystemViewTest extends SAITester
// create the index simulating a long build and verify that there is an empty record in the virtual table
Injections.inject(blockIndexBuild);
String v1IndexName = createIndex(String.format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
String v1IndexName = createIndexAsync(String.format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
assertRows(execute(SELECT), row(v1IndexName, "v1", false, true, true));
// unblock the long build and verify that there is a finished empty record in the virtual table
blockIndexBuild.countDown();
blockIndexBuild.disable();
waitForIndexQueryable();
waitForTableIndexesQueryable();
assertRows(execute(SELECT), row(v1IndexName, "v1", true, false, true));
// insert some data and verify that virtual table record is still empty since we haven't flushed yet

View File

@ -74,7 +74,6 @@ public class SSTablesSystemViewTest extends SAITester
{
createTable("CREATE TABLE %s (k text, c text, v1 text, v2 text, PRIMARY KEY (k, c))");
String v1IndexName = createIndex("CREATE CUSTOM INDEX ON %s(v1) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
String insert = "INSERT INTO %s(k, c, v1, v2) VALUES (?, ?, ?, ?)";
@ -101,7 +100,6 @@ public class SSTablesSystemViewTest extends SAITester
// create a second index, this should create a new additional entry in the table for each sstable
String v2IndexName = createIndex("CREATE CUSTOM INDEX ON %s(v2) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
Object[] row3 = readRow(v2IndexName, id1, "v2", 1L, 0L, 0L);
Object[] row4 = readRow(v2IndexName, id2, "v2", 2L, 0L, 1L);
assertRowsIgnoringOrder(execute(SELECT), row1, row2, row3, row4);

View File

@ -92,7 +92,6 @@ public class SegmentsSystemViewTest extends SAITester
{
createTable("CREATE TABLE %s (k int, c int, v1 text, PRIMARY KEY (k, c))");
String literalIndex = createIndex("CREATE CUSTOM INDEX ON %s(v1) USING 'StorageAttachedIndex'");
waitForIndexQueryable();
int num = 100;