[LNT] r309248 - Rework run merge strategies

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 26 20:46:14 PDT 2017


Author: matze
Date: Wed Jul 26 20:46:13 2017
New Revision: 309248

URL: http://llvm.org/viewvc/llvm-project?rev=309248&view=rev
Log:
Rework run merge strategies

You can now choose between 3 different merge strategies:
- reject: Reject submission if a run with the same order already exists.
- replace: Replace existing runs with the same order.
- append: Append to list of runs even if one with the same order already
          exists.

Modified:
    lnt/trunk/lnt/lnttool/common.py
    lnt/trunk/lnt/lnttool/import_data.py
    lnt/trunk/lnt/lnttool/main.py
    lnt/trunk/lnt/server/db/testsuitedb.py
    lnt/trunk/lnt/server/ui/api.py
    lnt/trunk/lnt/server/ui/views.py
    lnt/trunk/lnt/tests/builtintest.py
    lnt/trunk/lnt/tests/compile.py
    lnt/trunk/lnt/tests/nt.py
    lnt/trunk/lnt/tests/test_suite.py
    lnt/trunk/lnt/util/ImportData.py
    lnt/trunk/lnt/util/ServerUtil.py
    lnt/trunk/tests/lnttool/PostgresDB.shtest
    lnt/trunk/tests/lnttool/submit.shtest
    lnt/trunk/tests/server/db/ImportV4TestSuiteInstance.py
    lnt/trunk/tests/server/db/search.py

Modified: lnt/trunk/lnt/lnttool/common.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/lnttool/common.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/lnttool/common.py (original)
+++ lnt/trunk/lnt/lnttool/common.py Wed Jul 26 20:46:13 2017
@@ -1,7 +1,19 @@
 from lnt.util import logger
+import click
 import logging
 
 
+def submit_options(func):
+    func = click.option("--commit", is_flag=True,
+                        help="actually commit the data")(func)
+    func = click.option("--update-machine", is_flag=True,
+                        help="Update machine fields")(func)
+    func = click.option("--merge", default="replace", show_default=True,
+                        type=click.Choice(['reject', 'replace', 'append']),
+                        help="Merge strategy when run already exists")(func)
+    return func
+
+
 def init_logger(loglevel, show_sql=False, stream=None):
     handler = logging.StreamHandler(stream)
     handler.setLevel(loglevel)

Modified: lnt/trunk/lnt/lnttool/import_data.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/lnttool/import_data.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/lnttool/import_data.py (original)
+++ lnt/trunk/lnt/lnttool/import_data.py Wed Jul 26 20:46:13 2017
@@ -1,3 +1,4 @@
+from .common import submit_options
 import click
 import lnt.formats
 
@@ -10,7 +11,6 @@ import lnt.formats
 @click.option("--format", "output_format", show_default=True,
               type=click.Choice(lnt.formats.format_names + ['<auto>']),
               default='<auto>', help="input format")
- at click.option("--commit", is_flag=True, help="commit changes to the database")
 @click.option("--show-sql", is_flag=True, help="show SQL statements")
 @click.option("--show-sample-count", is_flag=True)
 @click.option("--show-raw-result", is_flag=True)
@@ -20,10 +20,10 @@ import lnt.formats
 @click.option("--quiet", "-q", is_flag=True, help="don't show test results")
 @click.option("--no-email", is_flag=True, help="don't send e-mail")
 @click.option("--no-report", is_flag=True, help="don't generate report")
- at click.option("--update-machine", is_flag=True, help="Update machine fields")
-def action_import(instance_path, files, database, output_format, commit,
-                  show_sql, show_sample_count, show_raw_result, testsuite,
-                  verbose, quiet, no_email, no_report, update_machine):
+ at submit_options
+def action_import(instance_path, files, database, output_format, show_sql,
+                  show_sample_count, show_raw_result, testsuite, verbose,
+                  quiet, no_email, no_report, commit, update_machine, merge):
     """import test data into a database"""
     import contextlib
     import lnt.server.instance
@@ -44,7 +44,8 @@ def action_import(instance_path, files,
             result = lnt.util.ImportData.import_and_report(
                 config, database, db, file_name,
                 output_format, testsuite, commit, show_sample_count,
-                no_email, no_report, updateMachine=update_machine)
+                no_email, no_report, updateMachine=update_machine,
+                mergeRun=merge)
 
             success &= result.get('success', False)
             if quiet:

Modified: lnt/trunk/lnt/lnttool/main.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/lnttool/main.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/lnttool/main.py (original)
+++ lnt/trunk/lnt/lnttool/main.py Wed Jul 26 20:46:13 2017
@@ -1,5 +1,6 @@
 """Implement the command line 'lnt' tool."""
 from .common import init_logger
