Ver código fonte

HPCC-11071 Regression setup needs to run on multiple clusters

Add 'setup' positional parameter to Regression Suite command line interface.

Change target parameter name from 'cluster' to 'target'

Remove setup from cluster list.

Remove setup as a valid target for run command.

Redesign main script structure:
    - move whole code into a class (to easier unit testing in future)
    - move long IF-ELSIF-..-ELSE code blocks into individual methods
    - add missing target testing for setup and run commands

Change password to '********' string in debug log.

Update README.rst

Signed-off-by: Attila Vamos <attila.vamos@gmail.com>
Attila Vamos 11 anos atrás
pai
commit
8887599b46

+ 79 - 57
testing/regress/README.rst

@@ -1,4 +1,4 @@
-Overview of Regression Suite usage (v:0.0.14)
+Overview of Regression Suite usage (v:0.0.15)
 ==============================================
 
 To use Regression Suite change directory to HPCC-Platform/testing/regress subdirectory.
@@ -19,13 +19,14 @@ Result:
 |                       [--loglevel [{info,debug}]] [--suiteDir [SUITEDIR]]
 |                       [--timeout [TIMEOUT]] [--keyDir [KEYDIR]]
 |                       [--ignoreResult]
-|                       {list,run,query} ...
+|                       {list,setup,run,query} ...
 | 
 |       HPCC Platform Regression suite
 | 
 |       positional arguments:
-|          {list,run,query}      sub-command help
+|          {list,setup,run,query} sub-command help
 |            list                list help
+|            setup               setup help
 |            run                 run help
 |            query               query help
 |
@@ -37,8 +38,7 @@ Result:
 |                                  set the log level. Use debug for more detailed logfile.
 |            --suiteDir [SUITEDIR], -s [SUITEDIR]
 |                                  suiteDir to use. Default value is the current directory and it can handle relative path.
-|            --timeout [TIMEOUT], -t [TIMEOUT]
-|                                  timeout for query execution in sec. Use -1 to disable timeout. Default value defined in ecl-test.json config file (see: 9.)
+|            --timeout [TIMEOUT]   timeout for query execution in sec. Use -1 to disable timeout. Default value defined in ecl-test.json config file (see: 9.)
 |            --keyDir [KEYDIR], -k [KEYDIR]
 |                                  key file directory to compare test output. Default value defined in regress.json config file.
 |            --ignoreResult, -i    completely ignore the result.
@@ -56,12 +56,31 @@ Result:
 |       usage: ecl-test list [-h]
 |
 |       positional arguments:
-|         clusters    Print clusters from config (ecl-test.json by default).
+|         targets     Print target clusters from config (ecl-test.json by default).
 |
 |       optional arguments:
 |         -h, --help  show this help message and exit
 |
 
+Parameters of Regression Suite setup sub-command:
+-------------------------------------------------
+
+Command:
+
+    ./ecl-test setup <-h|--help>
+
+Result:
+
+|
+|       usage: usage: ecl-test setup [-h] [--target [TARGET]]
+|
+|       optional arguments:
+|         -h, --help            show this help message and exit
+|         --target [TARGET], -t [TARGET]
+|                               Run the setup on target cluster. Default value is
+|                               thor.
+|
+
 Parameters of Regression Suite run sub-command:
 -----------------------------------------------
 
@@ -72,13 +91,12 @@ Command:
 Result:
 
 |
-|       usage: ecl-test run [-h] [--pq threadNumber] [cluster]
-|
-|       positional arguments:
-|         cluster            Run the cluster suite. Default value is setup.
+|       usage: ecl-test run [-h] [--target [TARGET]] [--pq threadNumber]
 |
 |       optional arguments:
 |         -h, --help         show this help message and exit
+|         --target [TARGET], -t [TARGET]
+|                            Run the cluster suite. Default value is thor.
 |         --pq threadNumber  Parallel query execution with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2)
 |
 
@@ -93,19 +111,19 @@ Command:
 Result:
 
 |
