def test_scaffold_image(): """Image scaffold tests.""" with using_temporary_directory() as tempdir: # Copy playground project_path = copy_sample("sample01", tempdir) # Scaffold new image scaffold_image(project_path, "postgres", "postgres") assert image_check_dockerfile(project_path, "postgres") content = image_load_in_memory(project_path, "postgres") assert content == "FROM postgres:latest\n" # Overwrite with mock_input("y"): scaffold_image(project_path, "postgres", "postgres") with mock_input("n"): scaffold_image(project_path, "postgres", "postgres") # Scaffold image version scaffold_image(project_path, "pouet", "ici/pouet", "2.1.1") assert image_check_dockerfile(project_path, "pouet") content = image_load_in_memory(project_path, "pouet") assert content == "FROM ici/pouet:2.1.1\n" # Scaffold in empty folder empty_folder = os.path.join(tempdir, "toto") os.makedirs(empty_folder) scaffold_image(empty_folder, "pouet", "ici/pouet")
def test_commands(): """Commands.""" shell = Shell() with using_temporary_directory() as tempdir: project_path = copy_sample("sample02", tempdir) def run_shell(args=None): args = args or [] shell.run(["--project", project_path, "--dry-run"] + args) with pytest.raises(SystemExit): run_shell(["custom"]) with pytest.raises(SystemExit): run_shell(["custom", "notebook"]) run_shell([ "config", "create", "toto", "-e", "default", "-S", "ipython", "pouet", "-N", "net", ]) run_shell(["custom", "notebook", "password"])
def test_template(): """Template test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project_config_root = os.path.join(project_path, ".docknv") session_file_path = os.path.join(project_config_root, ".docknv.yml") os.makedirs(project_config_root) with io_open(session_file_path, mode="w") as handle: handle.write(CONFIG_DATA) project = Project.load_from_path(project_path) config = project.database.get_configuration("config") # Missing template file with pytest.raises(MissingTemplate): renderer_render_template("toto.sh", config) # Creating file templates_path = os.path.join(project_path, "data", "files") with io_open(os.path.join(templates_path, "toto.sh"), mode="w") as handle: handle.write("...") # Malformed template file with pytest.raises(MalformedTemplate): renderer_render_template("toto.sh", config)
def test_scaffold_environment(): """Environment scaffold tests.""" with using_temporary_directory() as tempdir: # Copy playground project_path = copy_sample("sample01", tempdir) # Scaffold new environment scaffold_environment(project_path, "toto") assert os.path.isfile(env_get_yaml_path(project_path, "toto")) content = Environment.load_from_project(project_path, "toto") assert len(content) == 0 # Scaffold new environment with values scaffold_environment(project_path, "tata", {"POUET": 6}) assert os.path.isfile(env_get_yaml_path(project_path, "tata")) content = Environment.load_from_project(project_path, "tata") assert len(content) == 1 assert content["POUET"] == 6 # Scaffold existing environment with mock_input("n"): scaffold_environment(project_path, "tata", {"POUET": 6}) with mock_input("n"): scaffold_environment(project_path, "tata", {"POUET": 6}) # Copy existing environment scaffold_environment_copy(project_path, "tata", "tutu") assert os.path.isfile(env_get_yaml_path(project_path, "tutu")) content = Environment.load_from_project(project_path, "tutu") assert len(content) == 1 assert content["POUET"] == 6
def test_collection(): """Collection test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) # Load collection = EnvironmentCollection.load_from_project(project_path) assert len(collection) == 8 # Show collection.show_environments() # Error get with pytest.raises(MissingEnvironment): collection.get_environment("toto") with pytest.raises(MissingEnvironment): collection.get_environment_path("toto") # Inheritance default_env = collection.get_environment("default") env = collection.create_inherited_environment("default", "default2") assert os.path.isfile( os.path.join(project_path, "envs", "default2.env.yml")) assert len(collection) == 9 assert env.name == "default2" assert len(env) == len(default_env) # Inheritance errors with pytest.raises(MissingEnvironment): collection.create_inherited_environment("pouet", "pouet2") with pytest.raises(ExistingEnvironment): collection.create_inherited_environment("default", "default") with pytest.raises(ExistingEnvironment): collection.create_inherited_environment("inclusion", "default")
def test_lifecycle(): """Lifecycle test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project_config_root = os.path.join(project_path, ".docknv") session_file_path = os.path.join(project_config_root, ".docknv.yml") os.makedirs(project_config_root) with io_open(session_file_path, mode="w") as handle: handle.write(CONFIG_DATA) project = Project.load_from_path(project_path) lifecycle = project.lifecycle # Should raise, no active configuration with pytest.raises(MissingActiveConfiguration): lifecycle.config.start(dry_run=True) # Active tests project.set_current_configuration("config") lifecycle.config.start(dry_run=True) lifecycle.config.stop(dry_run=True) lifecycle.config.restart(dry_run=True) lifecycle.config.restart(force=True, dry_run=True) # Manual tests lifecycle.config.start(["config", "config2"], dry_run=True) # Service tests lifecycle.service.start("portainer", dry_run=True) lifecycle.service.stop("portainer", dry_run=True) lifecycle.service.restart("portainer", dry_run=True) lifecycle.service.restart("portainer", force=True, dry_run=True) lifecycle.service.execute("portainer", ["toto"], dry_run=True) lifecycle.service.execute("portainer", ["toto", "tutu"], dry_run=True) lifecycle.service.shell("portainer", dry_run=True) lifecycle.service.shell("portainer", shell="/bin/sh", dry_run=True) lifecycle.service.logs("portainer", dry_run=True) lifecycle.service.attach("portainer", dry_run=True) lifecycle.service.build("portainer", dry_run=True) # Update config lifecycle.config.update(dry_run=True) lifecycle.config.update("config2", dry_run=True) lifecycle.config.update(restart=True, dry_run=True) lifecycle.config.build(dry_run=True) lifecycle.config.update(environment="default", dry_run=True) lifecycle.config.update(services=[], dry_run=True) lifecycle.config.update(volumes=[], dry_run=True) lifecycle.config.update(networks=[], dry_run=True) lifecycle.config.update(namespace="", dry_run=True) lifecycle.config.update(namespace="hello", dry_run=True) # Create config lifecycle.config.create(name="tutu", services=["portainer"]) lifecycle.config.ps(dry_run=True)
def test_empty_database(): """Empty db test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project = Project.load_from_path(project_path) database = project.database assert len(database) == 0 database.show_configuration_list() database.save()
def test_scaffold_config(): """Config scaffold tests.""" with using_temporary_directory() as tempdir: # Copy playground project_path = copy_sample("sample01", tempdir) # Scaffold config scaffold_config(project_path) configfile = os.path.join(project_path, "config.yml") with io_open(configfile, mode="rt") as handle: content = handle.read() assert content == CONFIG_FILE_CONTENT
def test_project2(): """Test project2.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample02", tempdir) proj = Project.load_from_path(project_path) # Command config assert proj.get_command_parameters() == { "notebook": { "service": "ipython" } } assert proj.get_command_parameters("notebook") == { "service": "ipython" } assert proj.get_command_parameters("tutu") == {}
def test_environment(): """Environment test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) # Simple envdefault = Environment.load_from_project(project_path, "default") assert "PORTAINER_OUTPUT_PORT" in envdefault assert envdefault["PORTAINER_OUTPUT_PORT"] == 9000 assert envdefault["TEST_VALUE"] == "default" assert len(envdefault) == 11 # Error with pytest.raises(MissingEnvironment): Environment.load_from_project(project_path, "toto") # Import env = Environment.load_from_project(project_path, "inclusion") assert env["TEST_VALUE"] == "inclusion" assert env["TEST_ONE"] == 1 assert env["TEST_ONE_2"] == "toto:1" # Neg values assert env["TEST_NEG_ONE"] == 0 assert env["TEST_NEG_BOOL1"] is False assert env["TEST_NEG_BOOL2"] is True assert env["TEST_NEG_ONE_2"] == env["TEST_ONE_2"] # Inheritance env = Environment.load_from_project(project_path, "inclusion2") assert env["TEST_VALUE"] == "inclusion2" assert env["TEST_ONE"] == 2 assert env["TEST_ONE_2"] == "toto:2" # Loop test env = Environment.load_from_project(project_path, "inclusion-loop") assert env["POUET"] == "loop" # Multiple loop test env = Environment.load_from_project(project_path, "inclusion-loop-mul") assert env["POUET"] == "pouet" # Show env.show() # Key-value export envdefault.export_as_key_values()
def test_old_database(): """Test old database.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample03", tempdir) # Values key should be present db_file = os.path.join(project_path, ".docknv", ".docknv.yml") with io_open(db_file) as handle: data = yaml_ordered_load(handle.read()) assert "values" in data project = Project.load_from_path(project_path) assert len(project.database) == 2 with io_open(db_file) as handle: data = yaml_ordered_load(handle.read()) assert "values" not in data
def test_collection_error(): """Collection test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) # Remove envs shutil.rmtree(os.path.join(project_path, "envs")) # Load with pytest.raises(MalformedProject): EnvironmentCollection.load_from_project(project_path) # Create envs os.makedirs(os.path.join(project_path, "envs")) collection = EnvironmentCollection.load_from_project(project_path) # Show collection.show_environments()
def test_project(): """Test project.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) # Path validation assert Project.validate_path(project_path) assert not Project.validate_path(os.path.join(project_path, "toto")) # Project load proj = Project.load_from_path(project_path) repr(proj) assert len(proj.schemas) == 2 # Ensure current config with pytest.raises(MissingActiveConfiguration): proj.ensure_current_configuration() # Project load error with pytest.raises(MissingProject): Project.load_from_path(os.path.join(project_path, "toto")) # Get current config assert proj.get_current_configuration() is None # Create config proj.lifecycle.config.create("toto") # Set current config proj.set_current_configuration("toto") assert proj.get_current_configuration() == "toto" # Unset proj.unset_current_configuration() assert proj.get_current_configuration() is None # Temporary set with proj.using_temporary_configuration("toto"): assert proj.get_current_configuration() == "toto" assert proj.get_current_configuration() is None # Command config assert proj.get_command_parameters() == {}
def test_scaffold_ignore(): """Ignorefile scaffold tests.""" with using_temporary_directory() as tempdir: # Copy playground project_path = copy_sample("sample01", tempdir) # Scaffold ignore scaffold_ignore(project_path) ignorefile = os.path.join(project_path, ".gitignore") with io_open(ignorefile, mode="rt") as handle: content = handle.read() assert content == IGNORE_FILE_CONTENT with mock_input("y"): scaffold_ignore(project_path) with mock_input("n"): scaffold_ignore(project_path) with pytest.raises(MissingProject): scaffold_ignore("/a/b/c/d")
def test_compose(): """Compose test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project_config_root = os.path.join(project_path, ".docknv") session_file_path = os.path.join(project_config_root, ".docknv.yml") os.makedirs(project_config_root) with io_open(session_file_path, mode="w") as handle: handle.write(CONFIG_DATA) project = Project.load_from_path(project_path) database = project.database compose = ComposeDefinition.load_from_project(project_path) assert len(compose.get_networks()) == 1 assert len(compose.get_volumes()) == 1 assert len(compose.get_services()) == 3 test_path = os.path.join(project_path, "test.yml") compose.save_to_path(test_path) composeclone = ComposeDefinition.load_from_path(test_path) with pytest.raises(MissingComposefile): ComposeDefinition.load_from_path( os.path.join(project_path, "test2.yml")) assert compose.content == composeclone.content # Filter configuration conf = database.get_configuration("config") compose.apply_configuration(conf) assert len(compose.get_services()) == 2 # Namespace conf2 = database.get_configuration("config2") compose = ComposeDefinition.load_from_project(project_path) compose.apply_configuration(conf2) assert len(compose.get_services()) == 2
def test_database(): """Database test.""" database_file = """\ first: services: - ser1 - ser2 networks: - net1 volumes: - vol1 environment: default user: test namespace: second: services: - ser3 networks: [] volumes: [] environment: default user: tost namespace: hello\ """ with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) # Create directory os.makedirs(os.path.join(project_path, ".docknv")) with open(os.path.join(project_path, ".docknv", ".docknv.yml"), mode="w") as handle: handle.write(database_file) project = Project.load_from_path(project_path) database = project.database assert len(database) == 2 first = database.get_configuration("first") os.makedirs(first.get_path()) assert os.path.exists(first.get_path()) config = Configuration( database, "toto", user="******", environment="default", services=["toto"], volumes=[], networks=[], namespace=None, ) database.create_configuration(config) assert len(database) == 3 assert database["first"].has_permission() assert not database["second"].has_permission() assert database["toto"].has_permission() assert database.includes_configuration("first") assert not database.includes_configuration("pouet") first = database.get_configuration("first") first.environment = "inclusion" database.update_configuration(first) # Unknown name should fail first.name = "test1" with pytest.raises(MissingConfiguration): database.update_configuration(first) first.name = "first" # Second edit should fail second = database.get_configuration("second") second.environment = "inclusion" with pytest.raises(PermissionDenied): database.update_configuration(second) # Pouet does not exist with pytest.raises(MissingConfiguration): database.get_configuration("pouet") # Serialization test database.serialize() # Show test database.show_configuration_list() # Save test database.save() assert os.path.exists(first.get_composefile_path()) assert os.path.exists(first.get_environment_path()) # Paths test assert first.get_path() == os.path.join(project_path, ".docknv", "test", "first") assert second.get_path() == os.path.join(project_path, ".docknv", "tost", "second") assert first.get_environment_path() == os.path.join( project_path, ".docknv", "test", "first", "environment.env") assert second.get_environment_path() == os.path.join( project_path, ".docknv", "tost", "second", "environment.env") assert first.get_composefile_path() == os.path.join( project_path, ".docknv", "test", "first", "docker-compose.yml") assert second.get_composefile_path() == os.path.join( project_path, ".docknv", "tost", "second", "docker-compose.yml") # Removal test project.session.set_current_configuration("first") database.remove_configuration("first", force=True) assert project.session.get_current_configuration() is None assert len(database) == 2 with pytest.raises(MissingConfiguration): database.remove_configuration("pouet", force=True) with pytest.raises(PermissionDenied): database.remove_configuration("second", force=True) assert len(database) == 2
def test_shell(): """Shell test.""" shell = Shell() with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) def run_shell(args=None): args = args or [] shell.run(["--project", project_path, "--dry-run"] + args) with pytest.raises(SystemExit): run_shell([]) # Config create run_shell([ "config", "create", "toto", "-e", "default", "-S", "portainer", "pouet", "-V", "portainer", "-N", "net", ]) # Start config run_shell(["config", "start"]) # Stop config run_shell(["config", "stop"]) # Restart config run_shell(["config", "restart"]) run_shell(["config", "restart", "-f"]) # Set config run_shell(["config", "set", "toto"]) # Unset config run_shell(["config", "unset"]) with mock_input("y"): # Remove config run_shell(["config", "rm", "toto"]) # Status run_shell(["config", "status"]) # Toto run_shell([ "config", "create", "toto", "-e", "default", "-S", "portainer", "pouet", "-V", "portainer", "-N", "net", ]) run_shell(["config", "status"]) run_shell(["config", "update"]) run_shell(["config", "ls"]) run_shell(["config", "build"]) run_shell(["config", "ps"]) ######## # Service run_shell(["service", "build", "portainer"]) run_shell(["service", "start", "portainer"]) run_shell(["service", "stop", "portainer"]) run_shell(["service", "restart", "portainer"]) run_shell(["service", "restart", "portainer", "-f"]) run_shell(["service", "run", "portainer", "bash"]) run_shell(["service", "run", "portainer", "-d", "bash"]) run_shell(["service", "exec", "portainer", "bash"]) run_shell(["service", "shell", "portainer"]) run_shell(["service", "logs", "portainer"]) run_shell(["service", "push", "portainer", "./a", "/b"]) run_shell(["service", "pull", "portainer", "/a", "./b"]) ####### # Env run_shell(["env", "ls"]) run_shell(["env", "show", "default"]) try: run_shell(["env", "edit", "default"]) run_shell(["env", "edit", "default", "-e", "vim"]) except NoEditorFound: pass ######### # Schemas run_shell(["schema", "ls"]) ######## # Scaffold run_shell(["scaffold", "project", f"{project_path}/toto"]) run_shell(["scaffold", "image", "apzt", "otapti"]) run_shell(["scaffold", "env", "tototo"]) run_shell(["scaffold", "env", "totototo", "-i", "tototo"]) ###### # User try: run_shell(["user", "edit"]) run_shell(["user", "edit", "-e", "vim"]) run_shell(["user", "edit", "toto"]) except NoEditorFound: pass run_shell(["user", "rm-lock"]) with mock_input("y"): run_shell(["user", "clean", "toto"]) run_shell(["user", "clean"]) ######## # Custom with pytest.raises(SystemExit): run_shell(["custom"]) ######## # Machine with pytest.raises(SystemExit): run_shell(["machine"]) with pytest.raises(SystemExit): run_shell(["machine", "restart", "portainer"])