Index: palm/trunk/SCRIPTS/palmtest
===================================================================
--- palm/trunk/SCRIPTS/palmtest	(revision 3682)
+++ palm/trunk/SCRIPTS/palmtest	(revision 4091)
@@ -81,42 +81,52 @@
 
 
+def disable_color():
+    global disable_colored_output
+    disable_colored_output = True
+
+
 version = '1.0.1'
 
-scripts_dir = os.path.dirname(os.path.realpath(__file__))
-trunk_dir = os.path.realpath(os.path.join(scripts_dir, '..'))
-workspace_dir = os.path.realpath(os.path.join(trunk_dir, '..'))
-
-trunk_tests_dir = os.path.join(trunk_dir, 'TESTS')
-trunk_tests_cases_dir = os.path.join(trunk_tests_dir, 'cases')
-trunk_tests_builds_dir = os.path.join(trunk_tests_dir, 'builds')
-
-tests_dir = os.path.join(workspace_dir, 'tests')
-
-available_cores = multiprocessing.cpu_count()
-terminal_columns, terminal_lines = shutil.get_terminal_size()
-hline = '#' * min(terminal_columns, 300) + '\n'
-table_width_intro = 12
-table_width_builds = len(max([s for s in next(os.walk(trunk_tests_builds_dir))[1] if not s[0] == '.'], key=len)) + len('_debug')
-table_width_cases = len(max([s for s in next(os.walk(trunk_tests_cases_dir))[1] if not s[0] == '.'], key=len))
-table_width_cores = 7
-table_width_total = table_width_intro + table_width_builds + table_width_cases + table_width_cores + 3
-
-task_table_line_template = \
-    '{:' + str(table_width_intro) + '} ' + \
-    '{:' + str(table_width_cases) + '} ' + \
-    '{:' + str(table_width_builds) + '} ' + \
-    '{:' + str(table_width_cores) + '} '
-
-config_table_line_template = \
-    '{:' + str(table_width_intro) + '} ' + \
-    '{:' + str(max(table_width_builds, table_width_cases)) + '} ' + \
-    '{:8} '
-
-file_table_line_template = \
-    '{:' + str(table_width_intro) + '} ' + \
-    '{:' + str(table_width_cases + 13) + '} '
-
-# for debugging
-exist_ok = False
+
+class Environment:
+
+    scripts_dir = os.path.dirname(os.path.realpath(__file__))
+    trunk_dir = os.path.realpath(os.path.join(scripts_dir, '..'))
+    workspace_dir = os.path.realpath(os.path.join(trunk_dir, '..'))
+
+    trunk_tests_dir = os.path.join(trunk_dir, 'TESTS')
+    trunk_tests_cases_dir = os.path.join(trunk_tests_dir, 'cases')
+    trunk_tests_builds_dir = os.path.join(trunk_tests_dir, 'builds')
+
+    tests_dir = os.path.join(workspace_dir, 'tests')
+
+
+class LogFormatter:
+
+    terminal_columns, terminal_lines = shutil.get_terminal_size()
+    hline = '#' * min(terminal_columns, 300) + '\n'
+    table_width_intro = 12
+    table_width_builds = len(max([s for s in next(os.walk(Environment.trunk_tests_builds_dir))[1] if not s[0] == '.'], key=len)) + len('_debug')
+    table_width_cases = len(max([s for s in next(os.walk(Environment.trunk_tests_cases_dir))[1] if not s[0] == '.'], key=len))
+    table_width_cores = 7
+    table_width_total = table_width_intro + table_width_builds + table_width_cases + table_width_cores + 3
+
+    intro_table_line_template = \
+        '{:' + str(table_width_intro) + '} '
+
+    task_table_line_template = \
+        '{:' + str(table_width_intro) + '} ' + \
+        '{:' + str(table_width_cases) + '} ' + \
+        '{:' + str(table_width_builds) + '} ' + \
+        '{:' + str(table_width_cores) + '} '
+
+    config_table_line_template = \
+        '{:' + str(table_width_intro) + '} ' + \
+        '{:' + str(max(table_width_builds, table_width_cases)) + '} ' + \
+        '{:8} '
+
+    file_table_line_template = \
+        '{:' + str(table_width_intro) + '} ' + \
+        '{:' + str(table_width_cases + 13) + '} '
 
 
@@ -208,7 +218,7 @@
         with Logger(cwd, verbose=verbose) as logger:
             # read line without blocking
