blob: dec9ebe87404b5eb7d93534a0a01531380a22638 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001import 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',
Patrick Williamsf1e5d692016-03-30 15:21:19 -050039 'netlink init failed',
40 'Fast TSC calibration',
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050041 "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",
Patrick Williamsc124f4f2015-09-15 14:41:29 -050046 ]
47
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050048video_related = [
49 "uvesafb",
50]
51
Patrick Williamsc124f4f2015-09-15 14:41:29 -050052x86_common = [
53 '[drm:psb_do_init] *ERROR* Debug is',
54 'wrong ELF class',
55 'Could not enable PowerButton event',
56 'probe of LNXPWRBN:00 failed with error -22',
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050057 'pmd_set_huge: Cannot satisfy',
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058] + common_errors
59
60qemux86_common = [
Patrick Williamsc124f4f2015-09-15 14:41:29 -050061 'wrong ELF class',
62 "fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.",
63 "can't claim BAR ",
64] + common_errors
65
66ignore_errors = {
67 'default' : common_errors,
68 'qemux86' : [
69 'Failed to access perfctr msr (MSR',
70 ] + qemux86_common,
71 'qemux86-64' : qemux86_common,
72 'qemumips' : [
73 'Failed to load module "glx"',
74 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
75 ] + common_errors,
76 'qemumips64' : [
77 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
78 ] + common_errors,
79 'qemuppc' : [
80 'PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]',
81 'host side 80-wire cable detection failed, limiting max speed',
82 'mode "640x480" test failed',
83 'Failed to load module "glx"',
84 ] + common_errors,
85 'qemuarm' : [
86 'mmci-pl18x: probe of fpga:05 failed with error -22',
87 'mmci-pl18x: probe of fpga:0b failed with error -22',
88 'Failed to load module "glx"'
89 ] + common_errors,
90 'qemuarm64' : [
91 'Fatal server error:',
92 '(EE) Server terminated with error (1). Closing log file.',
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050093 'dmi: Firmware registration failed.',
Patrick Williamsc124f4f2015-09-15 14:41:29 -050094 ] + common_errors,
95 'emenlow' : [
96 '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
97 '(EE) Failed to load module "psb"',
98 '(EE) Failed to load module psb',
99 '(EE) Failed to load module "psbdrv"',
100 '(EE) Failed to load module psbdrv',
101 '(EE) open /dev/fb0: No such file or directory',
102 '(EE) AIGLX: reverting to software rendering',
103 ] + x86_common,
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500104 'intel-core2-32' : [
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500105 'ACPI: No _BQC method, cannot determine initial brightness',
106 '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
107 '(EE) Failed to load module "psb"',
108 '(EE) Failed to load module psb',
109 '(EE) Failed to load module "psbdrv"',
110 '(EE) Failed to load module psbdrv',
111 '(EE) open /dev/fb0: No such file or directory',
112 '(EE) AIGLX: reverting to software rendering',
113 ] + x86_common,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500114 'intel-corei7-64' : x86_common,
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500115 'crownbay' : x86_common,
116 'genericx86' : x86_common,
117 'genericx86-64' : x86_common,
118 'edgerouter' : [
119 'Fatal server error:',
120 ] + common_errors,
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500121 'jasperforest' : [
122 'Activated service \'org.bluez\' failed:',
123 'Unable to find NFC netlink family',
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124 ] + common_errors,
125}
126
127log_locations = ["/var/log/","/var/log/dmesg", "/tmp/dmesg_output.log"]
128
129class ParseLogsTest(oeRuntimeTest):
130
131 @classmethod
132 def setUpClass(self):
133 self.errors = errors
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500134
135 # When systemd is enabled we need to notice errors on
136 # circular dependencies in units.
137 if self.hasFeature("systemd"):
138 self.errors.extend([
139 'Found ordering cycle on',
140 'Breaking ordering cycle by deleting job',
141 'deleted to break ordering cycle',
142 'Ordering cycle found, skipping',
143 ])
144
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500145 self.ignore_errors = ignore_errors
146 self.log_locations = log_locations
147 self.msg = ""
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500148 (is_lsb, location) = oeRuntimeTest.tc.target.run("which LSB_Test.sh")
149 if is_lsb == 0:
150 for machine in self.ignore_errors:
151 self.ignore_errors[machine] = self.ignore_errors[machine] + video_related
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500152
153 def getMachine(self):
154 return oeRuntimeTest.tc.d.getVar("MACHINE", True)
155
156 #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.
157 def getHardwareInfo(self):
158 hwi = ""
159 (status, cpu_name) = self.target.run("cat /proc/cpuinfo | grep \"model name\" | head -n1 | awk 'BEGIN{FS=\":\"}{print $2}'")
160 (status, cpu_physical_cores) = self.target.run("cat /proc/cpuinfo | grep \"cpu cores\" | head -n1 | awk {'print $4'}")
161 (status, cpu_logical_cores) = self.target.run("cat /proc/cpuinfo | grep \"processor\" | wc -l")
162 (status, cpu_arch) = self.target.run("uname -m")
163 hwi += "Machine information: \n"
164 hwi += "*******************************\n"
165 hwi += "Machine name: "+self.getMachine()+"\n"
166 hwi += "CPU: "+str(cpu_name)+"\n"
167 hwi += "Arch: "+str(cpu_arch)+"\n"
168 hwi += "Physical cores: "+str(cpu_physical_cores)+"\n"
169 hwi += "Logical cores: "+str(cpu_logical_cores)+"\n"
170 hwi += "*******************************\n"
171 return hwi
172
173 #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
174 #it to that list
175 def getLogList(self, log_locations):
176 logs = []
177 for location in log_locations:
178 (status, output) = self.target.run("test -f "+str(location))
179 if (status == 0):
180 logs.append(str(location))
181 else:
182 (status, output) = self.target.run("test -d "+str(location))
183 if (status == 0):
184 (status, output) = self.target.run("find "+str(location)+"/*.log -maxdepth 1 -type f")
185 if (status == 0):
186 output = output.splitlines()
187 for logfile in output:
188 logs.append(os.path.join(location,str(logfile)))
189 return logs
190
191 #copy the log files to be parsed locally
192 def transfer_logs(self, log_list):
193 target_logs = 'target_logs'
194 if not os.path.exists(target_logs):
195 os.makedirs(target_logs)
196 for f in log_list:
197 self.target.copy_from(f, target_logs)
198
199 #get the local list of logs
200 def get_local_log_list(self, log_locations):
201 self.transfer_logs(self.getLogList(log_locations))
202 logs = [ os.path.join('target_logs',f) for f in os.listdir('target_logs') if os.path.isfile(os.path.join('target_logs',f)) ]
203 return logs
204
205 #build the grep command to be used with filters and exclusions
206 def build_grepcmd(self, errors, ignore_errors, log):
207 grepcmd = "grep "
208 grepcmd +="-Ei \""
209 for error in errors:
210 grepcmd += error+"|"
211 grepcmd = grepcmd[:-1]
212 grepcmd += "\" "+str(log)+" | grep -Eiv \'"
213 try:
214 errorlist = ignore_errors[self.getMachine()]
215 except KeyError:
216 self.msg += "No ignore list found for this machine, using default\n"
217 errorlist = ignore_errors['default']
218 for ignore_error in errorlist:
219 ignore_error = ignore_error.replace("(", "\(")
220 ignore_error = ignore_error.replace(")", "\)")
221 ignore_error = ignore_error.replace("'", ".")
222 ignore_error = ignore_error.replace("?", "\?")
223 ignore_error = ignore_error.replace("[", "\[")
224 ignore_error = ignore_error.replace("]", "\]")
225 ignore_error = ignore_error.replace("*", "\*")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500226 ignore_error = ignore_error.replace("0-9", "[0-9]")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500227 grepcmd += ignore_error+"|"
228 grepcmd = grepcmd[:-1]
229 grepcmd += "\'"
230 return grepcmd
231
232 #grep only the errors so that their context could be collected. Default context is 10 lines before and after the error itself
233 def parse_logs(self, errors, ignore_errors, logs, lines_before = 10, lines_after = 10):
234 results = {}
235 rez = []
236 grep_output = ''
237 for log in logs:
238 result = None
239 thegrep = self.build_grepcmd(errors, ignore_errors, log)
240 try:
241 result = subprocess.check_output(thegrep, shell=True)
242 except:
243 pass
244 if (result is not None):
245 results[log.replace('target_logs/','')] = {}
246 rez = result.splitlines()
247 for xrez in rez:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500248 try:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500249 grep_output = subprocess.check_output(['grep', '-F', xrez, '-B', str(lines_before), '-A', str(lines_after), log])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 except:
251 pass
252 results[log.replace('target_logs/','')][xrez]=grep_output
253 return results
254
255 #get the output of dmesg and write it in a file. This file is added to log_locations.
256 def write_dmesg(self):
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500257 (status, dmesg) = self.target.run("dmesg > /tmp/dmesg_output.log")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500258
259 @testcase(1059)
260 @skipUnlessPassed('test_ssh')
261 def test_parselogs(self):
262 self.write_dmesg()
263 log_list = self.get_local_log_list(self.log_locations)
264 result = self.parse_logs(self.errors, self.ignore_errors, log_list)
265 print self.getHardwareInfo()
266 errcount = 0
267 for log in result:
268 self.msg += "Log: "+log+"\n"
269 self.msg += "-----------------------\n"
270 for error in result[log]:
271 errcount += 1
272 self.msg += "Central error: "+str(error)+"\n"
273 self.msg += "***********************\n"
274 self.msg += result[str(log)][str(error)]+"\n"
275 self.msg += "***********************\n"
276 self.msg += "%s errors found in logs." % errcount
277 self.assertEqual(errcount, 0, msg=self.msg)