+from .common import submit_options
 from .convert import action_convert
 from .create import action_create
 from .import_data import action_import
@@ -177,11 +178,10 @@ def action_showtests():
 @click.command("submit")
 @click.argument("url")
 @click.argument("files", nargs=-1, type=click.Path(exists=True), required=True)
- at click.option("--commit", is_flag=True, help="actually commit the data")
- at click.option("--update-machine", is_flag=True, help="Update machine fields")
+ at submit_options
 @click.option("--verbose", "-v", is_flag=True,
               help="show verbose test results")
-def action_submit(url, files, commit, update_machine, verbose):
+def action_submit(url, files, commit, update_machine, merge, verbose):
     """submit a test report to the server"""
     from lnt.util import ServerUtil
     import lnt.util.ImportData
@@ -194,7 +194,8 @@ def action_submit(url, files, commit, up
                        "your results will not be saved at the server.")
 
     files = ServerUtil.submitFiles(url, files, commit, verbose,
-                                   updateMachine=update_machine)
+                                   updateMachine=update_machine,
+                                   mergeRun=merge)
     for submitted_file in files:
         if verbose:
             lnt.util.ImportData.print_report_result(

Modified: lnt/trunk/lnt/server/db/testsuitedb.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/testsuitedb.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/testsuitedb.py (original)
+++ lnt/trunk/lnt/server/db/testsuitedb.py Wed Jul 26 20:46:13 2017
@@ -831,16 +831,13 @@ class TestSuiteDB(object):
 
     def _getOrCreateOrder(self, run_parameters):
         """
-        _getOrCreateOrder(data) -> Order, bool
+        _getOrCreateOrder(data) -> Order
 
         Add or create (and insert) an Order record based on the given run
         parameters (as recorded by the test interchange format).
 
         The run parameters that define the order will be removed from the
         provided ddata argument.
-
-        The boolean result indicates whether the returned record was
-        constructed or not.
         """
 
         query = self.query(self.Order)
@@ -858,45 +855,52 @@ class TestSuiteDB(object):
             order.set_field(item, value)
 
         # Execute the query to see if we already have this order.
-        try:
-            return query.one(), False
-        except sqlalchemy.orm.exc.NoResultFound:
-            # If not, then we need to insert this order into the total ordering
-            # linked list.
-
-            # Add the new order and commit, to assign an ID.
-            self.add(order)
-            self.v4db.session.commit()
-
-            # Load all the orders.
-            orders = list(self.query(self.Order))
-
-            # Sort the objects to form the total ordering.
-            orders.sort()
-
-            # Find the order we just added.
-            index = orders.index(order)
-
-            # Insert this order into the linked list which forms the total
-            # ordering.
-            if index > 0:
-                previous_order = orders[index - 1]
-                previous_order.next_order_id = order.id
-                order.previous_order_id = previous_order.id
-            if index + 1 < len(orders):
-                next_order = orders[index + 1]
-                next_order.previous_order_id = order.id
-                order.next_order_id = next_order.id
+        existing = query.first()
+        if existing is not None:
+            return existing
+
+        # If not, then we need to insert this order into the total ordering
+        # linked list.
+
+        # Add the new order and commit, to assign an ID.
+        self.add(order)
+        self.v4db.session.commit()
+
+        # Load all the orders.
+        orders = list(self.query(self.Order))
+
+        # Sort the objects to form the total ordering.
+        orders.sort()
+
+        # Find the order we just added.
+        index = orders.index(order)
+
+        # Insert this order into the linked list which forms the total
+        # ordering.
+        if index > 0:
+            previous_order = orders[index - 1]
+            previous_order.next_order_id = order.id
+            order.previous_order_id = previous_order.id
+        if index + 1 < len(orders):
+            next_order = orders[index + 1]
+            next_order.previous_order_id = order.id
+            order.next_order_id = next_order.id
 
-            return order, True
+        return order
 
-    def _getOrCreateRun(self, run_data, machine):
+    def _getOrCreateRun(self, run_data, machine, merge):
         """
-        _getOrCreateRun(data) -> Run, bool
+        _getOrCreateRun(run_data, machine, merge) -> Run, bool
 
         Add a new Run record from the given data (as recorded by the test
         interchange format).
 
+        merge comes into play when there is already a run with the same order
+        fields:
+        - 'reject': Reject submission (raise ValueError).
+        - 'replace': Remove the existing submission(s), then add the new one.
+        - 'append': Add new submission.
+
         The boolean result indicates whether the returned record was
         constructed or not.
         """
@@ -914,7 +918,22 @@ class TestSuiteDB(object):
         run_parameters.pop('simple_run_id', None)
 
         # Find the order record.
-        order, inserted = self._getOrCreateOrder(run_parameters)
+        order = self._getOrCreateOrder(run_parameters)
+
+        if merge != 'append':
+            existing_runs = self.query(self.Run) \
+                .filter(self.Run.machine_id == machine.id) \
+                .filter(self.Run.order_id == order.id) \
+                .all()
+            if len(existing_runs) > 0:
+                if merge == 'reject':
+                    raise ValueError("Duplicate submission for '%s'" %
+                                     order.name)
+                elif merge == 'replace':
+                    for run in existing_runs:
+                        self.delete(run)
+                else:
+                    raise ValueError('Invalid Run mergeStrategy %r' % merge)
 
         # We'd like ISO8061 timestamps, but will also accept the old format.
         try:
@@ -922,45 +941,26 @@ class TestSuiteDB(object):
         except ValueError:
             start_time = datetime.datetime.strptime(run_data['start_time'],
                                                     "%Y-%m-%d %H:%M:%S")
+        run_parameters.pop('start_time')
 
         try:
             end_time = aniso8601.parse_datetime(run_data['end_time'])
         except ValueError:
             end_time = datetime.datetime.strptime(run_data['end_time'],
                                                   "%Y-%m-%d %H:%M:%S")
-        run_parameters.pop('start_time')
         run_parameters.pop('end_time')
 
-        # Convert the rundata into a run record. As with Machines, we construct
-        # the query to look for any existing run at the same time as we build
-        # up the record to possibly add.
-        #
-        # FIXME: This feels inelegant, can't SA help us out here?
-        query = self.query(self.Run).\
-            filter(self.Run.machine_id == machine.id).\
-            filter(self.Run.order_id == order.id).\
-            filter(self.Run.start_time == start_time).\
-            filter(self.Run.end_time == end_time)
         run = self.Run(machine, order, start_time, end_time)
 
         # First, extract all of the specified run fields.
         for item in self.run_fields:
             value = run_parameters.pop(item.name, None)
-            query = query.filter(item.column == value)
             run.set_field(item, value)
 
         # Any remaining parameters are saved as a JSON encoded array.
         run.parameters = run_parameters
-        query = query.filter(self.Run.parameters_data == run.parameters_data)
-
-        # Execute the query to see if we already have this run.
-        try:
-            return query.one(), False
-        except sqlalchemy.orm.exc.NoResultFound:
-            # If not, add the run.
-            self.add(run)
-
-            return run, True
+        self.add(run)
+        return run
 
     def _importSampleValues(self, tests_data, run, commit, config):
         # Load a map of all the tests, which we will extend when we find tests
@@ -1000,30 +1000,21 @@ class TestSuiteDB(object):
                     else:
                         sample.set_field(field, value)
 
-    def importDataFromDict(self, data, commit, config=None,
-                           updateMachine=False):
+    def importDataFromDict(self, data, commit, config, updateMachine,
+                           mergeRun):
         """
-        importDataFromDict(data) -> bool, Run
+        importDataFromDict(data, commit, config, updateMachine, mergeRun)
+            -> Run  (or throws ValueError exception)
 
         Import a new run from the provided test interchange data, and return
-        the constructed Run record.
-
-        The boolean result indicates whether the returned record was
-        constructed or not (i.e., whether the data was a duplicate submission).
+        the constructed Run record. May throw ValueError exceptions in cases
+        like mismatching machine data or duplicate run submission with
+        mergeRun == 'reject'.
         """
         machine = self._getOrCreateMachine(data['machine'], updateMachine)
-
-        # Construct the run entry.
-        run, inserted = self._getOrCreateRun(data['run'], machine)
-
-        # If we didn't construct a new run, this is a duplicate
-        # submission. Return the prior Run.
-        if not inserted:
-            return False, run
-
+        run = self._getOrCreateRun(data['run'], machine, mergeRun)
         self._importSampleValues(data['tests'], run, commit, config)
-
-        return True, run
+        return run
 
     # Simple query support (mostly used by templates)
 

Modified: lnt/trunk/lnt/server/ui/api.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/api.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/api.py (original)
+++ lnt/trunk/lnt/server/ui/api.py Wed Jul 26 20:46:13 2017
@@ -278,9 +278,10 @@ class Runs(Resource):
         db = request.get_db()
         data = request.data
         updateMachine = request.values.get('update_machine', False)
+        merge = request.values.get('merge', 'replace')
         result = lnt.util.ImportData.import_from_string(
             current_app.old_config, g.db_name, db, g.testsuite_name, data,
-            updateMachine=updateMachine)
+            updateMachine=updateMachine, mergeRun=merge)
 
         new_url = ('%sapi/db_%s/v4/%s/runs/%s' %
                    (request.url_root, g.db_name, g.testsuite_name,

Modified: lnt/trunk/lnt/server/ui/views.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/ui/views.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/server/ui/views.py (original)
+++ lnt/trunk/lnt/server/ui/views.py Wed Jul 26 20:46:13 2017
@@ -105,6 +105,7 @@ def _do_submit():
     input_data = request.form.get('input_data')
     commit = int(request.form.get('commit', 0)) != 0
     updateMachine = int(request.form.get('update_machine', 0)) != 0
+    merge = request.form.get('merge', 'replace')
 
     if input_file and not input_file.content_length:
         input_file = None
@@ -144,7 +145,7 @@ def _do_submit():
 
     result = lnt.util.ImportData.import_from_string(
         current_app.old_config, g.db_name, db, g.testsuite_name, data_value,
-        commit=commit, updateMachine=updateMachine)
+        commit=commit, updateMachine=updateMachine, mergeRun=merge)
 
     # It is nice to have a full URL to the run, so fixup the request URL
     # here were we know more about the flask instance.

Modified: lnt/trunk/lnt/tests/builtintest.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/tests/builtintest.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/tests/builtintest.py (original)
+++ lnt/trunk/lnt/tests/builtintest.py Wed Jul 26 20:46:13 2017
@@ -74,10 +74,9 @@ class BuiltinTest(object):
         server_report = None
         if config.submit_url is not None:
             self.log("submitting result to %r" % (config.submit_url,))
-            server_report = ServerUtil.submitFile(config.submit_url,
-                                                  report_path,
-                                                  commit,
-                                                  config.verbose)
+            server_report = ServerUtil.submitFile(
+                config.submit_url, report_path, commit, config.verbose,
+                updateMachine=config.update_machine, mergeRun=config.merge)
         else:
             server_report = lnt.util.ImportData.no_submit()
 

Modified: lnt/trunk/lnt/tests/compile.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/tests/compile.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/tests/compile.py (original)
+++ lnt/trunk/lnt/tests/compile.py Wed Jul 26 20:46:13 2017
@@ -24,6 +24,7 @@ from lnt.testing.util.misc import timest
 from lnt.tests import builtintest
 from lnt.util import stats
 from lnt.util import logger
+from lnt.lnttool.common import submit_options
 
 
 # For each test, compile with all these combinations of flags.
@@ -1054,8 +1055,7 @@ class CompileTest(builtintest.BuiltinTes
               help=("autosubmit the test result to the given server "
                     "(or local instance)"),
               type=click.UNPROCESSED, default=None)
- at click.option("--commit", "commit", is_flag=True, default=True,
-              help="whether the autosubmit result should be committed")
+ at submit_options
 @click.option("--output", "output", metavar="PATH",
               help="write raw report data to PATH (or stdout if '-')")
 @click.option("-v", "--verbose", "verbose",

Modified: lnt/trunk/lnt/tests/nt.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/tests/nt.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/tests/nt.py (original)
+++ lnt/trunk/lnt/tests/nt.py Wed Jul 26 20:46:13 2017
@@ -30,8 +30,8 @@ from lnt.testing.util.misc import timest
 
 from lnt.server.reporting.analysis import UNCHANGED_PASS, UNCHANGED_FAIL
 from lnt.server.reporting.analysis import REGRESSED, IMPROVED
-from lnt.util import logger
-from lnt.util import ImportData
+from lnt.util import logger, ImportData
+from lnt.lnttool.common import submit_options
 import builtintest
 
 
@@ -1986,9 +1986,6 @@ def _tools_check():
               help=("autosubmit the test result to the given server"
                     " (or local instance)"),
               type=click.UNPROCESSED, default=[], multiple=True)
- at click.option("--commit", "commit", is_flag=True,
-              help="whether the autosubmit result should be committed",
-              default=True)
 @click.option("--output", "output", metavar="PATH",
               help="write raw report data to PATH (or stdout if '-')",
               default=None)
@@ -1999,6 +1996,7 @@ def _tools_check():
               help="Do not submit the stat of this type ",
               multiple=True, type=click.Choice(KNOWN_SAMPLE_KEYS),
               default=['hash'])
