summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/runtime/parselogs.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/runtime/parselogs.py')
-rw-r--r--meta/lib/oeqa/runtime/parselogs.py178
1 files changed, 178 insertions, 0 deletions
diff --git a/meta/lib/oeqa/runtime/parselogs.py b/meta/lib/oeqa/runtime/parselogs.py
new file mode 100644
index 0000000000..42cb1b5e6f
--- /dev/null
+++ b/meta/lib/oeqa/runtime/parselogs.py
@@ -0,0 +1,178 @@
1import os
2import unittest
3from oeqa.oetest import oeRuntimeTest
4from oeqa.utils.decorators import *
5
6#in the future these lists could be moved outside of module
7errors = ["error", "cannot", "can\'t", "failed"]
8
9common_errors = [
10 '(WW) warning, (EE) error, (NI) not implemented, (??) unknown.',
11 'dma timeout',
12 'can\'t add hid device:',
13 'usbhid: probe of ',
14 ]
15
16x86_common = [
17 '[drm:psb_do_init] *ERROR* Debug is',
18 'wrong ELF class',
19 'Could not enable PowerButton event',
20 'probe of LNXPWRBN:00 failed with error -22',
21] + common_errors
22
23qemux86_common = [
24 'Fast TSC calibration',
25 '_OSC failed (AE_NOT_FOUND); disabling ASPM',
26 'Open ACPI failed (/var/run/acpid.socket) (No such file or directory)',
27 'Failed to load module "vesa"',
28 'Failed to load module "modesetting"',
29 'Failed to load module "glx"',
30 'wrong ELF class',
31] + common_errors
32
33ignore_errors = {
34 'default' : common_errors,
35 'qemux86' : [
36 'Failed to access perfctr msr (MSR c1 is 0)',
37 "fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.",
38 ] + qemux86_common,
39 'qemux86-64' : qemux86_common,
40 'qemumips' : [
41 'Failed to load module "glx"',
42 ] + common_errors,
43 'qemuppc' : [
44 'PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]',
45 'mode "640x480" test failed',
46 'Failed to load module "glx"',
47 ] + common_errors,
48 'qemuarm' : [
49 'mmci-pl18x: probe of fpga:05 failed with error -22',
50 'mmci-pl18x: probe of fpga:0b failed with error -22',
51 'Failed to load module "glx"'
52 ] + common_errors,
53 'emenlow' : x86_common,
54 'crownbay' : x86_common,
55 'genericx86' : x86_common,
56 'genericx86-64' : x86_common,
57}
58
59log_locations = ["/var/log/","/var/log/dmesg", "/tmp/dmesg_output.log"]
60
61class ParseLogsTest(oeRuntimeTest):
62
63 @classmethod
64 def setUpClass(self):
65 self.errors = errors
66 self.ignore_errors = ignore_errors
67 self.log_locations = log_locations
68 self.msg = ""
69
70 def getMachine(self):
71 (status, output) = self.target.run("uname -n")
72 return output
73
74 #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.
75 def getHardwareInfo(self):
76 hwi = ""
77 (status, cpu_name) = self.target.run("cat /proc/cpuinfo | grep \"model name\" | head -n1 | awk 'BEGIN{FS=\":\"}{print $2}'")
78 (status, cpu_physical_cores) = self.target.run("cat /proc/cpuinfo | grep \"cpu cores\" | head -n1 | awk {'print $4'}")
79 (status, cpu_logical_cores) = self.target.run("cat /proc/cpuinfo | grep \"processor\" | wc -l")
80 (status, cpu_arch) = self.target.run("uname -m")
81 hwi += "Machine information: \n"
82 hwi += "*******************************\n"
83 hwi += "Machine name: "+self.getMachine()+"\n"
84 hwi += "CPU: "+str(cpu_name)+"\n"
85 hwi += "Arch: "+str(cpu_arch)+"\n"
86 hwi += "Physical cores: "+str(cpu_physical_cores)+"\n"
87 hwi += "Logical cores: "+str(cpu_logical_cores)+"\n"
88 hwi += "*******************************\n"
89 return hwi
90
91 #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
92 #it to that list
93 def getLogList(self, log_locations):
94 logs = []
95 for location in log_locations:
96 (status, output) = self.target.run("test -f "+str(location))
97 if (status == 0):
98 logs.append(str(location))
99 else:
100 (status, output) = self.target.run("test -d "+str(location))
101 if (status == 0):
102 (status, output) = self.target.run("find "+str(location)+"/*.log -maxdepth 1 -type f")
103 output = output.splitlines()
104 for logfile in output:
105 logs.append(os.path.join(location,str(logfile)))
106 return logs
107
108 #build the grep command to be used with filters and exclusions
109 def build_grepcmd(self, errors, ignore_errors, log):
110 grepcmd = "grep "
111 grepcmd +="-Ei \""
112 for error in errors:
113 grepcmd += error+"|"
114 grepcmd = grepcmd[:-1]
115 grepcmd += "\" "+str(log)+" | grep -Eiv \'"
116 try:
117 errorlist = ignore_errors[self.getMachine()]
118 except KeyError:
119 self.msg += "No ignore list found for this machine, using default\n"
120 errorlist = ignore_errors['default']
121 for ignore_error in errorlist:
122 ignore_error = ignore_error.replace("(", "\(")
123 ignore_error = ignore_error.replace(")", "\)")
124 ignore_error = ignore_error.replace("'", ".")
125 ignore_error = ignore_error.replace("?", "\?")
126 ignore_error = ignore_error.replace("[", "\[")
127 ignore_error = ignore_error.replace("]", "\]")
128 ignore_error = ignore_error.replace("*", "\*")
129 grepcmd += ignore_error+"|"
130 grepcmd = grepcmd[:-1]
131 grepcmd += "\'"
132 return grepcmd
133
134 #grep only the errors so that their context could be collected. Default context is 10 lines before and after the error itself
135 def parse_logs(self, errors, ignore_errors, logs, lines_before = 10, lines_after = 10):
136 results = {}
137 rez = []
138 for log in logs:
139 thegrep = self.build_grepcmd(errors, ignore_errors, log)
140 try:
141 (status, result) = self.target.run(thegrep)
142 except:
143 pass
144 if result:
145 results[log] = {}
146 rez = result.splitlines()
147 for xrez in rez:
148 command = "grep \"\\"+str(xrez)+"\" -B "+str(lines_before)+" -A "+str(lines_after)+" "+str(log)
149 try:
150 (status, yrez) = self.target.run(command)
151 except:
152 pass
153 results[log][xrez]=yrez
154 return results
155
156 #get the output of dmesg and write it in a file. This file is added to log_locations.
157 def write_dmesg(self):
158 (status, dmesg) = self.target.run("dmesg")
159 (status, dmesg2) = self.target.run("echo \""+str(dmesg)+"\" > /tmp/dmesg_output.log")
160
161 @skipUnlessPassed('test_ssh')
162 def test_parselogs(self):
163 self.write_dmesg()
164 log_list = self.getLogList(self.log_locations)
165 result = self.parse_logs(self.errors, self.ignore_errors, log_list)
166 print self.getHardwareInfo()
167 errcount = 0
168 for log in result:
169 self.msg += "Log: "+log+"\n"
170 self.msg += "-----------------------\n"
171 for error in result[log]:
172 errcount += 1
173 self.msg += "Central error: "+str(error)+"\n"
174 self.msg += "***********************\n"
175 self.msg += result[str(log)][str(error)]+"\n"
176 self.msg += "***********************\n"
177 self.msg += "%s errors found in logs." % errcount
178 self.assertEqual(errcount, 0, msg=self.msg)