summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuildscripts/evergreen_gen_multiversion_tests.py12
-rw-r--r--buildscripts/tests/test_evergreen_gen_multiversion_tests.py197
-rw-r--r--etc/evergreen.yml13
3 files changed, 214 insertions, 8 deletions
diff --git a/buildscripts/evergreen_gen_multiversion_tests.py b/buildscripts/evergreen_gen_multiversion_tests.py
index 0ab8960361e..5973e9680f4 100755
--- a/buildscripts/evergreen_gen_multiversion_tests.py
+++ b/buildscripts/evergreen_gen_multiversion_tests.py
@@ -27,6 +27,8 @@ import buildscripts.evergreen_generate_resmoke_tasks as generate_resmoke
from buildscripts.evergreen_generate_resmoke_tasks import Suite, ConfigOptions
import buildscripts.evergreen_gen_fuzzer_tests as gen_fuzzer
+# pylint: disable=len-as-condition
+
LOGGER = structlog.getLogger(__name__)
REQUIRED_CONFIG_KEYS = {
@@ -353,6 +355,11 @@ class EvergreenMultiversionConfigGenerator(object):
shrub_project.add_build_variant(build_variant)
write_file_to_dir(CONFIG_DIR, f"{self.task}.json", shrub_project.json())
+ if len(os.listdir(CONFIG_DIR)) == 0:
+ raise RuntimeError(
+ f"Multiversion suite generator unexpectedly yielded no configuration in '{CONFIG_DIR}'"
+ )
+
@click.group()
def main():
@@ -425,6 +432,11 @@ def generate_exclude_yaml(suite: str, task_path_suffix: str, is_generated_suite:
suite_yaml_dict[file_name] = generate_resmoke.generate_resmoke_suite_config(
suite_config, file_name, excludes=list(files_to_exclude))
else:
+ if not os.path.exists(CONFIG_DIR) or len(os.listdir(CONFIG_DIR)) == 0:
+ LOGGER.info(
+ f"No configuration files exist in '{CONFIG_DIR}'. Skipping exclude file generation")
+ return
+
# We expect the generated suites to already have been generated in the generated config
# directory.
suites_dir = CONFIG_DIR
diff --git a/buildscripts/tests/test_evergreen_gen_multiversion_tests.py b/buildscripts/tests/test_evergreen_gen_multiversion_tests.py
new file mode 100644
index 00000000000..4fdba6e44f9
--- /dev/null
+++ b/buildscripts/tests/test_evergreen_gen_multiversion_tests.py
@@ -0,0 +1,197 @@
+''' Tests for the multiversion generators '''
+
+import os
+import shutil
+import unittest
+from tempfile import TemporaryDirectory, NamedTemporaryFile
+
+from mock import patch, MagicMock
+from shrub.v2 import BuildVariant, ShrubProject
+from shrub.variant import DisplayTaskDefinition
+from click.testing import CliRunner
+
+from buildscripts import evergreen_gen_multiversion_tests as under_test
+from buildscripts.evergreen_generate_resmoke_tasks import read_yaml
+import buildscripts.evergreen_generate_resmoke_tasks as generate_resmoke
+
+# pylint: disable=missing-docstring
+
+
+class TestRun(unittest.TestCase):
+ def setUp(self):
+ self._tmpdir = TemporaryDirectory()
+
+ def tearDown(self):
+ self._tmpdir.cleanup()
+ under_test.CONFIG_DIR = generate_resmoke.DEFAULT_CONFIG_VALUES
+
+ @patch.object(under_test.EvergreenMultiversionConfigGenerator, 'generate_evg_tasks')
+ @patch('buildscripts.evergreen_generate_resmoke_tasks.should_tasks_be_generated')
+ @patch('buildscripts.evergreen_gen_multiversion_tests.write_file_to_dir')
+ def test_empty_result_config_fails(self, generate_evg_tasks, should_tasks_be_generated,
+ write_file_to_dir):
+ # pylint: disable=unused-argument
+ ''' Hijacks the write_file_to_dir function to prevent the configuration
+ from being written to disk, and ensure the command fails '''
+ under_test.CONFIG_DIR = self._tmpdir.name
+
+ # NamedTemporaryFile doesn't work too well on Windows. We need to
+ # close the fd's so that run_generate_tasks can open the files,
+ # so we override the delete-on-close behaviour on Windows, and manually
+ # handle cleanup later
+ is_windows = os.name == 'nt'
+ with NamedTemporaryFile(mode='w',
+ delete=not is_windows) as expansions_file, NamedTemporaryFile(
+ mode='w', delete=not is_windows) as evg_conf:
+ expansions_file.write(EXPANSIONS)
+ expansions_file.flush()
+ should_tasks_be_generated.return_value = True
+ if is_windows:
+ # on windows we need to close the fd's so that
+ # run_generate_tasks can open the file handle
+ expansions_file.close()
+ evg_conf.close()
+
+ runner = CliRunner()
+ result = runner.invoke(
+ under_test.run_generate_tasks,
+ ['--expansion-file', expansions_file.name, '--evergreen-config', evg_conf.name])
+ self.assertEqual(result.exit_code, 1, result)
+ self.assertTrue(isinstance(result.exception, RuntimeError))
+ self.assertEqual(
+ str(result.exception),
+ f"Multiversion suite generator unexpectedly yielded no configuration in '{self._tmpdir.name}'"
+ )
+ self.assertEqual(write_file_to_dir.call_count, 1)
+ if is_windows:
+ # on windows we need to manually delete these files, since
+ # we've disabled the delete-on-close mechanics
+ os.remove(expansions_file.name)
+ os.remove(evg_conf.name)
+
+
+class TestGenerateExcludeFiles(unittest.TestCase):
+ def setUp(self):
+ self._tmpdir = TemporaryDirectory()
+ under_test.CONFIG_DIR = self._tmpdir.name
+
+ def tearDown(self):
+ if self._tmpdir is not None:
+ self._tmpdir.cleanup()
+ under_test.CONFIG_DIR = generate_resmoke.DEFAULT_CONFIG_VALUES["generated_config_dir"]
+
+ def test_missing_dir_okay(self):
+ self._tmpdir.cleanup()
+ self._tmpdir = None
+ self.assertFalse(os.path.exists(under_test.CONFIG_DIR))
+
+ runner = CliRunner()
+ result = runner.invoke(
+ under_test.generate_exclude_yaml,
+ ['--suite=test', '--task-path-suffix=test', '--is-generated-suite=true'])
+ self.assertEqual(result.exit_code, 0, result)
+
+ def test_empty_dir_okay(self):
+ runner = CliRunner()
+ result = runner.invoke(
+ under_test.generate_exclude_yaml,
+ ['--suite=test', '--task-path-suffix=test', '--is-generated-suite=true'])
+ self.assertEqual(result.exit_code, 0, result)
+ self.assertEqual(len(os.listdir(under_test.CONFIG_DIR)), 0)
+
+ @patch('buildscripts.evergreen_gen_multiversion_tests.get_exclude_files')
+ def test_adds_exclude_file(self, get_exclude_files):
+ get_exclude_files.return_value = set()
+ get_exclude_files.return_value.add('jstests/core/count_plan_summary.js')
+ with open(self._tmpdir.name + "/sharding_jscore_passthrough_00.yml", mode='w') as fh:
+ fh.write(CONF)
+
+ runner = CliRunner()
+ result = runner.invoke(
+ under_test.generate_exclude_yaml,
+ ['--suite=test', '--task-path-suffix=/data/multiversion', '--is-generated-suite=true'])
+ self.assertEqual(result.exit_code, 0, result)
+ self.assertEqual(get_exclude_files.call_count, 1)
+ new_conf = read_yaml(self._tmpdir.name, "sharding_jscore_passthrough_00.yml")
+ self.assertEqual(new_conf["selector"]["exclude_files"],
+ ["jstests/core/count_plan_summary.js"])
+
+
+CONF = """# DO NOT EDIT THIS FILE. All manual edits will be lost.
+# This file was generated by /data/mci/4d9a5adb3744dad3d44d93e5ff2a441f/src/buildscripts/evergreen_generate_resmoke_tasks.py from
+# sharded_collections_jscore_passthrough.
+executor:
+ archive:
+ hooks:
+ - CheckReplDBHash
+ - ValidateCollections
+ config:
+ shell_options:
+ eval: load("jstests/libs/override_methods/implicitly_shard_accessed_collections.js")
+ readMode: commands
+ fixture:
+ class: ShardedClusterFixture
+ enable_balancer: false
+ mongod_options:
+ set_parameters:
+ enableTestCommands: 1
+ mongos_options:
+ set_parameters:
+ enableTestCommands: 1
+ num_shards: 2
+ hooks:
+ - class: CheckReplDBHash
+ - class: ValidateCollections
+ - class: CleanEveryN
+ n: 20
+selector:
+ exclude_with_any_tags:
+ - assumes_against_mongod_not_mongos
+ - assumes_no_implicit_collection_creation_after_drop
+ - assumes_no_implicit_index_creation
+ - assumes_unsharded_collection
+ - cannot_create_unique_index_when_using_hashed_shard_key
+ - requires_profiling
+ roots:
+ - jstests/core/count_plan_summary.js
+ - jstests/core/json_schema/unique_items.js
+ - jstests/core/arrayfind9.js
+ - jstests/core/sort_numeric.js
+ - jstests/core/remove4.js
+ - jstests/core/aggregation_accepts_write_concern.js
+ - jstests/core/geo3.js
+ - jstests/core/minmax_edge.js
+ - jstests/core/json_schema/additional_properties.js
+ - jstests/core/update_min_max_examples.js
+ - jstests/core/where2.js
+ - jstests/core/geo_s2meridian.js
+ - jstests/core/bittest.js
+ - jstests/core/orj.js
+ - jstests/core/find_dedup.js
+ - jstests/core/hashed_index_queries.js
+ - jstests/core/geo_circle2a.js
+ - jstests/core/js4.js
+ - jstests/core/index_create_with_nul_in_name.js
+ - jstests/core/count_hint.js
+ - jstests/core/sorta.js
+ - jstests/core/orf.js
+ - jstests/core/geo_s2within.js
+ - jstests/core/json_schema/required.js
+ - jstests/core/pop_server_13516.js
+ - jstests/core/updatel.js
+ - jstests/core/geo_s2descindex.js
+test_kind: js_test
+use_in_multiversion: sharded_collections_jscore_multiversion_passthrough
+"""
+
+EXPANSIONS = """task: t
+build_variant: bv
+fallback_num_sub_suites: 5
+project: p
+task_id: t0
+task_name: t
+use_multiversion: "true"
+"""
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index 4940145370f..81a4a00a2af 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -1602,6 +1602,7 @@ functions:
params:
target: generate_tasks_config.tgz
source_dir: src/generated_resmoke_config
+ optional: true
include:
- "*"
@@ -2053,14 +2054,6 @@ functions:
${activate_virtualenv}
$python buildscripts/evergreen_gen_multiversion_tests.py run --expansion-file expansions.yml
- - command: shell.exec
- params:
- working_dir: src
- script: |
- set -o errexit
- set -o verbose
-
- ${activate_virtualenv}
$python buildscripts/evergreen_gen_multiversion_tests.py generate-exclude-files --suite=${task_name} --task-path-suffix=${task_path_suffix} --is-generated-suite=true
- command: archive.targz_pack
@@ -2080,9 +2073,13 @@ functions:
permissions: public-read
content_type: ${content_type|application/gzip}
display_name: Generated Task Config - Execution ${execution}
+ optional: true
- command: generate.tasks
params:
+ # Optional b/c reruns of this task will produce no JSON files to avoid
+ # generate.tasks failing
+ optional: true
files:
- src/generated_resmoke_config/*.json