maedhroz commented on code in PR #2329:
URL: https://github.com/apache/cassandra/pull/2329#discussion_r1192835455
##########
test/unit/org/apache/cassandra/cql3/CQLTester.java:
##########
@@ -1031,122 +1034,222 @@ protected void alterTableMayThrow(String query)
throws Throwable
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;
+ }
+
+ /**
+ * 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;
}
- protected String createFormattedIndex(String formattedQuery)
+ 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;
+ if (Strings.isNullOrEmpty(index))
+ {
+ String table = matcher.group(7);
+ if (Strings.isNullOrEmpty(table))
+ throw new IllegalArgumentException("Table name should be
specified: " + formattedQuery);
+
+ String column = matcher.group(9);
- String keyspace = matcher.group(5);
- if (Strings.isNullOrEmpty(keyspace))
- throw new IllegalArgumentException("Keyspace name should be
specified: " + formattedQuery);
+ String baseName = Strings.isNullOrEmpty(column)
+ ? IndexMetadata.generateDefaultIndexName(table)
+ : IndexMetadata.generateDefaultIndexName(table,
new ColumnIdentifier(column, true));
- String table = matcher.group(7);
- if (Strings.isNullOrEmpty(table))
- throw new IllegalArgumentException("Table name should be
specified: " + formattedQuery);
+ KeyspaceMetadata ks =
Schema.instance.getKeyspaceMetadata(keyspace);
+ assertNotNull(ks);
+ index = ks.findAvailableIndexName(baseName);
+ }
+
+ index = ParseUtils.isQuoted(index, '\"')
+ ? ParseUtils.unDoubleQuote(index)
+ : index.toLowerCase();
- String column = matcher.group(9);
+ return Pair.create(keyspace, index);
+ }
- String baseName = Strings.isNullOrEmpty(column)
- ? IndexMetadata.generateDefaultIndexName(table)
- : IndexMetadata.generateDefaultIndexName(table, new
ColumnIdentifier(column, true));
+ public void waitForTableIndexesQueryable()
+ {
+ waitForTableIndexesQueryable(currentTable());
+ }
- KeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspace);
- return ks.findAvailableIndexName(baseName);
+ public void waitForTableIndexesQueryable(String table)
+ {
+ waitForTableIndexesQueryable(KEYSPACE, table);
}
/**
- * 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.
+ * 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
*/
- protected boolean waitForIndex(String keyspace, String table, String
index) throws Throwable
+ public void waitForTableIndexesQueryable(String keyspace, String table)
{
- long start = currentTimeMillis();
- boolean indexCreated = false;
- while (!indexCreated)
- {
- 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;
- }
- }
+ waitForAssert(() -> assertTrue(areTableIndexesQueryable(keyspace,
table)), 60, TimeUnit.SECONDS);
+ }
- if (currentTimeMillis() - start > 5000)
- break;
+ public void waitForIndexQueryable(String index)
+ {
+ waitForIndexQueryable(KEYSPACE, index);
+ }
- Thread.sleep(10);
- }
+ /**
+ * Index creation is asynchronous, this method waits until the specified
index is queryable.
+ *
+ * @param keyspace the index keyspace name
+ * @param index the index name
+ */
+ public void waitForIndexQueryable(String keyspace, String index)
+ {
+ waitForAssert(() -> assertTrue(isIndexQueryable(keyspace, index)), 60,
TimeUnit.SECONDS);
+ }
- return indexCreated;
+ 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 #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.
+ * 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 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
+ protected void waitForIndexBuilds(String keyspace, String index)
+ {
+ waitForAssert(() -> assertFalse(isIndexBuilding(keyspace, index)), 60,
TimeUnit.SECONDS);
+ }
+
+ protected boolean areTableIndexesQueryable()
{
- long start = currentTimeMillis();
- SecondaryIndexManager indexManager =
getCurrentColumnFamilyStore(keyspace).indexManager;
+ return areTableIndexesQueryable(KEYSPACE, currentTable());
+ }
- while (true)
+ protected boolean areTableIndexesQueryable(String keyspace, String table)
Review Comment:
The test failures we're seeing lead me to believe that we should actually
have this method return the set of indexes that haven't yet become queryable.
That might give us some insight into what's going on if the assertion times
out. (In other words, we can use `assertEquals(<empty set>,
areTableIndexesQueryable(...))` in `waitForTableIndexesQueryable()` and get
more information on failure to help debug.)
##########
test/unit/org/apache/cassandra/cql3/CQLTester.java:
##########
@@ -1031,122 +1034,222 @@ protected void alterTableMayThrow(String query)
throws Throwable
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;
+ }
+
+ /**
+ * 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;
}
- protected String createFormattedIndex(String formattedQuery)
+ 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;
+ if (Strings.isNullOrEmpty(index))
+ {
+ String table = matcher.group(7);
+ if (Strings.isNullOrEmpty(table))
+ throw new IllegalArgumentException("Table name should be
specified: " + formattedQuery);
+
+ String column = matcher.group(9);
- String keyspace = matcher.group(5);
- if (Strings.isNullOrEmpty(keyspace))
- throw new IllegalArgumentException("Keyspace name should be
specified: " + formattedQuery);
+ String baseName = Strings.isNullOrEmpty(column)
+ ? IndexMetadata.generateDefaultIndexName(table)
+ : IndexMetadata.generateDefaultIndexName(table,
new ColumnIdentifier(column, true));
- String table = matcher.group(7);
- if (Strings.isNullOrEmpty(table))
- throw new IllegalArgumentException("Table name should be
specified: " + formattedQuery);
+ KeyspaceMetadata ks =
Schema.instance.getKeyspaceMetadata(keyspace);
+ assertNotNull(ks);
+ index = ks.findAvailableIndexName(baseName);
+ }
+
+ index = ParseUtils.isQuoted(index, '\"')
+ ? ParseUtils.unDoubleQuote(index)
+ : index.toLowerCase();
- String column = matcher.group(9);
+ return Pair.create(keyspace, index);
+ }
- String baseName = Strings.isNullOrEmpty(column)
- ? IndexMetadata.generateDefaultIndexName(table)
- : IndexMetadata.generateDefaultIndexName(table, new
ColumnIdentifier(column, true));
+ public void waitForTableIndexesQueryable()
+ {
+ waitForTableIndexesQueryable(currentTable());
+ }
- KeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspace);
- return ks.findAvailableIndexName(baseName);
+ public void waitForTableIndexesQueryable(String table)
+ {
+ waitForTableIndexesQueryable(KEYSPACE, table);
}
/**
- * 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.
+ * 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
*/
- protected boolean waitForIndex(String keyspace, String table, String
index) throws Throwable
+ public void waitForTableIndexesQueryable(String keyspace, String table)
{
- long start = currentTimeMillis();
- boolean indexCreated = false;
- while (!indexCreated)
- {
- 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;
- }
- }
+ waitForAssert(() -> assertTrue(areTableIndexesQueryable(keyspace,
table)), 60, TimeUnit.SECONDS);
+ }
- if (currentTimeMillis() - start > 5000)
- break;
+ public void waitForIndexQueryable(String index)
+ {
+ waitForIndexQueryable(KEYSPACE, index);
+ }
- Thread.sleep(10);
- }
+ /**
+ * Index creation is asynchronous, this method waits until the specified
index is queryable.
+ *
+ * @param keyspace the index keyspace name
+ * @param index the index name
+ */
+ public void waitForIndexQueryable(String keyspace, String index)
+ {
+ waitForAssert(() -> assertTrue(isIndexQueryable(keyspace, index)), 60,
TimeUnit.SECONDS);
+ }
- return indexCreated;
+ 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 #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.
+ * 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 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
+ protected void waitForIndexBuilds(String keyspace, String index)
+ {
+ waitForAssert(() -> assertFalse(isIndexBuilding(keyspace, index)), 60,
TimeUnit.SECONDS);
+ }
+
+ protected boolean areTableIndexesQueryable()
{
- long start = currentTimeMillis();
- SecondaryIndexManager indexManager =
getCurrentColumnFamilyStore(keyspace).indexManager;
+ return areTableIndexesQueryable(KEYSPACE, currentTable());
+ }
- while (true)
+ protected boolean areTableIndexesQueryable(String keyspace, String table)
Review Comment:
https://app.circleci.com/pipelines/github/adelapena/cassandra/2892/workflows/837b186e-6cd9-442c-baaf-8bc067f56b21/jobs/43816/tests#failed-test-0
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]