|
1 | 1 | # This file is part of cloud-init. See LICENSE file for license information. |
2 | 2 |
|
3 | 3 | import os |
| 4 | +import stat |
4 | 5 | from collections import namedtuple |
| 6 | +from unittest import mock |
5 | 7 |
|
6 | 8 | import pytest |
7 | 9 |
|
|
12 | 14 | from cloudinit.sources import DataSource |
13 | 15 | from cloudinit.stages import Init |
14 | 16 | from cloudinit.util import del_file, ensure_dir, sym_link, write_file |
15 | | -from tests.unittests.helpers import mock, wrap_and_call |
| 17 | +from tests.unittests.helpers import wrap_and_call |
16 | 18 |
|
17 | 19 | MyPaths = namedtuple("MyPaths", "cloud_dir") |
18 | 20 | CleanPaths = namedtuple( |
@@ -574,3 +576,34 @@ def test_status_main(self, clean_paths, init_class): |
574 | 576 | assert ( |
575 | 577 | clean_paths.log.exists() is False |
576 | 578 | ), f"Unexpected log {clean_paths.log}" |
| 579 | + |
| 580 | + @pytest.mark.parametrize("device_type", (stat.S_IFCHR, stat.S_IFBLK)) |
| 581 | + @pytest.mark.usefixtures("fake_filesystem") |
| 582 | + def test_remove_artifacts_preserves_device_logs( |
| 583 | + self, device_type, clean_paths, init_class |
| 584 | + ): |
| 585 | + """remove_artifacts does not remove log files that are device files.""" |
| 586 | + original_stat = os.stat |
| 587 | + |
| 588 | + def mock_stat(path): |
| 589 | + if path == clean_paths.log.strpath: |
| 590 | + st_result = mock.Mock() |
| 591 | + st_result.st_mode = device_type | 0o666 |
| 592 | + return st_result |
| 593 | + return original_stat(path) |
| 594 | + |
| 595 | + # Create a regular file and mock its stat |
| 596 | + clean_paths.log.write("device-file") |
| 597 | + clean_paths.output_log.write("cloud-init-output-log") |
| 598 | + with mock.patch("cloudinit.cmd.clean.os.stat", side_effect=mock_stat): |
| 599 | + retcode = clean.remove_artifacts( |
| 600 | + init=init_class, |
| 601 | + remove_logs=True, |
| 602 | + ) |
| 603 | + assert 0 == retcode |
| 604 | + assert ( |
| 605 | + clean_paths.log.exists() is True |
| 606 | + ), f"Device file {clean_paths.log} should not be removed" |
| 607 | + assert ( |
| 608 | + clean_paths.output_log.exists() is False |
| 609 | + ), f"Regular log {clean_paths.output_log} should be removed" |
0 commit comments