Skip to content

Commit

Permalink
extracting simultaneously tests for all variants, fix eclipse-sumo#7681
Browse files Browse the repository at this point in the history
  • Loading branch information
behrisch committed Oct 20, 2020
1 parent 80e53f5 commit 146cfc6
Showing 1 changed file with 154 additions and 138 deletions.
292 changes: 154 additions & 138 deletions tools/extractTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def get_options(args=None):
optParser.add_option("-i", "--intelligent-names", dest="names", action="store_true",
default=False, help="generate cfg name from directory name")
optParser.add_option("-v", "--verbose", action="store_true", default=False, help="more information")
optParser.add_option("-a", "--application", help="sets the application to be used")
optParser.add_option("-a", "--application", default="SMART", help="sets the application to be used")
optParser.add_option("-s", "--skip-configuration", default=False, action="store_true",
help="skips creation of an application config from the options.app file")
optParser.add_option("-x", "--skip-validation", default=False, action="store_true",
Expand Down Expand Up @@ -89,6 +89,22 @@ def generateTargetName(baseDir, source):
return source[len(os.path.commonprefix([baseDir, source])):].replace(os.sep, '_')


def mergedOptions(varOpts, appOpts):
voIdx = len(varOpts) - 1
aoIdx = len(appOpts) - 1
while aoIdx >= 0:
while voIdx >= 0 and len(os.path.dirname(varOpts[voIdx])) >= len(os.path.dirname(appOpts[aoIdx])):
yield varOpts[voIdx]
if len(os.path.dirname(varOpts[voIdx])) == len(os.path.dirname(appOpts[aoIdx])):
aoIdx -= 1
if aoIdx == -1:
break
voIdx -= 1
while aoIdx >= 0 and (voIdx < 0 or (voIdx >= 0 and len(os.path.dirname(varOpts[voIdx])) < len(os.path.dirname(appOpts[aoIdx])))):
yield appOpts[aoIdx]
aoIdx -= 1


def main(options):
targets = []
if options.file:
Expand Down Expand Up @@ -116,162 +132,162 @@ def main(options):
for p in [
''')
for source, target, app in targets:
outputFiles = glob.glob(join(source, "output.[0-9a-z]*"))
# print source, target, outputFiles
# XXX we should collect the options.app.variant files in all parent
# directories instead. This would allow us to save config files for all
# variants
appName = set([f.split('.')[-1] for f in outputFiles])
if len(appName) != 1:
if options.application in appName:
appName = set([options.application])
elif app in appName:
appName = set([app])
else:
print(("Skipping %s because the application was not unique (found %s).") % (
source, appName), file=sys.stderr)
continue
app = next(iter(appName))
optionsFiles = []
configFiles = []
optionsFiles = defaultdict(list)
configFiles = defaultdict(list)
potentials = defaultdict(list)
source = os.path.realpath(source)
curDir = source
if curDir[-1] == os.path.sep:
curDir = os.path.dirname(curDir)
while True:
for f in os.listdir(curDir):
for f in sorted(os.listdir(curDir)):
path = join(curDir, f)
if f not in potentials or os.path.isdir(path):
potentials[f].append(path)
if f == "options." + app:
optionsFiles.append(path)
config = join(curDir, "config." + app)
if f.startswith("options."):
optionsFiles[f[8:]].append(path)
if f.startswith("config."):
configFiles[f[7:]].append(path)
if curDir == join(SUMO_HOME, "tests") or curDir == os.path.dirname(curDir):
break
if os.path.exists(config):
configFiles.append(config)
curDir = os.path.dirname(curDir)
if not configFiles:
print("Config not found for %s." % source, file=sys.stderr)
continue
if target == "" and not options.noSubdir:
target = generateTargetName(
os.path.dirname(configFiles[-1]), source)
testPath = os.path.abspath(join(options.output, target))
if not os.path.exists(testPath):
os.makedirs(testPath)
net = None
skip = False
appOptions = []
for f in reversed(optionsFiles):
for o in shlex.split(open(f).read()):
if skip:
skip = False
continue
if o == "--xml-validation" and options.skip_validation:
skip = True
continue
if o == "{CLEAR}":
appOptions = []
continue
appOptions.append(o)
if "=" in o:
o = o.split("=")[-1]
if o[-8:] == ".net.xml":
net = o
nameBase = "test"
if options.names:
nameBase = os.path.basename(target)
exclude = []
# gather copy_test_path exclusions
for config in configFiles:
for line in open(config):
entry = line.strip().split(':')
if entry and entry[0] == "test_data_ignore":
exclude.append(entry[1])
# copy test data from the tree
for config in configFiles:
for line in open(config):
entry = line.strip().split(':')
if entry and "copy_test_path" in entry[0] and entry[1] in potentials:
if "net" in app or not net or entry[1][-8:] != ".net.xml" or entry[1] == net:
toCopy = potentials[entry[1]][0]
if os.path.isdir(toCopy):
# copy from least specific to most specific
merge = entry[0] == "copy_test_path_merge"
for toCopy in reversed(potentials[entry[1]]):
copy_merge(
toCopy, join(testPath, os.path.basename(toCopy)), merge, exclude)
if app == "":
for v in configFiles.keys():
if "." not in v:
app = v
break
haveVariant = False
for variant in set(optionsFiles.keys()) | set(configFiles.keys()):
if options.application == "SMART" and len(glob.glob(os.path.join(source, "*" + variant))) == 0:
if options.verbose:
print("ignoring variant %s for '%s'" % (variant, source))
continue
if options.application not in ("ALL", variant, variant.split(".")[-1]):
continue
haveVariant = True
cfg = configFiles[variant] + configFiles[app]
if target == "" and not options.noSubdir:
target = generateTargetName(os.path.dirname(cfg[-1]), source)
testPath = os.path.abspath(join(options.output, target))
if not os.path.exists(testPath):
os.makedirs(testPath)
net = None
skip = False
appOptions = []
for f in mergedOptions(optionsFiles[variant], optionsFiles[app]):
for o in shlex.split(open(f).read()):
if skip:
skip = False
continue
if o == "--xml-validation" and options.skip_validation:
skip = True
continue
if o == "{CLEAR}":
appOptions = []
continue
appOptions.append(o)
if "=" in o:
o = o.split("=")[-1]
if o[-8:] == ".net.xml":
net = o
nameBase = "test"
if options.names:
nameBase = os.path.basename(target)
if "." in variant:
nameBase += variant.split(".")[-1]
exclude = []
# gather copy_test_path exclusions
for config in cfg:
for line in open(config):
entry = line.strip().split(':')
if entry and entry[0] == "test_data_ignore":
exclude.append(entry[1])
# copy test data from the tree
for config in cfg:
for line in open(config):
entry = line.strip().split(':')
if entry and "copy_test_path" in entry[0] and entry[1] in potentials:
if "net" in app or not net or entry[1][-8:] != ".net.xml" or entry[1] == net:
toCopy = potentials[entry[1]][0]
if os.path.isdir(toCopy):
# copy from least specific to most specific
merge = entry[0] == "copy_test_path_merge"
for toCopy in reversed(potentials[entry[1]]):
copy_merge(toCopy, join(testPath, os.path.basename(toCopy)), merge, exclude)
else:
shutil.copy2(toCopy, testPath)
if options.python_script:
if app == "netgen":
call = ['join(SUMO_HOME, "bin", "netgenerate")'] + ['"%s"' % a for a in appOptions]
elif app == "tools":
call = ['"python"'] + ['"%s"' % a for a in appOptions]
call[1] = 'join(SUMO_HOME, "%s")' % appOptions[0]
elif app == "complex":
call = ['"python"']
for o in appOptions:
if o.endswith(".py"):
call.insert(1, '"./%s"' % os.path.basename(o))
else:
shutil.copy2(toCopy, testPath)
if options.python_script:
if app == "netgen":
call = ['join(SUMO_HOME, "bin", "netgenerate")'] + ['"%s"' % a for a in appOptions]
call.append('"%s"' % o)
else:
call = ['join(SUMO_HOME, "bin", "%s")' % app] + ['"%s"' % a for a in appOptions]
prefix = os.path.commonprefix((testPath, os.path.abspath(pyBatch.name)))
up = os.path.abspath(pyBatch.name)[len(prefix):].count(os.sep) * "../"
pyBatch.write(' subprocess.Popen([%s], cwd=join(THIS_DIR, r"%s%s")),\n' %
(', '.join(call), up, testPath[len(prefix):]))
if options.skip_configuration:
continue
oldWorkDir = os.getcwd()
os.chdir(testPath)
haveConfig = False
if app in ["dfrouter", "duarouter", "jtrrouter", "marouter", "netconvert",
"netgen", "netgenerate", "od2trips", "polyconvert", "sumo", "activitygen"]:
if app == "netgen":
# binary is now called differently but app still has the old name
app = "netgenerate"
if options.verbose:
print("calling %s for testPath '%s' with options '%s'" %
(checkBinary(app), testPath, " ".join(appOptions)))
try:
haveConfig = subprocess.call([checkBinary(app)] + appOptions +
['--save-configuration', '%s.%scfg' %
(nameBase, app[:4])]) == 0
except OSError:
print("Executable %s not found, generating shell scripts instead of config." % app, file=sys.stderr)
if not haveConfig:
appOptions.insert(0, "$SUMO_HOME/bin/" + app)
elif app == "tools":
call = ['"python"'] + ['"%s"' % a for a in appOptions]
call[1] = 'join(SUMO_HOME, "%s")' % appOptions[0]
for i, a in enumerate(appOptions):
if a.endswith(".py"):
del appOptions[i:i+1]
appOptions[0:0] = [os.environ.get("PYTHON", "python"), "$SUMO_HOME/" + a]
break
if a.endswith(".jar"):
del appOptions[i:i+1]
appOptions[0:0] = ["java", "-jar", "$SUMO_HOME/" + a]
break
elif app == "complex":
call = ['"python"']
for o in appOptions:
if o.endswith(".py"):
call.insert(1, '"./%s"' % os.path.basename(o))
else:
call.append('"%s"' % o)
else:
call = ['join(SUMO_HOME, "bin", "%s")' % app] + ['"%s"' % a for a in appOptions]
prefix = os.path.commonprefix((testPath, os.path.abspath(pyBatch.name)))
up = os.path.abspath(pyBatch.name)[len(prefix):].count(os.sep) * "../"
pyBatch.write(' subprocess.Popen([%s], cwd=join(THIS_DIR, r"%s%s")),\n' %
(', '.join(call), up, testPath[len(prefix):]))
if options.skip_configuration:
continue
oldWorkDir = os.getcwd()
os.chdir(testPath)
haveConfig = False
if app in ["dfrouter", "duarouter", "jtrrouter", "marouter", "netconvert",
"netgen", "netgenerate", "od2trips", "polyconvert", "sumo", "activitygen"]:
if app == "netgen":
# binary is now called differently but app still has the old name
app = "netgenerate"
if options.verbose:
print("calling %s for testPath '%s' with options '%s'" %
(checkBinary(app), testPath, " ".join(appOptions)))
try:
haveConfig = subprocess.call([checkBinary(app)] + appOptions +
['--save-configuration', '%s.%scfg' %
(nameBase, app[:4])]) == 0
except OSError:
print("Executable %s not found, generating shell scripts instead of config." % app, file=sys.stderr)
for i, a in enumerate(appOptions):
if a.endswith(".py"):
if os.path.exists(join(testPath, os.path.basename(a))):
a = os.path.basename(a)
del appOptions[i:i+1]
appOptions[0:0] = [os.environ.get("PYTHON", "python"), a]
break
if not haveConfig:
appOptions.insert(0, "$SUMO_HOME/bin/" + app)
elif app == "tools":
for i, a in enumerate(appOptions):
if a.endswith(".py"):
del appOptions[i:i+1]
appOptions[0:0] = [os.environ.get("PYTHON", "python"), "$SUMO_HOME/" + a]
break
if a.endswith(".jar"):
del appOptions[i:i+1]
appOptions[0:0] = ["java", "-jar", "$SUMO_HOME/" + a]
break
elif app == "complex":
for i, a in enumerate(appOptions):
if a.endswith(".py"):
if os.path.exists(join(testPath, os.path.basename(a))):
a = os.path.basename(a)
del appOptions[i:i+1]
appOptions[0:0] = [os.environ.get("PYTHON", "python"), a]
break
if not haveConfig:
if options.verbose:
print("generating shell scripts for testPath '%s' with call '%s'" %
(testPath, " ".join(appOptions)))
cmd = [o if " " not in o else "'%s'" % o for o in appOptions]
open(nameBase + ".sh", "w").write(" ".join(cmd))
cmd = [o.replace("$SUMO_HOME", "%SUMO_HOME%") if " " not in o else '"%s"' % o for o in appOptions]
open(nameBase + ".bat", "w").write(" ".join(cmd))
os.chdir(oldWorkDir)
if options.verbose:
print("generating shell scripts for testPath '%s' with call '%s'" %
(testPath, " ".join(appOptions)))
cmd = [o if " " not in o else "'%s'" % o for o in appOptions]
open(nameBase + ".sh", "w").write(" ".join(cmd))
cmd = [o.replace("$SUMO_HOME", "%SUMO_HOME%") if " " not in o else '"%s"' % o for o in appOptions]
open(nameBase + ".bat", "w").write(" ".join(cmd))
os.chdir(oldWorkDir)
if not haveVariant:
print("No suitable variant found for %s." % source, file=sys.stderr)
if options.python_script:
pyBatch.write(']:\n if p.wait() != 0:\n sys.exit(1)\n')

Expand Down

0 comments on commit 146cfc6

Please sign in to comment.