Exemple #1
0
    def test_config_disable_plugin(self) -> None:
        plugins_v0.DictPlugin({
            "name": "plugin1",
            "config": {
                "set": {
                    "KEY1": "value1"
                }
            }
        })
        plugins_v0.DictPlugin({
            "name": "plugin2",
            "config": {
                "set": {
                    "KEY2": "value2"
                }
            }
        })
        plugins.load("plugin1")
        plugins.load("plugin2")

        with temporary_root() as root:
            config = tutor_config.load_minimal(root)
            config_pre = config.copy()
            with patch.object(fmt, "STDOUT"):
                hooks.Actions.PLUGIN_UNLOADED.do("plugin1", "", config)
            config_post = tutor_config.load_minimal(root)

        self.assertEqual("value1", config_pre["KEY1"])
        self.assertEqual("value2", config_pre["KEY2"])
        self.assertNotIn("KEY1", config)
        self.assertNotIn("KEY1", config_post)
        self.assertEqual("value2", config["KEY2"])
Exemple #2
0
    def test_update_twice_should_return_same_config(self, _: Mock) -> None:
        with temporary_root() as root:
            config1 = tutor_config.load_minimal(root)
            tutor_config.save_config_file(root, config1)
            config2 = tutor_config.load_minimal(root)

        self.assertEqual(config1, config2)
Exemple #3
0
 def test_config_printvalue(self) -> None:
     with temporary_root() as root:
         self.invoke_in_root(root, ["config", "save"])
         result = self.invoke_in_root(
             root, ["config", "printvalue", "MYSQL_ROOT_PASSWORD"])
     self.assertFalse(result.exception)
     self.assertEqual(0, result.exit_code)
     self.assertTrue(result.output)
Exemple #4
0
 def test_config_render(self) -> None:
     with tempfile.TemporaryDirectory() as dest:
         with temporary_root() as root:
             self.invoke_in_root(root, ["config", "save"])
             result = self.invoke_in_root(root,
                                          ["config", "render", root, dest])
     self.assertEqual(0, result.exit_code)
     self.assertFalse(result.exception)
Exemple #5
0
 def test_save_full(self) -> None:
     with temporary_root() as root:
         config = tutor_config.load_full(root)
         with patch.object(fmt, "STDOUT"):
             env.save(root, config)
         self.assertTrue(
             os.path.exists(
                 os.path.join(env.base_dir(root), "local",
                              "docker-compose.yml")))
Exemple #6
0
 def test_config_save_unset_value(self) -> None:
     with temporary_root() as root:
         result1 = self.invoke_in_root(root,
                                       ["config", "save", "-U", "key"])
         result2 = self.invoke_in_root(root,
                                       ["config", "printvalue", "key"])
     self.assertFalse(result1.exception)
     self.assertEqual(0, result1.exit_code)
     self.assertEqual(1, result2.exit_code)
Exemple #7
0
 def test_initialise(self, mock_stdout: StringIO) -> None:
     with temporary_root() as root:
         context = TestContext(root)
         config = tutor_config.load_full(root)
         runner = context.job_runner(config)
         jobs.initialise(runner)
         output = mock_stdout.getvalue().strip()
         self.assertTrue(output.startswith("Initialising all services..."))
         self.assertTrue(output.endswith("All services initialised."))
Exemple #8
0
 def test_create_testcontext(self) -> None:
     with temporary_root() as root:
         context = TestContext(root)
         config = tutor_config.load_full(root)
         runner = context.job_runner(config)
         self.assertTrue(os.path.exists(context.root))
         self.assertFalse(
             os.path.exists(os.path.join(context.root, tutor_config.CONFIG_FILENAME))
         )
         self.assertTrue(isinstance(runner, TestJobRunner))
Exemple #9
0
 def test_save_full_with_https(self) -> None:
     with temporary_root() as root:
         config = tutor_config.load_full(root)
         config["ENABLE_HTTPS"] = True
         with patch.object(fmt, "STDOUT"):
             env.save(root, config)
             with open(
                 os.path.join(env.base_dir(root), "apps", "caddy", "Caddyfile"),
                 encoding="utf-8",
             ) as f:
                 self.assertIn("www.myopenedx.com{$default_site_port}", f.read())
Exemple #10
0
 def test_current_version_in_latest_env(self) -> None:
     with temporary_root() as root:
         os.makedirs(env.base_dir(root))
         with open(
                 os.path.join(env.base_dir(root), env.VERSION_FILENAME),
                 "w",
                 encoding="utf-8",
         ) as f:
             f.write(__version__)
         self.assertEqual(__version__, env.current_version(root))
         self.assertEqual("nutmeg", env.get_env_release(root))
         self.assertIsNone(env.should_upgrade_from_release(root))
         self.assertTrue(env.is_up_to_date(root))