-|       usage: ecl-test query [-h] [--cluster [target_cluster | all]] [--publish]
+|       usage: ecl-test query [-h] [--target [target_cluster | all]] [--publish]
 |                  [--pq threadNumber]
-|                  ECL query [ECL query ...]
+|                  ECL_query [ECL_query ...]
 |
 |       positional arguments:
-|         ECL query                   Name of one or more ECL file(s). It can contain wildcards. (mandatory).
+|         ECL_query                   Name of one or more ECL file(s). It can contain wildcards. (mandatory).
 |
 |       optional arguments:
-|         -h, --help                    Show this help message and exit
-|         --cluster [target_cluster | all], -c [target_cluster | all]
-|                                            Cluster for single query run. If cluster = 'all' then run query on all clusters. Default value is thor.
+|         -h, --help                  Show this help message and exit
+|         --target [target_cluster | all], -t [target_cluster | all]
+|                                     Target cluster for single query run. If target = 'all' then run query on all clusters. Default value is thor.
 |         --publish, -p               Publish compiled query instead of run.
-|         --pq threadNumber    Parallel query execution for multiple test cases specified in CLI with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )
+|         --pq threadNumber           Parallel query execution for multiple test cases specified in CLI with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )
 |
 
 Steps to run Regression Suite
@@ -123,7 +141,6 @@ Command:
 The result looks like this:
 
         Available Clusters: 
-            - setup
             - hthor
             - thor
             - roxie
@@ -135,36 +152,43 @@ The result looks like this:
 
 Command:
 
-        ./ecl-test run
+        ./ecl-test setup
+
+to run setup on the default (thor) cluster
 
 or
+        ./ecl-test setup -t <target cluster>
 
-        ./ecl-test run setup
+to run setup on a selected cluster
 
 The result:
 
 |
-|        [Action] Suite: setup
-|        [Action] Queries: 3
-|        [Action] 1. Test: setup_fetch.ecl
-|        [Pass] Pass W20130617-095047
-|        [Pass] URL `http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20130617-095047`
-|        [Action] 2. Test: setupxml.ecl
-|        [Pass] Pass W20130617-095049
-|        [Pass] URL `http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20130617-095049`
-|        [Action] 3. Test: setup.ecl
-|        [Pass] Pass W20130617-095051
-|        [Pass] URL `http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20130617-095051`
+|        [Action] Suite: thor (setup)
+|        [Action] Queries: 4
+|        [Action]   1. Test: setup.ecl
+|        [Pass]   1. Pass W20140410-133419 (8 sec)
+|        [Pass]   1. URL http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20140410-133419
+|        [Action]   2. Test: setup_fetch.ecl
+|        [Pass]   2. Pass W20140410-133428 (3 sec)
+|        [Pass]   2. URL http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20140410-133428
+|        [Action]   3. Test: setupsq.ecl
+|        [Pass]   3. Pass W20140410-133432 (5 sec)
+|        [Pass]   3. URL http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20140410-133432
+|        [Action]   4. Test: setupxml.ecl
+|        [Pass]   4. Pass W20140410-133438 (2 sec)
+|        [Pass]   4. URL http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20140410-133438
 |        [Action]
-|
 |            Results
-|            `-------------------------------------------------`
-|            Passing: 3
+|            -------------------------------------------------
+|            Passing: 4
 |            Failure: 0
-|            `-------------------------------------------------`
-|            Log: /var/log/HPCCSystems/regression/setup.13-06-17-09-50.log
-|            `-------------------------------------------------`
-
+|            -------------------------------------------------
+|            Log: /home/ati/HPCCSystems-regression/log/thor.14-04-10-13-34-18.log
+|            -------------------------------------------------
+|            Elapsed time: 24 sec  (00:00:24)
+|            -------------------------------------------------
+|
 
 
 
@@ -172,13 +196,12 @@ The result:
 -------------------------------------------------------------
 Command:
 
-        ./ecl-test run cluster [-h] [--pq threadNumber]
-
-Positional arguments:
-  cluster            Run the cluster suite (default: setup).
+        ./ecl-test run [-t <target cluster>] [-h] [--pq threadNumber]
 
 Optional arguments:
   -h, --help         show help message and exit
