You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2020/06/11 15:25:51 UTC

[james-project] 14/17: JAMES-3204 Allow recording executed Cassandra statements

This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit c4b95da664bc591ef6a01139e6d78553d32dc632
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jun 8 17:36:52 2020 +0700

    JAMES-3204 Allow recording executed Cassandra statements
    
    This enables to test executed statements and allows enabling assertions
    on query count reduction, for performance purpose.
---
 .../james/backends/cassandra/CassandraCluster.java |  4 +-
 .../cassandra/CassandraClusterExtension.java       |  2 +-
 .../backends/cassandra/StatementRecorder.java      | 43 ++++++++++++++++++++++
 .../james/backends/cassandra/TestingSession.java   | 23 ++++++++++++
 .../backends/cassandra/TestingSessionTest.java     | 42 +++++++++++++++++++++
 5 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
index f4b576c..2090236 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.james.backends.cassandra;
 
-import static org.apache.james.backends.cassandra.Scenario.NOTHING;
-
 import java.util.Optional;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
@@ -85,7 +83,7 @@ public final class CassandraCluster implements AutoCloseable {
 
     @Override
     public void close() {
-        nonPrivilegedSession.registerScenario(NOTHING);
+        nonPrivilegedSession.resetInstrumentation();
         if (!nonPrivilegedCluster.isClosed()) {
             clearTables();
             closeCluster();
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterExtension.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterExtension.java
index 603fcf3..68b5478 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterExtension.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraClusterExtension.java
@@ -76,7 +76,7 @@ public class CassandraClusterExtension implements BeforeAllCallback, BeforeEachC
     @Override
     public void afterEach(ExtensionContext extensionContext) {
         cassandraCluster.clearTables();
-        cassandraCluster.getConf().registerScenario(Scenario.NOTHING);
+        cassandraCluster.getConf().resetInstrumentation();
     }
 
     @Override
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java
new file mode 100644
index 0000000..e8773f5
--- /dev/null
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/StatementRecorder.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.james.backends.cassandra;
+
+
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedDeque;
+
+import com.datastax.driver.core.Statement;
+import com.google.common.collect.ImmutableList;
+
+public class StatementRecorder {
+    private final ConcurrentLinkedDeque statements;
+
+    public StatementRecorder() {
+        statements = new ConcurrentLinkedDeque();
+    }
+
+    void recordStatement(Statement statement) {
+        statements.add(statement);
+    }
+
+    public List<Statement> listExecutedStatements() {
+        return ImmutableList.copyOf(statements);
+    }
+}
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java
index f591286..4b9e235 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSession.java
@@ -20,6 +20,7 @@
 package org.apache.james.backends.cassandra;
 
 import java.util.Map;
+import java.util.Optional;
 
 import com.datastax.driver.core.BoundStatement;
 import com.datastax.driver.core.CloseFuture;
@@ -37,17 +38,29 @@ public class TestingSession implements Session {
     private final Session delegate;
     private volatile Scenario scenario;
     private volatile boolean printStatements;
+    private volatile Optional<StatementRecorder> statementRecorder;
 
     public TestingSession(Session delegate) {
         this.delegate = delegate;
         this.scenario = Scenario.NOTHING;
         this.printStatements = false;
+        this.statementRecorder = Optional.empty();
     }
 
     public void printStatements() {
         printStatements = true;
     }
 
+    public void resetInstrumentation() {
+        stopRecordingStatements();
+        stopPrintingStatements();
+        registerScenario(Scenario.NOTHING);
+    }
+
+    public void stopPrintingStatements() {
+        printStatements = false;
+    }
+
     public void registerScenario(Scenario scenario) {
         this.scenario = scenario;
     }
@@ -56,6 +69,14 @@ public class TestingSession implements Session {
         this.scenario = Scenario.combine(hooks);
     }
 
+    public void recordStatements(StatementRecorder statementRecorder) {
+        this.statementRecorder = Optional.of(statementRecorder);
+    }
+
+    public void stopRecordingStatements() {
+        this.statementRecorder = Optional.empty();
+    }
+
     @Override
     public String getLoggedKeyspace() {
         return delegate.getLoggedKeyspace();
@@ -92,6 +113,7 @@ public class TestingSession implements Session {
     @Override
     public ResultSet execute(Statement statement) {
         printStatement(statement);
+        statementRecorder.ifPresent(recorder -> recorder.recordStatement(statement));
         return delegate.execute(statement);
     }
 
@@ -116,6 +138,7 @@ public class TestingSession implements Session {
     @Override
     public ResultSetFuture executeAsync(Statement statement) {
         printStatement(statement);
+        statementRecorder.ifPresent(recorder -> recorder.recordStatement(statement));
         return scenario
             .getCorrespondingBehavior(statement)
             .execute(delegate, statement);
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java
index 27a191a..e496e34 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/TestingSessionTest.java
@@ -42,6 +42,8 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
+import com.datastax.driver.core.BoundStatement;
+
 import reactor.core.scheduler.Schedulers;
 
 class TestingSessionTest {
@@ -73,6 +75,46 @@ class TestingSessionTest {
     }
 
     @Test
+    void recordStatementsShouldKeepTraceOfExecutedStatement(CassandraCluster cassandra) {
+        StatementRecorder statementRecorder = new StatementRecorder();
+        cassandra.getConf().recordStatements(statementRecorder);
+
+        dao.getCurrentSchemaVersion().block();
+
+        assertThat(statementRecorder.listExecutedStatements())
+            .filteredOn(statement -> statement instanceof BoundStatement)
+            .extracting(BoundStatement.class::cast)
+            .extracting(statement -> statement.preparedStatement().getQueryString())
+            .containsExactly("SELECT value FROM schemaVersion;");
+    }
+
+    @Test
+    void recordStatementsShouldKeepTraceOfExecutedStatements(CassandraCluster cassandra) {
+        StatementRecorder statementRecorder = new StatementRecorder();
+        cassandra.getConf().recordStatements(statementRecorder);
+
+        dao.updateVersion(new SchemaVersion(36)).block();
+        dao.getCurrentSchemaVersion().block();
+
+        assertThat(statementRecorder.listExecutedStatements())
+            .filteredOn(statement -> statement instanceof BoundStatement)
+            .extracting(BoundStatement.class::cast)
+            .extracting(statement -> statement.preparedStatement().getQueryString())
+            .containsExactly("INSERT INTO schemaVersion (key,value) VALUES (:key,:value);", "SELECT value FROM schemaVersion;");
+    }
+
+    @Test
+    void recordStatementsShouldNotKeepTraceOfExecutedStatementsBeforeRecording(CassandraCluster cassandra) {
+        dao.getCurrentSchemaVersion().block();
+
+        StatementRecorder statementRecorder = new StatementRecorder();
+        cassandra.getConf().recordStatements(statementRecorder);
+
+        assertThat(statementRecorder.listExecutedStatements())
+            .isEmpty();
+    }
+
+    @Test
     void daoOperationShouldNotBeInstrumentedWhenNotMatching(CassandraCluster cassandra) {
         cassandra.getConf()
             .registerScenario(fail()


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org