mozreview: send a series of commands to SQLite running in docker container (bug 1248008) r=smacleod draft
authorPiotr Zalewa <pzalewa@mozilla.com>
Tue, 31 Jan 2017 08:45:27 +0100
changeset 10419 76de7a741f4cabff73ffc0421358ef3f79a775f6
parent 10411 e01531f0d4e1a3d4ea0b7de00c740ba1376f1eda
child 10420 fc01e3bb606a0503bc20e965421b9e9e8399b6a9
push id1535
push userbmo:pzalewa@mozilla.com
push dateFri, 17 Feb 2017 12:08:20 +0000
reviewerssmacleod
bugs1248008
mozreview: send a series of commands to SQLite running in docker container (bug 1248008) r=smacleod Sending a series of commands to SQLite is a complicated process, it involves creating a file, copying it over to docker container and finally ordering SQLite to read from it. This patch is creating a `mozreview sql` mach command to make the process simple to use within integration tests. Command reads from STDIN and creates a temporary file which is copied to docker container. After SQLite finishes, all created files are removed. MozReview-Commit-ID: Gaj9SnHd9Jf
testing/vcttesting/mozreview_mach_commands.py
--- a/testing/vcttesting/mozreview_mach_commands.py
+++ b/testing/vcttesting/mozreview_mach_commands.py
@@ -1,15 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import argparse
 import os
 import subprocess
+import sys
+import tempfile
 
 from mach.decorators import (
     CommandArgument,
     CommandProvider,
     Command,
 )
 
 
@@ -363,8 +365,51 @@ class MozReviewCommands(object):
                               shell=True)
         subprocess.check_call('docker exec %s tar -C %s -zxf /rb.tgz' % (
                               mr.rbweb_id, rbweb_site_packages),
                               shell=True)
 
         print('restarting rbweb container')
         subprocess.check_call('docker exec %s /kill-wsgi-procs' % mr.rbweb_id,
                               shell=True)
+
+    @Command('sql', category='mozreview',
+             description='Send commands to sqlite database')
+    @CommandArgument('name', help='Name of container to shell into',
+                     choices={'rbweb'})
+    def sql(self, name):
+        """Run sequence of SQL commands provided in STDIN.
+
+        A tempporary file is created in local filesystem and then copied to the
+        docker container. It is used by sqlite to run stored command sequence.
+        After that file is deleted on the container.
+        """
+        mr = self._get_mozreview(None)
+        container_id = getattr(mr, '%s_id' % name, None)
+        if not container_id:
+            print('No container for %s was found running' % name)
+            return 1
+
+        # Read SQL commands from stdin and store in temp file which will be
+        # deleted when closed.
+        with tempfile.NamedTemporaryFile('w+b') as f:
+            for line in sys.stdin:
+                f.write(line)
+            f.flush()
+            os.fsync(f.fileno())
+
+            # Copy file to the container.
+            subprocess.check_call(
+                'docker cp %(file)s %(container_id)s:/temp_query_file.sql' %
+                {'file': f.name, 'container_id': container_id}, shell=True)
+
+        args = '' if 'TESTTMP' in os.environ else '-it'
+        # Run queries from file on the container's database.
+        subprocess.check_call(
+            'docker exec %(args)s %(container_id)s bash -c "%(sql_cmd)s"' % {
+                'sql_cmd': ('sqlite3 /reviewboard/data/reviewboard.db '
+                            '< /temp_query_file.sql'),
+                'args': args, 'container_id': container_id}, shell=True)
+
+        # Remove the file from the container.
+        subprocess.check_call(
+            'docker exec %(args)s %(container_id)s rm /temp_query_file.sql' % {
+                'args': args, 'container_id': container_id}, shell=True)