+  --target [TARGET], -t [TARGET]
+                     Run the cluster suite. Default value is thor.
   --pq threadNumber  Parallel query execution with threadNumber threads.
                     ('-1' can be use to calculate usable thread count on a single node system)
 
@@ -188,7 +211,7 @@ The first and last couple of lines look like this:
 
 |
 |        [Action] Suite: thor
-|        [Action] Queries: 257
+|        [Action] Queries: 320
 |        [Action]
 |        [Action]   1. Test: agglist.ecl
 |        [Pass]   1. Pass W20131119-173524 (2 sec)
@@ -201,21 +224,21 @@ The first and last couple of lines look like this:
 |        .
 |        .
 |        .
-|        [Action] 256. Test: xmlout2.ecl
+|        [Action] 319. Test: xmlout2.ecl
 |        [Pass] Pass W20131119-182536 (1 sec)
 |        [Pass] URL http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20131119-182536
-|        [Action] 257. Test: xmlparse.ecl
+|        [Action] 320. Test: xmlparse.ecl
 |        [Pass] Pass W20131119-182537 (1 sec)
 |        [Pass] URL http://127.0.0.1:8010/WsWorkunits/WUInfo?Wuid=W20131119-182537
 |
 |         Results
 |         `-------------------------------------------------`
-|         Passing: 257
+|         Passing: 320
 |         Failure: 0
 |         `-------------------------------------------------`
 |         Log: /home/ati/HPCCSystems-regression/log/thor.13-11-19-17-52-27.log
 |         `-------------------------------------------------`
-|         Elapsed time: 1992 sec  (00:33:12)
+|         Elapsed time: 2367 sec  (00:39:27)
 |         `-------------------------------------------------`
 |
 
@@ -223,7 +246,7 @@ If --pq option used (in this case with 16 threads) then then the content of the
 
 |
 |        [Action] Suite: thor
-|        [Action] Queries: 257
+|        [Action] Queries: 320
 |        [Action]
 |        [Action]   1. Test: agglist.ecl
 |        [Action]   2. Test: aggregate.ecl
@@ -296,12 +319,12 @@ If --pq option used (in this case with 16 threads) then then the content of the
 |        [Action]
 |         Results
 |         `-------------------------------------------------`
-|         Passing: 257
+|         Passing: 320
 |         Failure: 0
 |         `-------------------------------------------------`
-|         Log: /home/ati/HPCCSystems-regression/log/thor.13-11-19-15-55-32.log
+|         Log: /home/ati/HPCCSystems-regression/log/thor.14-04-10-16-12-30.log
 |         `-------------------------------------------------`
-|         Elapsed time: 701 sec  (00:11:41)
+|         Elapsed time: 1498 sec  (00:24:58)
 |         `-------------------------------------------------`
 |
 
@@ -313,18 +336,17 @@ The logfile generated into the HPCCSystems-regression/log subfolder of the user
 
 Command:
 
-        ./ecl-test query test_name [test_name...] [-h] [--cluster cluster|all] [--pq threadNumber|-1]
+        ./ecl-test query test_name [test_name...] [-h] [--target <cluster|all>] [--publish] [--pq <threadNumber|-1>]
 
 Positional arguments:
         test_name               Name of a single ECL query. It can contain wildcards. (mandatory).
-        target cluster | all    Cluster for single query run (default: thor).
-                                If cluster = 'all' then run ECL query on all clusters.
+
 Optional arguments:
         -h, --help            Show help message and exit
-        --cluster [target_cluster | all]
-                                   Cluster for single query run. If cluster = 'all' then run query on all clusters. Default value is thor.
+        --target [target_cluster | all], -t [target_cluster | all]
+                              Target cluster for query to run. If target = 'all' then run query on all clusters. Default value is thor.
         --publish             Publish compiled query instead of run.
-        --pq threadNumber    Parallel query execution for multiple test cases specified in CLI with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )
+        --pq threadNumber     Parallel query execution for multiple test cases specified in CLI with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )
 
 
 