Exemple #11
0
    def test_interactive(self) -> None:
        def mock_prompt(*_args: None, **kwargs: str) -> str:
            return kwargs["default"]

        with temporary_root() as rootdir:
            with patch.object(click, "prompt", new=mock_prompt):
                with patch.object(click, "confirm", new=mock_prompt):
                    config = tutor_config.load_minimal(rootdir)
                    interactive.ask_questions(config)

        self.assertIn("MYSQL_ROOT_PASSWORD", config)
        self.assertEqual(8, len(get_typed(config, "MYSQL_ROOT_PASSWORD", str)))
        self.assertEqual("www.myopenedx.com", config["LMS_HOST"])
        self.assertEqual("studio.www.myopenedx.com", config["CMS_HOST"])
Exemple #12
0
    def test_set_theme(self, mock_stdout: StringIO) -> None:
        with temporary_root() as root:
            context = TestContext(root)
            config = tutor_config.load_full(root)
            runner = context.job_runner(config)
            jobs.set_theme("sample_theme", ["domain1", "domain2"], runner)

            output = mock_stdout.getvalue()
            service = re.search(r"Service: (\w*)", output)
            commands = re.search(r"(-----)([\S\s]+)(-----)", output)
            assert service is not None
            assert commands is not None
            self.assertEqual(service.group(1), "lms")
            self.assertTrue(
                commands.group(2).strip().startswith(
                    'echo "Loading settings $DJANGO_SETTINGS_MODULE"'))
Exemple #13
0
    def test_plugin_templates(self) -> None:
        with tempfile.TemporaryDirectory() as plugin_templates:
            DictPlugin({
                "name": "plugin1",
                "version": "0",
                "templates": plugin_templates
            })
            # Create two templates
            os.makedirs(os.path.join(plugin_templates, "plugin1", "apps"))
            with open(
                    os.path.join(plugin_templates, "plugin1",
                                 "unrendered.txt"),
                    "w",
                    encoding="utf-8",
            ) as f:
                f.write("This file should not be rendered")
            with open(
                    os.path.join(plugin_templates, "plugin1", "apps",
                                 "rendered.txt"),
                    "w",
                    encoding="utf-8",
            ) as f:
                f.write("Hello my ID is {{ ID }}")

            # Render templates
            with temporary_root() as root:
                # Create configuration
                config: Config = tutor_config.load_full(root)
                config["ID"] = "Hector Rumblethorpe"
                plugins.load("plugin1")
                tutor_config.save_enabled_plugins(config)

                # Render environment
                with patch.object(fmt, "STDOUT"):
                    env.save(root, config)

                # Check that plugin template was rendered
                root_env = os.path.join(root, "env")
                dst_unrendered = os.path.join(root_env, "plugins", "plugin1",
                                              "unrendered.txt")
                dst_rendered = os.path.join(root_env, "plugins", "plugin1",
                                            "apps", "rendered.txt")
                self.assertFalse(os.path.exists(dst_unrendered))
                self.assertTrue(os.path.exists(dst_rendered))
                with open(dst_rendered, encoding="utf-8") as f:
                    self.assertEqual("Hello my ID is Hector Rumblethorpe",
                                     f.read())
Exemple #14
0
 def test_config_render_with_extra_configs(self) -> None:
     with tempfile.TemporaryDirectory() as dest:
         with temporary_root() as root:
             self.invoke_in_root(root, ["config", "save"])
             result = self.invoke_in_root(
                 root,
                 [
                     "config",
                     "render",
                     "-x",
                     os.path.join(root, tutor_config.CONFIG_FILENAME),
                     root,
                     dest,
                 ],
             )
     self.assertEqual(0, result.exit_code)
     self.assertFalse(result.exception)
Exemple #15
0
    def test_removed_entry_is_added_on_save(self, _: Mock) -> None:
        with temporary_root() as root:
            mock_random_string = Mock()

            hooks.Filters.ENV_TEMPLATE_FILTERS.add_item(
                ("random_string", mock_random_string), )
            mock_random_string.return_value = "abcd"
            config1 = tutor_config.load_full(root)
            password1 = config1.pop("MYSQL_ROOT_PASSWORD")

            tutor_config.save_config_file(root, config1)

            mock_random_string.return_value = "efgh"
            config2 = tutor_config.load_full(root)
            password2 = config2["MYSQL_ROOT_PASSWORD"]

        self.assertEqual("abcd", password1)
        self.assertEqual("efgh", password2)