-            logger.to_log(hline)
+            logger.to_log(LogFormatter.hline)
             logger.to_log('CMD: ' + cmd_str + '\n')
-            logger.to_log(hline)
+            logger.to_log(LogFormatter.hline)
             while t.is_alive():
                 try:
@@ -226,5 +236,5 @@
                 else:  # got line
                     logger.to_log(line.decode("utf-8"))
-            logger.to_log(hline)
+            logger.to_log(LogFormatter.hline)
 
         rc = p.poll()
@@ -379,6 +389,6 @@
         self.job_name = self.setup_name + '__' + build_name + '__' + str(self.cores)
         self.job_dir = os.path.join(self.test_dir, 'JOBS', self.job_name)
-        self.ref_monitoring_dir = os.path.join(trunk_tests_cases_dir, self.setup_name, 'MONITORING')
-        self.ref_output_dir = os.path.join(trunk_tests_cases_dir, self.setup_name, 'OUTPUT')
+        self.ref_monitoring_dir = os.path.join(Environment.trunk_tests_cases_dir, self.setup_name, 'MONITORING')
+        self.ref_output_dir = os.path.join(Environment.trunk_tests_cases_dir, self.setup_name, 'OUTPUT')
         self.res_monitoring_dir = os.path.join(self.job_dir, 'MONITORING')
         self.res_output_dir = os.path.join(self.job_dir, 'OUTPUT')
@@ -449,5 +459,5 @@
                 ext_list = [file_dict['extension']] if file_dict['extension'] else []
                 file_specific_ending = '.'.join([file_dict['postfix']] + file_dict['cycle_info'] + ext_list )
-                logger.to_all(file_table_line_template.format('Checking:', self.setup_name + file_specific_ending))
+                logger.to_all(LogFormatter.file_table_line_template.format('Checking:', self.setup_name + file_specific_ending))
                 ref_file_path = os.path.join(file_dict['ref_path'], self.setup_name + file_specific_ending)
                 res_file_path = os.path.join(file_dict['res_path'], self.job_name + file_specific_ending)
@@ -530,5 +540,5 @@
         if os.path.isdir(source_data_dir_path) and re.match('.+_d3d.*', source_data_dir):
             job_restart_dir = os.path.join(self.test_dir, 'JOBS', name, 'RESTART')
-            os.makedirs(job_restart_dir, exist_ok=exist_ok)
+            os.makedirs(job_restart_dir, exist_ok=False)
             job_data_dir_path = os.path.join(job_restart_dir, name + '_d3d')
             os.symlink(source_data_dir_path, job_data_dir_path, target_is_directory=True)
@@ -593,5 +603,5 @@
         if not attempted:
             with Logger(self.test_dir, verbose=self.verbose) as logger:
-                status_prefix = task_table_line_template.format('Testing:', self.test_case.name, build_name, self.cores)
+                status_prefix = LogFormatter.task_table_line_template.format('Testing:', self.test_case.name, build_name, self.cores)
                 logger.to_all(status_prefix)
                 logger.to_log('[started]' + '\n')
@@ -601,5 +611,5 @@
 
                 input_dir = os.path.join(self.test_dir, 'JOBS', name, 'INPUT')
-                os.makedirs(input_dir, exist_ok=exist_ok)
+                os.makedirs(input_dir, exist_ok=False)
 
                 # copying needs to be done per file, because input files need to be renamed
@@ -672,5 +682,5 @@
     def configure(self):
         try:
-            with open(os.path.join(trunk_tests_builds_dir, self.build_name, 'build_config.yml'), 'r') as f:
+            with open(os.path.join(Environment.trunk_tests_builds_dir, self.build_name, 'build_config.yml'), 'r') as f:
                 build_config = yaml.load(f)
         except:
@@ -745,5 +755,5 @@
 
         try:
-            with open(os.path.join(workspace_dir, 'palmtest.yml'), 'r') as f:
+            with open(os.path.join(Environment.workspace_dir, 'palmtest.yml'), 'r') as f:
                 palmtest_config = yaml.load(f)
         except:
@@ -758,5 +768,5 @@
         except:
             try:
-                with open(os.path.join(scripts_dir, '.palm.config.default.in'), 'r') as palm_config_template_file:
+                with open(os.path.join(Environment.scripts_dir, '.palm.config.default.in'), 'r') as palm_config_template_file:
                     template = palm_config_template_file.read()
             except:
@@ -770,5 +780,5 @@
         cpp_options_str = ['-D' + s for s in self.compiler['definitions']]
         template = template.replace('@PALM_CPP_OPTIONS_STR@', ' '.join(cpp_options_str))
-        template = template.replace('@PALM_CORES@', str(available_cores))
+        template = template.replace('@PALM_CORES@', str(multiprocessing.cpu_count()))
         template = template.replace('@PALM_COMPILER_OPTIONS@', '{{palmtest.compiler.options}} ' + ' '.join(self.compiler['includes']))
         template = template.replace('@PALM_LINKER_OPTIONS@', ' '.join(self.linker['options']))
@@ -873,5 +883,5 @@
         if not attempted:
             with Logger(self.test_dir, verbose=self.verbose) as logger:
-                status_prefix = task_table_line_template.format('Building:', '', build_name, '')
+                status_prefix = LogFormatter.task_table_line_template.format('Building:', '', build_name, '')
                 logger.to_all(status_prefix)
                 logger.to_log('[started]' + '\n')
@@ -907,6 +917,6 @@
         self.verbose = verbose
         self.dry_run = dry_run
-        self.user_code_dir = os.path.join(trunk_tests_cases_dir, self.name, 'USER_CODE')
-        self.input_dir = os.path.join(trunk_tests_cases_dir, self.name, 'INPUT')
+        self.user_code_dir = os.path.join(Environment.trunk_tests_cases_dir, self.name, 'USER_CODE')
+        self.input_dir = os.path.join(Environment.trunk_tests_cases_dir, self.name, 'INPUT')
         self.number_of_cores = []
         self.build_names = []
@@ -915,5 +925,5 @@
 
     def configure(self, requested_build_names, requested_cores):
-        f_name = os.path.join(trunk_tests_cases_dir, self.name, 'case_config.yml')
+        f_name = os.path.join(Environment.trunk_tests_cases_dir, self.name, 'case_config.yml')
         try:
             with open(f_name, 'r') as f:
@@ -983,18 +993,18 @@
 
     def prepare(self):
-        global disable_colored_output
-        disable_colored_output = self.no_color
-        self.test_dir = os.path.join(tests_dir, self.test_id)
+        if self.no_color:
+            disable_color()
+        self.test_dir = os.path.join(Environment.tests_dir, self.test_id)
         try:
-            os.makedirs(self.test_dir, exist_ok=exist_ok)
+            os.makedirs(self.test_dir, exist_ok=False)
         except:
             print('ERROR: Found existing test directory: ' + self.test_dir)
             exit(1)
         with Logger(self.test_dir, verbose=self.verbose) as logger:
-            logger.to_all(hline)
+            logger.to_all(LogFormatter.hline)
             logger.to_all('This is the PALM tester  (version: ' + version + ')' + '\n')
-            logger.to_all(hline)
+            logger.to_all(LogFormatter.hline)
             try:
-                with open(os.path.join(workspace_dir, 'palmtest.yml'), 'r') as f:
+                with open(os.path.join(Environment.workspace_dir, 'palmtest.yml'), 'r') as f:
                     pass
             except:
@@ -1005,10 +1015,10 @@
 
             self.execution_trunk_dir = os.path.join(self.test_dir, 'trunk')
-            os.symlink(trunk_dir, self.execution_trunk_dir)
+            os.symlink(Environment.trunk_dir, self.execution_trunk_dir)
             self.execution_jobs_dir = os.path.join(self.test_dir, 'JOBS')