+ 196 - 165
testing/regress/ecl-test

@@ -32,172 +32,203 @@ from hpcc.util.ecl.file import ECLFile
 from hpcc.util.util import checkPqParam,  getVersionNumbers
 from hpcc.common.error import Error
 
-prog_version = "0.0.14"
-
-if __name__ == "__main__":
-
-    prog = "ecl-test"
-    versionStr = prog+" v:"+prog_version
-    description = 'HPCC Platform Regression suite'
-    pythonVer = getVersionNumbers()
+prog_version = "0.0.15"
+
+class RegressMain:
+
+    def listClusters(self):
+        Clusters = []
+        for cluster in self.regress.config.Clusters:
+            Clusters.append(str(cluster))
+        print "Avaliable Clusters: "
+        for i in Clusters:
+            print i
+
+    def query(self):
+        if not self.args.query:
+            print "\nMissing ECL query file!\n"
+            parser_query.print_help()
+            exit()
+        eclfiles=[]   # List for ECL filenames to be executed
+        for ecl in self.args.query:
+            if not ('.ecl' in ecl):
+                logging.error("%s. Not an ECL file:'%s'!" % (1,  ecl))
+            elif  ('*' in ecl) or ('?' in ecl):
+                # If there is any wildcard in ECL file name, resolve it
+                eclwild = os.path.join(self.regress.dir_ec, ecl)
+                eclfiles.extend( glob.glob(eclwild))
+            else:
+                # We have simple ECL file in parameter list, put it on the eclfile list
+                eclPath = os.path.join(self.regress.dir_ec, ecl)
+                eclfiles.append(eclPath)
+
+        if len(eclfiles) > 1:
+            # Remove duplicates
+            tempList = list(set(eclfiles))
+            eclfiles = tempList
+
+            # Sort ECL filenames to ensure correct execution order
+            eclfiles.sort()
+
+        targetClusters = []
+        if 'all' == self.args.target:
+            for cluster in self.regress.config.Clusters:
+                targetClusters.append(str(cluster))
+        else:
+            if self.args.target in self.regress.config.Clusters:
+                targetClusters.append(self.args.target)
+            else:
+                logging.error("%s. Unknown target cluster:'%s'!" % (1,  self.args.target))
+                raise Error("4000")
+        # Go through the cluster list
+        for cluster in targetClusters:
+            try:
+                if len(eclfiles) > 1:
+                    #Execute multiple ECL files like RUN to generates summary results and diff report.
+                    self.regress.bootstrap(cluster, eclfiles)
+                    if  'pq' in self.args:
+                        self.regress.runSuiteP(cluster, self.regress.suites[cluster])
+                    else:
+                        self.regress.runSuite(cluster, self.regress.suites[cluster])
+                elif len(eclfiles) == 1:
+                    # Execute one ECL file on the cluster
+                    for ecl in eclfiles:
+                        eclfile = ECLFile(ecl, self.regress.dir_a, self.regress.dir_ex, self.regress.dir_r, cluster)
+                        # Check if this query is not skip on this cluster and not part of setup
+                        if (not eclfile.testSkip(cluster)['skip']) and (not eclfile.testSkip('setup')['skip'] ):
+                            if not eclfile.testExclusion(cluster):
+                                self.regress.runSuiteQ(cluster, eclfile)
+                            else:
+                                logging.warn("%s. %s excluded on %s cluster." % (1,  eclfile.getBaseEcl(), cluster))
+                        else:
+                            logging.warn("%s. %s skipped on %s cluster." % (1, eclfile.getBaseEcl(), cluster))
+                else:
+                    logging.error("%s. No ECL file match for cluster:'%s'!" % (1,  self.args.target))
+                    raise Error("4001")
+            except IOError:
+                logging.error("%s. Query %s does not exist!" % (1,  eclfile.getBaseEcl()))
+                exit()
 
