def test_source_date_epoch(self): """Test getting and setting SOURCE_DATE_EPOCH.""" config = Config() self.assertIsNone(config.source_date_epoch) with unittest.mock.patch("time.time", return_value=1581694618.0388665): config.set_source_date_epoch() self.assertEqual(config.source_date_epoch, 1581694618)
def test_config_and_arguments(self): """Test Config.add_command_line_arguments() with config file and arguments.""" args = parse_args([ "-c", os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml"), "--name", "Debian-unstable", "--variant", "standard", "--mode", "root", "--aptopt", 'Apt::Install-Recommends "0"', "--keyring", "/usr/share/keyrings", "--dpkgopt", "force-confdef", "--dpkgopt", "force-confold", "--include", "ionit,netconsole", "--components", "main,non-free", "--architectures", "i386", "--mirrors", "http://deb.debian.org/debian", "unstable", "unstable.tar", ]) config = Config() config.add_command_line_arguments(args) self.assertDictEqual( config, { "mmdebstrap": { "aptopts": ['Apt::Install-Recommends "0"'], "architectures": ["i386"], "components": ["main", "non-free"], "dpkgopts": ["force-confdef", "force-confold"], "keyrings": [ "/usr/share/keyrings/debian-archive-keyring.gpg", "/usr/share/keyrings", ], "mirrors": ["http://deb.debian.org/debian"], "mode": "root", "packages": ["ionit", "netconsole"], "suite": "unstable", "target": "unstable.tar", "variant": "standard", }, "name": "Debian-unstable", }, )
def test_env_items(self): """Test environment variables for example unstable.yaml.""" config = Config() config.load(os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml")) config["name"] = "Debian-unstable" self.assertEqual( config.env_items(), [ ("BDEBSTRAP_HOOKS", HOOKS_DIR), ("BDEBSTRAP_NAME", "Debian-unstable"), ("BDEBSTRAP_OUTPUT_DIR", "/tmp/bdebstrap-output"), ], )
def test_hooks(self): """Test Mmdebstrap with custom hooks.""" mmdebstrap = Mmdebstrap( Config( mmdebstrap={ "cleanup-hooks": ['rm -f "$0/etc/udev/rules.d/70-persistent-net.rules"'], "customize-hooks": [ 'chroot "$0" update-alternatives --set editor /usr/bin/vim.basic' ], "essential-hooks": ["copy-in /etc/bash.bashrc /etc"], "hostname": "example", "setup-hooks": [], "suite": "buster", "target": "buster.tar.xz", } ) ) self.assertEqual( mmdebstrap.construct_parameters("/output"), [ "mmdebstrap", '--essential-hook=mkdir -p "$1/tmp/bdebstrap-output"', "--essential-hook=copy-in /etc/bash.bashrc /etc", '--customize-hook=chroot "$0" update-alternatives --set editor /usr/bin/vim.basic', '--customize-hook=rm -f "$0/etc/udev/rules.d/70-persistent-net.rules"', '--customize-hook=echo "example" > "$1/etc/hostname"', "--customize-hook=chroot \"$1\" dpkg-query -f='${Package}\\t${Version}\\n' -W " '> "$1/tmp/bdebstrap-output/manifest"', '--customize-hook=sync-out "/tmp/bdebstrap-output" "/output"', '--customize-hook=rm -rf "$1/tmp/bdebstrap-output"', "buster", "buster.tar.xz", ], )
def test_debian_example(self): """Test Mmdebstrap with Debian unstable config.""" mmdebstrap = Mmdebstrap( Config( mmdebstrap={ "architectures": ["i386"], "install-recommends": True, "keyrings": ["/usr/share/keyrings/debian-archive-keyring.gpg"], "mode": "unshare", "suite": "unstable", "target": "example.tar.xz", "variant": "minbase", } ) ) self.assertEqual( mmdebstrap.construct_parameters("/output"), [ "mmdebstrap", "--variant=minbase", "--mode=unshare", "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg", "--architectures=i386", '--essential-hook=mkdir -p "$1/tmp/bdebstrap-output"', '--aptopt=Apt::Install-Recommends "true"', "--customize-hook=chroot \"$1\" dpkg-query -f='${Package}\\t${Version}\\n' -W " '> "$1/tmp/bdebstrap-output/manifest"', '--customize-hook=sync-out "/tmp/bdebstrap-output" "/output"', '--customize-hook=rm -rf "$1/tmp/bdebstrap-output"', "unstable", "example.tar.xz", ], )
def test_log_level_debug(self): """Test Mmdebstrap with log level debug.""" logging.getLogger(__script_name__).setLevel(logging.DEBUG) mmdebstrap = Mmdebstrap(Config()) self.assertEqual( mmdebstrap.construct_parameters("/output")[0:2], ["mmdebstrap", "--debug"] )
def test_extra_opts(self): """Test Mmdebstrap with extra options.""" mmdebstrap = Mmdebstrap( Config( mmdebstrap={ "aptopts": ['Acquire::http { Proxy "http://proxy:3128/"; }'], "components": ["main", "non-free", "contrib"], "dpkgopts": ["force-confdef", "force-confold"], "packages": ["bash-completions", "vim"], "suite": "unstable", "target": "example.tar.xz", }, ) ) self.assertEqual( mmdebstrap.construct_parameters("/output"), [ "mmdebstrap", '--aptopt=Acquire::http { Proxy "http://proxy:3128/"; }', "--dpkgopt=force-confdef", "--dpkgopt=force-confold", "--include=bash-completions,vim", "--components=main,non-free,contrib", '--essential-hook=mkdir -p "$1/tmp/bdebstrap-output"', "--customize-hook=chroot \"$1\" dpkg-query -f='${Package}\\t${Version}\\n' -W " '> "$1/tmp/bdebstrap-output/manifest"', '--customize-hook=sync-out "/tmp/bdebstrap-output" "/output"', '--customize-hook=rm -rf "$1/tmp/bdebstrap-output"', "unstable", "example.tar.xz", ], )
def test_log_level_warning(self): """Test Mmdebstrap with log level warning.""" logging.getLogger(__script_name__).setLevel(logging.WARNING) mmdebstrap = Mmdebstrap(Config()) self.assertEqual( mmdebstrap.construct_parameters("/output")[0:2], ["mmdebstrap", '--essential-hook=mkdir -p "$1/tmp/bdebstrap-output"'], )
def test_loading(self): """Test loading a YAML configuration file.""" config = Config() config.load(os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml")) self.assertEqual( config, { "mmdebstrap": { "keyrings": ["/usr/share/keyrings/debian-archive-keyring.gpg"], "mode": "unshare", "suite": "unstable", "target": "root.tar.xz", "variant": "minbase", } }, )
def test_clamp_mtime(self, utime_mock, stat_mock): """Test clamping mtime of output files/directories.""" stat_mock.return_value = os.stat_result( (33261, 16535979, 64769, 1, 1000, 1000, 17081, 1581451059, 1581451059, 1581451059) ) config = Config( env={"SOURCE_DATE_EPOCH": 1581433737}, mmdebstrap={"target": "/output/test.tar"} ) mmdebstrap = Mmdebstrap(config) mmdebstrap.clamp_mtime("/output") self.assertEqual(utime_mock.call_count, 3)
def test_wrong_element_type(self): """Test error message for wrong list element type.""" config = Config() config.load(os.path.join(TEST_CONFIG_DIR, "wrong-element-type.yaml")) with self.assertRaisesRegex( ValueError, "'customize-hooks' has type 'CommentedMap'"): config.check()
def test_add_command_line_arguments(self): """Test Config.add_command_line_arguments().""" args = parse_args([ "-c", os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml"), "--name", "Debian-unstable", ]) config = Config() config.add_command_line_arguments(args) self.assertEqual( config, { "mmdebstrap": { "keyrings": ["/usr/share/keyrings/debian-archive-keyring.gpg"], "mode": "unshare", "suite": "unstable", "target": "root.tar.xz", "variant": "minbase", }, "name": "Debian-unstable", }, )
def test_yaml_rendering(self): """Test that config.yaml is formatted correctly.""" config = Config() config_filename = os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml") config.load(config_filename) with tempfile.NamedTemporaryFile() as temp_file: config.save(temp_file.name) with open(temp_file.name, encoding="utf-8") as config_file: output_config = config_file.read() with open(config_filename, encoding="utf-8") as config_file: input_config = config_file.read() self.assertEqual(output_config, input_config)
def test_dry_run(self): """Test Mmdebstrap with dry run set.""" mmdebstrap = Mmdebstrap( Config(mmdebstrap={"suite": "unstable", "target": "example.tar.xz"}) ) self.assertEqual( mmdebstrap.construct_parameters("/output", True), [ "mmdebstrap", "--simulate", '--essential-hook=mkdir -p "$1/tmp/bdebstrap-output"', "--customize-hook=chroot \"$1\" dpkg-query -f='${Package}\\t${Version}\\n' -W " '> "$1/tmp/bdebstrap-output/manifest"', '--customize-hook=sync-out "/tmp/bdebstrap-output" "/output"', '--customize-hook=rm -rf "$1/tmp/bdebstrap-output"', "unstable", "example.tar.xz", ], )
def test_clamp_mtime_permission(self, utime_mock, stat_mock): """Test permission error when clamping mtime of output files/directories.""" stat_mock.return_value = os.stat_result( (33261, 16535979, 64769, 1, 1000, 1000, 17081, 1581451059, 1581451059, 1581451059) ) utime_mock.side_effect = PermissionError(1, "Operation not permitted") config = Config( env={"SOURCE_DATE_EPOCH": 1581433737}, mmdebstrap={"target": "/output/test.tar"} ) mmdebstrap = Mmdebstrap(config) with self.assertLogs("bdebstrap", level="ERROR") as context_manager: mmdebstrap.clamp_mtime("/output") self.assertEqual(utime_mock.call_count, 3) self.assertEqual( [ "ERROR:bdebstrap:Failed to change modification time of '/output/manifest': " "[Errno 1] Operation not permitted", "ERROR:bdebstrap:Failed to change modification time of '/output/test.tar': " "[Errno 1] Operation not permitted", "ERROR:bdebstrap:Failed to change modification time of '/output': " "[Errno 1] Operation not permitted", ], context_manager.output, )
def test_log_level_error(self): """Test Mmdebstrap with log level error.""" logging.getLogger(__script_name__).setLevel(logging.ERROR) mmdebstrap = Mmdebstrap(Config()) self.assertEqual(mmdebstrap.construct_parameters("/output")[0:2], ["mmdebstrap", "-q"])
def test_commented_packages(): """Test commented-packages.yaml file.""" config = Config() config.load(os.path.join(TEST_CONFIG_DIR, "commented-packages.yaml")) config.sanitize_packages() config.check()
def test_check_example(): """Test example unstable.yaml file.""" config = Config() config.load(os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml")) config["name"] = "Debian-unstable" config.check()