+ at submit_options
 def cli_action(*args, **kwargs):
     _tools_check()
     nt = NTTest()

Modified: lnt/trunk/lnt/tests/test_suite.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/tests/test_suite.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/tests/test_suite.py (original)
+++ lnt/trunk/lnt/tests/test_suite.py Wed Jul 26 20:46:13 2017
@@ -18,6 +18,7 @@ from collections import defaultdict
 import jinja2
 import click
 
+from lnt.lnttool.common import submit_options
 from lnt.util import logger
 import lnt.testing
 import lnt.testing.profile
@@ -1063,8 +1064,6 @@ class TestSuiteTest(BuiltinTest):
               help="autosubmit the test result to the given server"
                    " (or local instance)",
               type=click.UNPROCESSED, default=None)
- at click.option("--commit", "commit", is_flag=True, default=True,
-              help="whether the autosubmit result should be committed")
 @click.option("--output", "output", metavar="PATH",
               help="write raw report data to PATH (or stdout if '-')",
               default=None)
@@ -1094,6 +1093,7 @@ class TestSuiteTest(BuiltinTest):
 @click.option("--use-lit", "lit", metavar="PATH", type=click.UNPROCESSED,
               default="llvm-lit",
               help="Path to the LIT test runner [llvm-lit]")
+ at submit_options
 def cli_action(*args, **kwargs):
     test_suite = TestSuiteTest()
 