-            os.makedirs(self.execution_jobs_dir, exist_ok=exist_ok)
+            os.makedirs(self.execution_jobs_dir, exist_ok=False)
 
             try:
-                with open(os.path.join(scripts_dir, '.palm.iofiles'), 'r') as iofiles_template_file:
+                with open(os.path.join(Environment.scripts_dir, '.palm.iofiles'), 'r') as iofiles_template_file:
                     iofiles_template = iofiles_template_file.read()
                 with open(os.path.join(self.test_dir, '.palm.iofiles'), 'w') as iofiles_file:
@@ -1018,11 +1028,12 @@
                 exit(1)
 
+            available_cores = multiprocessing.cpu_count()
             final_cores_list = list(filter(lambda x: x <= available_cores, self.requested_cores))
 
-            logger.to_all(config_table_line_template.format('Object:', 'Name:', 'Action:') + 'Status:\n')
-            logger.to_all(hline)
+            logger.to_all(LogFormatter.config_table_line_template.format('Object:', 'Name:', 'Action:') + 'Status:\n')
+            logger.to_all(LogFormatter.hline)
 
             if 'all' in self.requested_build_names:
-                self.requested_build_names = [name for name in next(os.walk(trunk_tests_builds_dir))[1] if not name[0] == '.']
+                self.requested_build_names = [name for name in next(os.walk(Environment.trunk_tests_builds_dir))[1] if not name[0] == '.']
             found_build_names = []
             for build_name in self.requested_build_names:
@@ -1032,13 +1043,13 @@
                     self.build_database[build_name] = build
                     found_build_names.append(build_name)
-                    logger.to_all(config_table_line_template.format('Build', build_name, 'approved'))
+                    logger.to_all(LogFormatter.config_table_line_template.format('Build', build_name, 'approved'))
                     logger.to_all(message + '\n')
                 else:
-                    logger.to_all(config_table_line_template.format('Build', build_name, 'rejected'))
+                    logger.to_all(LogFormatter.config_table_line_template.format('Build', build_name, 'rejected'))
                     logger.to_all(message + '\n')
             final_build_list = found_build_names
 
             if 'all' in self.test_case_names:
-                self.test_case_names = sorted([name for name in next(os.walk(trunk_tests_cases_dir))[1] if not name[0] == '.'])
+                self.test_case_names = sorted([name for name in next(os.walk(Environment.trunk_tests_cases_dir))[1] if not name[0] == '.'])
 
             additional_initial_runs_2 = [self.test_case_names]
@@ -1079,5 +1090,5 @@
                         # removing as configuration failed should only apply to added dependencies
                         approved_test_case_order[i].remove(test_case_name)
-                        logger.to_all(config_table_line_template.format(info, test_case_name, 'rejected'))
+                        logger.to_all(LogFormatter.config_table_line_template.format(info, test_case_name, 'rejected'))
                         logger.to_all(message + '\n')
                     elif test_case.requires_binary_files:
@@ -1085,11 +1096,11 @@
                             # removing as dependency is already removed
                             approved_test_case_order[i].remove(test_case_name)
-                            logger.to_all(config_table_line_template.format(info, test_case_name, 'disabled'))
+                            logger.to_all(LogFormatter.config_table_line_template.format(info, test_case_name, 'disabled'))
                             logger.to_all(colored('[requires dependency \"' + test_case.use_binary_files_from + '\"]', 'red') + '\n')
                         else:
-                            logger.to_all(config_table_line_template.format(info, test_case_name, 'approved'))
+                            logger.to_all(LogFormatter.config_table_line_template.format(info, test_case_name, 'approved'))
                             logger.to_all(message + '\n')
                     else:
-                        logger.to_all(config_table_line_template.format(info, test_case_name, 'approved'))
+                        logger.to_all(LogFormatter.config_table_line_template.format(info, test_case_name, 'approved'))
                         logger.to_all(message + '\n')
 
@@ -1123,12 +1134,14 @@
                 if not test_case_configuration_failed:
                     self.test_case_queue.append(test_case)
