-
Notifications
You must be signed in to change notification settings - Fork 447
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: pluggable
local/dev/k8s do <job>
commands
We introduce a new filter to implement custom commands in arbitrary containers. It becomes easy to write convenient ad-hoc commands that users will then be able to run either on Kubernetes or locally using a documented CLI. Pluggable jobs are declared as Click commands and are responsible for parsing their own arguments. See the new CLI_DO_COMMANDS filter. Close openedx-unsupported/wg-developer-experience#75
- Loading branch information
Showing
18 changed files
with
268 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,74 @@ | ||
import re | ||
import unittest | ||
from io import StringIO | ||
from unittest.mock import patch | ||
|
||
from tests.helpers import TestContext, temporary_root | ||
from tutor import config as tutor_config | ||
from tests.helpers import PluginsTestCase, temporary_root | ||
from tutor.commands import jobs | ||
|
||
from .base import TestCommandMixin | ||
|
||
class JobsTests(unittest.TestCase): | ||
@patch("sys.stdout", new_callable=StringIO) | ||
def test_initialise(self, mock_stdout: StringIO) -> None: | ||
|
||
class JobsTests(PluginsTestCase, TestCommandMixin): | ||
def test_initialise(self) -> 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.")) | ||
self.invoke_in_root(root, ["config", "save"]) | ||
result = self.invoke_in_root(root, ["local", "do", "init"]) | ||
self.assertIsNone(result.exception) | ||
self.assertEqual(0, result.exit_code) | ||
self.assertIn("All services initialised.", result.output) | ||
|
||
def test_create_user_command_without_staff(self) -> None: | ||
command = jobs.create_user_template("superuser", False, "username", "email", "p4ssw0rd") | ||
def test_create_user_template_without_staff(self) -> None: | ||
command = jobs.create_user_template( | ||
"superuser", False, "username", "email", "p4ssw0rd" | ||
) | ||
self.assertNotIn("--staff", command) | ||
self.assertIn("set_password", command) | ||
|
||
def test_create_user_command_with_staff(self) -> None: | ||
command = jobs.create_user_template("superuser", True, "username", "email", "p4ssw0rd") | ||
def test_create_user_template_with_staff(self) -> None: | ||
command = jobs.create_user_template( | ||
"superuser", True, "username", "email", "p4ssw0rd" | ||
) | ||
self.assertIn("--staff", command) | ||
|
||
@patch("sys.stdout", new_callable=StringIO) | ||
def test_import_demo_course(self, mock_stdout: StringIO) -> None: | ||
def test_import_demo_course(self) -> None: | ||
with temporary_root() as root: | ||
context = TestContext(root) | ||
config = tutor_config.load_full(root) | ||
runner = context.job_runner(config) | ||
runner.run_job_from_str("cms", jobs.import_demo_course_template()) | ||
|
||
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), "cms") | ||
self.assertTrue( | ||
commands.group(2) | ||
.strip() | ||
.startswith('echo "Loading settings $DJANGO_SETTINGS_MODULE"') | ||
) | ||
self.invoke_in_root(root, ["config", "save"]) | ||
with patch("tutor.utils.docker_compose") as mock_docker_compose: | ||
result = self.invoke_in_root(root, ["local", "do", "importdemocourse"]) | ||
dc_args, _dc_kwargs = mock_docker_compose.call_args | ||
self.assertIsNone(result.exception) | ||
self.assertEqual(0, result.exit_code) | ||
self.assertIn("cms-job", dc_args) | ||
self.assertTrue( | ||
dc_args[-1] | ||
.strip() | ||
.startswith('echo "Loading settings $DJANGO_SETTINGS_MODULE"') | ||
) | ||
|
||
@patch("sys.stdout", new_callable=StringIO) | ||
def test_set_theme(self, mock_stdout: StringIO) -> None: | ||
def test_set_theme(self) -> None: | ||
with temporary_root() as root: | ||
context = TestContext(root) | ||
config = tutor_config.load_full(root) | ||
runner = context.job_runner(config) | ||
command = jobs.set_theme_template("sample_theme", ["domain1", "domain2"]) | ||
runner.run_job_from_str("lms", command) | ||
self.invoke_in_root(root, ["config", "save"]) | ||
with patch("tutor.utils.docker_compose") as mock_docker_compose: | ||
result = self.invoke_in_root( | ||
root, | ||
[ | ||
"local", | ||
"do", | ||
"settheme", | ||
"--domain", | ||
"domain1", | ||
"--domain", | ||
"domain2", | ||
"beautiful", | ||
], | ||
) | ||
dc_args, _dc_kwargs = mock_docker_compose.call_args | ||
|
||
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.assertIsNone(result.exception) | ||
self.assertEqual(0, result.exit_code) | ||
self.assertIn("lms-job", dc_args) | ||
self.assertTrue( | ||
commands.group(2) | ||
dc_args[-1] | ||
.strip() | ||
.startswith('echo "Loading settings $DJANGO_SETTINGS_MODULE"') | ||
) | ||
self.assertIn("assign_theme('beautiful', 'domain1')", dc_args[-1]) | ||
self.assertIn("assign_theme('beautiful', 'domain2')", dc_args[-1]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.