Files
mongo/buildscripts/tests/test_burn_in_tests.py

1207 lines
55 KiB
Python

"""Unit tests for buildscripts/burn_in_tests.py."""
from __future__ import absolute_import
import collections
import os
import sys
import subprocess
import unittest
from mock import Mock, mock_open, patch, MagicMock
import buildscripts.burn_in_tests as burn_in
import buildscripts.ciconfig.evergreen as evg
# pylint: disable=missing-docstring,protected-access,too-many-lines
BURN_IN = "buildscripts.burn_in_tests"
EVG_CI = "buildscripts.ciconfig.evergreen"
EVG_CLIENT = "buildscripts.client.evergreen"
GIT = "buildscripts.git"
RESMOKELIB = "buildscripts.resmokelib"
GENERATE_RESMOKE_TASKS_BASENAME = "this_is_a_gen_task"
GENERATE_RESMOKE_TASKS_NAME = GENERATE_RESMOKE_TASKS_BASENAME + "_gen"
GET_GENERATE_RESMOKE_TASKS_NAME = lambda _: GENERATE_RESMOKE_TASKS_NAME
GENERATE_RESMOKE_TASKS_COMMAND = {
"func": "generate resmoke tasks",
"vars": {"suite": "suite3", "resmoke_args": "--shellWriteMode=commands"}
}
GENERATE_RESMOKE_TASKS_COMMAND2 = {
"func": "generate resmoke tasks", "vars": {"resmoke_args": "--shellWriteMode=commands"}
}
MULTIVERSION_PATH = "/data/multiversion"
GENERATE_RESMOKE_TASKS_MULTIVERSION_COMMAND = {
"func": "generate resmoke tasks",
"vars": {"resmoke_args": "--shellWriteMode=commands", "use_multiversion": MULTIVERSION_PATH}
}
MULTIVERSION_COMMAND = {"func": "do multiversion setup"}
RUN_TESTS_MULTIVERSION_COMMAND = {
"func": "run tests",
"vars": {"resmoke_args": "--shellWriteMode=commands", "task_path_suffix": MULTIVERSION_PATH}
}
def tasks_mock( #pylint: disable=too-many-arguments
tasks, generate_resmoke_tasks_command=None, get_vars_task_name=None, run_tests_command=None,
multiversion_path=None, multiversion_setup_command=None):
task_list = Mock()
task_list.tasks = []
for idx, task in enumerate(tasks):
task_list.tasks.append(Mock())
task_list.tasks[idx].is_generate_resmoke_task = generate_resmoke_tasks_command is not None
task_list.tasks[idx].is_run_tests_task = run_tests_command is not None
task_list.tasks[idx].is_multiversion_task = multiversion_path is not None
task_list.tasks[idx].generate_resmoke_tasks_command = generate_resmoke_tasks_command
task_list.tasks[idx].run_tests_command = run_tests_command
task_list.tasks[idx].get_vars_task_name = get_vars_task_name
task_list.tasks[idx].name = task["name"]
resmoke_args = task.get("combined_resmoke_args")
task_list.tasks[idx].combined_resmoke_args = resmoke_args
task_list.tasks[idx].resmoke_suite = evg.ResmokeArgs.get_arg(
resmoke_args, "suites") if resmoke_args else None
task_list.tasks[idx].multiversion_path = multiversion_path
task_list.tasks[idx].multiversion_setup_command = multiversion_setup_command
if task["name"].endswith("_gen"):
task_list.tasks[idx].generated_task_name = task["name"][:-4]
return task_list
VARIANTS = {
"variantall":
tasks_mock([{"name": "task1", "combined_resmoke_args": "--suites=suite1 var1arg1"},
{"name": "task2", "combined_resmoke_args": "--suites=suite1 var1arg2"},
{"name": "task3", "combined_resmoke_args": "--suites=suite1 var1arg3"}]),
"variant1":
tasks_mock([{"name": "task1", "combined_resmoke_args": "--suites=suite1 var1arg1"},
{"name": "task2"}]),
"variant2":
tasks_mock([{"name": "task2", "combined_resmoke_args": "var2arg1"},
{"name": "task3", "combined_resmoke_args": "--suites=suite3 var2arg3"}]),
"variant3":
tasks_mock([{"name": "task2", "combined_resmoke_args": "var3arg1"}]),
"variant4":
tasks_mock([]),
"variant_multiversion":
tasks_mock(
[{"name": "multiversion_task", "combined_resmoke_args": "--suites=suite3 vararg"}],
run_tests_command=RUN_TESTS_MULTIVERSION_COMMAND,
multiversion_setup_command=RUN_TESTS_MULTIVERSION_COMMAND,
multiversion_path=MULTIVERSION_PATH),
"variant_generate_tasks":
tasks_mock([{
"name": GENERATE_RESMOKE_TASKS_NAME, "combined_resmoke_args": "--suites=suite3 vararg"
}], generate_resmoke_tasks_command=GENERATE_RESMOKE_TASKS_COMMAND,
get_vars_task_name=GET_GENERATE_RESMOKE_TASKS_NAME),
"variant_generate_tasks_no_suite":
tasks_mock([{
"name": GENERATE_RESMOKE_TASKS_NAME, "combined_resmoke_args": "--suites=suite3 vararg"
}], generate_resmoke_tasks_command=GENERATE_RESMOKE_TASKS_COMMAND2,
get_vars_task_name=GET_GENERATE_RESMOKE_TASKS_NAME),
"variant_generate_tasks_diff_names":
tasks_mock([{
"name": "gen_task_name_different_from_vars_task_name",
"combined_resmoke_args": "--suites=suite3 vararg"
}], generate_resmoke_tasks_command=GENERATE_RESMOKE_TASKS_COMMAND,
get_vars_task_name=GET_GENERATE_RESMOKE_TASKS_NAME),
"variant_generate_tasks_multiversion":
tasks_mock([{
"name": GENERATE_RESMOKE_TASKS_NAME, "combined_resmoke_args": "--suites=suite3 vararg"
}], generate_resmoke_tasks_command=GENERATE_RESMOKE_TASKS_MULTIVERSION_COMMAND,
get_vars_task_name=GET_GENERATE_RESMOKE_TASKS_NAME,
multiversion_path=MULTIVERSION_PATH),
}
EVERGREEN_CONF = Mock()
EVERGREEN_CONF.get_variant = VARIANTS.get
EVERGREEN_CONF.variant_names = VARIANTS.keys()
def _mock_parser():
parser = Mock()
parser.error = Mock()
return parser
class TestValidateOptions(unittest.TestCase):
@staticmethod
def _mock_options():
options = Mock()
options.repeat_tests_num = None
options.repeat_tests_max = None
options.repeat_tests_min = None
options.repeat_tests_secs = None
options.buildvariant = None
options.run_buildvariant = None
options.test_list_file = None
return options
def test_validate_options_listfile_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.test_list_file = "list_file.json"
options.buildvariant = "variant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_not_called()
def test_validate_options_nolistfile_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.buildvariant = "variant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_not_called()
def test_validate_options_listfile_nobuildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.test_list_file = "list_file.json"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_not_called()
def test_validate_options_no_listfile_no_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.buildvariant = "variant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_not_called()
def test_validate_options_run_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.buildvariant = "variant1"
options.run_buildvariant = "variant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_not_called()
def test_validate_options_bad_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.buildvariant = "badvariant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_bad_run_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.run_buildvariant = "badvariant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_tests_max_no_tests_secs(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.repeat_tests_max = 3
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_tests_min_no_tests_secs(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.repeat_tests_min = 3
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_tests_min_gt_tests_max(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.repeat_tests_min = 3
options.repeat_tests_max = 2
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_tests_secs(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.buildvariant = "variant1"
options.repeat_tests_min = 2
options.repeat_tests_max = 1000
options.repeat_tests_secs = 3
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_not_called()
def test_validate_options_tests_secs_and_tests_num(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.buildvariant = "variant1"
options.repeat_tests_num = 1
options.repeat_tests_min = 1
options.repeat_tests_max = 3
options.repeat_tests_secs = 3
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
def test_validate_options_tests_secs_no_buildvariant(self):
mock_parser = _mock_parser()
options = self._mock_options()
options.repeat_tests_min = 1
options.repeat_tests_max = 3
options.repeat_tests_secs = 3
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.validate_options(mock_parser, options)
mock_parser.error.assert_called()
class TestGetResmokeRepeatOptions(unittest.TestCase):
@staticmethod
def _options_mock():
options = Mock()
options.repeat_tests_secs = None
options.repeat_tests_min = None
options.repeat_tests_max = None
options.repeat_tests_num = None
return options
def test_get_resmoke_repeat_options_default(self):
options = self._options_mock()
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertEqual(repeat_options, "--repeatSuites={}".format(burn_in.REPEAT_SUITES))
def test_get_resmoke_repeat_options_num(self):
options = self._options_mock()
options.repeat_tests_num = 5
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertEqual(repeat_options, "--repeatSuites={}".format(options.repeat_tests_num))
def test_get_resmoke_repeat_options_secs(self):
options = self._options_mock()
options.repeat_tests_secs = 5
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertEqual(repeat_options, "--repeatTestsSecs={}".format(options.repeat_tests_secs))
def test_get_resmoke_repeat_options_secs_min(self):
options = self._options_mock()
options.repeat_tests_secs = 5
options.repeat_tests_min = 2
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertIn("--repeatTestsSecs={}".format(options.repeat_tests_secs), repeat_options)
self.assertIn("--repeatTestsMin={}".format(options.repeat_tests_min), repeat_options)
self.assertNotIn("--repeatTestsMax", repeat_options)
self.assertNotIn("--repeatSuites", repeat_options)
def test_get_resmoke_repeat_options_secs_max(self):
options = self._options_mock()
options.repeat_tests_secs = 5
options.repeat_tests_max = 2
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertIn("--repeatTestsSecs={}".format(options.repeat_tests_secs), repeat_options)
self.assertIn("--repeatTestsMax={}".format(options.repeat_tests_max), repeat_options)
self.assertNotIn("--repeatTestsMin", repeat_options)
self.assertNotIn("--repeatSuites", repeat_options)
def test_get_resmoke_repeat_options_secs_min_max(self):
options = self._options_mock()
options.repeat_tests_secs = 5
options.repeat_tests_min = 2
options.repeat_tests_max = 2
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertIn("--repeatTestsSecs={}".format(options.repeat_tests_secs), repeat_options)
self.assertIn("--repeatTestsMin={}".format(options.repeat_tests_min), repeat_options)
self.assertIn("--repeatTestsMax={}".format(options.repeat_tests_max), repeat_options)
self.assertNotIn("--repeatSuites", repeat_options)
def test_get_resmoke_repeat_options_min(self):
options = self._options_mock()
options.repeat_tests_min = 2
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertEqual(repeat_options, "--repeatSuites={}".format(burn_in.REPEAT_SUITES))
def test_get_resmoke_repeat_options_max(self):
options = self._options_mock()
options.repeat_tests_max = 2
repeat_options = burn_in.get_resmoke_repeat_options(options)
self.assertEqual(repeat_options, "--repeatSuites={}".format(burn_in.REPEAT_SUITES))
class TestCheckVariant(unittest.TestCase):
@staticmethod
def test_check_variant():
mock_parser = _mock_parser()
buildvariant = "variant1"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.check_variant(buildvariant, mock_parser)
mock_parser.error.assert_not_called()
@staticmethod
def test_check_variant_badvariant():
mock_parser = _mock_parser()
buildvariant = "badvariant"
with patch(EVG_CI + ".parse_evergreen_file", return_value=EVERGREEN_CONF):
burn_in.check_variant(buildvariant, mock_parser)
mock_parser.error.assert_called()
class TestGetRunBuildvariant(unittest.TestCase):
def test__get_run_buildvariant_rb(self):
run_buildvariant = "variant1"
buildvariant = "variant2"
options = Mock()
options.run_buildvariant = run_buildvariant
options.buildvariant = buildvariant
self.assertEqual(run_buildvariant, burn_in._get_run_buildvariant(options))
def test__get_run_buildvariant_bv(self):
buildvariant = "variant2"
options = Mock()
options.run_buildvariant = None
options.buildvariant = buildvariant
self.assertEqual(buildvariant, burn_in._get_run_buildvariant(options))
class TestGetTaskName(unittest.TestCase):
def test__get_task_name(self):
name = "mytask"
task = Mock()
task.is_generate_resmoke_task = False
task.name = name
self.assertEqual(name, burn_in._get_task_name(task))
def test__get_task_name_generate_resmoke_task(self):
task_name = "mytask"
task = Mock(is_generate_resmoke_task=True, generated_task_name=task_name)
self.assertEqual(task_name, burn_in._get_task_name(task))
class TestSetResmokeArgs(unittest.TestCase):
def test__set_resmoke_args(self):
resmoke_args = "--suites=suite1 test1.js"
task = Mock()
task.combined_resmoke_args = resmoke_args
task.is_generate_resmoke_task = False
self.assertEqual(resmoke_args, burn_in._set_resmoke_args(task))
def test__set_resmoke_args_gen_resmoke_task(self):
resmoke_args = "--suites=suite1 test1.js"
new_suite = "suite2"
new_resmoke_args = "--suites={} test1.js".format(new_suite)
task = Mock()
task.combined_resmoke_args = resmoke_args
task.is_generate_resmoke_task = True
task.get_vars_suite_name = lambda cmd_vars: cmd_vars["suite"]
task.generate_resmoke_tasks_command = {"vars": {"suite": new_suite}}
self.assertEqual(new_resmoke_args, burn_in._set_resmoke_args(task))
def test__set_resmoke_args_gen_resmoke_task_no_suite(self):
suite = "suite1"
resmoke_args = "--suites={} test1.js".format(suite)
task = Mock()
task.combined_resmoke_args = resmoke_args
task.is_generate_resmoke_task = True
task.get_vars_suite_name = lambda cmd_vars: cmd_vars["task"]
task.generate_resmoke_tasks_command = {"vars": {"task": suite}}
self.assertEqual(resmoke_args, burn_in._set_resmoke_args(task))
class TestSetResmokeCmd(unittest.TestCase):
def test__set_resmoke_cmd_no_opts_no_args(self):
with patch(BURN_IN + ".get_resmoke_repeat_options", return_value=""):
self.assertListEqual([sys.executable, "buildscripts/resmoke.py"],
burn_in._set_resmoke_cmd(None, None))
def test__set_resmoke_cmd_no_opts(self):
args = ["arg1", "arg2"]
with patch(BURN_IN + ".get_resmoke_repeat_options", return_value=""):
self.assertListEqual(args, burn_in._set_resmoke_cmd(None, args))
def test__set_resmoke_cmd(self):
opts = "myopt1 myopt2"
args = ["arg1", "arg2"]
new_cmd = args + opts.split()
with patch(BURN_IN + ".get_resmoke_repeat_options", return_value=opts):
self.assertListEqual(new_cmd, burn_in._set_resmoke_cmd(opts, args))
class TestSubTaskName(unittest.TestCase):
def test__sub_task_name(self):
options = MagicMock(buildvariant="myvar", run_buildvariant=None)
task = "mytask"
task_num = 0
self.assertEqual("burn_in:myvar_mytask_0", burn_in._sub_task_name(options, task, task_num))
def test__sub_task_name_with_run_bv(self):
options = MagicMock(buildvariant="myvar", run_buildvariant="run_var")
task = "mytask"
task_num = 0
self.assertEqual("burn_in:run_var_mytask_0", burn_in._sub_task_name(
options, task, task_num))
TESTS_BY_TASK = {
"task1": {
"resmoke_args": "--suites=suite1",
"tests": ["jstests/test1.js", "jstests/test2.js"]},
"task2": {
"resmoke_args": "--suites=suite1",
"tests": ["jstests/test1.js", "jstests/test3.js"]},
"task3": {
"resmoke_args": "--suites=suite3",
"tests": ["jstests/test4.js", "jstests/test5.js"]},
"task4": {
"resmoke_args": "--suites=suite4", "tests": []},
"taskmulti": {
"resmoke_args": "--suites=suite4",
"tests": ["jstests/multi1.js"],
"use_multiversion": "/data/multi"},
} # yapf: disable
class TestCreateGenerateTasksFile(unittest.TestCase):
@staticmethod
def _options_mock():
options = Mock()
options.buildvariant = None
options.run_buildvariant = None
options.distro = None
return options
@staticmethod
def _get_tests(tests_by_task):
tests = []
for task in tests_by_task:
tests.extend(tests_by_task[task]["tests"])
return tests
def test_create_generate_tasks_file_tasks(self):
options = self._options_mock()
options.buildvariant = "myvariant"
tests_by_task = TESTS_BY_TASK
test_tasks = self._get_tests(tests_by_task)
with patch(BURN_IN + "._write_json_file") as mock_write_json:
burn_in.create_generate_tasks_file(options, tests_by_task)
evg_config = mock_write_json.call_args_list[0][0][0]
evg_tasks = evg_config["tasks"]
self.assertEqual(len(evg_tasks), len(test_tasks))
# Check task1 - test1.js
task = evg_tasks[0]
self.assertEqual(task["name"], "burn_in:myvariant_task1_0")
self.assertEqual(len(task["depends_on"]), 1)
self.assertEqual(task["depends_on"][0]["name"], "compile")
self.assertEqual(len(task["commands"]), 2)
self.assertEqual(task["commands"][0]["func"], "do setup")
self.assertEqual(task["commands"][1]["func"], "run tests")
resmoke_args = task["commands"][1]["vars"]["resmoke_args"]
self.assertIn("--suites=suite1", resmoke_args)
self.assertIn("jstests/test1.js", resmoke_args)
# Check task1 - test2.js
task = evg_tasks[1]
self.assertEqual(task["name"], "burn_in:myvariant_task1_1")
self.assertEqual(len(task["depends_on"]), 1)
self.assertEqual(task["depends_on"][0]["name"], "compile")
self.assertEqual(len(task["commands"]), 2)
self.assertEqual(task["commands"][0]["func"], "do setup")
self.assertEqual(task["commands"][1]["func"], "run tests")
resmoke_args = task["commands"][1]["vars"]["resmoke_args"]
self.assertIn("--suites=suite1", resmoke_args)
self.assertIn("jstests/test2.js", resmoke_args)
# task[2] - task[5] are similar to task[0] & task[1]
# Check taskmulti - multi1.js
taskmulti = evg_tasks[6]
self.assertEqual(taskmulti["name"], "burn_in:myvariant_taskmulti_0")
self.assertEqual(len(taskmulti["depends_on"]), 1)
self.assertEqual(taskmulti["depends_on"][0]["name"], "compile")
self.assertEqual(len(taskmulti["commands"]), 3)
self.assertEqual(taskmulti["commands"][0]["func"], "do setup")
self.assertEqual(taskmulti["commands"][1]["func"], "do multiversion setup")
self.assertEqual(taskmulti["commands"][2]["func"], "run tests")
resmoke_args = taskmulti["commands"][2]["vars"]["resmoke_args"]
self.assertIn("--suites=suite4", resmoke_args)
self.assertIn("jstests/multi1.js", resmoke_args)
self.assertEqual(taskmulti["commands"][2]["vars"]["task_path_suffix"], "/data/multi")
def test_create_generate_tasks_file_variants(self):
options = self._options_mock()
options.buildvariant = "myvariant"
tests_by_task = TESTS_BY_TASK
with patch(BURN_IN + "._write_json_file") as mock_write_json:
burn_in.create_generate_tasks_file(options, tests_by_task)
evg_config = mock_write_json.call_args_list[0][0][0]
self.assertEqual(len(evg_config["buildvariants"]), 1)
self.assertEqual(evg_config["buildvariants"][0]["name"], "myvariant")
self.assertEqual(len(evg_config["buildvariants"][0]["tasks"]), 7)
self.assertEqual(len(evg_config["buildvariants"][0]["display_tasks"]), 1)
display_task = evg_config["buildvariants"][0]["display_tasks"][0]
self.assertEqual(display_task["name"], burn_in.BURN_IN_TESTS_TASK)
execution_tasks = display_task["execution_tasks"]
self.assertEqual(len(execution_tasks), 8)
self.assertEqual(execution_tasks[0], burn_in.BURN_IN_TESTS_GEN_TASK)
self.assertEqual(execution_tasks[1], "burn_in:myvariant_task1_0")
self.assertEqual(execution_tasks[2], "burn_in:myvariant_task1_1")
self.assertEqual(execution_tasks[3], "burn_in:myvariant_task2_0")
self.assertEqual(execution_tasks[4], "burn_in:myvariant_task2_1")
self.assertEqual(execution_tasks[5], "burn_in:myvariant_task3_0")
self.assertEqual(execution_tasks[6], "burn_in:myvariant_task3_1")
self.assertEqual(execution_tasks[7], "burn_in:myvariant_taskmulti_0")
def test_create_generate_tasks_file_run_variants(self):
options = self._options_mock()
options.buildvariant = "myvariant"
options.run_buildvariant = "run_variant"
tests_by_task = TESTS_BY_TASK
with patch(BURN_IN + "._write_json_file") as mock_write_json:
burn_in.create_generate_tasks_file(options, tests_by_task)
evg_config = mock_write_json.call_args_list[0][0][0]
self.assertEqual(len(evg_config["buildvariants"]), 1)
self.assertEqual(evg_config["buildvariants"][0]["name"], "run_variant")
self.assertEqual(len(evg_config["buildvariants"][0]["tasks"]), 7)
self.assertEqual(len(evg_config["buildvariants"][0]["display_tasks"]), 1)
display_task = evg_config["buildvariants"][0]["display_tasks"][0]
self.assertEqual(display_task["name"], burn_in.BURN_IN_TESTS_TASK)
execution_tasks = display_task["execution_tasks"]
self.assertEqual(len(execution_tasks), 8)
self.assertEqual(execution_tasks[0], burn_in.BURN_IN_TESTS_GEN_TASK)
self.assertEqual(execution_tasks[1], "burn_in:run_variant_task1_0")
self.assertEqual(execution_tasks[2], "burn_in:run_variant_task1_1")
self.assertEqual(execution_tasks[3], "burn_in:run_variant_task2_0")
self.assertEqual(execution_tasks[4], "burn_in:run_variant_task2_1")
self.assertEqual(execution_tasks[5], "burn_in:run_variant_task3_0")
self.assertEqual(execution_tasks[6], "burn_in:run_variant_task3_1")
self.assertEqual(execution_tasks[7], "burn_in:run_variant_taskmulti_0")
def test_create_generate_tasks_file_distro(self):
options = self._options_mock()
options.buildvariant = "myvariant"
options.distro = "mydistro"
tests_by_task = TESTS_BY_TASK
test_tasks = self._get_tests(tests_by_task)
with patch(BURN_IN + "._write_json_file") as mock_write_json:
burn_in.create_generate_tasks_file(options, tests_by_task)
evg_config = mock_write_json.call_args_list[0][0][0]
self.assertEqual(len(evg_config["tasks"]), len(test_tasks))
self.assertEqual(len(evg_config["buildvariants"]), 1)
for variant in evg_config["buildvariants"]:
for task in variant.get("tasks", []):
self.assertEqual(len(task["distros"]), 1)
self.assertEqual(task["distros"][0], options.distro)
def test_create_generate_tasks_file_no_tasks(self):
variant = "myvariant"
options = self._options_mock()
options.buildvariant = variant
tests_by_task = {}
with patch(BURN_IN + "._write_json_file") as mock_write_json:
burn_in.create_generate_tasks_file(options, tests_by_task)
evg_config = mock_write_json.call_args_list[0][0][0]
self.assertEqual(len(evg_config), 1)
self.assertEqual(len(evg_config["buildvariants"]), 1)
self.assertEqual(evg_config["buildvariants"][0]["name"], variant)
display_tasks = evg_config["buildvariants"][0]["display_tasks"]
self.assertEqual(len(display_tasks), 1)
self.assertEqual(display_tasks[0]["name"], burn_in.BURN_IN_TESTS_TASK)
execution_tasks = display_tasks[0]["execution_tasks"]
self.assertEqual(len(execution_tasks), 1)
self.assertEqual(execution_tasks[0], burn_in.BURN_IN_TESTS_GEN_TASK)
class UpdateReportDataTests(unittest.TestCase):
def test_update_report_data_nofile(self):
data = {}
task = ""
pathname = "file_exists"
with patch("os.path.isfile", return_value=False) as mock_isfile,\
patch("json.load", return_value=data) as mock_json:
burn_in._update_report_data(data, pathname, task)
self.assertEqual(mock_isfile.call_count, 1)
self.assertEqual(mock_json.call_count, 0)
def test_update_report_data(self):
task1 = "task1"
task2 = "task2"
data = {
"failures": 1,
"results": [
{"test_file": "test1:" + task1},
{"test_file": "test2:" + task1}]
} # yapf: disable
new_data = {
"failures": 1,
"results": [
{"test_file": "test3"},
{"test_file": "test4"}]
} # yapf: disable
pathname = "file_exists"
with patch("os.path.isfile", return_value=True),\
patch("builtins.open", mock_open()),\
patch("json.load", return_value=new_data):
burn_in._update_report_data(data, pathname, task2)
self.assertEqual(len(data["results"]), 4)
self.assertEqual(data["failures"], 2)
self.assertIn({"test_file": "test1:" + task1}, data["results"])
self.assertIn({"test_file": "test3:" + task2}, data["results"])
class RunTests(unittest.TestCase):
class SysExit(Exception):
pass
def _test_run_tests(self, no_exec, tests_by_task, resmoke_cmd):
with patch("subprocess.check_call", return_value=None) as mock_subproc,\
patch(BURN_IN + "._update_report_data", return_value=None),\
patch(BURN_IN + "._write_json_file", return_value=None):
burn_in.run_tests(no_exec, tests_by_task, resmoke_cmd, None)
self.assertEqual(mock_subproc.call_count, len(tests_by_task.keys()))
for idx, task in enumerate(sorted(tests_by_task)):
for task_test in tests_by_task[task].get("tests", []):
self.assertIn(task_test, mock_subproc.call_args_list[idx][0][0])
def test_run_tests_noexec(self):
no_exec = True
resmoke_cmd = None
with patch("subprocess.check_call", return_value=None) as mock_subproc,\
patch(BURN_IN + "._write_json_file", return_value=None) as mock_write_json:
burn_in.run_tests(no_exec, TESTS_BY_TASK, resmoke_cmd, None)
self.assertEqual(mock_subproc.call_count, 0)
self.assertEqual(mock_write_json.call_count, 0)
def test_run_tests_notests(self):
no_exec = False
tests_by_task = {}
resmoke_cmd = ["python", "buildscripts/resmoke.py", "--continueOnFailure"]
self._test_run_tests(no_exec, tests_by_task, resmoke_cmd)
def test_run_tests_tests(self):
no_exec = False
resmoke_cmd = ["python", "buildscripts/resmoke.py", "--continueOnFailure"]
self._test_run_tests(no_exec, TESTS_BY_TASK, resmoke_cmd)
def test_run_tests_tests_resmoke_failure(self):
no_exec = False
resmoke_cmd = ["python", "buildscripts/resmoke.py", "--continueOnFailure"]
error_code = -1
with patch("subprocess.check_call", return_value=None) as mock_subproc,\
patch("sys.exit", return_value=error_code) as mock_exit,\
patch(BURN_IN + "._update_report_data", return_value=None),\
patch(BURN_IN + "._write_json_file", return_value=None):
mock_subproc.side_effect = subprocess.CalledProcessError(error_code, "err1")
mock_exit.side_effect = self.SysExit(error_code)
with self.assertRaises(self.SysExit):
burn_in.run_tests(no_exec, TESTS_BY_TASK, resmoke_cmd, None)
class FindLastActivated(unittest.TestCase):
REVISION_BUILDS = {
"rev1": {
"not_mongodb_mongo_master_variant1_build1": {"activated": False}, # force line break
"mongodb_mongo_unmaster_variant_build1": {"activated": True},
"mongodb_mongo_master_variant1_build1": {"activated": True},
"mongodb_mongo_master_variant2_build1": {"activated": False},
"mongodb_mongo_master_variant3_build1": {"activated": False}
},
"rev2": {
"not_mongodb_mongo_master_variant1_build1": {"activated": True},
"mongodb_mongo_unmaster_variant_build1": {"activated": True},
"mongodb_mongo_master_variant1_build1": {"activated": True},
"mongodb_mongo_master_variant2_build1": {"activated": False}
},
"rev3": {
"not_mongodb_mongo_master_variant1_build1": {"activated": True},
"mongodb_mongo_unmaster_variant_build1": {"activated": True},
"mongodb_mongo_master_variant1_build1": {"activated": True},
"mongodb_mongo_master_variant2_build1": {"activated": False},
},
"rev4": {
"not_mongodb_mongo_master_variant1_build1": {"activated": True},
"mongodb_mongo_unmaster_variant_build1": {"activated": True},
"mongodb_mongo_master_variant1_build1": {"activated": True}, # force line break
"mongodb_mongo_master_variant2_build1": {"activated": False},
"mongodb_mongo_master_variant3_build1": {"activated": True}
},
}
@staticmethod
def builds_url(build):
"""Return build URL."""
return "{}{}builds/{}".format(burn_in.API_SERVER_DEFAULT, burn_in.API_REST_PREFIX, build)
@staticmethod
def revisions_url(project, revision):
"""Return revisions URL."""
return "{}{}projects/{}/revisions/{}".format(burn_in.API_SERVER_DEFAULT,
burn_in.API_REST_PREFIX, project, revision)
@staticmethod
def load_urls(request, project, revision_builds):
"""Store request in URLs to support REST APIs."""
for revision in revision_builds:
builds = revision_builds[revision]
# The 'revisions' endpoint contains the list of builds.
url = FindLastActivated.revisions_url(project, revision)
build_list = []
for build in builds:
build_list.append("{}_{}".format(build, revision))
build_data = {"builds": build_list}
request.put(url, None, build_data)
for build in builds:
# The 'builds' endpoint contains the activated & revision field.
url = FindLastActivated.builds_url("{}_{}".format(build, revision))
build_data = builds[build]
build_data["revision"] = revision
request.put(url, None, build_data)
def _test_find_last_activated_task(self, branch, variant, revision,
revisions=REVISION_BUILDS.keys()):
with patch(BURN_IN + ".requests", MockRequests()),\
patch(EVG_CLIENT + ".read_evg_config", return_value=None):
self.load_urls(burn_in.requests, "mongodb-mongo-master", self.REVISION_BUILDS)
last_revision = burn_in.find_last_activated_task(revisions, variant, branch)
self.assertEqual(last_revision, revision)
def test_find_last_activated_task_first_rev(self):
self._test_find_last_activated_task("master", "variant1", "rev1")
def test_find_last_activated_task_last_rev(self):
self._test_find_last_activated_task("master", "variant3", "rev4")
def test_find_last_activated_task_no_rev(self):
self._test_find_last_activated_task("master", "variant2", None)
def test_find_last_activated_task_no_variant(self):
self._test_find_last_activated_task("master", "novariant", None)
def test_find_last_activated_task_no_branch(self):
with self.assertRaises(AttributeError):
self._test_find_last_activated_task("nobranch", "variant2", None)
def test_find_last_activated_norevisions(self):
self._test_find_last_activated_task("master", "novariant", None, [])
MEMBERS_MAP = {
"test1.js": ["suite1", "suite2"], "test2.js": ["suite1", "suite3"], "test3.js": [],
"test4.js": ["suite1", "suite2", "suite3"], "test5.js": ["suite2"]
}
SUITE1 = Mock()
SUITE1.tests = ["test1.js", "test2.js", "test4.js"]
SUITE2 = Mock()
SUITE2.tests = ["test1.js"]
SUITE3 = Mock()
SUITE3.tests = ["test2.js", "test4.js"]
def _create_executor_list(suites, exclude_suites):
with patch(RESMOKELIB + ".suitesconfig.create_test_membership_map", return_value=MEMBERS_MAP):
return burn_in.create_executor_list(suites, exclude_suites)
class CreateExecutorList(unittest.TestCase):
def test_create_executor_list_no_excludes(self):
suites = [SUITE1, SUITE2]
exclude_suites = []
executor_list = _create_executor_list(suites, exclude_suites)
self.assertEqual(executor_list["suite1"], SUITE1.tests)
self.assertEqual(executor_list["suite2"], ["test1.js", "test4.js"])
self.assertEqual(executor_list["suite3"], ["test2.js", "test4.js"])
def test_create_executor_list_excludes(self):
suites = [SUITE1, SUITE2]
exclude_suites = ["suite3"]
executor_list = _create_executor_list(suites, exclude_suites)
self.assertEqual(executor_list["suite1"], SUITE1.tests)
self.assertEqual(executor_list["suite2"], ["test1.js", "test4.js"])
self.assertEqual(executor_list["suite3"], [])
def test_create_executor_list_nosuites(self):
executor_list = _create_executor_list([], [])
self.assertEqual(executor_list, collections.defaultdict(list))
@patch(RESMOKELIB + ".testing.suite.Suite")
@patch(RESMOKELIB + ".suitesconfig.get_named_suites")
def test_create_executor_list_runs_core_suite(self, mock_get_named_suites, mock_suite_class):
mock_get_named_suites.return_value = ["core"]
burn_in.create_executor_list([], [])
self.assertEqual(mock_suite_class.call_count, 1)
@patch(RESMOKELIB + ".testing.suite.Suite")
@patch(RESMOKELIB + ".suitesconfig.get_named_suites")
def test_create_executor_list_ignores_dbtest_suite(self, mock_get_named_suites,
mock_suite_class):
mock_get_named_suites.return_value = ["dbtest"]
burn_in.create_executor_list([], [])
self.assertEqual(mock_suite_class.call_count, 0)
class CreateTaskList(unittest.TestCase):
def test_create_task_list(self):
variant = "variantall"
suites = [SUITE1, SUITE2, SUITE3]
exclude_suites = []
suite_list = _create_executor_list(suites, exclude_suites)
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), len(VARIANTS["variantall"].tasks))
self.assertIn("task1", task_list)
self.assertEqual(task_list["task1"]["resmoke_args"], "--suites=suite1 var1arg1")
self.assertEqual(task_list["task1"]["tests"], SUITE1.tests)
self.assertIsNone(task_list["task1"]["use_multiversion"])
self.assertIn("task2", task_list)
self.assertEqual(task_list["task2"]["resmoke_args"], "--suites=suite1 var1arg2")
self.assertEqual(task_list["task2"]["tests"], SUITE1.tests)
self.assertIsNone(task_list["task2"]["use_multiversion"])
self.assertIn("task3", task_list)
self.assertEqual(task_list["task3"]["resmoke_args"], "--suites=suite1 var1arg3")
self.assertEqual(task_list["task3"]["tests"], SUITE1.tests)
self.assertIsNone(task_list["task3"]["use_multiversion"])
def test_create_task_list_multiversion(self):
variant = "variant_multiversion"
suites = [SUITE1, SUITE2, SUITE3]
exclude_suites = []
suite_list = _create_executor_list(suites, exclude_suites)
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), len(VARIANTS["variant_multiversion"].tasks))
self.assertEqual(task_list["multiversion_task"]["use_multiversion"], MULTIVERSION_PATH)
def test_create_task_list_gen_tasks(self):
variant = "variant_generate_tasks"
suites = [SUITE3]
exclude_suites = []
suite_list = _create_executor_list(suites, exclude_suites)
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), len(VARIANTS["variant_generate_tasks"].tasks))
self.assertIn(GENERATE_RESMOKE_TASKS_BASENAME, task_list)
self.assertEqual(task_list[GENERATE_RESMOKE_TASKS_BASENAME]["tests"], SUITE3.tests)
self.assertIsNone(task_list[GENERATE_RESMOKE_TASKS_BASENAME]["use_multiversion"])
def test_create_task_list_gen_tasks_multiversion(self):
variant = "variant_generate_tasks_multiversion"
suites = [SUITE3]
exclude_suites = []
suite_list = _create_executor_list(suites, exclude_suites)
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), len(VARIANTS["variant_generate_tasks_multiversion"].tasks))
self.assertEqual(task_list[GENERATE_RESMOKE_TASKS_BASENAME]["use_multiversion"],
MULTIVERSION_PATH)
def test_create_task_list_gen_tasks_no_suite(self):
variant = "variant_generate_tasks_no_suite"
suites = [SUITE3]
exclude_suites = []
suite_list = _create_executor_list(suites, exclude_suites)
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), len(VARIANTS["variant_generate_tasks_no_suite"].tasks))
self.assertIn(GENERATE_RESMOKE_TASKS_BASENAME, task_list)
self.assertEqual(task_list[GENERATE_RESMOKE_TASKS_BASENAME]["tests"], SUITE3.tests)
def test_create_task_list_no_excludes(self):
variant = "variant1"
suites = [SUITE1, SUITE2]
exclude_suites = []
suite_list = _create_executor_list(suites, exclude_suites)
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), 1)
self.assertIn("task1", task_list)
self.assertEqual(task_list["task1"]["resmoke_args"], "--suites=suite1 var1arg1")
self.assertEqual(task_list["task1"]["tests"], SUITE1.tests)
self.assertNotIn("task2", task_list)
self.assertNotIn("task3", task_list)
def test_create_task_list_with_excludes(self):
variant = "variant2"
suites = [SUITE1, SUITE2, SUITE3]
suite_list = _create_executor_list(suites, [])
exclude_suites = ["suite2"]
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), 1)
self.assertIn("task3", task_list)
self.assertEqual(task_list["task3"]["resmoke_args"], "--suites=suite3 var2arg3")
self.assertEqual(task_list["task3"]["tests"], SUITE3.tests)
self.assertNotIn("task1", task_list)
self.assertNotIn("task2", task_list)
def test_create_task_list_no_suites(self):
variant = "variant2"
suite_list = {}
exclude_suites = ["suite2"]
task_list = burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, exclude_suites)
self.assertEqual(len(task_list), 0)
self.assertEqual(task_list, {})
def test_create_task_list_novariant(self):
class BadVariant(Exception):
pass
def _raise_bad_variant(code=0):
raise BadVariant("Bad variant {}".format(code))
variant = "novariant"
suites = [SUITE1, SUITE2, SUITE3]
suite_list = _create_executor_list(suites, [])
with patch("sys.exit", _raise_bad_variant):
with self.assertRaises(BadVariant):
burn_in.create_task_list(EVERGREEN_CONF, variant, suite_list, [])
class FindChangedTests(unittest.TestCase):
NUM_COMMITS = 10
MOD_FILES = [os.path.normpath("jstests/test1.js"), os.path.normpath("jstests/test2.js")]
REV_DIFF = dict(zip([str(x) for x in range(NUM_COMMITS)],
[MOD_FILES] * NUM_COMMITS)) #type: ignore
NO_REV_DIFF = dict(
zip([str(x) for x in range(NUM_COMMITS)], [None for _ in range(NUM_COMMITS)]))
UNTRACKED_FILES = [
os.path.normpath("jstests/untracked1.js"),
os.path.normpath("jstests/untracked2.js")
]
@staticmethod
def _copy_rev_diff(rev_diff):
"""Use this method instead of copy.deepcopy().
Note - it was discovered during testing that after using copy.deepcopy() that
updating one key would update all of them, i.e.,
rev_diff = {"1": ["abc"], 2": ["abc"]}
copy_rev_diff = copy.deepcopy(rev_diff)
copy_rev_diff["2"] += "xyz"
print(rev_diff)
Result: {"1": ["abc"], 2": ["abc"]}
print(copy_rev_diff)
Result: {"1": ["abc", "xyz"], 2": ["abc", "xyz"]}
At this point no identifiable issue could be found related to this problem.
"""
copy_rev_diff = {}
for key in rev_diff:
copy_rev_diff[key] = []
for file_name in rev_diff[key]:
copy_rev_diff[key].append(file_name)
return copy_rev_diff
@staticmethod
def _get_rev_list(range1, range2):
return [str(num) for num in range(range1, range2 + 1)]
def _mock_git_repository(self, directory):
return MockGitRepository(directory, FindChangedTests._get_rev_list(self.rev1, self.rev2),
self.rev_diff, self.untracked_files)
def _test_find_changed_tests( #pylint: disable=too-many-arguments
self, commit, max_revisions, variant, check_evg, rev1, rev2, rev_diff, untracked_files,
last_activated_task=None):
branch = "master"
# pylint: disable=attribute-defined-outside-init
self.rev1 = rev1
self.rev2 = rev2
self.rev_diff = rev_diff
self.untracked_files = untracked_files
self.expected_changed_tests = []
if commit is None and rev_diff:
self.expected_changed_tests += rev_diff[str(self.NUM_COMMITS - 1)]
elif rev_diff.get(commit, []):
self.expected_changed_tests += rev_diff.get(commit, [])
self.expected_changed_tests += untracked_files
# pylint: enable=attribute-defined-outside-init
with patch(EVG_CLIENT + ".read_evg_config", return_value=None),\
patch(GIT + ".Repository", self._mock_git_repository),\
patch("os.path.isfile", return_value=True),\
patch(BURN_IN + ".find_last_activated_task", return_value=last_activated_task):
return burn_in.find_changed_tests(branch, commit, max_revisions, variant, check_evg)
def test_find_changed_tests(self):
commit = "3"
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.expected_changed_tests)
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.expected_changed_tests)
def test_find_changed_tests_no_changes(self):
commit = "3"
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3,
self.NO_REV_DIFF, [])
self.assertEqual(changed_tests, [])
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3,
self.NO_REV_DIFF, [], "1")
self.assertEqual(changed_tests, [])
def test_find_changed_tests_check_evergreen(self):
commit = "1"
rev_diff = self._copy_rev_diff(self.REV_DIFF)
rev_diff["2"] += [os.path.normpath("jstests/test.js")]
expected_changed_tests = self.REV_DIFF[commit] + self.UNTRACKED_FILES
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3, rev_diff,
self.UNTRACKED_FILES)
self.assertEqual(changed_tests, expected_changed_tests)
rev_diff = self._copy_rev_diff(self.REV_DIFF)
rev_diff["3"] += [os.path.normpath("jstests/test.js")]
expected_changed_tests = rev_diff["3"] + self.UNTRACKED_FILES
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3, rev_diff,
self.UNTRACKED_FILES, "1")
self.assertEqual(changed_tests, expected_changed_tests)
def test_find_changed_tests_no_diff(self):
commit = "3"
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3,
self.NO_REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.UNTRACKED_FILES)
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3,
self.NO_REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.UNTRACKED_FILES)
def test_find_changed_tests_no_untracked(self):
commit = "3"
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3,
self.REV_DIFF, [])
self.assertEqual(changed_tests, self.REV_DIFF[commit])
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3,
self.REV_DIFF, [])
self.assertEqual(changed_tests, self.REV_DIFF[commit])
def test_find_changed_tests_no_base_commit(self):
changed_tests = self._test_find_changed_tests(None, 5, "myvariant", False, 0, 3,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.expected_changed_tests)
changed_tests = self._test_find_changed_tests(None, 5, "myvariant", True, 0, 3,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.expected_changed_tests)
def test_find_changed_tests_non_js(self):
commit = "3"
rev_diff = self._copy_rev_diff(self.REV_DIFF)
rev_diff[commit] += [os.path.normpath("jstests/test.yml")]
untracked_files = self.UNTRACKED_FILES + [os.path.normpath("jstests/untracked.yml")]
expected_changed_tests = self.REV_DIFF[commit] + self.UNTRACKED_FILES
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3, rev_diff,
untracked_files)
self.assertEqual(changed_tests, expected_changed_tests)
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3, rev_diff,
untracked_files)
self.assertEqual(changed_tests, expected_changed_tests)
def test_find_changed_tests_not_in_jstests(self):
commit = "3"
rev_diff = self._copy_rev_diff(self.REV_DIFF)
rev_diff[commit] += [os.path.normpath("other/test.js")]
untracked_files = self.UNTRACKED_FILES + [os.path.normpath("other/untracked.js")]
expected_changed_tests = self.REV_DIFF[commit] + self.UNTRACKED_FILES
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 3, rev_diff,
untracked_files)
self.assertEqual(changed_tests, expected_changed_tests)
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 3, rev_diff,
untracked_files)
self.assertEqual(changed_tests, expected_changed_tests)
def test_find_changed_tests_no_revisions(self):
commit = "3"
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 0,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.expected_changed_tests)
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 0,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, self.expected_changed_tests)
def test_find_changed_tests_too_many_revisions(self):
commit = "3"
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", False, 0, 9,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, [])
changed_tests = self._test_find_changed_tests(commit, 5, "myvariant", True, 0, 9,
self.REV_DIFF, self.UNTRACKED_FILES)
self.assertEqual(changed_tests, [])
class MockGitRepository(object):
def __init__(self, _, rev_list, rev_diff, untracked_files):
self.rev_list = rev_list
self.rev_diff = rev_diff
self.untracked_files = untracked_files
def _get_revs(self, rev_range):
revs = rev_range.split("...")
if not revs:
return revs
elif len(revs) == 1:
revs.append("HEAD")
if revs[1] == "HEAD" and self.rev_list:
revs[1] = self.rev_list[-1]
return revs
def __get_rev_range(self, rev_range):
commits = []
if len(self.rev_list) < 2:
return commits
revs = self._get_revs(rev_range)
latest_commit_found = False
for commit in self.rev_list:
latest_commit_found = latest_commit_found or revs[0] == commit
if revs[1] == commit:
break
if latest_commit_found:
commits.append(commit)
return commits
def get_merge_base(self, _):
return self.rev_list[-1]
def git_rev_list(self, args):
return "\n".join(self.__get_rev_range(args[0])[::-1])
def git_diff(self, args):
revs = self._get_revs(args[1])
if revs:
diff_list = self.rev_diff.get(revs[-1], [])
if diff_list:
return "\n".join(diff_list)
return ""
def git_status(self, args):
revs = self._get_revs(args[0])
modified_files = [""]
if revs:
diff_list = self.rev_diff.get(revs[-1], [])
if diff_list:
modified_files = [" M {}".format(untracked) for untracked in diff_list]
untracked_files = ["?? {}".format(untracked) for untracked in self.untracked_files]
return "\n".join(modified_files + untracked_files)
class MockResponse(object):
def __init__(self, response, json_data):
self.response = response
self.json_data = json_data
def json(self):
return self.json_data
class MockRequests(object):
def __init__(self):
self.responses = {}
def put(self, url, response, json_data):
self.responses[url] = MockResponse(response, json_data)
def get(self, url):
if url in self.responses:
return self.responses[url]
return None