tolbertam commented on code in PR #3917:
URL: https://github.com/apache/cassandra/pull/3917#discussion_r2040848056
##########
test/unit/org/apache/cassandra/cql3/PstmtPersistenceTest.java:
##########
@@ -142,19 +148,103 @@ public void testPstmtInvalidation() throws Throwable
createTable("CREATE TABLE %s (key int primary key, val int)");
+ long initialEvicted = numberOfEvictedStatements();
+
for (int cnt = 1; cnt < 10000; cnt++)
{
prepareStatement("INSERT INTO %s (key, val) VALUES (?, ?) USING
TIMESTAMP " + cnt, clientState);
- if (numberOfEvictedStatements() > 0)
+ if (numberOfEvictedStatements() - initialEvicted > 0)
{
+ assertEquals("Number of statements in table and in cache don't
match", numberOfStatementsInMemory(), numberOfStatementsOnDisk());
+
+ // prepare a more statements to trigger more evictions
+ for (int cnt2 = cnt + 1; cnt2 < cnt + 10; cnt2++)
+ prepareStatement("INSERT INTO %s (key, val) VALUES (?, ?)
USING TIMESTAMP " + cnt2, clientState);
+
+ // each new prepared statement should have caused an eviction
+ assertEquals("eviction count didn't increase by the expected
number", 10, numberOfEvictedStatements() - initialEvicted);
+ assertEquals("Number of statements in memory (expected) and
table (actual) don't match", numberOfStatementsInMemory(),
numberOfStatementsOnDisk());
+
return;
}
}
fail("Prepared statement eviction does not work");
}
+
+
+ @Test
+ public void testAsyncPstmtInvalidation() throws Throwable
+ {
+ ClientState clientState = ClientState.forInternalCalls();
+ createTable("CREATE TABLE %s (key int primary key, val int)");
+
+ // prepare statements concurrently in a thread pool to exercise bug
encountered in CASSANDRA-19703 where
+ // delete from table occurs before the insert due to early eviction.
+ final ExecutorService executor = Executors.newFixedThreadPool(10);
+
+ long initialEvicted = numberOfEvictedStatements();
+ try
+ {
+ int statementsToPrepare = 10000;
+ List<CompletableFuture<MD5Digest>> prepareFutures = new
ArrayList<>(statementsToPrepare);
+ for (int cnt = 1; cnt < statementsToPrepare; cnt++)
+ {
+ final int localCnt = cnt;
+ prepareFutures.add(CompletableFuture.supplyAsync(() ->
prepareStatement("INSERT INTO %s (key, val) VALUES (?, ?) USING TIMESTAMP " +
localCnt, clientState), executor));
+ }
+
+ // Await completion
+
CompletableFuture.allOf(prepareFutures.toArray(futureArray)).get(10,
TimeUnit.SECONDS);
+
+ assertNotEquals("Should have evicted some prepared statements", 0,
numberOfEvictedStatements() - initialEvicted);
+
+ // ensure the number of statements on disk match the number in
memory, if number of statements on disk eclipses in memory, there was a leak.
+ assertEquals("Number of statements in memory (expected) and table
(actual) don't match", numberOfStatementsInMemory(),
numberOfStatementsOnDisk());
+ }
+ finally
+ {
+ executor.shutdown();
+ }
+ }
+
+ @Test
+ public void testPreloadPreparedStatements() throws Throwable
Review Comment:
I couldn't find a good example of paging tests using byteman to assert that
paging actually happened, but I did find a lot of good inspiration in tests
using byteman generally to make this work, hopefully the way I went about this
looks alright.
I figured I would keep this test since `testCachedPreparedStatements` only
creates a very small amount of prepared statements (~7) and working with on the
order of hundreds of statements made it a little easier to validate paging and
also validate the additional logic I had to prevent loading past a maximum
amount of statements.
--
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]