-    if (pythonVer['main'] <= 2) and (pythonVer['minor'] <=6) and (pythonVer['patch'] <6):
-        print "\nError!"
-        print "Your system has Python version "+platform.python_version()
-        print "To run "+description+", you need version: 2.6.6 or higher, but less than 3.x!\n"
-        exit()
+    def setup(self):
+        if self.args.target in self.regress.config.Clusters:
+            self.regress.bootstrap(self.args.target)
+            self.regress.runSuite(self.args.target, self.regress.Setup())
+        else:
+            logging.error("%s. Unknown target cluster:'%s'!" % (1,  self.args.target))
+            raise Error("4000")
+
+    def run(self):
+        if self.args.target in self.regress.config.Clusters:
+            self.regress.bootstrap(self.args.target)
+            if  self.args.pq :
+                self.regress.runSuiteP(self.args.target, self.regress.suites[self.args.target])
+            else:
+                self.regress.runSuite(self.args.target, self.regress.suites[self.args.target])
+        else:
+            logging.error("%s. Unknown target cluster:'%s'!" % (1,  self.args.target))
+            raise Error("4000")
+
+    def main(self):
+        prog = "ecl-test"
+        versionStr = prog+' v:'+prog_version
+        description = 'HPCC Platform Regression suite'
+        pythonVer = getVersionNumbers()
+
+        if (pythonVer['main'] <= 2) and (pythonVer['minor'] <=6) and (pythonVer['patch'] <6):
+            print "\nError!"
+            print "Your system has Python version "+platform.python_version()
+            print "To run "+description+", you need version: 2.6.6 or higher, but less than 3.x!\n"
+            exit()
+
+        if pythonVer['main'] >= 3:
+            print "\nError!"
+            print "Your system has Python version "+platform.python_version()
+            print "Actually "+description+", supports version >= 2.6.6 and <= 2.7.x\n"
+            exit()
+
+        if (pythonVer['main'] >= 2) and (pythonVer['minor'] >= 7):
+            atexit.register(logging.shutdown)
+
+        parser = argparse.ArgumentParser(prog=prog, description=description)
+        parser.add_argument('--version', '-v', action='version',
+                            version=versionStr)
+        parser.add_argument('--config', help="config file to use. Default: ecl-test.json",
+                            nargs='?', default="ecl-test.json")
+        parser.add_argument('--loglevel', help="set the log level. Use debug for more detailed logfile.",
+                            nargs='?', default="info",
+                            choices=['info', 'debug'])
+        parser.add_argument('--suiteDir', '-s', help="suiteDir to use. Default value is the current directory and it can handle relative path.",
+                            nargs='?', default=".")
+        parser.add_argument('--timeout', help="timeout for query execution in sec. Use -1 to disable timeout. Default value defined in ecl-test.json config file.",
+                            nargs='?', default="0")
+        parser.add_argument('--keyDir', '-k', help="key file directory to compare test output. Default value defined in ecl-test.json config file.",
+                            nargs='?', default="ecl/key")
+        parser.add_argument('--ignoreResult', '-i', help="completely ignore the result.",
+                            action='store_true')
 