Exemple #16
0
    def test_copyfrom(self) -> None:
        with temporary_root() as root:
            with tempfile.TemporaryDirectory() as directory:
                with patch(
                        "tutor.utils.docker_compose") as mock_docker_compose:
                    self.invoke_in_root(root, ["config", "save"])

                    # Copy to existing directory
                    result = self.invoke_in_root(root, [
                        "local", "copyfrom", "lms", "/openedx/venv", directory
                    ])
                    self.assertIsNone(result.exception)
                    self.assertEqual(0, result.exit_code)
                    self.assertIn(
                        f"--volume={directory}:/tmp/mount",
                        mock_docker_compose.call_args[0],
                    )
                    self.assertIn(
                        "cp --recursive --preserve /openedx/venv /tmp/mount",
                        mock_docker_compose.call_args[0],
                    )

                    # Copy to non-existing directory
                    result = self.invoke_in_root(
                        root,
                        [
                            "local",
                            "copyfrom",
                            "lms",
                            "/openedx/venv",
                            os.path.join(directory, "venv2"),
                        ],
                    )
                    self.assertIsNone(result.exception)
                    self.assertEqual(0, result.exit_code)
                    self.assertIn(
                        f"--volume={directory}:/tmp/mount",
                        mock_docker_compose.call_args[0],
                    )
                    self.assertIn(
                        "cp --recursive --preserve /openedx/venv /tmp/mount/venv2",
                        mock_docker_compose.call_args[0],
                    )
Exemple #17
0
    def test_json_config_is_overwritten_by_yaml(self, _: Mock) -> None:
        with temporary_root() as root:
            # Create config from scratch
            config_yml_path = os.path.join(root, tutor_config.CONFIG_FILENAME)
            config_json_path = os.path.join(
                root, tutor_config.CONFIG_FILENAME.replace("yml", "json"))
            config = tutor_config.load_full(root)

            # Save config to json
            with open(config_json_path, "w", encoding="utf-8") as f:
                json.dump(config, f, ensure_ascii=False, indent=4)
            self.assertFalse(os.path.exists(config_yml_path))
            self.assertTrue(os.path.exists(config_json_path))

            # Reload and compare
            current = tutor_config.load_full(root)
            self.assertTrue(os.path.exists(config_yml_path))
            self.assertFalse(os.path.exists(config_json_path))
            self.assertEqual(config, current)
Exemple #18
0
 def test_images_build_plugin(self, mock_image_build: Mock) -> None:
     plugins.v0.DictPlugin(
         {
             "name": "plugin1",
             "hooks": {
                 "build-image": {
                     "service1": "service1:1.0.0",
                     "service2": "service2:2.0.0",
                 }
             },
         }
     )
     plugins.load("plugin1")
     with temporary_root() as root:
         self.invoke_in_root(root, ["config", "save"])
         result = self.invoke_in_root(root, ["images", "build", "service1"])
     self.assertIsNone(result.exception)
     self.assertEqual(0, result.exit_code)
     mock_image_build.assert_called()
     self.assertIn("service1:1.0.0", mock_image_build.call_args[0])
Exemple #19
0
 def test_images_build_plugin_with_args(self, image_build: Mock) -> None:
     plugins.v0.DictPlugin(
         {
             "name": "plugin1",
             "hooks": {
                 "build-image": {
                     "service1": "service1:1.0.0",
                     "service2": "service2:2.0.0",
                 }
             },
         }
     )
     plugins.load("plugin1")
     build_args = [
         "images",
         "build",
         "--no-cache",
         "-a",
         "myarg=value",
         "--add-host",
         "host",
         "--target",
         "target",
         "-d",
         "docker_args",
         "service1",
     ]
     with temporary_root() as root:
         self.invoke_in_root(root, ["config", "save"])
         result = self.invoke_in_root(root, build_args)
     self.assertIsNone(result.exception)
     self.assertEqual(0, result.exit_code)
     image_build.assert_called()
     self.assertIn("service1:1.0.0", image_build.call_args[0])
     for arg in image_build.call_args[0][2:]:
         # The only extra args are `--build-arg`
         if arg != "--build-arg":
             self.assertIn(arg, build_args)
Exemple #20
0
 def test_config_printroot(self) -> None:
     with temporary_root() as root:
         result = self.invoke_in_root(root, ["config", "printroot"])
     self.assertFalse(result.exception)
     self.assertEqual(0, result.exit_code)
     self.assertIn(root, result.output)
Exemple #21
0
 def test_get_all_openedx_domains(self) -> None:
     with temporary_root() as root:
         config = tutor_config.load_full(root)
         domains = jobs.get_all_openedx_domains(config)
         self.assertTrue(domains)
         self.assertEqual(6, len(domains))
Exemple #22
0
 def invoke(args: t.List[str]) -> click.testing.Result:
     with temporary_root() as root:
         return TestCommandMixin.invoke_in_root(root, args)
Exemple #23
0
 def test_pathjoin(self) -> None:
     with temporary_root() as root:
         self.assertEqual(os.path.join(env.base_dir(root), "dummy"),
                          env.pathjoin(root, "dummy"))
Exemple #24
0
 def test_current_version_in_empty_env(self) -> None:
     with temporary_root() as root:
         self.assertIsNone(env.current_version(root))
         self.assertIsNone(env.get_env_release(root))
         self.assertIsNone(env.should_upgrade_from_release(root))
         self.assertTrue(env.is_up_to_date(root))