Modified: lnt/trunk/lnt/util/ImportData.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/util/ImportData.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/util/ImportData.py (original)
+++ lnt/trunk/lnt/util/ImportData.py Wed Jul 26 20:46:13 2017
@@ -14,7 +14,7 @@ import time
 def import_and_report(config, db_name, db, file, format, ts_name,
                       commit=False, show_sample_count=False,
                       disable_email=False, disable_report=False,
-                      updateMachine=False):
+                      updateMachine=False, mergeRun='replace'):
     """
     import_and_report(config, db_name, db, file, format, ts_name,
                       [commit], [show_sample_count],
@@ -89,8 +89,9 @@ def import_and_report(config, db_name, d
                                (data_schema, ts_name))
             return result
 
-        success, run = ts.importDataFromDict(data, commit, config=db_config,
-                                             updateMachine=updateMachine)
+        run = ts.importDataFromDict(data, commit, config=db_config,
+                                    updateMachine=updateMachine,
+                                    mergeRun=mergeRun)
     except KeyboardInterrupt:
         raise
     except Exception as e:
@@ -103,9 +104,6 @@ def import_and_report(config, db_name, d
     run.imported_from = file
 
     result['import_time'] = time.time() - importStartTime
-    if not success:
-        # Record the original run this is a duplicate of.
-        result['original_run'] = run.id
 
     reportStartTime = time.time()
     result['report_to_address'] = toAddress
@@ -118,7 +116,7 @@ def import_and_report(config, db_name, d
         #  This has the side effect of building the run report for
         #  this result.
         NTEmailReport.emailReport(result, db, run, report_url, email_config,
-                                  toAddress, success)
+                                  toAddress, True)
 
     result['added_machines'] = ts.getNumMachines() - numMachines
     result['added_runs'] = ts.getNumRuns() - numRuns
@@ -310,7 +308,7 @@ def print_report_result(result, out, err
 
 
 def import_from_string(config, db_name, db, ts_name, data, commit=True,
-                       updateMachine=False):
+                       updateMachine=False, mergeRun='replace'):
     # Stash a copy of the raw submission.
     #
     # To keep the temporary directory organized, we keep files in
@@ -338,5 +336,6 @@ def import_from_string(config, db_name,
     # should at least reject overly large inputs.
 
     result = lnt.util.ImportData.import_and_report(config, db_name, db,
-            path, '<auto>', ts_name, commit, updateMachine=updateMachine)
+        path, '<auto>', ts_name, commit, updateMachine=updateMachine,
+        mergeRun=mergeRun)
     return result

Modified: lnt/trunk/lnt/util/ServerUtil.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/util/ServerUtil.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/lnt/util/ServerUtil.py (original)
+++ lnt/trunk/lnt/util/ServerUtil.py Wed Jul 26 20:46:13 2017
@@ -28,11 +28,14 @@ def _show_json_error(reply):
     if message:
         sys.stderr.write(message + '\n')
 
-def submitFileToServer(url, file, commit, updateMachine):
+def submitFileToServer(url, file, commit, updateMachine, mergeRun):
     with open(file, 'rb') as f:
-        values = {'input_data' : f.read(),
-                  'commit' : "1" if commit else "0",
-                  'update_machine': "1" if updateMachine else "0"}
+        values = {
+            'input_data' : f.read(),
+            'commit' : "1" if commit else "0",
+            'update_machine': "1" if updateMachine else "0",
+            'merge': mergeRun,
+        }
     headers = {'Accept': 'application/json'}
     data = urllib.urlencode(values)
     try:
@@ -59,7 +62,8 @@ def submitFileToServer(url, file, commit
     return reply
 
 
-def submitFileToInstance(path, file, commit, updateMachine=False):
+def submitFileToInstance(path, file, commit, updateMachine=False,
+                         mergeRun='replace'):
     # Otherwise, assume it is a local url and submit to the default database
     # in the instance.
     instance = lnt.server.instance.Instance.frompath(path)
@@ -70,24 +74,26 @@ def submitFileToInstance(path, file, com
             raise ValueError("no default database in instance: %r" % (path,))
         return lnt.util.ImportData.import_and_report(
             config, db_name, db, file, format='<auto>', ts_name='nts',
-            commit=commit, updateMachine=updateMachine)
+            commit=commit, updateMachine=updateMachine, mergeRun=mergeRun)
 
 
-def submitFile(url, file, commit, verbose, updateMachine=False):
+def submitFile(url, file, commit, verbose, updateMachine=False,
+               mergeRun='replace'):
     # If this is a real url, submit it using urllib.
     if '://' in url:
-        result = submitFileToServer(url, file, commit, updateMachine)
-        if result is None:
-            return
+        result = submitFileToServer(url, file, commit, updateMachine, mergeRun)
     else:
-        result = submitFileToInstance(url, file, commit, updateMachine)
+        result = submitFileToInstance(url, file, commit, updateMachine,
+                                      mergeRun)
     return result
 
 
-def submitFiles(url, files, commit, verbose, updateMachine=False):
+def submitFiles(url, files, commit, verbose, updateMachine=False,
+                mergeRun='replace'):
     results = []
     for file in files:
-        result = submitFile(url, file, commit, verbose, updateMachine)
+        result = submitFile(url, file, commit, verbose, updateMachine,
+                            mergeRun)
         if result:
             results.append(result)
     return results

Modified: lnt/trunk/tests/lnttool/PostgresDB.shtest
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/lnttool/PostgresDB.shtest?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/tests/lnttool/PostgresDB.shtest (original)
+++ lnt/trunk/tests/lnttool/PostgresDB.shtest Wed Jul 26 20:46:13 2017
@@ -15,7 +15,7 @@ lnt create "${TESTDIR}/instance" --db-di
 lnt import "${TESTDIR}/instance" "${SHARED_INPUTS}/sample-a-small.plist" --commit --show-sample-count
 
 # Import a test set.
-lnt import "${TESTDIR}/instance" "${SHARED_INPUTS}/sample-a-small.plist" --commit --show-sample-count
+lnt import "${TESTDIR}/instance" "${SHARED_INPUTS}/sample-b-small.plist" --commit --show-sample-count
 
 # Check that we remove both the sample and the run, and that we don't commit by
 # default.
@@ -41,7 +41,7 @@ lnt updatedb "${TESTDIR}/instance" --tes
 # RUN: FileCheck --check-prefix CHECK-MACHINERM %s < "%t.install/machinerm.out"
 
 # CHECK-MACHINERM: DELETE FROM "NT_Sample" WHERE "NT_Sample"."ID" = %(ID)s
-# CHECK-MACHINERM-NEXT: ({'ID': 3}, {'ID': 4})
+# CHECK-MACHINERM-NEXT: ({'ID': 3}, {'ID': 4}, {'ID': 5})
 # CHECK-MACHINERM: DELETE FROM "NT_Run" WHERE "NT_Run"."ID" = %(ID)s
 # CHECK-MACHINERM-NEXT: {'ID': 2}
 # CHECK-MACHINERM: DELETE FROM "NT_Machine" WHERE "NT_Machine"."ID" = %(ID)s

Modified: lnt/trunk/tests/lnttool/submit.shtest
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/lnttool/submit.shtest?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/tests/lnttool/submit.shtest (original)
+++ lnt/trunk/tests/lnttool/submit.shtest Wed Jul 26 20:46:13 2017
@@ -28,16 +28,18 @@ lnt submit "http://localhost:9091/db_def
 
 
 lnt submit "http://localhost:9091/db_default/submitRun" --commit "${SHARED_INPUTS}/sample-report.json" > "${OUTPUT_DIR}/submit0.txt"
-# RUN: FileCheck %s --check-prefix=CHECK-DEFAULT < %T/submit0.txt
+# RUN: FileCheck %s --check-prefix=CHECK-SUBMIT0 < %T/submit0.txt
 #
 # Make sure the old --commit=1 style argument is still accepted.
 lnt submit "http://localhost:9091/db_default/submitRun" --commit=1 "${SHARED_INPUTS}/sample-report.json" > "${OUTPUT_DIR}/submit1.txt"
-# RUN: FileCheck %s --check-prefix=CHECK-DEFAULT < %T/submit1.txt
+# RUN: FileCheck %s --check-prefix=CHECK-SUBMIT1 < %T/submit1.txt
 
 lnt submit "http://localhost:9091/db_default/submitRun" --commit 1 "${SHARED_INPUTS}/sample-report.json" > "${OUTPUT_DIR}/submit2.txt"
-# RUN: FileCheck %s --check-prefix=CHECK-DEFAULT < %T/submit2.txt
+# RUN: FileCheck %s --check-prefix=CHECK-SUBMIT2 < %T/submit2.txt
 
-# CHECK-DEFAULT: http://localhost:9091/db_default/v4/nts/3
+# CHECK-SUBMIT0: http://localhost:9091/db_default/v4/nts/4
+# CHECK-SUBMIT1: http://localhost:9091/db_default/v4/nts/5
+# CHECK-SUBMIT2: http://localhost:9091/db_default/v4/nts/6
 
 
 lnt submit "http://localhost:9091/db_default/v4/compile/submitRun" --commit "${INPUTS}/compile_submission.json" -v > "${OUTPUT_DIR}/submit_compile.txt"
@@ -71,7 +73,7 @@ lnt submit "http://localhost:9091/db_def
 # CHECK-NEWFORMAT: Results
 # CHECK-NEWFORMAT: ----------------
 # CHECK-NEWFORMAT: PASS : 10
-# CHECK-NEWFORMAT: Results available at: http://localhost:9091/db_default/v4/nts/4
+# CHECK-NEWFORMAT: Results available at: http://localhost:9091/db_default/v4/nts/7
 
 # For the old submitters/formats we have some detection logic to determine the
 # test-suite based on the Info.Run.tag field instead of the URL. The result
@@ -84,7 +86,7 @@ lnt submit "http://localhost:9091/db_def
 # CHECK-COMPILE1: Results
 # CHECK-COMPILE1: ----------------
 # CHECK-COMPILE1: PASS : 10
-# CHECK-COMPILE1: Results available at: http://localhost:9091/db_default/v4/compile/5
+# CHECK-COMPILE1: Results available at: http://localhost:9091/db_default/v4/compile/6
 
 # Check some error handling/reporting
 rm -f "${OUTPUT_DIR}/submit_errors.txt"
@@ -121,7 +123,7 @@ lnt submit "http://localhost:9091/db_def
 # CHECK-MACHINEDIFF: Results
 # CHECK-MACHINEDIFF: ----------------
 # CHECK-MACHINEDIFF: PASS : 9
-# CHECK-MACHINEDIFF: Results available at: http://localhost:9091/db_default/v4/compile/6
+# CHECK-MACHINEDIFF: Results available at: http://localhost:9091/db_default/v4/compile/7
 
 # Test updating existing machine
 lnt submit "http://localhost:9091/db_default/v4/compile/submitRun" --commit "${INPUTS}/compile_submission_machine_diff_reject.json" --update-machine -v > "${OUTPUT_DIR}/submit_compile_machine_update.txt"
@@ -136,4 +138,4 @@ lnt submit "http://localhost:9091/db_def
 # CHECK-UPDATEMACHINE: Results
 # CHECK-UPDATEMACHINE: ----------------
 # CHECK-UPDATEMACHINE: PASS : 9
-# CHECK-UPDATEMACHINE: Results available at: http://localhost:9091/db_default/v4/compile/7
+# CHECK-UPDATEMACHINE: Results available at: http://localhost:9091/db_default/v4/compile/8

Modified: lnt/trunk/tests/server/db/ImportV4TestSuiteInstance.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/db/ImportV4TestSuiteInstance.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/tests/server/db/ImportV4TestSuiteInstance.py (original)
+++ lnt/trunk/tests/server/db/ImportV4TestSuiteInstance.py Wed Jul 26 20:46:13 2017
@@ -13,6 +13,8 @@
 # IMPORT-A-1: Added Runs : 1
 # IMPORT-A-1: Added Tests : 1
 # IMPORT-A-1: Added Samples : 2
+#
+# IMPORT-A-1: PASS : 5
 
 # Import the second test set.
 # RUN: lnt import %t.install %{shared_inputs}/sample-b-small.plist \
@@ -22,12 +24,36 @@
 # IMPORT-B: Added Runs : 1
 # IMPORT-B: Added Samples : 1
 
-# Check that reimporting the first test set properly reports as a duplicate.
+# Check appending to an existing order
+# RUN: lnt import %t.install %{shared_inputs}/sample-a-small.plist \
+# RUN:     --commit --show-sample-count --merge=append >& %t_append.log
+# RUN: FileCheck -check-prefix=IMPORT-A-APPEND %s < %t_append.log
+#
+# IMPORT-A-APPEND-NOT: Added Machines
+# IMPORT-A-APPEND: Added Runs : 1
+# IMPORT-A-APPEND-NOT: Added Tests
+# IMPORT-A-APPEND: Added Samples : 2
+#
+# IMPORT-A-APPEND: PASS : 5
+
+# Check that reimporting replaces the existing run.
 # RUN: lnt import %t.install %{shared_inputs}/sample-a-small.plist \
-# RUN:     --commit --show-sample-count > %t3.log
-# RUN: FileCheck -check-prefix=IMPORT-A-2 %s < %t3.log
+# RUN:     --commit --show-sample-count --merge=replace >& %t_replace.log
+# RUN: FileCheck -check-prefix=IMPORT-A-REPLACE %s < %t_replace.log
+#
+# IMPORT-A-REPLACE-NOT: Added Machines
+# IMPORT-A-REPLACE: Added Runs : -1
+# IMPORT-A-REPLACE-NOT: Added Tests
+# IMPORT-A-REPLACE: Added Samples : -2
+#
+# IMPORT-A-REPLACE: PASS : 5
+
+# Check that reimporting the first test set properly reports as a duplicate.
+# RUN: not lnt import %t.install %{shared_inputs}/sample-a-small.plist \
+# RUN:     --commit --show-sample-count --merge=reject >& %t_reject.log
+# RUN: FileCheck -check-prefix=IMPORT-A-REJECT %s < %t_reject.log
 #
-# IMPORT-A-2: This submission is a duplicate of run 1
+# IMPORT-A-REJECT: Duplicate submission for '1'
 
 # Dump a copy of the database, so it will show up in logs.
 # RUN: sqlite3 %t.install/data/lnt.db .dump
@@ -87,7 +113,7 @@ assert order_b.next_order_id is None
 assert order_b.llvm_project_revision == '2'
 
 # Validate the runs.
-runs = list(ts.query(ts.Run))
+runs = list(ts.query(ts.Run).order_by(ts.Run.order_id))
 assert len(runs) == 2
 run_a,run_b = runs
 assert run_a.machine is machine
@@ -102,7 +128,9 @@ assert sorted(run_a.parameters.items())
 assert sorted(run_b.parameters.items()) == [('inferred_run_order', '2')]
 
 # Validate the samples.
-samples = list(ts.query(ts.Sample))
+samples = list(ts.query(ts.Sample)\
+    .join(ts.Run) \
+    .order_by(ts.Run.order_id, ts.Sample.id))
 assert len(samples) == 3
 sample_a_0,sample_a_1,sample_b = samples
 assert sample_a_0.run is run_a

Modified: lnt/trunk/tests/server/db/search.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/tests/server/db/search.py?rev=309248&r1=309247&r2=309248&view=diff
==============================================================================
--- lnt/trunk/tests/server/db/search.py (original)
+++ lnt/trunk/tests/server/db/search.py Wed Jul 26 20:46:13 2017
@@ -33,7 +33,6 @@ class SearchTest(unittest.TestCase):
         # Get the database.
         self.db = config.get_database('default', echo=False)
         # Load the database.
-        success = True
         for r in imported_runs:
             with tempfile.NamedTemporaryFile() as f:
                 data = open(os.path.join(base_path, 'Inputs/report.json.in')) \
@@ -44,12 +43,12 @@ class SearchTest(unittest.TestCase):
     
                 result = lnt.util.ImportData.import_and_report(
                     None, 'default', self.db, f.name,
-                    '<auto>', 'nts', True, False,
-                    True, True)
+                    format='<auto>', ts_name='nts', commit=True,
+                    show_sample_count=False, disable_email=True,
+                    disable_report=True, updateMachine=False,
+                    mergeRun='reject')
 
-                success &= result.get('success', False)
-
-        assert success
+                assert result.get('success', False)
 
     def _mangleResults(self, rs):
         return [(r.machine.name, str(r.order.llvm_project_revision))




More information about the llvm-commits mailing list