-    if pythonVer['main'] >= 3:
-        print "\nError!"
-        print "Your system has Python version "+platform.python_version()
-        print "Actually "+description+", supports version >= 2.6.6 and <= 2.7.x\n"
+        subparsers = parser.add_subparsers(help='sub-command help')
+
+        parser_list = subparsers.add_parser('list', help='list help')
+        parser_list.set_defaults(func='list')
+        parser_list.add_argument('targets', help="Print target clusters from config (ecl-test.json by default).",
+                                 action='store_true')
+
+        parser_setup = subparsers.add_parser('setup', help='setup help')
+        parser_setup.set_defaults(func='setup')
+        parser_setup.add_argument('--target', '-t', help="Run the setup on target cluster. Default value is thor.",
+                                nargs='?', type=str,  default='thor')
+
+        parser_run = subparsers.add_parser('run', help='run help')
+        parser_run.set_defaults(func='run')
+        parser_run.add_argument('--target', '-t', help="Run the cluster suite. Default value is thor.",
+                                nargs='?', type=str,  default='thor')
+        parser_run.add_argument('--pq', help="Parallel query execution with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )",
+                                type=checkPqParam,  default = 0,   metavar="threadNumber")
+
+        parser_query = subparsers.add_parser('query', help='query help')
+        parser_query.set_defaults(func='query')
+        parser_query.add_argument('query', help="One or more ECL file(s). It can contain wildcards. (mandatory).",
+                                  nargs='+', metavar="ECL_query")
+        parser_query.add_argument('--target', '-t', help="Target cluster for query to run. If target = 'all' then run query on all clusters. Default value is thor.",
+                                nargs='?', default='thor', metavar="target_cluster | all")
+        parser_query.add_argument('--publish', '-p', help="Publish compiled query instead of run.",
+                                action='store_true')
+        parser_query.add_argument('--pq', help="Parallel query execution with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )",
+                                type=checkPqParam,  default = 0,   metavar="threadNumber")
+
+        self.args = parser.parse_args()
+
+        # Resolve Regression Suite starting path for ecl-test.json config file
+        # It is necessary when Regression Suite doesn't started from its home directory
+        regressionSuiteMainDir = os.path.dirname(__file__)
+        regressionSuiteFullPath = os.path.realpath(regressionSuiteMainDir)
+        self.args.config = str(os.path.join(regressionSuiteFullPath, self.args.config))
+
+        self.regress = Regression(self.args)
+        logging.debug("Suite version:%s",  versionStr)
+        logging.debug("Suite full path:%s",  regressionSuiteFullPath)
+
+        try:
+            if self.args.func == 'list':
+                self.listClusters()
+            elif self.args.func == 'query':
+                self.query()
+            elif self.args.func == 'setup':
+                self.setup()
+            elif self.args.func == 'run':
+                self.run()
+        except Error as e:
+            logging.critical(e)
+            exit(e.getErrorCode());
+        except Exception as e:
+            logging.critical(e)
+            logging.critical(traceback.format_exc())
+        except KeyboardInterrupt:
+            logging.critical("Keyboard Interrupt Caught.")
+        finally:
+            self.regress.StopTimeoutThread()
         exit()
 
