Commit e25730f5 authored by Daniel Lehmberg's avatar Daniel Lehmberg
Browse files

adapt Python script and add config file needed for NelderMeadTest

parent b71c6533
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
# python Tools/my_script.py # python Tools/my_script.py
import argparse import argparse
import copy
import fnmatch import fnmatch
import os import os
import re import re
...@@ -22,11 +23,12 @@ short_timeout_in_seconds = 2 * 60 ...@@ -22,11 +23,12 @@ short_timeout_in_seconds = 2 * 60
def parse_command_line_arguments(): def parse_command_line_arguments():
parser = argparse.ArgumentParser(description="Run all scenario files.") parser = argparse.ArgumentParser(description="Run all scenario files.")
parser.add_argument("scenario", type=str, nargs="?", help="Run only the given scenario file and not all. E.g., \"VadereModelTests/TestOSM/scenarios/basic_2_density_discrete_ca.scenario\"")
args = parser.parse_args() parser.add_argument("scenario", type=str, nargs="?",
help="Run only the given scenario file and not all. E.g., "
"\"VadereModelTests/TestOSM/scenarios/basic_2_density_discrete_ca.scenario\"")
return args return parser.parse_args()
def run_all_model_tests(): def run_all_model_tests():
...@@ -48,23 +50,32 @@ def run_all_model_tests(): ...@@ -48,23 +50,32 @@ def run_all_model_tests():
excluded_scenarios.extend(long_running_scenarios) excluded_scenarios.extend(long_running_scenarios)
scenario_files_regular_length = find_scenario_files(path="VadereModelTests", exclude_patterns=excluded_scenarios) scenario_files_regular_length = find_scenario_files(path="VadereModelTests", exclude_patterns=excluded_scenarios)
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(scenario_files_regular_length, scenario_timeout_in_sec=short_timeout_in_seconds)
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(
scenario_files_regular_length, scenario_timeout_in_sec=short_timeout_in_seconds)
for scenario in long_running_scenarios: for scenario in long_running_scenarios:
search_pattern = "*" + scenario + "*.scenario" search_pattern = "*" + scenario + "*.scenario"
scenario_files_long = find_scenario_files(path="VadereModelTests", scenario_search_pattern=search_pattern) scenario_files_long = find_scenario_files(path="VadereModelTests", scenario_search_pattern=search_pattern)
tmp_passed_and_failed_scenarios = run_scenario_files_with_vadere_console(scenario_files_long,
scenario_timeout_in_sec=long_timeout_in_seconds) tmp_passed_and_failed_scenarios = run_scenario_files_with_vadere_console(
passed_and_failed_scenarios["passed"].extend(tmp_passed_and_failed_scenarios["passed"]) scenario_files_long, scenario_timeout_in_sec=long_timeout_in_seconds)
passed_and_failed_scenarios["failed"].extend(tmp_passed_and_failed_scenarios["failed"])
passed_and_failed_scenarios["failed_summary"].extend(tmp_passed_and_failed_scenarios["failed_summary"]) passed_and_failed_scenarios = result_dict_merge(merge_into=passed_and_failed_scenarios,
merge_from=tmp_passed_and_failed_scenarios)
return passed_and_failed_scenarios return passed_and_failed_scenarios
def run_all_optimization_tests(): def run_all_optimization_tests():
scenario_files = find_scenario_files(path="VadereOptimizationTests") scenario_files = find_scenario_files(path="VadereOptimizationTests")
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(scenario_files, scenario_timeout_in_sec=short_timeout_in_seconds)
# enables flag to compare optimization with brute force solution
config_filepath = os.path.join("VadereOptimizationTests", "TestNelderMead", "vadere.conf")
# NOTE: it is likely that the set config file is not required by new optimization tests
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(
scenario_files, scenario_timeout_in_sec=short_timeout_in_seconds, config_filepath=config_filepath)
return passed_and_failed_scenarios return passed_and_failed_scenarios
...@@ -92,14 +103,14 @@ def find_scenario_files(path, scenario_search_pattern="*.scenario", exclude_patt ...@@ -92,14 +103,14 @@ def find_scenario_files(path, scenario_search_pattern="*.scenario", exclude_patt
if match: if match:
scenario_path_excluded = True scenario_path_excluded = True
if scenario_path_excluded == False: if not scenario_path_excluded:
scenario_files.append(scenario_path) scenario_files.append(scenario_path)
return sorted(scenario_files) return sorted(scenario_files)
def run_scenario_files_with_vadere_console(scenario_files, vadere_console="VadereSimulator/target/vadere-console.jar", def run_scenario_files_with_vadere_console(scenario_files, vadere_console="VadereSimulator/target/vadere-console.jar",
scenario_timeout_in_sec=short_timeout_in_seconds, vadere_config_filepath=None): scenario_timeout_in_sec=short_timeout_in_seconds, config_filepath=None):
output_dir = "output" output_dir = "output"
log_base_dir = "vadere_logs" log_base_dir = "vadere_logs"
...@@ -115,7 +126,7 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader ...@@ -115,7 +126,7 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader
for i, scenario_file in enumerate(scenario_files): for i, scenario_file in enumerate(scenario_files):
try: try:
print("Running scenario file ({}/{}): {}".format(i + 1, total_scenario_files, scenario_file)) print(f"Running scenario file ({i + 1}/{total_scenario_files}): {scenario_file}")
# A scenario filename has the form "VadereModelTests/TestOSM/scenarios/chicken_floorfield_ok.scenario" # A scenario filename has the form "VadereModelTests/TestOSM/scenarios/chicken_floorfield_ok.scenario"
# Use second-level directory as subdirectory for logging (e.g., "TestOSM"). # Use second-level directory as subdirectory for logging (e.g., "TestOSM").
...@@ -125,19 +136,29 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader ...@@ -125,19 +136,29 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader
makedirs_if_non_existing(log_dir) makedirs_if_non_existing(log_dir)
scenario_name = os.path.basename(scenario_file).split('.')[0] scenario_name = os.path.basename(scenario_file).split('.')[0]
log_file = os.path.join(log_dir, scenario_name + ".log") log_file = os.path.join(log_dir, ".".join([scenario_name, "log"]))
print(" Log file: " + log_file) print(" Log file: " + log_file)
# Measure wall time and not CPU time. # Measure wall time and not CPU time.
wall_time_start = time.time() wall_time_start = time.time()
# TODO: tread vadere_config_file_path # Build subprocess args:
# Basic, always enable asserttions for tests
# Use timout feature, check return value and capture stdout/stderr to a PIPE (use completed_process.stdout to get it). subprocess_args = ["java",
completed_process = subprocess.run(args=["java", "-enableassertions", "-jar", vadere_console, "-enableassertions",
"--logname", log_file, "scenario-run", "-f", "-jar", vadere_console,
scenario_file, "-o", output_dir], "--logname", log_file]
# add config file if required
if config_filepath is not None:
subprocess_args += ["--config-file", config_filepath]
# run per scenario given the scenario path and output directory
subprocess_args += ["scenario-run", "-f", scenario_file, "-o", output_dir]
# Use timout feature, check return value and capture stdout/stderr to a PIPE (use completed_process.stdout
# to get it).
completed_process = subprocess.run(args=subprocess_args,
timeout=scenario_timeout_in_sec, timeout=scenario_timeout_in_sec,
check=True, check=True,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
...@@ -159,18 +180,18 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader ...@@ -159,18 +180,18 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader
except subprocess.CalledProcessError as exception: except subprocess.CalledProcessError as exception:
print("Scenario file failed: {}".format(scenario_file)) print("Scenario file failed: {}".format(scenario_file))
print("-> Reason: non-zero return value {}".format(exception.returncode)) print("-> Reason: non-zero return value {}".format(exception.returncode))
print(" {}".format(read_first_error_linies(exception.stderr))) print(" {}".format(read_first_error_lines(exception.stderr)))
failed_summary.append("Scenario file failed: {}".format(scenario_file)) failed_summary.append("Scenario file failed: {}".format(scenario_file))
failed_summary.append("-> Reason: non-zero return value {}".format(exception.returncode)) failed_summary.append("-> Reason: non-zero return value {}".format(exception.returncode))
failed_summary.append(" {}".format(read_first_error_linies(exception.stderr))) failed_summary.append(" {}".format(read_first_error_lines(exception.stderr)))
failed_scenarios_with_exception.append((scenario_file, exception)) failed_scenarios_with_exception.append((scenario_file, exception))
if os.path.exists(output_dir): if os.path.exists(output_dir):
shutil.rmtree(output_dir) shutil.rmtree(output_dir)
return {"passed": passed_scenarios, "failed": failed_scenarios_with_exception, "failed_summary": failed_summary} return result_dict_create(passed_scenarios, failed_scenarios_with_exception, failed_summary)
def makedirs_if_non_existing(directory): def makedirs_if_non_existing(directory):
...@@ -178,17 +199,21 @@ def makedirs_if_non_existing(directory): ...@@ -178,17 +199,21 @@ def makedirs_if_non_existing(directory):
os.makedirs(directory) os.makedirs(directory)
def read_first_error_linies(error_byte_string): def read_first_error_lines(error_byte_string):
err_string_lines = error_byte_string.decode('utf-8').split('\n') err_string_lines = error_byte_string.decode('utf-8').split('\n')
if len(err_string_lines) >= 2: if len(err_string_lines) >= 2:
return re.sub('\s+', ' ', ' '.join(err_string_lines[:2])) return re.sub('\s+', ' ', ' '.join(err_string_lines[:2]))
else: else:
return 'unknown error see vadere log file.' return 'Unknown error see Vadere log file.'
def print_summary(passed_and_failed_scenarios): def result_dict_create(passed, failed, failed_summary):
return {"passed": passed, "failed": failed, "failed_summary": failed_summary}
def result_dict_print_summary(passed_and_failed_scenarios):
total_passed_scenarios = len(passed_and_failed_scenarios["passed"]) total_passed_scenarios = len(passed_and_failed_scenarios["passed"])
total_failed_scenarios = + len(passed_and_failed_scenarios["failed"]) total_failed_scenarios = len(passed_and_failed_scenarios["failed"])
total_scenarios = total_passed_scenarios + total_failed_scenarios total_scenarios = total_passed_scenarios + total_failed_scenarios
faild_summary = passed_and_failed_scenarios["failed_summary"] faild_summary = passed_and_failed_scenarios["failed_summary"]
...@@ -208,10 +233,22 @@ def print_summary(passed_and_failed_scenarios): ...@@ -208,10 +233,22 @@ def print_summary(passed_and_failed_scenarios):
print("Failed: {}".format(total_failed_scenarios)) print("Failed: {}".format(total_failed_scenarios))
def has_failed_scenarios(passed_and_failed_scenarios): def result_dict_has_failed_tests(passed_and_failed_scenarios):
return len(passed_and_failed_scenarios["failed"]) > 0 return len(passed_and_failed_scenarios["failed"]) > 0
def result_dict_merge(merge_into, merge_from):
# both dict and list (values in result_dict) are mutable, so it is safer to make a copy of both and return a fresh
# instance
merge_into = copy.deepcopy(merge_into)
merge_from = copy.deepcopy(merge_from)
merge_into["failed"].extend(merge_from["failed"])
merge_into["passed"].extend(merge_from["passed"])
merge_into["failed_summary"].extend(merge_from["failed_summary"])
return merge_into
if __name__ == "__main__": if __name__ == "__main__":
args = parse_command_line_arguments() args = parse_command_line_arguments()
...@@ -219,24 +256,22 @@ if __name__ == "__main__": ...@@ -219,24 +256,22 @@ if __name__ == "__main__":
passed_and_failed_scenarios_model = run_all_model_tests() passed_and_failed_scenarios_model = run_all_model_tests()
if not has_failed_scenarios(passed_and_failed_scenarios_model): if not result_dict_has_failed_tests(passed_and_failed_scenarios_model):
passed_and_failed_scenarios_optimization = run_all_optimization_tests() passed_and_failed_scenarios_optimization = run_all_optimization_tests()
else: else:
print("Skipping optimization tests...") print("Skipping optimization tests...")
passed_and_failed_scenarios_optimization = {"failed": [], "passed": [], "failed_summary": []} # empty passed_and_failed_scenarios_optimization = {"failed": [], "passed": [], "failed_summary": []} # empty
# Make a summery of all scenario files # Make a summery of all scenario files
all_passed_and_failed_scenarios = passed_and_failed_scenarios_model all_passed_and_failed_scenarios = result_dict_merge(passed_and_failed_scenarios_model,
all_passed_and_failed_scenarios["failed"].extend(passed_and_failed_scenarios_optimization["failed"]) passed_and_failed_scenarios_optimization)
all_passed_and_failed_scenarios["passed"].extend(passed_and_failed_scenarios_optimization["passed"])
all_passed_and_failed_scenarios["failed_summary"].extend(passed_and_failed_scenarios_optimization["failed_summary"])
else: else:
all_passed_and_failed_scenarios = run_scenario_files_with_vadere_console([args.scenario]) all_passed_and_failed_scenarios = run_scenario_files_with_vadere_console([args.scenario])
print_summary(all_passed_and_failed_scenarios) result_dict_print_summary(all_passed_and_failed_scenarios)
if has_failed_scenarios(all_passed_and_failed_scenarios): if result_dict_has_failed_tests(all_passed_and_failed_scenarios):
exit(1) exit(1)
else: else:
exit(0) exit(0)
Density.measurementRadius = 15
Density.measurementScale = 10.0
Density.standardDeviation = 0.5
Gui.dataProcessingViewMode = json
Gui.lastSavePoint = /home/daniel
Gui.toolbar.size = 40
Messages.language = en
Pedestrian.radius = 0.195
PostVis.SVGHeight = 768
PostVis.SVGWidth = 1024
PostVis.cellWidth = 1.0
PostVis.enableJsonInformationPanel = true
PostVis.framesPerSecond = 5
PostVis.maxCellWidth = 10.0
PostVis.maxFramePerSecond = 30
PostVis.maxNumberOfSaveDirectories = 5
PostVis.minCellWidth = 0.01
ProjectView.cellWidth = 1.0
ProjectView.defaultDirectory = /home/daniel/REPOS/vadere/VadereModelTests/TestOSM
ProjectView.defaultDirectoryAttributes = /home/daniel
ProjectView.defaultDirectoryScenarios = /home/daniel
ProjectView.icon.height.value = 35
ProjectView.icon.width.value = 35
ProjectView.maxCellWidth = 10.0
ProjectView.minCellWidth = 0.01
SettingsDialog.dataFormat = yyyy_MM_dd_HH_mm_ss
SettingsDialog.maxNumberOfTargets = 10
SettingsDialog.outputDirectory.path = .
SettingsDialog.showLogo = false
SettingsDialog.snapshotDirectory.path = .
Testing.stepCircleOptimization.compareBruteForceSolution = true
TopographyCreator.dotRadius = 0.5
History.lastUsedProject = /home/daniel/REPOS/vadere/VadereModelTests/TestOSM/vadere.project
History.recentProjects = /home/daniel/REPOS/vadere/VadereModelTests/TestOSM/vadere.project,/home/daniel/REPOS/vadere/VadereModelTests/TestNelderMead,/home/daniel/REPOS/vadere/VadereModelTests/TestOSM,/home/daniel/REPOS/vadere/VadereModelTests/TestOSMGroup,/home/daniel/REPOS/vadere/VadereModelTests/TestOSMGroup/vadere.project
...@@ -106,7 +106,7 @@ public class VadereConfig { ...@@ -106,7 +106,7 @@ public class VadereConfig {
} }
} }
// Static Setters // Static setters
/** /**
* With this setter one can inject a different config file instead of using "~/.config/vadere.conf". * With this setter one can inject a different config file instead of using "~/.config/vadere.conf".
* *
...@@ -117,7 +117,7 @@ public class VadereConfig { ...@@ -117,7 +117,7 @@ public class VadereConfig {
CONFIG_FILENAME = CONFIG_PATH.getFileName().toString(); CONFIG_FILENAME = CONFIG_PATH.getFileName().toString();
} }
// Static Setters // Static setters
/** /**
* Use Apache Common Configuration API on the returned object to retrieve Vadere's config options. * Use Apache Common Configuration API on the returned object to retrieve Vadere's config options.
* *
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment