summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/runtime_cases/parselogs.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/runtime_cases/parselogs.py')
-rw-r--r--meta/lib/oeqa/runtime_cases/parselogs.py325
1 files changed, 325 insertions, 0 deletions
diff --git a/meta/lib/oeqa/runtime_cases/parselogs.py b/meta/lib/oeqa/runtime_cases/parselogs.py
new file mode 100644
index 0000000000..cc2d0617f5
--- /dev/null
+++ b/meta/lib/oeqa/runtime_cases/parselogs.py
@@ -0,0 +1,325 @@
1import os
2import unittest
3import subprocess
4from oeqa.oetest import oeRuntimeTest
5from oeqa.utils.decorators import *
6
7#in the future these lists could be moved outside of module
8errors = ["error", "cannot", "can\'t", "failed"]
9
10common_errors = [
11 "(WW) warning, (EE) error, (NI) not implemented, (??) unknown.",
12 "dma timeout",
13 "can\'t add hid device:",
14 "usbhid: probe of ",
15 "_OSC failed (AE_ERROR)",
16 "_OSC failed (AE_SUPPORT)",
17 "AE_ALREADY_EXISTS",
18 "ACPI _OSC request failed (AE_SUPPORT)",
19 "can\'t disable ASPM",
20 "Failed to load module \"vesa\"",
21 "Failed to load module vesa",
22 "Failed to load module \"modesetting\"",
23 "Failed to load module modesetting",
24 "Failed to load module \"glx\"",
25 "Failed to load module \"fbdev\"",
26 "Failed to load module fbdev",
27 "Failed to load module glx",
28 "[drm] Cannot find any crtc or sizes - going 1024x768",
29 "_OSC failed (AE_NOT_FOUND); disabling ASPM",
30 "Open ACPI failed (/var/run/acpid.socket) (No such file or directory)",
31 "NX (Execute Disable) protection cannot be enabled: non-PAE kernel!",
32 "hd.: possibly failed opcode",
33 'NETLINK INITIALIZATION FAILED',
34 'kernel: Cannot find map file',
35 'omap_hwmod: debugss: _wait_target_disable failed',
36 'VGA arbiter: cannot open kernel arbiter, no multi-card support',
37 'Failed to find URL:http://ipv4.connman.net/online/status.html',
38 'Online check failed for',
39 'netlink init failed',
40 'Fast TSC calibration',
41 "BAR 0-9",
42 "Failed to load module \"ati\"",
43 "controller can't do DEVSLP, turning off",
44 "stmmac_dvr_probe: warning: cannot get CSR clock",
45 "error: couldn\'t mount because of unsupported optional features",
46 "GPT: Use GNU Parted to correct GPT errors",
47 ]
48
49video_related = [
50 "uvesafb",
51]
52
53x86_common = [
54 '[drm:psb_do_init] *ERROR* Debug is',
55 'wrong ELF class',
56 'Could not enable PowerButton event',
57 'probe of LNXPWRBN:00 failed with error -22',
58 'pmd_set_huge: Cannot satisfy',
59 'failed to setup card detect gpio',
60 'amd_nb: Cannot enumerate AMD northbridges',
61 'failed to retrieve link info, disabling eDP',
62 'Direct firmware load for iwlwifi',
63] + common_errors
64
65qemux86_common = [
66 'wrong ELF class',
67 "fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.",
68 "can't claim BAR ",
69 'amd_nb: Cannot enumerate AMD northbridges',
70 'uvesafb: 5000 ms task timeout, infinitely waiting',
71 'tsc: HPET/PMTIMER calibration failed',
72] + common_errors
73
74ignore_errors = {
75 'default' : common_errors,
76 'qemux86' : [
77 'Failed to access perfctr msr (MSR',
78 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
79 ] + qemux86_common,
80 'qemux86-64' : qemux86_common,
81 'qemumips' : [
82 'Failed to load module "glx"',
83 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
84 ] + common_errors,
85 'qemumips64' : [
86 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
87 ] + common_errors,
88 'qemuppc' : [
89 'PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]',
90 'host side 80-wire cable detection failed, limiting max speed',
91 'mode "640x480" test failed',
92 'Failed to load module "glx"',
93 'can\'t handle BAR above 4GB',
94 'Cannot reserve Legacy IO',
95 ] + common_errors,
96 'qemuarm' : [
97 'mmci-pl18x: probe of fpga:05 failed with error -22',
98 'mmci-pl18x: probe of fpga:0b failed with error -22',
99 'Failed to load module "glx"',
100 'OF: amba_device_add() failed (-19) for /amba/smc@10100000',
101 'OF: amba_device_add() failed (-19) for /amba/mpmc@10110000',
102 'OF: amba_device_add() failed (-19) for /amba/sctl@101e0000',
103 'OF: amba_device_add() failed (-19) for /amba/watchdog@101e1000',
104 'OF: amba_device_add() failed (-19) for /amba/sci@101f0000',
105 'OF: amba_device_add() failed (-19) for /amba/ssp@101f4000',
106 'OF: amba_device_add() failed (-19) for /amba/fpga/sci@a000',
107 'Failed to initialize \'/amba/timer@101e3000\': -22',
108 'jitterentropy: Initialization failed with host not compliant with requirements: 2',
109 ] + common_errors,
110 'qemuarm64' : [
111 'Fatal server error:',
112 '(EE) Server terminated with error (1). Closing log file.',
113 'dmi: Firmware registration failed.',
114 'irq: type mismatch, failed to map hwirq-27 for /intc',
115 ] + common_errors,
116 'emenlow' : [
117 '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
118 '(EE) Failed to load module "psb"',
119 '(EE) Failed to load module psb',
120 '(EE) Failed to load module "psbdrv"',
121 '(EE) Failed to load module psbdrv',
122 '(EE) open /dev/fb0: No such file or directory',
123 '(EE) AIGLX: reverting to software rendering',
124 ] + x86_common,
125 'intel-core2-32' : [
126 'ACPI: No _BQC method, cannot determine initial brightness',
127 '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
128 '(EE) Failed to load module "psb"',
129 '(EE) Failed to load module psb',
130 '(EE) Failed to load module "psbdrv"',
131 '(EE) Failed to load module psbdrv',
132 '(EE) open /dev/fb0: No such file or directory',
133 '(EE) AIGLX: reverting to software rendering',
134 'dmi: Firmware registration failed.',
135 'ioremap error for 0x78',
136 ] + x86_common,
137 'intel-corei7-64' : [
138 'can\'t set Max Payload Size to 256',
139 'intel_punit_ipc: can\'t request region for resource',
140 '[drm] parse error at position 4 in video mode \'efifb\'',
141 'ACPI Error: Could not enable RealTimeClock event',
142 'ACPI Warning: Could not enable fixed event - RealTimeClock',
143 'hci_intel INT33E1:00: Unable to retrieve gpio',
144 'hci_intel: probe of INT33E1:00 failed',
145 'can\'t derive routing for PCI INT A',
146 'failed to read out thermal zone',
147 'Bluetooth: hci0: Setting Intel event mask failed',
148 'ttyS2 - failed to request DMA',
149 ] + x86_common,
150 'crownbay' : x86_common,
151 'genericx86' : x86_common,
152 'genericx86-64' : [
153 'Direct firmware load for i915',
154 'Failed to load firmware i915',
155 'Failed to fetch GuC',
156 'Failed to initialize GuC',
157 'Failed to load DMC firmware',
158 'The driver is built-in, so to load the firmware you need to',
159 ] + x86_common,
160 'edgerouter' : [
161 'Fatal server error:',
162 ] + common_errors,
163 'jasperforest' : [
164 'Activated service \'org.bluez\' failed:',
165 'Unable to find NFC netlink family',
166 ] + common_errors,
167}
168
169log_locations = ["/var/log/","/var/log/dmesg", "/tmp/dmesg_output.log"]
170
171class ParseLogsTest(oeRuntimeTest):
172
173 @classmethod
174 def setUpClass(self):
175 self.errors = errors
176
177 # When systemd is enabled we need to notice errors on
178 # circular dependencies in units.
179 if self.hasFeature("systemd"):
180 self.errors.extend([
181 'Found ordering cycle on',
182 'Breaking ordering cycle by deleting job',
183 'deleted to break ordering cycle',
184 'Ordering cycle found, skipping',
185 ])
186
187 self.ignore_errors = ignore_errors
188 self.log_locations = log_locations
189 self.msg = ""
190 (is_lsb, location) = oeRuntimeTest.tc.target.run("which LSB_Test.sh")
191 if is_lsb == 0:
192 for machine in self.ignore_errors:
193 self.ignore_errors[machine] = self.ignore_errors[machine] + video_related
194
195 def getMachine(self):
196 return oeRuntimeTest.tc.d.getVar("MACHINE")
197
198 def getWorkdir(self):
199 return oeRuntimeTest.tc.d.getVar("WORKDIR")
200
201 #get some information on the CPU of the machine to display at the beginning of the output. This info might be useful in some cases.
202 def getHardwareInfo(self):
203 hwi = ""
204 (status, cpu_name) = self.target.run("cat /proc/cpuinfo | grep \"model name\" | head -n1 | awk 'BEGIN{FS=\":\"}{print $2}'")
205 (status, cpu_physical_cores) = self.target.run("cat /proc/cpuinfo | grep \"cpu cores\" | head -n1 | awk {'print $4'}")
206 (status, cpu_logical_cores) = self.target.run("cat /proc/cpuinfo | grep \"processor\" | wc -l")
207 (status, cpu_arch) = self.target.run("uname -m")
208 hwi += "Machine information: \n"
209 hwi += "*******************************\n"
210 hwi += "Machine name: "+self.getMachine()+"\n"
211 hwi += "CPU: "+str(cpu_name)+"\n"
212 hwi += "Arch: "+str(cpu_arch)+"\n"
213 hwi += "Physical cores: "+str(cpu_physical_cores)+"\n"
214 hwi += "Logical cores: "+str(cpu_logical_cores)+"\n"
215 hwi += "*******************************\n"
216 return hwi
217
218 #go through the log locations provided and if it's a folder create a list with all the .log files in it, if it's a file just add
219 #it to that list
220 def getLogList(self, log_locations):
221 logs = []
222 for location in log_locations:
223 (status, output) = self.target.run("test -f "+str(location))
224 if (status == 0):
225 logs.append(str(location))
226 else:
227 (status, output) = self.target.run("test -d "+str(location))
228 if (status == 0):
229 (status, output) = self.target.run("find "+str(location)+"/*.log -maxdepth 1 -type f")
230 if (status == 0):
231 output = output.splitlines()
232 for logfile in output:
233 logs.append(os.path.join(location,str(logfile)))
234 return logs
235
236 #copy the log files to be parsed locally
237 def transfer_logs(self, log_list):
238 workdir = self.getWorkdir()
239 self.target_logs = workdir + '/' + 'target_logs'
240 target_logs = self.target_logs
241 if not os.path.exists(target_logs):
242 os.makedirs(target_logs)
243 bb.utils.remove(self.target_logs + "/*")
244 for f in log_list:
245 self.target.copy_from(f, target_logs)
246
247 #get the local list of logs
248 def get_local_log_list(self, log_locations):
249 self.transfer_logs(self.getLogList(log_locations))
250 logs = [ os.path.join(self.target_logs, f) for f in os.listdir(self.target_logs) if os.path.isfile(os.path.join(self.target_logs, f)) ]
251 return logs
252
253 #build the grep command to be used with filters and exclusions
254 def build_grepcmd(self, errors, ignore_errors, log):
255 grepcmd = "grep "
256 grepcmd +="-Ei \""
257 for error in errors:
258 grepcmd += error+"|"
259 grepcmd = grepcmd[:-1]
260 grepcmd += "\" "+str(log)+" | grep -Eiv \'"
261 try:
262 errorlist = ignore_errors[self.getMachine()]
263 except KeyError:
264 self.msg += "No ignore list found for this machine, using default\n"
265 errorlist = ignore_errors['default']
266 for ignore_error in errorlist:
267 ignore_error = ignore_error.replace("(", "\(")
268 ignore_error = ignore_error.replace(")", "\)")
269 ignore_error = ignore_error.replace("'", ".")
270 ignore_error = ignore_error.replace("?", "\?")
271 ignore_error = ignore_error.replace("[", "\[")
272 ignore_error = ignore_error.replace("]", "\]")
273 ignore_error = ignore_error.replace("*", "\*")
274 ignore_error = ignore_error.replace("0-9", "[0-9]")
275 grepcmd += ignore_error+"|"
276 grepcmd = grepcmd[:-1]
277 grepcmd += "\'"
278 return grepcmd
279
280 #grep only the errors so that their context could be collected. Default context is 10 lines before and after the error itself
281 def parse_logs(self, errors, ignore_errors, logs, lines_before = 10, lines_after = 10):
282 results = {}
283 rez = []
284 grep_output = ''
285 for log in logs:
286 result = None
287 thegrep = self.build_grepcmd(errors, ignore_errors, log)
288 try:
289 result = subprocess.check_output(thegrep, shell=True).decode("utf-8")
290 except:
291 pass
292 if (result is not None):
293 results[log.replace('target_logs/','')] = {}
294 rez = result.splitlines()
295 for xrez in rez:
296 try:
297 grep_output = subprocess.check_output(['grep', '-F', xrez, '-B', str(lines_before), '-A', str(lines_after), log]).decode("utf-8")
298 except:
299 pass
300 results[log.replace('target_logs/','')][xrez]=grep_output
301 return results
302
303 #get the output of dmesg and write it in a file. This file is added to log_locations.
304 def write_dmesg(self):
305 (status, dmesg) = self.target.run("dmesg > /tmp/dmesg_output.log")
306
307 @testcase(1059)
308 @skipUnlessPassed('test_ssh')
309 def test_parselogs(self):
310 self.write_dmesg()
311 log_list = self.get_local_log_list(self.log_locations)
312 result = self.parse_logs(self.errors, self.ignore_errors, log_list)
313 print(self.getHardwareInfo())
314 errcount = 0
315 for log in result:
316 self.msg += "Log: "+log+"\n"
317 self.msg += "-----------------------\n"
318 for error in result[log]:
319 errcount += 1
320 self.msg += "Central error: "+str(error)+"\n"
321 self.msg += "***********************\n"
322 self.msg += result[str(log)][str(error)]+"\n"
323 self.msg += "***********************\n"
324 self.msg += "%s errors found in logs." % errcount
325 self.assertEqual(errcount, 0, msg=self.msg)