1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
# Copyright (C) 2021-2022 Benjamin Drung <bdrung@posteo.de>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""Test main function of bdebstrap."""
import os
import subprocess
import unittest
import unittest.mock
from bdebstrap import OUTPUT_DIR, main
EXAMPLE_CONFIG_DIR = os.path.join(os.path.dirname(__file__), "..", "examples")
def default_hooks(output_dir: str) -> list[str]:
"""Return the list of default hooks."""
return [
f'--essential-hook=mkdir -p "$1{OUTPUT_DIR}"',
"--customize-hook=chroot \"$1\" dpkg-query -f='${Package}\\t${Version}\\n' -W "
f'> "$1{OUTPUT_DIR}/manifest"',
f'--customize-hook=sync-out "{OUTPUT_DIR}" "{output_dir}"',
f'--customize-hook=rm -rf "$1{OUTPUT_DIR}"',
]
class TestMain(unittest.TestCase):
"""
This unittest class tests the main function.
"""
@unittest.mock.patch("bdebstrap.Config.save")
@unittest.mock.patch("bdebstrap.prepare_output_dir")
@unittest.mock.patch("bdebstrap.Mmdebstrap.call")
def test_debian_example(
self,
mmdebstrap_call_mock: unittest.mock.MagicMock,
prepare_output_dir_mock: unittest.mock.MagicMock,
config_save_mock: unittest.mock.MagicMock,
) -> None:
"""Test Debian unstable example."""
args = [
"-c",
os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml"),
"--name",
"Debian-unstable",
]
with self.assertLogs("bdebstrap", level="INFO") as context_manager:
self.assertEqual(main(args), 0)
self.assertIn("Execution time", context_manager.output[-1])
config_save_mock.assert_called_once_with("./Debian-unstable/config.yaml", False)
mmdebstrap_call_mock.assert_called_once_with("./Debian-unstable", False)
prepare_output_dir_mock.assert_called_once_with("./Debian-unstable", False, False)
@unittest.mock.patch("bdebstrap.Config.save")
@unittest.mock.patch("bdebstrap.prepare_output_dir")
@unittest.mock.patch("bdebstrap.Mmdebstrap.call")
def test_failed_mmdebstrap(
self,
mmdebstrap_call_mock: unittest.mock.MagicMock,
prepare_output_dir_mock: unittest.mock.MagicMock,
config_save_mock: unittest.mock.MagicMock,
) -> None:
"""Test failure of mmdebstrap call."""
mmdebstrap_call_mock.side_effect = subprocess.CalledProcessError(42, "mmdebstrap")
args = ["-c", os.path.join(EXAMPLE_CONFIG_DIR, "Debian-unstable.yaml"), "--name", "foobar"]
with self.assertLogs("bdebstrap", level="ERROR") as context_manager:
self.assertEqual(main(args), 1)
self.assertEqual(
["ERROR:bdebstrap:mmdebstrap failed with exit code 42. See above for details."],
context_manager.output,
)
config_save_mock.assert_called_once_with("./foobar/config.yaml", False)
mmdebstrap_call_mock.assert_called_once_with("./foobar", False)
prepare_output_dir_mock.assert_called_once_with("./foobar", False, False)
@unittest.mock.patch("bdebstrap.Config.save")
@unittest.mock.patch("bdebstrap.prepare_output_dir")
@unittest.mock.patch("bdebstrap.Mmdebstrap.call")
def test_empty_target(
self,
mmdebstrap_call_mock: unittest.mock.MagicMock,
prepare_output_dir_mock: unittest.mock.MagicMock,
config_save_mock: unittest.mock.MagicMock,
) -> None:
"""Test keeping target empty."""
with self.assertLogs("bdebstrap", level="INFO"):
self.assertEqual(main(["--name", "empty-target", "unstable"]), 0)
config_save_mock.assert_called_once_with("./empty-target/config.yaml", False)
mmdebstrap_call_mock.assert_called_once_with("./empty-target", False)
prepare_output_dir_mock.assert_called_once_with("./empty-target", False, False)
@unittest.mock.patch("bdebstrap.Config.save")
@unittest.mock.patch("bdebstrap.prepare_output_dir")
@unittest.mock.patch("subprocess.check_call")
def test_minus_target(
self,
check_call_mock: unittest.mock.MagicMock,
prepare_output_dir_mock: unittest.mock.MagicMock,
config_save_mock: unittest.mock.MagicMock,
) -> None:
"""Test --target=-."""
with self.assertLogs("bdebstrap", level="INFO"):
self.assertEqual(main(["--target=-", "--name", "minus-target", "unstable"]), 0)
check_call_mock.assert_called_once_with(
["mmdebstrap", "-v"] + default_hooks("./minus-target") + ["unstable", "-"]
)
config_save_mock.assert_called_once_with("./minus-target/config.yaml", False)
prepare_output_dir_mock.assert_called_once_with("./minus-target", False, False)
|