2020-04-22 17:38:25 +02:00
|
|
|
# Copyright 2020 MongoDB Inc.
|
2020-01-07 19:48:42 +01:00
|
|
|
#
|
2020-04-22 17:38:25 +02:00
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
# a copy of this software and associated documentation files (the
|
|
|
|
# "Software"), to deal in the Software without restriction, including
|
|
|
|
# without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
# permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
# the following conditions:
|
2020-01-07 19:48:42 +01:00
|
|
|
#
|
2020-04-22 17:38:25 +02:00
|
|
|
# The above copyright notice and this permission notice shall be included
|
|
|
|
# in all copies or substantial portions of the Software.
|
|
|
|
#
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
|
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
|
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2020-01-07 19:48:42 +01:00
|
|
|
#
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
import SCons
|
2020-01-07 19:48:42 +01:00
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
import auto_install_binaries
|
|
|
|
|
|
|
|
_proof_scanner_cache_key = "proof_scanner_cache"
|
|
|
|
_associated_proof = "associated_proof_key"
|
|
|
|
|
|
|
|
def proof_generator_command_scanner_func(node, env, path):
|
|
|
|
results = getattr(node.attributes, _proof_scanner_cache_key, None)
|
|
|
|
if results is not None:
|
|
|
|
return results
|
|
|
|
results = env.GetTransitivelyInstalledFiles(node)
|
|
|
|
setattr(node.attributes, _proof_scanner_cache_key, results)
|
|
|
|
return results
|
|
|
|
|
|
|
|
proof_generator_command_scanner = SCons.Scanner.Scanner(
|
|
|
|
function=proof_generator_command_scanner_func,
|
|
|
|
path_function=None,
|
|
|
|
recursive=True
|
|
|
|
)
|
|
|
|
|
|
|
|
def auto_prove_task(env, component, role):
|
|
|
|
entry = auto_install_binaries.get_alias_map_entry(env, component, role)
|
|
|
|
return [
|
|
|
|
getattr(f.attributes, _associated_proof)
|
|
|
|
for f in entry.files
|
|
|
|
if hasattr(f.attributes, _associated_proof)
|
|
|
|
]
|
2020-04-28 20:25:40 +02:00
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
def generate_test_execution_aliases(env, test):
|
2020-04-28 20:25:40 +02:00
|
|
|
installed = [test]
|
|
|
|
if env.get("AUTO_INSTALL_ENABLED", False) and env.GetAutoInstalledFiles(test):
|
|
|
|
installed = env.GetAutoInstalledFiles(test)
|
2020-01-07 19:48:42 +01:00
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
target_name = os.path.basename(installed[0].path)
|
|
|
|
|
|
|
|
target_command = env.Command(
|
|
|
|
target=f"#+{target_name}",
|
|
|
|
source=installed[0],
|
|
|
|
action="$( $ICERUN $) ${SOURCES[0]} $UNITTEST_FLAGS",
|
2020-01-07 19:48:42 +01:00
|
|
|
NINJA_POOL="console",
|
|
|
|
)
|
2021-08-04 23:11:45 +02:00
|
|
|
env.Pseudo(target_command)
|
|
|
|
env.Alias("test-execution-aliases", target_command)
|
2020-01-07 19:48:42 +01:00
|
|
|
|
|
|
|
for source in test.sources:
|
|
|
|
source_base_name = os.path.basename(source.get_path())
|
|
|
|
# Strip suffix
|
|
|
|
dot_idx = source_base_name.rfind(".")
|
|
|
|
suffix = source_base_name[dot_idx:]
|
2021-05-06 02:12:00 +02:00
|
|
|
if suffix in env["TEST_EXECUTION_SUFFIX_DENYLIST"]:
|
2020-01-07 19:48:42 +01:00
|
|
|
continue
|
|
|
|
|
|
|
|
source_name = source_base_name[:dot_idx]
|
|
|
|
if target_name == source_name:
|
|
|
|
continue
|
|
|
|
|
|
|
|
source_command = env.Command(
|
2021-08-04 23:11:45 +02:00
|
|
|
target=f"#+{source_name}",
|
|
|
|
source=installed[0],
|
|
|
|
action="$( $ICERUN $) ${SOURCES[0]} -fileNameFilter $TEST_SOURCE_FILE_NAME $UNITTEST_FLAGS",
|
2020-01-07 19:48:42 +01:00
|
|
|
TEST_SOURCE_FILE_NAME=source_name,
|
|
|
|
NINJA_POOL="console",
|
|
|
|
)
|
2021-08-04 23:11:45 +02:00
|
|
|
env.Pseudo(source_command)
|
|
|
|
env.Alias('test-execution-aliases', source_command)
|
|
|
|
|
|
|
|
proof_generator_command = env.Command(
|
|
|
|
target=[
|
|
|
|
'${SOURCE}.log',
|
|
|
|
'${SOURCE}.status',
|
|
|
|
],
|
|
|
|
source=installed[0],
|
|
|
|
action=SCons.Action.Action(
|
|
|
|
"$PROOF_GENERATOR_COMMAND",
|
|
|
|
"$PROOF_GENERATOR_COMSTR"
|
|
|
|
),
|
|
|
|
source_scanner=proof_generator_command_scanner
|
|
|
|
)
|
|
|
|
|
|
|
|
# We assume tests are provable by default, but some tests may not
|
|
|
|
# be. Such tests can be tagged with UNDECIDABLE_TEST=True. If a
|
|
|
|
# test isn't provable, we disable caching its results and require
|
|
|
|
# it to be always rebuilt.
|
|
|
|
if installed[0].env.get('UNDECIDABLE_TEST', False):
|
|
|
|
env.NoCache(proof_generator_command)
|
|
|
|
env.AlwaysBuild(proof_generator_command)
|
|
|
|
|
|
|
|
proof_analyzer_command = env.Command(
|
|
|
|
target='${SOURCES[1].base}.proof',
|
|
|
|
source=proof_generator_command,
|
|
|
|
action=SCons.Action.Action(
|
|
|
|
"$PROOF_ANALYZER_COMMAND",
|
|
|
|
"$PROOF_ANALYZER_COMSTR"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
proof_analyzer_alias = env.Alias(
|
|
|
|
f"prove-{target_name}",
|
|
|
|
proof_analyzer_command,
|
|
|
|
)
|
2020-01-07 19:48:42 +01:00
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
setattr(installed[0].attributes, _associated_proof, proof_analyzer_alias)
|
2020-01-07 19:48:42 +01:00
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
# TODO: Should we enable proof at the file level?
|
2020-01-07 19:48:42 +01:00
|
|
|
|
|
|
|
def exists(env):
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def generate(env):
|
|
|
|
# Used for Ninja generator to collect the test execution aliases
|
|
|
|
env.Alias("test-execution-aliases")
|
|
|
|
env.AddMethod(generate_test_execution_aliases, "GenerateTestExecutionAliases")
|
|
|
|
|
2021-05-06 02:12:00 +02:00
|
|
|
env["TEST_EXECUTION_SUFFIX_DENYLIST"] = env.get(
|
|
|
|
"TEST_EXECUTION_SUFFIX_DENYLIST", [".in"]
|
2020-01-07 19:48:42 +01:00
|
|
|
)
|
|
|
|
|
2021-08-04 23:11:45 +02:00
|
|
|
env.AppendUnique(
|
|
|
|
AIB_TASKS={
|
|
|
|
"prove": (auto_prove_task, False),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
# TODO: Should we have some sort of prefix_xdir for the output location for these? Something like
|
|
|
|
# $PREFIX_VARCACHE and which in our build is pre-populated to $PREFIX/var/cache/mongo or similar?
|
|
|
|
|
|
|
|
if env['PLATFORM'] == 'win32':
|
|
|
|
env["PROOF_GENERATOR_COMMAND"] = "$( $ICERUN $) ${SOURCES[0]} $UNITTEST_FLAGS > ${TARGETS[0]} 2>&1 & call echo %^errorlevel% > ${TARGETS[1]}"
|
|
|
|
|
|
|
|
# Keeping this here for later, but it only works if cmd.exe is
|
|
|
|
# launched with /V, and SCons doesn't do that.
|
|
|
|
#
|
|
|
|
# env["PROOF_ANALYZER_COMMAND"] = "set /p nextErrorLevel=<${SOURCES[1]} & if \"!nextErrorLevel!\"==\"0 \" (type nul > $TARGET) else (exit 1)"
|
|
|
|
#
|
|
|
|
# Instead, use grep! I mean findstr.
|
|
|
|
env["PROOF_ANALYZER_COMMAND"] = "findstr /B /L 0 ${SOURCES[1]} && (type nul > $TARGET) || (exit 1)"
|
|
|
|
else:
|
|
|
|
env["PROOF_GENERATOR_COMMAND"] = "$( $ICERUN $) ${SOURCES[0]} $UNITTEST_FLAGS > ${TARGETS[0]} 2>&1 ; echo $? > ${TARGETS[1]}"
|
|
|
|
env["PROOF_ANALYZER_COMMAND"] = "if $$(exit $$(cat ${SOURCES[1]})) ; then touch $TARGET ; else exit 1 ; fi"
|
|
|
|
|
|
|
|
# TODO: Condition this on verbosity
|
|
|
|
env['PROOF_GENERATOR_COMSTR'] = "Running test ${SOURCES[0]}"
|
|
|
|
env['PROOF_ANALYZER_COMSTR'] = "Analyzing test results in ${SOURCES[1]}"
|