-    if (pythonVer['main'] >= 2) and (pythonVer['minor'] >= 7):
-        atexit.register(logging.shutdown)
-
-    parser = argparse.ArgumentParser(prog=prog, description=description)
-    parser.add_argument('--version', '-v', action='version',
-                        version=versionStr)
-    parser.add_argument('--config', help="config file to use. Default: ecl-test.json",
-                        nargs='?', default="ecl-test.json")
-    parser.add_argument('--loglevel', help="set the log level. Use debug for more detailed logfile.",
-                        nargs='?', default="info",
-                        choices=['info', 'debug'])
-    parser.add_argument('--suiteDir', '-s', help="suiteDir to use. Default value is the current directory and it can handle relative path.",
-                        nargs='?', default=".")
-    parser.add_argument('--timeout', '-t', help="timeout for query execution in sec. Use -1 to disable timeout. Default value defined in ecl-test.json config file.",
-                        nargs='?', default="0")
-    parser.add_argument('--keyDir', '-k', help="key file directory to compare test output. Default value defined in ecl-test.json config file.",
-                        nargs='?', default="ecl/key")
-    parser.add_argument('--ignoreResult', '-i', help="completely ignore the result.",
-                        action='store_true')
-
-    subparsers = parser.add_subparsers(help='sub-command help')
-    parser_list = subparsers.add_parser('list', help='list help')
-    parser_list.add_argument('clusters', help="Print clusters from config (ecl-test.json by default).",
-                             action='store_true')
-
-    parser_run = subparsers.add_parser('run', help='run help')
-    parser_run.add_argument('cluster', help="Run the cluster suite. Default value is setup.",
-                            nargs='?', type=str,  default='setup')
-    parser_run.add_argument('--pq', help="Parallel query execution with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )",
-                            type=checkPqParam,  default = 0,   metavar="threadNumber")
-
-    parser_query = subparsers.add_parser('query', help='query help')
-    parser_query.add_argument('query', help="One or more ECL file(s). It can contain wildcards. (mandatory).",
-                              nargs='+', metavar="ECL query")
-    parser_query.add_argument('--cluster', '-c', help="Cluster for query to run. If cluster = 'all' then run query on all clusters. Default value is thor.",
-                            nargs='?', default='thor', metavar="target_cluster | all")
-    parser_query.add_argument('--publish', '-p', help="Publish compiled query instead of run.",
-                            action='store_true')
-    parser_query.add_argument('--pq', help="Parallel query execution with threadNumber threads. (If threadNumber is '-1' on a single node system then threadNumer = numberOfLocalCore * 2 )",
-                            type=checkPqParam,  default = 0,   metavar="threadNumber")
-
-    args = parser.parse_args()
-
-    # Resolve Regression Suite starting path for ecl-test.json config file
-    # It is necessary when Regression Suite doesn't started from its home directory
-    regressionSuiteMainDir = os.path.dirname(__file__)
-    regressionSuiteFullPath = os.path.realpath(regressionSuiteMainDir)
-    args.config = str(os.path.join(regressionSuiteFullPath, args.config))
-
-    regress = Regression(args)
-    logging.debug("Suite version:%s",  versionStr)
-    logging.debug("Suite full path:%s",  regressionSuiteFullPath)
-
-    try:
-        if 'clusters' in args:
-            Clusters = ['setup']
-            for cluster in regress.config.Clusters:
-                Clusters.append(str(cluster))
-            print "Avaliable Clusters: "
-            for i in Clusters:
-                print i
-        if 'query' in args:
-            if not args.query:
-                print "\nMissing ECL query file!\n"
-                parser_query.print_help()
-                exit()
-            eclfiles=[]   # List for ECL filenames to be executed
-            for ecl in args.query:
-                if not ('.ecl' in ecl):
-                    logging.error("%s. Not an ECL file:'%s'!" % (1,  ecl))
-                elif  ('*' in ecl) or ('?' in ecl):
-                    # If there is any wildcard in ECL file name, resolve it
-                    eclwild = os.path.join(regress.dir_ec, ecl)
-                    eclfiles.extend( glob.glob(eclwild))
-                else:
-                    # We have simple ECL file in parameter list, put it on the eclfile list
-                    eclPath = os.path.join(regress.dir_ec, ecl)
-                    eclfiles.append(eclPath)
-
-            if len(eclfiles) > 1:
-                # Remove duplicates
-                tempList = list(set(eclfiles))
-                eclfiles = tempList
-
-                # Sort ECL filenames to ensure correct execution order
-                eclfiles.sort()
-
-            targetClusters = []
-            if 'all' == args.cluster:
-                for cluster in regress.config.Clusters:
-                    targetClusters.append(str(cluster))
-            else:
-                if args.cluster in regress.config.Clusters:
-                    targetClusters.append(args.cluster)
-                else:
-                    logging.error("%s. Unknown cluster:'%s'!" % (1,  args.cluster))
-                    raise Error("4000")
-            # Go through the cluster list
-            for cluster in targetClusters:
-                try:
-                    if len(eclfiles) > 1:
-                        #Execute multiple ECL files like RUN to generates summary results and diff report.
-                        regress.bootstrap(cluster, eclfiles)
-                        if  'pq' in args:
-                            regress.runSuiteP(cluster, regress.suites[cluster])
-                        else:
-                            regress.runSuite(cluster, regress.suites[cluster])
-                    elif len(eclfiles) == 1:
-                        # Execute one ECL file on the cluster
-                        for ecl in eclfiles:
-                            eclfile = ECLFile(ecl, regress.dir_a, regress.dir_ex, regress.dir_r, cluster)
-                            # Check if this query is not skip on this cluster and not part of setup
-                            if (not eclfile.testSkip(cluster)['skip']) and (not eclfile.testSkip('setup')['skip'] ):
-                                if not eclfile.testExclusion(cluster):
-                                    regress.runSuiteQ(cluster, eclfile)
-                                else:
-                                    logging.warn("%s. %s excluded on %s cluster." % (1,  eclfile.getBaseEcl(), cluster))
-                            else:
-                                logging.warn("%s. %s skipped on %s cluster." % (1, eclfile.getBaseEcl(), cluster))
-                    else:
-                        logging.error("%s. No ECL file match for cluster:'%s'!" % (1,  args.cluster))
-                        raise Error("4001")
-                except IOError:
-                    logging.error("%s. Query %s does not exist!" % (1,  eclfile.getBaseEcl()))
-                    exit()
-            print("End.")
-        elif 'cluster' in args:
-            regress.bootstrap(args.cluster)
-            if 'setup' in args.cluster:
-                regress.runSuite('setup', regress.Setup())
-            else:
-                if  args.pq :
-                    regress.runSuiteP(args.cluster, regress.suites[args.cluster])
-                else:
-                    regress.runSuite(args.cluster, regress.suites[args.cluster])
-            print("End.")
-    except Error as e:
-        logging.critical(e)
-        exit(e.getErrorCode());
-    except Exception as e:
-        logging.critical(e)
-        logging.critical(traceback.format_exc())
-    except KeyboardInterrupt:
-        logging.critical("Keyboard Interrupt Caught.")
-    finally:
-        regress.StopTimeoutThread()
-
-    exit()
+if __name__ == "__main__":
+    regressMain = RegressMain()
+    regressMain.main()

