|
3 | 3 |
|
4 | 4 | import re
|
5 | 5 | from pathlib import PurePosixPath
|
6 |
| -from typing import cast |
| 6 | +from typing import List, Pattern, cast |
7 | 7 |
|
8 | 8 | from assertpy.assertpy import assert_that
|
9 | 9 |
|
@@ -59,6 +59,148 @@ class AzureImageStandard(TestSuite):
|
59 | 59 | r"rhui-(?P<name>\S+)\s+(?P<source>\S+)\s+(enabled|disabled)"
|
60 | 60 | )
|
61 | 61 |
|
| 62 | + # pattern to get failure, error, warnings from dmesg, syslog/messages |
| 63 | + _error_fail_warnings_pattern: List[Pattern[str]] = [ |
| 64 | + re.compile(r"^(.*fail.*)$", re.MULTILINE), |
| 65 | + re.compile(r"^(.*error.*)$", re.MULTILINE), |
| 66 | + re.compile(r"^(.*warning.*)$", re.MULTILINE), |
| 67 | + ] |
| 68 | + |
| 69 | + # ignorable failure, error, warnings pattern which got confirmed |
| 70 | + _error_fail_warnings_ignorable_str_list: List[Pattern[str]] = [ |
| 71 | + re.compile(r"^(.*Perf event create on CPU 0 failed with -2.*)$", re.M), |
| 72 | + re.compile(r"^(.*Fast TSC calibration.*)$", re.M), |
| 73 | + re.compile(r"^(.*acpi PNP0A03:00.*)$", re.M), |
| 74 | + re.compile(r"^(.*systemd-journald-audit.socket.*)$", re.M), |
| 75 | + re.compile( |
| 76 | + r"^(.*Failed to set file attributes: Inappropriate ioctl for device.*)$", |
| 77 | + re.M, |
| 78 | + ), |
| 79 | + re.compile( |
| 80 | + r"^(.*Failed to create new system journal: No such file or directory.*)$", |
| 81 | + re.M, |
| 82 | + ), |
| 83 | + re.compile(r"^(.*failed to get extended button data.*)$", re.M), |
| 84 | + re.compile(r"^(.*ipmi_si.*)$", re.M), |
| 85 | + re.compile(r"^(.*pci_root PNP0A03:00.*)$", re.M), |
| 86 | + re.compile(r"^(.*disabling PCIe ASPM.*)$", re.M), |
| 87 | + re.compile(r"^(.*systemd-journald.*)$", re.M), |
| 88 | + re.compile(r"^(.*Cannot add dependency job.*)$", re.M), |
| 89 | + re.compile(r"^(.*failsafe.*)$", re.M), |
| 90 | + re.compile(r"^(.*startpar-bridge.*)$", re.M), |
| 91 | + re.compile(r"^(.*Failed to spawn.*)$", re.M), |
| 92 | + re.compile(r"^(.*display-manager.service.*)$", re.M), |
| 93 | + re.compile(r"^(.*ACPI PCC probe failed.*)$", re.M), |
| 94 | + re.compile(r"^(.*Failed to access perfctr msr.*)$", re.M), |
| 95 | + re.compile(r"^(.*Failed to init entropy source hwrng.*)$", re.M), |
| 96 | + re.compile(r"^(.*augenrules.*: failure 1.*)$", re.M), |
| 97 | + re.compile( |
| 98 | + r"^(.*microcode_ctl: kernel version .* failed early load check for .*, skipping.*)$", # noqa: E501 |
| 99 | + re.M, |
| 100 | + ), |
| 101 | + re.compile( |
| 102 | + r"^(.*rngd: Failed to init entropy source 0: Hardware RNG Device.*)$", re.M |
| 103 | + ), |
| 104 | + re.compile( |
| 105 | + r"^(.*open /dev/vmbus/hv_fcopy failed; error: 2 No such file or directory.*)$", # noqa: E501 |
| 106 | + re.M, |
| 107 | + ), |
| 108 | + re.compile( |
| 109 | + r"^(.*open /dev/vmbus/hv_vss failed; error: 2 No such file or directory.*)$", # noqa: E501 |
| 110 | + re.M, |
| 111 | + ), |
| 112 | + re.compile( |
| 113 | + r"^(.*hv-vss-daemon.service: Main process exited, code=exited, status=1/FAILURE.*)$", # noqa: E501 |
| 114 | + re.M, |
| 115 | + ), |
| 116 | + re.compile( |
| 117 | + r"^(.*hv-vss-daemon.service: Failed with result 'exit-code'.*)$", re.M |
| 118 | + ), |
| 119 | + re.compile( |
| 120 | + r"^(.*hv-fcopy-daemon.service: Main process exited, code=exited, status=1/FAILURE.*)$", # noqa: E501 |
| 121 | + re.M, |
| 122 | + ), |
| 123 | + re.compile( |
| 124 | + r"^(.*hv-fcopy-daemon.service: Failed with result 'exit-code'.*)$", re.M |
| 125 | + ), |
| 126 | + re.compile(r"^(.*dnf.*: Failed determining last makecache time.*)$", re.M), |
| 127 | + re.compile( |
| 128 | + r"^(.*dbus-daemon.*: .system. Activation via systemd failed for unit 'dbus-org.freedesktop.resolve1.service': Unit dbus-org.freedesktop.resolve1.service not found.*)$", # noqa: E501 |
| 129 | + re.M, |
| 130 | + ), |
| 131 | + re.compile(r"^(.*TLS record write failed.*)$", re.M), |
| 132 | + re.compile(r"^(.*state ensure error.*)$", re.M), |
| 133 | + re.compile(r"^(.*got unexpected HTTP status code.*)$", re.M), |
| 134 | + re.compile( |
| 135 | + r'^(.*Error getting hardware address for "eth0": No such device.*)$', re.M |
| 136 | + ), |
| 137 | + re.compile(r"^(.*codec can't encode character.*)$", re.M), |
| 138 | + re.compile( |
| 139 | + r"^(.*Failed to set certificate key file \\[gnutls error -64: Error while reading file.\\].*)$", # noqa: E501 |
| 140 | + re.M, |
| 141 | + ), |
| 142 | + re.compile( |
| 143 | + r"^(.*audispd: Error - /etc/audisp/plugins.d/wdgsmart-syslog.conf isn't owned by root.*)$", # noqa: E501 |
| 144 | + re.M, |
| 145 | + ), |
| 146 | + re.compile( |
| 147 | + r"^(.*Condition check resulted in Process error reports when automatic reporting is enabled.*)$", # noqa: E501 |
| 148 | + re.M, |
| 149 | + ), |
| 150 | + re.compile( |
| 151 | + r"^(.*error trying to compare the snap system key: system-key missing on disk.*)$", # noqa: E501 |
| 152 | + re.M, |
| 153 | + ), |
| 154 | + re.compile( |
| 155 | + r"^(.*open /dev/vmbus/hv_fcopy failed; error: 2 No such file or directory.*)$", # noqa: E501 |
| 156 | + re.M, |
| 157 | + ), |
| 158 | + re.compile( |
| 159 | + r"^(.*open /dev/vmbus/hv_vss failed; error: 2 No such file or directory.*)$", # noqa: E501 |
| 160 | + re.M, |
| 161 | + ), |
| 162 | + re.compile(r"^(.*mitigating potential DNS violation DVE-2018-0001.*)$", re.M), |
| 163 | + re.compile(r"^(.*end_request: I/O error, dev fd0, sector 0.*)$", re.M), |
| 164 | + re.compile(r"^(.*blk_update_request: I/O error, dev fd0, sector 0.*)$", re.M), |
| 165 | + re.compile(r"^(.*floppy: error -5 while reading block 0.*)$", re.M), |
| 166 | + re.compile(r"^(.*Broken pipe.*)$", re.M), |
| 167 | + re.compile(r"^(.*errors=remount-ro.*)$", re.M), |
| 168 | + re.compile( |
| 169 | + r"^(.*smartd.*: Device: /dev/.*, Bad IEC \\(SMART\\) mode page, err=5, skip device.*)$", # noqa: E501 |
| 170 | + re.M, |
| 171 | + ), |
| 172 | + re.compile(r"^(.*GPT: Use GNU Parted to correct GPT errors.*)$", re.M), |
| 173 | + re.compile(r"^(.*RAS: Correctable Errors collector initialized.*)$", re.M), |
| 174 | + re.compile(r"^(.*BERT: Boot Error Record Table support is disabled.*)$", re.M), |
| 175 | + re.compile(r"^( Enable it by using bert_enable as kernel parameter.*)$", re.M), |
| 176 | + re.compile( |
| 177 | + r"^(.*WARNING Daemon VM is provisioned, but the VM unique identifie has changed -- clearing cached state.*)$", # noqa: E501 |
| 178 | + re.M, |
| 179 | + ), |
| 180 | + re.compile(r"^(.*WARNING! Cached DHCP leases will be deleted.*)$", re.M), |
| 181 | + re.compile( |
| 182 | + r"^(.*Unconfined exec qualifier \\(ux\\) allows some dangerous environment variables.*)$", # noqa: E501 |
| 183 | + re.M, |
| 184 | + ), |
| 185 | + re.compile(r"^(.*Stopped Write warning to Azure ephemeral disk.*)$", re.M), |
| 186 | + re.compile(r"^(.*reloading interface list.*)$", re.M), |
| 187 | + re.compile(r"^(.*Server preferred version:.*)$", re.M), |
| 188 | + re.compile(r"^(.*WARNING Hostname record does not exist,.*)$", re.M), |
| 189 | + re.compile(r"^(.*Dhcp client is not running.*)$", re.M), |
| 190 | + re.compile(r"^(.*Starting Write warning to Azure ephemeral disk.*)$", re.M), |
| 191 | + re.compile(r"^(.*Added ephemeral disk warning to.*)$", re.M), |
| 192 | + re.compile(r"^(.*Proceeding WITHOUT firewalling in effect!.*)$", re.M), |
| 193 | + re.compile(r"^(.*urandom warning\\(s\\) missed due to ratelimiting.*)$", re.M), |
| 194 | + re.compile( |
| 195 | + r"^(.*kdumpctl.*: Warning: There might not be enough space to save a vmcore.*)$", # noqa: E501 |
| 196 | + re.M, |
| 197 | + ), |
| 198 | + re.compile( |
| 199 | + r"^(.*WARNING ExtHandler ExtHandler cgroups v2 mounted at.*)$", re.M |
| 200 | + ), |
| 201 | + re.compile(r"^(.*dataloss warning file.*)$", re.M), |
| 202 | + ] |
| 203 | + |
62 | 204 | @TestCaseMetadata(
|
63 | 205 | description="""
|
64 | 206 | This test will verify that `Defaults targetpw` is not enabled in the
|
@@ -590,3 +732,52 @@ def verify_bash_history_is_empty(self, node: Node) -> None:
|
590 | 732 | assert_that(bash_history).described_as(
|
591 | 733 | "/root/.bash_history is not empty, this image is not prepared well."
|
592 | 734 | ).is_empty()
|
| 735 | + |
| 736 | + @TestCaseMetadata( |
| 737 | + description=""" |
| 738 | + This test will check error, failure, warning messages from demsg, |
| 739 | + /var/log/syslog or /var/log/messages file. |
| 740 | +
|
| 741 | + Steps: |
| 742 | + 1. Get failure, error, warning messages from dmesg, /var/log/syslog or |
| 743 | + /var/log/messages file. |
| 744 | + 2. If any unexpected failure, error, warning messages excluding ignorable ones |
| 745 | + existing, fail the case. |
| 746 | + """, |
| 747 | + priority=1, |
| 748 | + ) |
| 749 | + def verify_boot_error_fail_warnings(self, node: Node) -> None: |
| 750 | + dmesg = node.tools[Dmesg] |
| 751 | + cat = node.tools[Cat] |
| 752 | + log_output = dmesg.get_output(force_run=True) |
| 753 | + if node.shell.exists(node.get_pure_path("/var/log/syslog")): |
| 754 | + log_output += cat.read("/var/log/syslog", force_run=True, sudo=True) |
| 755 | + if node.shell.exists(node.get_pure_path("/var/log/messages")): |
| 756 | + log_output += cat.read("/var/log/messages", force_run=True, sudo=True) |
| 757 | + |
| 758 | + ignored_candidates = list( |
| 759 | + ( |
| 760 | + set( |
| 761 | + [ |
| 762 | + x |
| 763 | + for sublist in find_patterns_in_lines( |
| 764 | + log_output, self._error_fail_warnings_ignorable_str_list |
| 765 | + ) |
| 766 | + for x in sublist |
| 767 | + if x |
| 768 | + ] |
| 769 | + ) |
| 770 | + ) |
| 771 | + ) |
| 772 | + found_results = [ |
| 773 | + x |
| 774 | + for sublist in find_patterns_in_lines( |
| 775 | + log_output, self._error_fail_warnings_pattern |
| 776 | + ) |
| 777 | + for x in sublist |
| 778 | + if x and x not in ignored_candidates |
| 779 | + ] |
| 780 | + assert_that(found_results).described_as( |
| 781 | + "unexpected error/failure/warnings shown up in bootup log of distro" |
| 782 | + f" {node.os.name} {node.os.information.version}" |
| 783 | + ).is_empty() |
0 commit comments