Repository: cassandra-dtest
Updated Branches:
  refs/heads/master 104835d88 -> c0d9c9744


Add basic tests for fqltool replay+compare

Patch by marcuse; reviewed by Stefan Podkowinski for CASSANDRA-14690


Project: http://git-wip-us.apache.org/repos/asf/cassandra-dtest/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra-dtest/commit/c0d9c974
Tree: http://git-wip-us.apache.org/repos/asf/cassandra-dtest/tree/c0d9c974
Diff: http://git-wip-us.apache.org/repos/asf/cassandra-dtest/diff/c0d9c974

Branch: refs/heads/master
Commit: c0d9c97442434806ae074d0de3605366effc2e60
Parents: 104835d
Author: Marcus Eriksson <[email protected]>
Authored: Wed Sep 5 09:33:35 2018 +0200
Committer: Marcus Eriksson <[email protected]>
Committed: Fri Oct 19 08:43:10 2018 +0200

----------------------------------------------------------------------
 fqltool_test.py | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra-dtest/blob/c0d9c974/fqltool_test.py
----------------------------------------------------------------------
diff --git a/fqltool_test.py b/fqltool_test.py
new file mode 100644
index 0000000..f175e58
--- /dev/null
+++ b/fqltool_test.py
@@ -0,0 +1,159 @@
+import pytest
+import logging
+import os
+import subprocess
+import tempfile
+
+from dtest import Tester
+from shutil import rmtree
+
+since = pytest.mark.since
+logger = logging.getLogger(__name__)
+
+
+@since('4.0')
+class TestFQLTool(Tester):
+    """
+    Makes sure fqltool replay and fqltool compare work
+    @jira_ticket CASSANDRA-14690
+    """
+    def test_replay(self):
+        """
+        Generates a full query log, wipes the nodes and replays the
+        query log, then makes sure that the data is correct.
+        @jira_ticket CASSANDRA-14690
+        """
+        self.cluster.populate(2).start(wait_for_binary_proto=True)
+        node1, node2 = self.cluster.nodelist()
+
+        with tempfile.TemporaryDirectory() as temp_dir:
+            tmpdir = tempfile.mkdtemp(dir=temp_dir)
+            tmpdir2 = tempfile.mkdtemp(dir=temp_dir)
+            node1.nodetool("enablefullquerylog --path={}".format(tmpdir))
+            node2.nodetool("enablefullquerylog --path={}".format(tmpdir2))
+            node1.stress(['write', 'n=1000'])
+            node1.flush()
+            node2.flush()
+            node1.nodetool("disablefullquerylog")
+            node2.nodetool("disablefullquerylog")
+            node1.stop(wait_other_notice=True)
+            node2.stop(wait_other_notice=True)
+            node1.clear()
+            node2.clear()
+
+            node1.start(wait_for_binary_proto=True)
+            node2.start(wait_for_binary_proto=True, wait_other_notice=True)
+            # make sure the node is empty:
+            got_exception = False
+            try:
+                node1.stress(['read', 'n=1000'])
+            except Exception:
+                got_exception = True
+            assert got_exception
+            # replay the log files
+            self._run_fqltool_replay(node1, [tmpdir, tmpdir2], "127.0.0.1", 
None, None)
+            # and verify the data is there
+            node1.stress(['read', 'n=1000'])
+
+    def test_compare(self):
+        """
+        uses fqltool replay to compare two runs of the same query log and makes
+        sure that the results match
+        @jira_ticket CASSANDRA-14690
+        """
+        self.cluster.populate(1).start(wait_for_binary_proto=True)
+        node1 = self.cluster.nodelist()[0]
+
+        with tempfile.TemporaryDirectory() as temp_dir:
+            results1 = tempfile.mkdtemp(dir=temp_dir)
+            queries1 = tempfile.mkdtemp(dir=temp_dir)
+            results2 = tempfile.mkdtemp(dir=temp_dir)
+            queries2 = tempfile.mkdtemp(dir=temp_dir)
+            fqldir = tempfile.mkdtemp(dir=temp_dir)
+
+            node1.stress(['write', 'n=1000'])
+            node1.flush()
+            node1.nodetool("enablefullquerylog --path={}".format(fqldir))
+            node1.stress(['read', 'n=1000'])
+            node1.nodetool("disablefullquerylog")
+            self._run_fqltool_replay(node1, [fqldir], "127.0.0.1", queries1, 
results1)
+            self._run_fqltool_replay(node1, [fqldir], "127.0.0.1", queries2, 
results2)
+            output = self._run_fqltool_compare(node1, queries1, [results1, 
results2])
+            assert b"MISMATCH" not in output  # running the same reads against 
the same data
+
+    def test_compare_mismatch(self):
+        """
+        generates two fql log files with different data (seq is different when 
running stress)
+        then asserts that the replays of each generates a mismatch
+        @jira_ticket CASSANDRA-14690
+        """
+        self.cluster.populate(1).start(wait_for_binary_proto=True)
+        node1 = self.cluster.nodelist()[0]
+
+        with tempfile.TemporaryDirectory() as temp_dir:
+            fqldir1 = tempfile.mkdtemp(dir=temp_dir)
+            fqldir2 = tempfile.mkdtemp(dir=temp_dir)
+            results1 = tempfile.mkdtemp(dir=temp_dir)
+            queries1 = tempfile.mkdtemp(dir=temp_dir)
+            results2 = tempfile.mkdtemp(dir=temp_dir)
+            queries2 = tempfile.mkdtemp(dir=temp_dir)
+
+            node1.nodetool("enablefullquerylog --path={}".format(fqldir1))
+            node1.stress(['write', 'n=1000'])
+            node1.flush()
+            node1.stress(['read', 'n=1000'])
+            node1.nodetool("disablefullquerylog")
+
+            node1.stop()
+            for d in node1.data_directories():
+                rmtree(d)
+                os.mkdir(d)
+            node1.start(wait_for_binary_proto=True)
+
+            node1.nodetool("enablefullquerylog --path={}".format(fqldir2))
+            node1.stress(['write', 'n=1000', '-pop', 'seq=1000..2000'])
+            node1.flush()
+            node1.stress(['read', 'n=1000', '-pop', 'seq=1000..2000'])
+            node1.nodetool("disablefullquerylog")
+            node1.stop()
+            for d in node1.data_directories():
+                rmtree(d)
+                os.mkdir(d)
+            node1.start(wait_for_binary_proto=True)
+
+            self._run_fqltool_replay(node1, [fqldir1], "127.0.0.1", queries1, 
results1)
+            node1.stop()
+            for d in node1.data_directories():
+                rmtree(d)
+                os.mkdir(d)
+            node1.start(wait_for_binary_proto=True)
+            self._run_fqltool_replay(node1, [fqldir2], "127.0.0.1", queries2, 
results2)
+
+            output = self._run_fqltool_compare(node1, queries1, [results1, 
results2])
+            assert b"MISMATCH" in output  # compares two different stress 
runs, should mismatch
+
+    def _run_fqltool_replay(self, node, logdirs, target, queries, results):
+        fqltool = self.fqltool(node)
+        args = [fqltool, "replay", "--target {}".format(target)]
+        if queries is not None:
+            args.append("--store-queries {}".format(queries))
+        if results is not None:
+            args.append("--results {}".format(results))
+        args.extend(logdirs)
+        rc = subprocess.call(args)
+        assert rc == 0
+
+    def _run_fqltool_compare(self, node, queries, results):
+        fqltool = self.fqltool(node)
+        args = [fqltool, "compare", "--queries {}".format(queries)]
+        args.extend([os.path.join(r, "127.0.0.1") for r in results])
+        logger.info(args)
+        p = subprocess.Popen(args, stdout=subprocess.PIPE, 
stderr=subprocess.PIPE)
+        (stdout, stderr) = p.communicate()
+        logger.info(stdout)
+        return stdout
+
+    def fqltool(self, node):
+        cdir = node.get_install_dir()
+        fqltool = os.path.join(cdir, 'tools', 'bin', 'fqltool')
+        return fqltool


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to