+ 10 - 3
testing/regress/hpcc/common/shell.py

@@ -41,11 +41,18 @@ class Shell:
             return self.__run(*all_args)
         return __command
 
+    def __hidePassw(self,  item):
+        if '--password' in item:
+            return '--password=********'
+        else:
+            return item
+
     def __run(self, *args, **kwargs):
-        args = [i for i in args if i is not None]
-        logging.debug("CMD: " + " ". join(args))
+        _args = [i for i in args if i is not None]
+        argsLog = [self.__hidePassw(i) for i in args if i is not None ]
+        logging.debug("CMD: " + " ". join(argsLog))
         process = Popen(
-            args, stdout=kwargs.pop('stdout', PIPE),
+            _args, stdout=kwargs.pop('stdout', PIPE),
             stderr=kwargs.pop('stderr', PIPE),
             close_fds=kwargs.pop('close_fds', True), **kwargs)
         stdout, stderr = process.communicate()

+ 8 - 2
testing/regress/hpcc/regression/regress.py

@@ -166,6 +166,9 @@ class Regression:
         else:
             cluster = name
 
+        if 'setup' in suite.getSuiteName():
+            name = name + ' (setup)'
+
         self.taskParam = []
         self.taskParam = [{'taskId':0,  'jobName':'',  'timeoutValue':0,  'retryCount': 0} for i in range(self.maxthreads)]
         self.goodStates = ('compiling', 'blocked')
@@ -272,7 +275,7 @@ class Regression:
             self.StopTimeoutThread()
             logging.warn('%s','' , extra={'filebuffer':True,  'filesort':True})
             suite.setEndTime(time.time())
-            Regression.displayReport(report, suite.getelapsTime())
+            Regression.displayReport(report, suite.getElapsTime())
 
         except Exception as e:
             self.StopTimeoutThread()
@@ -317,6 +320,9 @@ class Regression:
         else:
             cluster = name
 
+        if 'setup' in suite.getSuiteName():
+            name = name + ' (setup)'
+
         logging.warn("Suite: %s" % name)
         logging.warn("Queries: %s" % repr(len(suite.getSuite())))
         suite.setStarTime(time.time())
@@ -343,7 +349,7 @@ class Regression:
             self.StopTimeoutThread()
 
             suite.setEndTime(time.time())
-            Regression.displayReport(report, suite.getelapsTime())
+            Regression.displayReport(report, suite.getElapsTime())
 
         except Exception as e:
             self.StopTimeoutThread()

+ 4 - 1
testing/regress/hpcc/regression/suite.py

@@ -89,5 +89,8 @@ class Suite:
     def setEndTime(self,  time):
         self.endTime=time
 
-    def getelapsTime(self):
+    def getElapsTime(self):
         return self.endTime-self.startTime
+
+    def getSuiteName(self):
+        return self.name