-            logger.to_all(hline)
-
-            r = '{:' + str(table_width_intro) + '} '
-
-            logger.to_all(r.format('Test ID:') + self.test_id + '\n')
-            logger.to_all(r.format('Builds:') + str('\n' + r.format('')).join(sorted(self.build_database.keys())) + '\n')
-            logger.to_all(r.format('Cases:') + str('\n' + r.format('')).join([c.name for c in self.test_case_queue]) + '\n')
-            logger.to_all(r.format('Cores:') + ' '.join([str(i) for i in final_cores_list]) + '\n')
+            logger.to_all(LogFormatter.hline)
+
+            logger.to_all(LogFormatter.intro_table_line_template.format('Test ID:') +
+                          self.test_id + '\n')
+            logger.to_all(LogFormatter.intro_table_line_template.format('Builds:') +
+                          str('\n' + LogFormatter.intro_table_line_template.format('')).join(sorted(self.build_database.keys())) + '\n')
+            logger.to_all(LogFormatter.intro_table_line_template.format('Cases:') +
+                          str('\n' + LogFormatter.intro_table_line_template.format('')).join([c.name for c in self.test_case_queue]) + '\n')
+            logger.to_all(LogFormatter.intro_table_line_template.format('Cores:') +
+                          ' '.join([str(i) for i in final_cores_list]) + '\n')
 
     def _execute(self, test_case, build_name, cores):
@@ -1186,12 +1199,12 @@
     def execute(self):
         with Logger(self.test_dir, verbose=self.verbose) as logger:
-            logger.to_all(hline)
-            logger.to_all(task_table_line_template.format('Task:', 'Case:', 'Build:', 'Cores:') + 'Status:\n')
-            logger.to_all(hline)
+            logger.to_all(LogFormatter.hline)
+            logger.to_all(LogFormatter.task_table_line_template.format('Task:', 'Case:', 'Build:', 'Cores:') + 'Status:\n')
+            logger.to_all(LogFormatter.hline)
             self.test_report = dict()
             for test_case in self.test_case_queue:
-                logger.to_log(hline)
-                logger.to_file(hline)
-                logger.to_file(hline)
+                logger.to_log(LogFormatter.hline)
+                logger.to_file(LogFormatter.hline)
+                logger.to_file(LogFormatter.hline)
                 status_dict = dict()
                 for build_name in test_case.build_names:
@@ -1200,10 +1213,10 @@
                         status_dict[build_name][cores] = self._execute(test_case, build_name, cores)
                 self.test_report[test_case.name] = status_dict
-                logger.to_log(hline)
+                logger.to_log(LogFormatter.hline)
                 logger.to_file('\n' * 10)
 
     def report(self):
         with Logger(self.test_dir, verbose=self.verbose) as logger:
-            logger.to_all(hline)
+            logger.to_all(LogFormatter.hline)
             r = '{:10}' + '    total: ' + '{:<3d}' + \
                              '    ok: ' + colored('{:<3d}', 'green') + \
@@ -1274,5 +1287,5 @@
 
     def get_items(self):
-        case_names = [name for name in next(os.walk(trunk_tests_cases_dir))[1] if not name[0] == '.']
+        case_names = [name for name in next(os.walk(Environment.trunk_tests_cases_dir))[1] if not name[0] == '.']
         return case_names + ['all']
 
@@ -1281,5 +1294,5 @@
 
     def get_items(self):
-        build_names = [name for name in next(os.walk(trunk_tests_builds_dir))[1] if not name[0] == '.']
+        build_names = [name for name in next(os.walk(Environment.trunk_tests_builds_dir))[1] if not name[0] == '.']
         return build_names + ['all']
 
@@ -1367,6 +1380,6 @@
             action='store',
             dest='cores',
-            default=[i for i in range(1, available_cores+1)],
-            choices=[i for i in range(1, available_cores+1)],
+            default=[i for i in range(1, multiprocessing.cpu_count()+1)],
+            choices=[i for i in range(1, multiprocessing.cpu_count()+1)],
             help='The number of cores tests are supposed to be executed on. (default: %(default)s)',
             nargs='+',
