xref: /aosp_15_r20/system/extras/perf_tools/bats/lcan.py (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker#!/usr/bin/python3
2*288bf522SAndroid Build Coastguard Worker# -------------------------------------------
3*288bf522SAndroid Build Coastguard Worker# logcat analysis
4*288bf522SAndroid Build Coastguard Worker# -------------------------------------------
5*288bf522SAndroid Build Coastguard Workerfrom ast import keyword
6*288bf522SAndroid Build Coastguard Workerfrom curses import keyname
7*288bf522SAndroid Build Coastguard Workerimport argparse
8*288bf522SAndroid Build Coastguard Workerimport os
9*288bf522SAndroid Build Coastguard Workerfrom string import digits
10*288bf522SAndroid Build Coastguard Workerfrom sbtaTools import TextFile
11*288bf522SAndroid Build Coastguard Workerimport datetime
12*288bf522SAndroid Build Coastguard Workerimport re
13*288bf522SAndroid Build Coastguard Workerimport shlex
14*288bf522SAndroid Build Coastguard Workerimport glob
15*288bf522SAndroid Build Coastguard Worker
16*288bf522SAndroid Build Coastguard Workerclass LCItem:
17*288bf522SAndroid Build Coastguard Worker	def __init__(self, lCTimeProcessor):
18*288bf522SAndroid Build Coastguard Worker		self.dateTime = 0
19*288bf522SAndroid Build Coastguard Worker		self.relativeTime = 0
20*288bf522SAndroid Build Coastguard Worker		self.key = ""
21*288bf522SAndroid Build Coastguard Worker		self.moduleName = ""
22*288bf522SAndroid Build Coastguard Worker		self.keyword = ""
23*288bf522SAndroid Build Coastguard Worker		self.valueMsec = 0
24*288bf522SAndroid Build Coastguard Worker		self.lCTimeProcessor = lCTimeProcessor
25*288bf522SAndroid Build Coastguard Worker		self.lines = []
26*288bf522SAndroid Build Coastguard Worker
27*288bf522SAndroid Build Coastguard Worker	def set(self, dateTime, moduleName, keyText, valueMsec):
28*288bf522SAndroid Build Coastguard Worker		try:
29*288bf522SAndroid Build Coastguard Worker			self.dateTime = dateTime
30*288bf522SAndroid Build Coastguard Worker			self.relativeTime = self.lCTimeProcessor.toRelativeTime(self.dateTime)
31*288bf522SAndroid Build Coastguard Worker			self.moduleName = moduleName
32*288bf522SAndroid Build Coastguard Worker			self.keyword = keyText
33*288bf522SAndroid Build Coastguard Worker			self.key = moduleName+":" + keyText
34*288bf522SAndroid Build Coastguard Worker			self.valueMsec = valueMsec
35*288bf522SAndroid Build Coastguard Worker		except Exception as e:
36*288bf522SAndroid Build Coastguard Worker			errLine = "LCItem:set() ERROR Failed: " + str(e)
37*288bf522SAndroid Build Coastguard Worker			assert False, errLine
38*288bf522SAndroid Build Coastguard Worker
39*288bf522SAndroid Build Coastguard Worker	def copy(self, otherLCItem):
40*288bf522SAndroid Build Coastguard Worker		self.dateTime = otherLCItem.dataTime
41*288bf522SAndroid Build Coastguard Worker		self.relativeTime = otherLCItem.relativeTime
42*288bf522SAndroid Build Coastguard Worker		self.key = otherLCItem.key
43*288bf522SAndroid Build Coastguard Worker		self.moduleName = otherLCItem.moduleName
44*288bf522SAndroid Build Coastguard Worker		self.keyword = otherLCItem.keyword
45*288bf522SAndroid Build Coastguard Worker		self.valueMsec = otherLCItem.valueMsec
46*288bf522SAndroid Build Coastguard Worker		self.lCTimeProcessor = otherLCItem.lcTimeProcessor
47*288bf522SAndroid Build Coastguard Worker		self.lines = otherLCItem.lines
48*288bf522SAndroid Build Coastguard Worker
49*288bf522SAndroid Build Coastguard Worker	def appendLine(self, line):
50*288bf522SAndroid Build Coastguard Worker		self.lines.append(line)
51*288bf522SAndroid Build Coastguard Worker
52*288bf522SAndroid Build Coastguard Worker	def keyEqual(self, otherItem):
53*288bf522SAndroid Build Coastguard Worker		if self.key != otherItem.key:
54*288bf522SAndroid Build Coastguard Worker			return False
55*288bf522SAndroid Build Coastguard Worker		return True
56*288bf522SAndroid Build Coastguard Worker
57*288bf522SAndroid Build Coastguard Worker	def add(self, otherItem):
58*288bf522SAndroid Build Coastguard Worker		assert(self.key==otherItem.key)
59*288bf522SAndroid Build Coastguard Worker		self.lines.extend(otherItem.lines)
60*288bf522SAndroid Build Coastguard Worker		self.valueMsec = self.valueMsec + otherItem.valueMsec
61*288bf522SAndroid Build Coastguard Worker		return True
62*288bf522SAndroid Build Coastguard Worker
63*288bf522SAndroid Build Coastguard Worker	def addValue(self, otherLCItem):
64*288bf522SAndroid Build Coastguard Worker		if self.key=="":
65*288bf522SAndroid Build Coastguard Worker			self.copy(otherLCItem)
66*288bf522SAndroid Build Coastguard Worker		else:
67*288bf522SAndroid Build Coastguard Worker			assert(self.key==otherLCItem.key)
68*288bf522SAndroid Build Coastguard Worker			self.valueMsec = self.valueMsec + otherLCItem.valueMsec
69*288bf522SAndroid Build Coastguard Worker		return True
70*288bf522SAndroid Build Coastguard Worker
71*288bf522SAndroid Build Coastguard Worker	def divideValue(self, number):	# scaler divide
72*288bf522SAndroid Build Coastguard Worker		self.valueMsec = self.valueMsec / number
73*288bf522SAndroid Build Coastguard Worker		return True
74*288bf522SAndroid Build Coastguard Worker
75*288bf522SAndroid Build Coastguard Worker	def key(self):
76*288bf522SAndroid Build Coastguard Worker		return self.key
77*288bf522SAndroid Build Coastguard Worker
78*288bf522SAndroid Build Coastguard Worker	def print(self):
79*288bf522SAndroid Build Coastguard Worker		#systemTime = self.lCTimeProcessor.toSystemTime(self.dateTime)
80*288bf522SAndroid Build Coastguard Worker		#relativeTime = self.lCTimeProcessor.toRelativeTime(self.dateTime)
81*288bf522SAndroid Build Coastguard Worker		newTimeString = str(self.relativeTime)
82*288bf522SAndroid Build Coastguard Worker		if (len(self.lines)>0):
83*288bf522SAndroid Build Coastguard Worker			print("{} {}: {} {:.4f} - {}".format(newTimeString, self.moduleName, self.keyword, self.valueMsec, self.lines[0]))
84*288bf522SAndroid Build Coastguard Worker		else:
85*288bf522SAndroid Build Coastguard Worker			print("{} {}: {} {:.4f} -".format(newTimeString, self.moduleName, self.keyword, self.valueMsec))
86*288bf522SAndroid Build Coastguard Worker
87*288bf522SAndroid Build Coastguard Worker	def printLines(self, prefix, min):
88*288bf522SAndroid Build Coastguard Worker		if (len(self.lines)<min):
89*288bf522SAndroid Build Coastguard Worker			return
90*288bf522SAndroid Build Coastguard Worker		for line in self.lines:
91*288bf522SAndroid Build Coastguard Worker			print("     {}{}".format(prefix, line))
92*288bf522SAndroid Build Coastguard Worker
93*288bf522SAndroid Build Coastguard Worker	def findModuleName(self, lineTextWords):
94*288bf522SAndroid Build Coastguard Worker		colonIndex = -1
95*288bf522SAndroid Build Coastguard Worker		try:
96*288bf522SAndroid Build Coastguard Worker			colonIndex = lineTextWords.index(":")
97*288bf522SAndroid Build Coastguard Worker			# address case of colon with no space
98*288bf522SAndroid Build Coastguard Worker			moduleName = lineTextWords[colonIndex-1]
99*288bf522SAndroid Build Coastguard Worker		except:
100*288bf522SAndroid Build Coastguard Worker			moduleName = ""
101*288bf522SAndroid Build Coastguard Worker		if colonIndex==-1:
102*288bf522SAndroid Build Coastguard Worker			for word in reversed(lineTextWords):
103*288bf522SAndroid Build Coastguard Worker				index = word.find(":")
104*288bf522SAndroid Build Coastguard Worker				if index!=-1:
105*288bf522SAndroid Build Coastguard Worker					moduleName = word[:index]
106*288bf522SAndroid Build Coastguard Worker					break
107*288bf522SAndroid Build Coastguard Worker		moduleName = moduleName.strip()
108*288bf522SAndroid Build Coastguard Worker		return colonIndex, moduleName
109*288bf522SAndroid Build Coastguard Worker
110*288bf522SAndroid Build Coastguard Worker	def parseLineWithTook(self, line):
111*288bf522SAndroid Build Coastguard Worker		maxLineLength = 100
112*288bf522SAndroid Build Coastguard Worker		stage = 0
113*288bf522SAndroid Build Coastguard Worker		try:
114*288bf522SAndroid Build Coastguard Worker			words = line.split("  ")
115*288bf522SAndroid Build Coastguard Worker			dataTimeO = self.lCTimeProcessor.parseTimeStamp(line)
116*288bf522SAndroid Build Coastguard Worker			if line.find("took to complete") != -1:
117*288bf522SAndroid Build Coastguard Worker				stage = 1
118*288bf522SAndroid Build Coastguard Worker				tookIndex = line.find(" took to complete:")
119*288bf522SAndroid Build Coastguard Worker				uptoEnd= line[:tookIndex]
120*288bf522SAndroid Build Coastguard Worker				lineTextWords = uptoEnd.split()
121*288bf522SAndroid Build Coastguard Worker				colonIndex, moduleName = self.findModuleName(lineTextWords)
122*288bf522SAndroid Build Coastguard Worker				keyword  = " ".join([lineTextWords[6]])
123*288bf522SAndroid Build Coastguard Worker				value = re.findall(r'\d+', line[tookIndex:])[-1]
124*288bf522SAndroid Build Coastguard Worker				value = float(value)
125*288bf522SAndroid Build Coastguard Worker
126*288bf522SAndroid Build Coastguard Worker			elif line.find("took") != -1:
127*288bf522SAndroid Build Coastguard Worker				stage = 2
128*288bf522SAndroid Build Coastguard Worker				tookIndex = line.find(" took")
129*288bf522SAndroid Build Coastguard Worker				uptoEnd= line[:tookIndex]
130*288bf522SAndroid Build Coastguard Worker				uptoBracket = uptoEnd.rfind("(")
131*288bf522SAndroid Build Coastguard Worker				if uptoBracket != -1:
132*288bf522SAndroid Build Coastguard Worker					uptoEnd = uptoEnd[:uptoBracket]
133*288bf522SAndroid Build Coastguard Worker				#uptoEnd = uptoEnd.replace(":", "")
134*288bf522SAndroid Build Coastguard Worker				lineTextWords = shlex.split(uptoEnd)
135*288bf522SAndroid Build Coastguard Worker				colonIndex, moduleName = self.findModuleName(lineTextWords)
136*288bf522SAndroid Build Coastguard Worker				# if there is colon only take words after it
137*288bf522SAndroid Build Coastguard Worker				if colonIndex!=-1:
138*288bf522SAndroid Build Coastguard Worker					lineTextWords = lineTextWords[colonIndex+1:]
139*288bf522SAndroid Build Coastguard Worker				numWords = len(lineTextWords)
140*288bf522SAndroid Build Coastguard Worker				keyword = ""
141*288bf522SAndroid Build Coastguard Worker				stage = 3
142*288bf522SAndroid Build Coastguard Worker				try:
143*288bf522SAndroid Build Coastguard Worker					for i in range(max(numWords-3, 0), numWords, 1):
144*288bf522SAndroid Build Coastguard Worker						keyword  = keyword + " " + lineTextWords[i]
145*288bf522SAndroid Build Coastguard Worker				except Exception as e:
146*288bf522SAndroid Build Coastguard Worker					errLine = "LCItem:parseLineWithTook() ERROR Failed to parse1: " + str(e)
147*288bf522SAndroid Build Coastguard Worker					print(errLine)
148*288bf522SAndroid Build Coastguard Worker					assert False, errLine
149*288bf522SAndroid Build Coastguard Worker
150*288bf522SAndroid Build Coastguard Worker				# reduce length
151*288bf522SAndroid Build Coastguard Worker				keyword = keyword[:maxLineLength]
152*288bf522SAndroid Build Coastguard Worker				keyword = keyword.strip()
153*288bf522SAndroid Build Coastguard Worker				# using regex expression to replace all numbers
154*288bf522SAndroid Build Coastguard Worker				keyword = re.sub(r'\d', "_", keyword)
155*288bf522SAndroid Build Coastguard Worker				value = 0
156*288bf522SAndroid Build Coastguard Worker				stage = 4
157*288bf522SAndroid Build Coastguard Worker				try:
158*288bf522SAndroid Build Coastguard Worker					multplier = 1
159*288bf522SAndroid Build Coastguard Worker					tookSubstring = line[tookIndex:]
160*288bf522SAndroid Build Coastguard Worker					secondsIndex = tookSubstring.find("seconds")
161*288bf522SAndroid Build Coastguard Worker					msIndex = tookSubstring.find("ms")
162*288bf522SAndroid Build Coastguard Worker					if (secondsIndex!=-1):
163*288bf522SAndroid Build Coastguard Worker						tookSubstring = tookSubstring[:secondsIndex]
164*288bf522SAndroid Build Coastguard Worker						multiplier = 1000
165*288bf522SAndroid Build Coastguard Worker					elif msIndex != -1:
166*288bf522SAndroid Build Coastguard Worker						tookSubstring = tookSubstring[:msIndex]
167*288bf522SAndroid Build Coastguard Worker					else:
168*288bf522SAndroid Build Coastguard Worker						# known exception
169*288bf522SAndroid Build Coastguard Worker						if tookSubstring.find("properties")==-1:
170*288bf522SAndroid Build Coastguard Worker							errLine = "LCItem:parseLineWithTook() ERROR invalid took in substring 1B {}".format(line)
171*288bf522SAndroid Build Coastguard Worker							print(errLine)
172*288bf522SAndroid Build Coastguard Worker							assert False, errLine
173*288bf522SAndroid Build Coastguard Worker							return False
174*288bf522SAndroid Build Coastguard Worker
175*288bf522SAndroid Build Coastguard Worker					values = re.findall(r'[\d\.\d]+', tookSubstring)
176*288bf522SAndroid Build Coastguard Worker					while "." in values:
177*288bf522SAndroid Build Coastguard Worker						values.remove(".")
178*288bf522SAndroid Build Coastguard Worker					value = float(values[-1])
179*288bf522SAndroid Build Coastguard Worker					if line.find("seconds") != -1:
180*288bf522SAndroid Build Coastguard Worker						value = value * multiplier
181*288bf522SAndroid Build Coastguard Worker				except Exception as e:
182*288bf522SAndroid Build Coastguard Worker					errLine = "LCItem:parseLineWithTook() ERROR Failed to parse2: " + str(e)
183*288bf522SAndroid Build Coastguard Worker					print(errLine)
184*288bf522SAndroid Build Coastguard Worker					assert False, errLine
185*288bf522SAndroid Build Coastguard Worker				stage = 5
186*288bf522SAndroid Build Coastguard Worker
187*288bf522SAndroid Build Coastguard Worker			else:
188*288bf522SAndroid Build Coastguard Worker				return False
189*288bf522SAndroid Build Coastguard Worker
190*288bf522SAndroid Build Coastguard Worker			stage = 6
191*288bf522SAndroid Build Coastguard Worker			self.set(dataTimeO, moduleName, keyword, value)
192*288bf522SAndroid Build Coastguard Worker			stage = 7
193*288bf522SAndroid Build Coastguard Worker			self.lines.append(line)
194*288bf522SAndroid Build Coastguard Worker
195*288bf522SAndroid Build Coastguard Worker			return True
196*288bf522SAndroid Build Coastguard Worker
197*288bf522SAndroid Build Coastguard Worker		except Exception as e:
198*288bf522SAndroid Build Coastguard Worker			errLine = "LCItem:parseLineWithTook() ERROR Failed to parse3:" + str(e)
199*288bf522SAndroid Build Coastguard Worker			print(errLine, stage)
200*288bf522SAndroid Build Coastguard Worker			assert False, errLine
201*288bf522SAndroid Build Coastguard Worker
202*288bf522SAndroid Build Coastguard Worker	def parseLine(self, line):
203*288bf522SAndroid Build Coastguard Worker		try:
204*288bf522SAndroid Build Coastguard Worker			words = line.split("  ")
205*288bf522SAndroid Build Coastguard Worker			dateTimeO = self.lCTimeProcessor.parseTimeStamp(line)
206*288bf522SAndroid Build Coastguard Worker			if (dateTimeO!=None):
207*288bf522SAndroid Build Coastguard Worker				#lcItem = LCItem(self.lCTimeProcessor)
208*288bf522SAndroid Build Coastguard Worker				newLine = line[19:].rstrip()
209*288bf522SAndroid Build Coastguard Worker				self.set(dateTimeO, "", newLine, 0)
210*288bf522SAndroid Build Coastguard Worker				#self.print()
211*288bf522SAndroid Build Coastguard Worker				return
212*288bf522SAndroid Build Coastguard Worker			else:
213*288bf522SAndroid Build Coastguard Worker				return None
214*288bf522SAndroid Build Coastguard Worker
215*288bf522SAndroid Build Coastguard Worker		except Exception as e:
216*288bf522SAndroid Build Coastguard Worker			errLine = "LCItem:parseLine() ERROR Failed to parse3:" + str(e)
217*288bf522SAndroid Build Coastguard Worker			print(errLine)
218*288bf522SAndroid Build Coastguard Worker			assert False, errLine
219*288bf522SAndroid Build Coastguard Worker
220*288bf522SAndroid Build Coastguard Worker	def find(self, keyword):
221*288bf522SAndroid Build Coastguard Worker		if self.key.find(keyword)!=-1:
222*288bf522SAndroid Build Coastguard Worker			return True
223*288bf522SAndroid Build Coastguard Worker		for line in self.lines:
224*288bf522SAndroid Build Coastguard Worker			if line.find(keyword)!=-1:
225*288bf522SAndroid Build Coastguard Worker				return True
226*288bf522SAndroid Build Coastguard Worker
227*288bf522SAndroid Build Coastguard Worker	def createLogLine(self):
228*288bf522SAndroid Build Coastguard Worker		line = ""
229*288bf522SAndroid Build Coastguard Worker		msecs = self.dateTime.strftime("%f")
230*288bf522SAndroid Build Coastguard Worker		timeString = self.dateTime.strftime("%m-%d %H:%M:%S.")
231*288bf522SAndroid Build Coastguard Worker		#timeString = timeString + msecs[]
232*288bf522SAndroid Build Coastguard Worker		return line
233*288bf522SAndroid Build Coastguard Worker
234*288bf522SAndroid Build Coastguard Workerclass LCItemSet:
235*288bf522SAndroid Build Coastguard Worker	def __init__(self, item1, item2):
236*288bf522SAndroid Build Coastguard Worker		self.item1 = item1
237*288bf522SAndroid Build Coastguard Worker		self.item2 = item2
238*288bf522SAndroid Build Coastguard Worker		if (item1.key != "" and item2.key != ""):
239*288bf522SAndroid Build Coastguard Worker			assert(item1.key == item2.key)
240*288bf522SAndroid Build Coastguard Worker		if (item1.key!=""):
241*288bf522SAndroid Build Coastguard Worker			self.key = item1.key
242*288bf522SAndroid Build Coastguard Worker		else:
243*288bf522SAndroid Build Coastguard Worker			self.key = item2.key
244*288bf522SAndroid Build Coastguard Worker		self.diff = item2.valueMsec - item1.valueMsec
245*288bf522SAndroid Build Coastguard Worker
246*288bf522SAndroid Build Coastguard Worker	def __gt__(self, other):
247*288bf522SAndroid Build Coastguard Worker			if(self.diff>other.diff):
248*288bf522SAndroid Build Coastguard Worker				return True
249*288bf522SAndroid Build Coastguard Worker			else:
250*288bf522SAndroid Build Coastguard Worker				return False
251*288bf522SAndroid Build Coastguard Worker
252*288bf522SAndroid Build Coastguard Worker	def add(item):
253*288bf522SAndroid Build Coastguard Worker		assert(False)
254*288bf522SAndroid Build Coastguard Worker
255*288bf522SAndroid Build Coastguard Worker	def print(self, min, printAll):
256*288bf522SAndroid Build Coastguard Worker		self.diff = self.item2.valueMsec - self.item1.valueMsec
257*288bf522SAndroid Build Coastguard Worker		if abs(self.diff)<min:
258*288bf522SAndroid Build Coastguard Worker			return
259*288bf522SAndroid Build Coastguard Worker		flag = "12"
260*288bf522SAndroid Build Coastguard Worker		if self.item1.key=="":
261*288bf522SAndroid Build Coastguard Worker			flag = "-2"
262*288bf522SAndroid Build Coastguard Worker
263*288bf522SAndroid Build Coastguard Worker		if self.item2.key=="":
264*288bf522SAndroid Build Coastguard Worker			flag = "1-"
265*288bf522SAndroid Build Coastguard Worker
266*288bf522SAndroid Build Coastguard Worker		print("{}, {}, {}, {}, {}".format(self.key, self.item1.valueMsec, self.item2.valueMsec, self.diff, flag))
267*288bf522SAndroid Build Coastguard Worker		if printAll:
268*288bf522SAndroid Build Coastguard Worker			self.item1.printLines("1> ", 1)
269*288bf522SAndroid Build Coastguard Worker			self.item2.printLines("2> ", 1)
270*288bf522SAndroid Build Coastguard Worker
271*288bf522SAndroid Build Coastguard Workerclass LCItemMap:
272*288bf522SAndroid Build Coastguard Worker	def __init__(self):
273*288bf522SAndroid Build Coastguard Worker		self.map = {}
274*288bf522SAndroid Build Coastguard Worker
275*288bf522SAndroid Build Coastguard Worker	def put(self, newItem):
276*288bf522SAndroid Build Coastguard Worker		item = self.map.get(newItem.key)
277*288bf522SAndroid Build Coastguard Worker		if item==None:
278*288bf522SAndroid Build Coastguard Worker			self.map[newItem.key] = newItem
279*288bf522SAndroid Build Coastguard Worker		else:
280*288bf522SAndroid Build Coastguard Worker			item.add(newItem)
281*288bf522SAndroid Build Coastguard Worker
282*288bf522SAndroid Build Coastguard Worker	def print(self):
283*288bf522SAndroid Build Coastguard Worker		for key in self.map:
284*288bf522SAndroid Build Coastguard Worker			self.map[key].print()
285*288bf522SAndroid Build Coastguard Worker
286*288bf522SAndroid Build Coastguard Worker	def find(self, keyword):
287*288bf522SAndroid Build Coastguard Worker		lCItems = []
288*288bf522SAndroid Build Coastguard Worker		for index, lCItem in self.map:
289*288bf522SAndroid Build Coastguard Worker			if lCItem.find(keyword):
290*288bf522SAndroid Build Coastguard Worker				lCItems.append(lCItem)
291*288bf522SAndroid Build Coastguard Worker		return lCItems
292*288bf522SAndroid Build Coastguard Worker
293*288bf522SAndroid Build Coastguard Worker	def addValues(self, other):
294*288bf522SAndroid Build Coastguard Worker		for index, item in other.map.items():
295*288bf522SAndroid Build Coastguard Worker			if item.key in self.map:
296*288bf522SAndroid Build Coastguard Worker				self.map[item.key].addValue(item)
297*288bf522SAndroid Build Coastguard Worker			else:
298*288bf522SAndroid Build Coastguard Worker				self.map[item.key] = item
299*288bf522SAndroid Build Coastguard Worker
300*288bf522SAndroid Build Coastguard Worker	def divideValue(self, number):
301*288bf522SAndroid Build Coastguard Worker		for index, item in self.map:
302*288bf522SAndroid Build Coastguard Worker			item.divideValue(number)
303*288bf522SAndroid Build Coastguard Worker
304*288bf522SAndroid Build Coastguard Workerclass LCItemSetMap:
305*288bf522SAndroid Build Coastguard Worker	def __init__(self):
306*288bf522SAndroid Build Coastguard Worker		self.map = {}
307*288bf522SAndroid Build Coastguard Worker
308*288bf522SAndroid Build Coastguard Worker	def put(self, itemSet):
309*288bf522SAndroid Build Coastguard Worker		item = self.map.get(itemSet.key)
310*288bf522SAndroid Build Coastguard Worker		if item==None:
311*288bf522SAndroid Build Coastguard Worker			self.map[itemSet.key] = itemSet
312*288bf522SAndroid Build Coastguard Worker		else:
313*288bf522SAndroid Build Coastguard Worker			item.add(itemSet)
314*288bf522SAndroid Build Coastguard Worker
315*288bf522SAndroid Build Coastguard Worker	def printSorted(self, printAll):
316*288bf522SAndroid Build Coastguard Worker		a = sorted(self.map.items(), key=lambda x: (x[1], x[0]), reverse=True)
317*288bf522SAndroid Build Coastguard Worker		cumDif = 0
318*288bf522SAndroid Build Coastguard Worker		print("Key, Value1, Value2, diff")
319*288bf522SAndroid Build Coastguard Worker		for item in a:
320*288bf522SAndroid Build Coastguard Worker			item[1].print(1, printAll)
321*288bf522SAndroid Build Coastguard Worker			cumDif = cumDif + item[1].diff
322*288bf522SAndroid Build Coastguard Worker		print("CUMULATIVE DIFF: {}".format(cumDif))
323*288bf522SAndroid Build Coastguard Worker
324*288bf522SAndroid Build Coastguard Workerclass LCTimeProcessor:
325*288bf522SAndroid Build Coastguard Worker	def __init__(self):
326*288bf522SAndroid Build Coastguard Worker		self.firstKernelTimeStamp = 0
327*288bf522SAndroid Build Coastguard Worker		self.lastKernelTimeStamp = 0
328*288bf522SAndroid Build Coastguard Worker		self.firstSystemTimesStamp = 0
329*288bf522SAndroid Build Coastguard Worker		self.lastTimeStamp = 0
330*288bf522SAndroid Build Coastguard Worker		self.zeroRelativeTime = 0
331*288bf522SAndroid Build Coastguard Worker		today = datetime.datetime.now()
332*288bf522SAndroid Build Coastguard Worker		year = str(today.year)
333*288bf522SAndroid Build Coastguard Worker		self.currentYear = year[-2:] # 2022/2023
334*288bf522SAndroid Build Coastguard Worker
335*288bf522SAndroid Build Coastguard Worker	def parseTimeStamp(self, line):
336*288bf522SAndroid Build Coastguard Worker		try:
337*288bf522SAndroid Build Coastguard Worker			if len(line)<19:
338*288bf522SAndroid Build Coastguard Worker				return None
339*288bf522SAndroid Build Coastguard Worker			currentYear = self.currentYear	# 22
340*288bf522SAndroid Build Coastguard Worker			words = line.split("  ")
341*288bf522SAndroid Build Coastguard Worker			timeString = words[0]
342*288bf522SAndroid Build Coastguard Worker			#timeString = re.sub("[^0-9: -.]", "", timeString)
343*288bf522SAndroid Build Coastguard Worker			timeString = timeString.strip()
344*288bf522SAndroid Build Coastguard Worker			timeString = timeString[:18]
345*288bf522SAndroid Build Coastguard Worker			timeString = currentYear + "-" + timeString
346*288bf522SAndroid Build Coastguard Worker			dataTimeO = datetime.datetime.strptime(timeString, "%Y-%m-%d %H:%M:%S.%f")
347*288bf522SAndroid Build Coastguard Worker			return dataTimeO
348*288bf522SAndroid Build Coastguard Worker		except Exception as e:
349*288bf522SAndroid Build Coastguard Worker			# If no time stamp on this line
350*288bf522SAndroid Build Coastguard Worker			if line.find("beginning of")!=-1:
351*288bf522SAndroid Build Coastguard Worker				return None
352*288bf522SAndroid Build Coastguard Worker			errLine = "LCItem:parseTimeStamp() ERROR Failed to parse:" + str(e)
353*288bf522SAndroid Build Coastguard Worker			print(errLine)
354*288bf522SAndroid Build Coastguard Worker			assert False, errLine
355*288bf522SAndroid Build Coastguard Worker			return None
356*288bf522SAndroid Build Coastguard Worker
357*288bf522SAndroid Build Coastguard Worker
358*288bf522SAndroid Build Coastguard Worker	def process(self, line):
359*288bf522SAndroid Build Coastguard Worker		timeStamp = self.parseTimeStamp(line)
360*288bf522SAndroid Build Coastguard Worker		if timeStamp==None:
361*288bf522SAndroid Build Coastguard Worker			return False
362*288bf522SAndroid Build Coastguard Worker
363*288bf522SAndroid Build Coastguard Worker		if self.firstKernelTimeStamp==0:
364*288bf522SAndroid Build Coastguard Worker			self.firstKernelTimeStamp = timeStamp
365*288bf522SAndroid Build Coastguard Worker		else:
366*288bf522SAndroid Build Coastguard Worker			if timeStamp < self.firstKernelTimeStamp:
367*288bf522SAndroid Build Coastguard Worker				return False
368*288bf522SAndroid Build Coastguard Worker
369*288bf522SAndroid Build Coastguard Worker			timeChange = timeStamp - self.lastTimeStamp
370*288bf522SAndroid Build Coastguard Worker			if (timeChange.total_seconds() > 68*5):
371*288bf522SAndroid Build Coastguard Worker				if self.firstSystemTimesStamp ==0:
372*288bf522SAndroid Build Coastguard Worker					self.firstSystemTimesStamp = timeStamp
373*288bf522SAndroid Build Coastguard Worker					self.lastKernelTimeStamp = self.lastTimeStamp
374*288bf522SAndroid Build Coastguard Worker					self.zeroRelativeTime = self.toSystemTime(self.firstKernelTimeStamp)
375*288bf522SAndroid Build Coastguard Worker
376*288bf522SAndroid Build Coastguard Worker		self.lastTimeStamp = timeStamp
377*288bf522SAndroid Build Coastguard Worker		return True
378*288bf522SAndroid Build Coastguard Worker
379*288bf522SAndroid Build Coastguard Worker	def toSystemTime(self, timeStamp):
380*288bf522SAndroid Build Coastguard Worker		try:
381*288bf522SAndroid Build Coastguard Worker			# if no systemTime is found, it must all be system time
382*288bf522SAndroid Build Coastguard Worker			if self.firstSystemTimesStamp==0:
383*288bf522SAndroid Build Coastguard Worker				self.firstSystemTimesStamp = self.firstKernelTimeStamp
384*288bf522SAndroid Build Coastguard Worker				self.lastKernelTimeStamp = self.lastTimeStamp
385*288bf522SAndroid Build Coastguard Worker				self.zeroRelativeTime = self.firstKernelTimeStamp
386*288bf522SAndroid Build Coastguard Worker				return timeStamp
387*288bf522SAndroid Build Coastguard Worker			if timeStamp >= self.firstSystemTimesStamp:
388*288bf522SAndroid Build Coastguard Worker				return timeStamp
389*288bf522SAndroid Build Coastguard Worker			else:
390*288bf522SAndroid Build Coastguard Worker				timeChange = timeStamp - self.lastKernelTimeStamp
391*288bf522SAndroid Build Coastguard Worker				systemTime = self.firstSystemTimesStamp + timeChange
392*288bf522SAndroid Build Coastguard Worker				return systemTime
393*288bf522SAndroid Build Coastguard Worker		except Exception as e:
394*288bf522SAndroid Build Coastguard Worker			errLine = "LogLine:parseLine() ERROR Failed to parse3:" + str(e)
395*288bf522SAndroid Build Coastguard Worker			print(errLine)
396*288bf522SAndroid Build Coastguard Worker			assert False, errLine
397*288bf522SAndroid Build Coastguard Worker
398*288bf522SAndroid Build Coastguard Worker	def toRelativeTime(self, timeStamp):
399*288bf522SAndroid Build Coastguard Worker		systemTime = self.toSystemTime(timeStamp)
400*288bf522SAndroid Build Coastguard Worker		relativeTime = systemTime - self.zeroRelativeTime
401*288bf522SAndroid Build Coastguard Worker		return relativeTime
402*288bf522SAndroid Build Coastguard Worker
403*288bf522SAndroid Build Coastguard Worker		if timeStamp< self.firstSystemTimesStamp:
404*288bf522SAndroid Build Coastguard Worker			timeChange = timeStamp - self.lastKernelTimeStamp
405*288bf522SAndroid Build Coastguard Worker			systemTime = self.firstSystemTimesStamp + timeChange
406*288bf522SAndroid Build Coastguard Worker			return systemTime
407*288bf522SAndroid Build Coastguard Worker		else:
408*288bf522SAndroid Build Coastguard Worker			return timeStamp
409*288bf522SAndroid Build Coastguard Worker
410*288bf522SAndroid Build Coastguard Worker	def toString(self, timeStamp):
411*288bf522SAndroid Build Coastguard Worker		return timeStamp.strftime("%Y-%m-%d %H:%M:%S.%f")
412*288bf522SAndroid Build Coastguard Worker
413*288bf522SAndroid Build Coastguard Workerclass LCLogLine:
414*288bf522SAndroid Build Coastguard Worker	def __init__(self, lCTimeProcessor):
415*288bf522SAndroid Build Coastguard Worker		self.dateTime = 0
416*288bf522SAndroid Build Coastguard Worker		self.relativeTime = 0
417*288bf522SAndroid Build Coastguard Worker		self.lineText = ""
418*288bf522SAndroid Build Coastguard Worker		self.lCTimeProcessor = lCTimeProcessor
419*288bf522SAndroid Build Coastguard Worker
420*288bf522SAndroid Build Coastguard Worker	def set(self, dateTime, lineText):
421*288bf522SAndroid Build Coastguard Worker		self.dateTime = dateTime
422*288bf522SAndroid Build Coastguard Worker		self.relativeTime = self.lCTimeProcessor.toRelativeTime(self.dateTime)
423*288bf522SAndroid Build Coastguard Worker		self.lineText = lineText
424*288bf522SAndroid Build Coastguard Worker
425*288bf522SAndroid Build Coastguard Worker	def print(self):
426*288bf522SAndroid Build Coastguard Worker		newTimeString = str(self.relativeTime)
427*288bf522SAndroid Build Coastguard Worker		print("{}{}".format(newTimeString, self.lineText))
428*288bf522SAndroid Build Coastguard Worker
429*288bf522SAndroid Build Coastguard Worker	def parseLine(self, line):
430*288bf522SAndroid Build Coastguard Worker		try:
431*288bf522SAndroid Build Coastguard Worker			dateTimeO = self.lCTimeProcessor.parseTimeStamp(line)
432*288bf522SAndroid Build Coastguard Worker			if (dateTimeO!=None):
433*288bf522SAndroid Build Coastguard Worker				lineText = line[19:].rstrip()
434*288bf522SAndroid Build Coastguard Worker				self.set(dateTimeO, lineText)
435*288bf522SAndroid Build Coastguard Worker				return
436*288bf522SAndroid Build Coastguard Worker			else:
437*288bf522SAndroid Build Coastguard Worker				return None
438*288bf522SAndroid Build Coastguard Worker
439*288bf522SAndroid Build Coastguard Worker		except Exception as e:
440*288bf522SAndroid Build Coastguard Worker			errLine = "LogLine:parseLine() ERROR Failed to parse3:" + str(e)
441*288bf522SAndroid Build Coastguard Worker			print(errLine)
442*288bf522SAndroid Build Coastguard Worker			assert False, errLine
443*288bf522SAndroid Build Coastguard Worker
444*288bf522SAndroid Build Coastguard Worker	def find(self, word):
445*288bf522SAndroid Build Coastguard Worker		if (self.lineText.find(word)!=-1):
446*288bf522SAndroid Build Coastguard Worker			return True
447*288bf522SAndroid Build Coastguard Worker		else:
448*288bf522SAndroid Build Coastguard Worker			return False
449*288bf522SAndroid Build Coastguard Worker
450*288bf522SAndroid Build Coastguard Worker	def findAll(self, words):
451*288bf522SAndroid Build Coastguard Worker		for word in words:
452*288bf522SAndroid Build Coastguard Worker			if (self.lineText.find(word)==-1):
453*288bf522SAndroid Build Coastguard Worker				return False
454*288bf522SAndroid Build Coastguard Worker		return True
455*288bf522SAndroid Build Coastguard Worker
456*288bf522SAndroid Build Coastguard Workerclass LCLogFile(TextFile):
457*288bf522SAndroid Build Coastguard Worker	priorTimeStamp = 0.0
458*288bf522SAndroid Build Coastguard Worker	def __init__(self, _fileName = ""):
459*288bf522SAndroid Build Coastguard Worker		super(LCLogFile, self).__init__(_fileName)
460*288bf522SAndroid Build Coastguard Worker		self.linesWithTook = []
461*288bf522SAndroid Build Coastguard Worker		self.linesWithTookToComplete = []
462*288bf522SAndroid Build Coastguard Worker		self.linesWithoutTookToComplete = []
463*288bf522SAndroid Build Coastguard Worker		self.firstKernelTimeStamp = 0
464*288bf522SAndroid Build Coastguard Worker		self.lastKernelTimeStamp = 0
465*288bf522SAndroid Build Coastguard Worker		self.firstSystemTimesStamp = 0
466*288bf522SAndroid Build Coastguard Worker		self.lastTimeStamp = 0
467*288bf522SAndroid Build Coastguard Worker		self.lCTimeProcessor = LCTimeProcessor()
468*288bf522SAndroid Build Coastguard Worker		self.dumpLinesBeforeBeginning()
469*288bf522SAndroid Build Coastguard Worker
470*288bf522SAndroid Build Coastguard Worker	def dumpLinesBeforeBeginning(self):
471*288bf522SAndroid Build Coastguard Worker		# start from --------- beginning of kernel
472*288bf522SAndroid Build Coastguard Worker		beginningFound = False
473*288bf522SAndroid Build Coastguard Worker		_lines = []
474*288bf522SAndroid Build Coastguard Worker		for line in self.lines:
475*288bf522SAndroid Build Coastguard Worker			if beginningFound==True:
476*288bf522SAndroid Build Coastguard Worker				_lines.append(line)
477*288bf522SAndroid Build Coastguard Worker				self.lCTimeProcessor.process(line)
478*288bf522SAndroid Build Coastguard Worker
479*288bf522SAndroid Build Coastguard Worker			elif line.find("beginning of kernel") != -1:
480*288bf522SAndroid Build Coastguard Worker				beginningFound = True
481*288bf522SAndroid Build Coastguard Worker
482*288bf522SAndroid Build Coastguard Worker		self.lines = _lines
483*288bf522SAndroid Build Coastguard Worker
484*288bf522SAndroid Build Coastguard Worker
485*288bf522SAndroid Build Coastguard Worker	def scanTook(self):
486*288bf522SAndroid Build Coastguard Worker		lCItemMap = LCItemMap()
487*288bf522SAndroid Build Coastguard Worker		foundBeginning = False
488*288bf522SAndroid Build Coastguard Worker		for line in self.lines:
489*288bf522SAndroid Build Coastguard Worker			# start at beginning
490*288bf522SAndroid Build Coastguard Worker			if not foundBeginning:
491*288bf522SAndroid Build Coastguard Worker				if line.find("beginning of kernel=1") != -1:
492*288bf522SAndroid Build Coastguard Worker					foundBeginning = True
493*288bf522SAndroid Build Coastguard Worker					continue
494*288bf522SAndroid Build Coastguard Worker
495*288bf522SAndroid Build Coastguard Worker			# stop if boot complete
496*288bf522SAndroid Build Coastguard Worker			if line.find("sys.boot_completed=1") != -1:
497*288bf522SAndroid Build Coastguard Worker				break
498*288bf522SAndroid Build Coastguard Worker
499*288bf522SAndroid Build Coastguard Worker			if line.find("took") != -1:
500*288bf522SAndroid Build Coastguard Worker				self.linesWithTook.append(line.rstrip())
501*288bf522SAndroid Build Coastguard Worker
502*288bf522SAndroid Build Coastguard Worker		for line in self.linesWithTook:
503*288bf522SAndroid Build Coastguard Worker			lCItem = LCItem(self.lCTimeProcessor)
504*288bf522SAndroid Build Coastguard Worker			if lCItem.parseLineWithTook(line)==True:
505*288bf522SAndroid Build Coastguard Worker				lCItemMap.put(lCItem)
506*288bf522SAndroid Build Coastguard Worker
507*288bf522SAndroid Build Coastguard Worker		return lCItemMap
508*288bf522SAndroid Build Coastguard Worker
509*288bf522SAndroid Build Coastguard Worker	def print(self, numItems=None):
510*288bf522SAndroid Build Coastguard Worker		self.scanTook()
511*288bf522SAndroid Build Coastguard Worker
512*288bf522SAndroid Build Coastguard Worker	def convert(self, numItems=None):
513*288bf522SAndroid Build Coastguard Worker		lcLogLines = []
514*288bf522SAndroid Build Coastguard Worker		for line in self.lines:
515*288bf522SAndroid Build Coastguard Worker			lcLogLine = LCLogLine(self.lCTimeProcessor)
516*288bf522SAndroid Build Coastguard Worker			lcLogLine.parseLine(line)
517*288bf522SAndroid Build Coastguard Worker			lcLogLines.append(lcLogLine)
518*288bf522SAndroid Build Coastguard Worker		return lcLogLines
519*288bf522SAndroid Build Coastguard Worker'''
520*288bf522SAndroid Build Coastguard Worker	def createLCFile(self, fileName):
521*288bf522SAndroid Build Coastguard Worker		# create LCTimeProcessor
522*288bf522SAndroid Build Coastguard Worker		# create LCItem
523*288bf522SAndroid Build Coastguard Worker		# create LCLogLine
524*288bf522SAndroid Build Coastguard Worker		# write LCLogLine to file
525*288bf522SAndroid Build Coastguard Worker'''
526*288bf522SAndroid Build Coastguard Workerclass ScanFile:
527*288bf522SAndroid Build Coastguard Worker	def __init__(self):
528*288bf522SAndroid Build Coastguard Worker		self.fileName = "none"
529*288bf522SAndroid Build Coastguard Worker
530*288bf522SAndroid Build Coastguard Worker	def scanKeyWords(self, fileName):
531*288bf522SAndroid Build Coastguard Worker		print("Scanning {}".format(fileName))
532*288bf522SAndroid Build Coastguard Worker		cmd = "grep \"apexd: wait for '\/dev\/loop-control'\" {}".format(fileName)
533*288bf522SAndroid Build Coastguard Worker		x = os.system(cmd)
534*288bf522SAndroid Build Coastguard Worker		cmd = "grep \"Service 'apexd-bootstrap\" {}".format(fileName)
535*288bf522SAndroid Build Coastguard Worker		x = os.system(cmd)
536*288bf522SAndroid Build Coastguard Worker		cmd = "grep apexd.status=activated {}".format(fileName)
537*288bf522SAndroid Build Coastguard Worker		x = os.system(cmd)
538*288bf522SAndroid Build Coastguard Worker		cmd = "grep \"Service 'bpfloader'\" {}".format(fileName)
539*288bf522SAndroid Build Coastguard Worker		x = os.system(cmd)
540*288bf522SAndroid Build Coastguard Worker		cmd = "grep \"sys.boot_completed=1\" {} | head -n 1".format(fileName)
541*288bf522SAndroid Build Coastguard Worker		x = os.system(cmd)
542*288bf522SAndroid Build Coastguard Worker
543*288bf522SAndroid Build Coastguard Worker	def scanTook(self, fileName):
544*288bf522SAndroid Build Coastguard Worker		lCLogFile = LCLogFile(fileName)
545*288bf522SAndroid Build Coastguard Worker		lCItemMap = lCLogFile.scanTook()
546*288bf522SAndroid Build Coastguard Worker
547*288bf522SAndroid Build Coastguard Worker	def convert(self, fileName):
548*288bf522SAndroid Build Coastguard Worker		lCLogFile = LCLogFile(fileName)
549*288bf522SAndroid Build Coastguard Worker		lcItems = lCLogFile.convert()
550*288bf522SAndroid Build Coastguard Worker		for lcItem in lcItems:
551*288bf522SAndroid Build Coastguard Worker			lcItem.print()
552*288bf522SAndroid Build Coastguard Worker
553*288bf522SAndroid Build Coastguard Worker	def phases(self, fileName):
554*288bf522SAndroid Build Coastguard Worker		keywordFile = TextFile("keywords")
555*288bf522SAndroid Build Coastguard Worker		#keywords = ['init first', 'init second', "Starting phase 200", "boot_completed"]
556*288bf522SAndroid Build Coastguard Worker
557*288bf522SAndroid Build Coastguard Worker		lCLogFile = LCLogFile(fileName)
558*288bf522SAndroid Build Coastguard Worker		keywordSets = []
559*288bf522SAndroid Build Coastguard Worker		for line in keywordFile.lines:
560*288bf522SAndroid Build Coastguard Worker			line = line.strip()
561*288bf522SAndroid Build Coastguard Worker			keywordSet = line.split(", ")
562*288bf522SAndroid Build Coastguard Worker			keywordSets.append(keywordSet)
563*288bf522SAndroid Build Coastguard Worker
564*288bf522SAndroid Build Coastguard Worker		lcLogLines = lCLogFile.convert()
565*288bf522SAndroid Build Coastguard Worker		for keywordSet in keywordSets:
566*288bf522SAndroid Build Coastguard Worker			for lcLogLine in lcLogLines:
567*288bf522SAndroid Build Coastguard Worker				if lcLogLine.findAll(keywordSet)==True:
568*288bf522SAndroid Build Coastguard Worker					lcLogLine.print()
569*288bf522SAndroid Build Coastguard Worker					break
570*288bf522SAndroid Build Coastguard Worker
571*288bf522SAndroid Build Coastguard Workerclass Compare:
572*288bf522SAndroid Build Coastguard Worker	def __init__(self):
573*288bf522SAndroid Build Coastguard Worker		self.fileName = "none"
574*288bf522SAndroid Build Coastguard Worker
575*288bf522SAndroid Build Coastguard Worker	def compareLCItemMaps(self, lCItemMap1, lCItemMap2):
576*288bf522SAndroid Build Coastguard Worker		lCItemSetMap = LCItemSetMap()
577*288bf522SAndroid Build Coastguard Worker
578*288bf522SAndroid Build Coastguard Worker		for item1key in lCItemMap1.map:
579*288bf522SAndroid Build Coastguard Worker			found = False
580*288bf522SAndroid Build Coastguard Worker			for item2key in lCItemMap2.map:
581*288bf522SAndroid Build Coastguard Worker				if item2key==item1key:
582*288bf522SAndroid Build Coastguard Worker					lcItemSet = LCItemSet(lCItemMap1.map[item1key], lCItemMap2.map[item2key])
583*288bf522SAndroid Build Coastguard Worker					lCItemSetMap.put(lcItemSet)
584*288bf522SAndroid Build Coastguard Worker					found = True
585*288bf522SAndroid Build Coastguard Worker					break
586*288bf522SAndroid Build Coastguard Worker			# if item1Key is not in ItemMap2, add a null item
587*288bf522SAndroid Build Coastguard Worker			if found==False:
588*288bf522SAndroid Build Coastguard Worker				lCTimeProcessor = LCTimeProcessor()
589*288bf522SAndroid Build Coastguard Worker				nullLCItem = LCItem(lCTimeProcessor)
590*288bf522SAndroid Build Coastguard Worker				lcItemSet = LCItemSet(nullLCItem, lCItemMap1.map[item1key])
591*288bf522SAndroid Build Coastguard Worker				lCItemSetMap.put(lcItemSet)
592*288bf522SAndroid Build Coastguard Worker				found = True
593*288bf522SAndroid Build Coastguard Worker
594*288bf522SAndroid Build Coastguard Worker		lCItemSetMap.printSorted(printAll)
595*288bf522SAndroid Build Coastguard Worker		return lCItemSetMap
596*288bf522SAndroid Build Coastguard Worker
597*288bf522SAndroid Build Coastguard Worker	def compareFiles(self, fileName1, fileName2, printAll):
598*288bf522SAndroid Build Coastguard Worker		print("---------------------------------------------------------------")
599*288bf522SAndroid Build Coastguard Worker		print("lcan.py -cmp {} {}".format(fileName1, fileName2))
600*288bf522SAndroid Build Coastguard Worker		print("---------------------------------------------------------------")
601*288bf522SAndroid Build Coastguard Worker		lCLogFile1 = LCLogFile(fileName1)
602*288bf522SAndroid Build Coastguard Worker		lCItemMap1 = lCLogFile1.scanTook()
603*288bf522SAndroid Build Coastguard Worker		lCLogFile2 = LCLogFile(fileName2)
604*288bf522SAndroid Build Coastguard Worker		lCItemMap2 = lCLogFile2.scanTook()
605*288bf522SAndroid Build Coastguard Worker
606*288bf522SAndroid Build Coastguard Worker		lCItemSetMap = LCItemSetMap()
607*288bf522SAndroid Build Coastguard Worker
608*288bf522SAndroid Build Coastguard Worker		for item1key in lCItemMap1.map:
609*288bf522SAndroid Build Coastguard Worker			found = False
610*288bf522SAndroid Build Coastguard Worker			for item2key in lCItemMap2.map:
611*288bf522SAndroid Build Coastguard Worker				if item2key==item1key:
612*288bf522SAndroid Build Coastguard Worker					lcItemSet = LCItemSet(lCItemMap1.map[item1key], lCItemMap2.map[item2key])
613*288bf522SAndroid Build Coastguard Worker					lCItemSetMap.put(lcItemSet)
614*288bf522SAndroid Build Coastguard Worker					found = True
615*288bf522SAndroid Build Coastguard Worker					break
616*288bf522SAndroid Build Coastguard Worker			# if item1Key is not in ItemMap2, add a null item
617*288bf522SAndroid Build Coastguard Worker			if found==False:
618*288bf522SAndroid Build Coastguard Worker				lCTimeProcessor = LCTimeProcessor()
619*288bf522SAndroid Build Coastguard Worker				nullLCItem = LCItem(lCTimeProcessor)
620*288bf522SAndroid Build Coastguard Worker				lcItemSet = LCItemSet(nullLCItem, lCItemMap1.map[item1key])
621*288bf522SAndroid Build Coastguard Worker				lCItemSetMap.put(lcItemSet)
622*288bf522SAndroid Build Coastguard Worker				found = True
623*288bf522SAndroid Build Coastguard Worker
624*288bf522SAndroid Build Coastguard Worker		lCItemSetMap.printSorted(printAll)
625*288bf522SAndroid Build Coastguard Worker		return lCItemSetMap
626*288bf522SAndroid Build Coastguard Worker
627*288bf522SAndroid Build Coastguard Worker	def getAverageOfDir(self, buildId):
628*288bf522SAndroid Build Coastguard Worker		#get average values for build1
629*288bf522SAndroid Build Coastguard Worker		dirList = glob.glob("{}/LC-{}*.txt".format(buildId, buildId))
630*288bf522SAndroid Build Coastguard Worker		numFiles = len(dirList)
631*288bf522SAndroid Build Coastguard Worker		#iterate in numerical order
632*288bf522SAndroid Build Coastguard Worker		lCItemMapS = LCItemMap()
633*288bf522SAndroid Build Coastguard Worker		for index in range(numFiles):
634*288bf522SAndroid Build Coastguard Worker			fileName = "{}/LC-{}-{}.txt".format(buildId, buildId, index)
635*288bf522SAndroid Build Coastguard Worker		#for index, fileName in enumerate(dirList):
636*288bf522SAndroid Build Coastguard Worker			lCLogFile = LCLogFile(fileName)
637*288bf522SAndroid Build Coastguard Worker			lCItemMap = lCLogFile.scanTook()
638*288bf522SAndroid Build Coastguard Worker			lCItemMapS.addValues(lCItemMap)
639*288bf522SAndroid Build Coastguard Worker		lCItemMapS.divideValue(numFiles)
640*288bf522SAndroid Build Coastguard Worker		return lCItemMapS
641*288bf522SAndroid Build Coastguard Worker
642*288bf522SAndroid Build Coastguard Worker	def compareDirs(self, buildId1, buildId2, printAll):
643*288bf522SAndroid Build Coastguard Worker		print("---------------------------------------------------------------")
644*288bf522SAndroid Build Coastguard Worker		print("lcan.py -cmpd {} {} {}".format(buildId1, buildId2, printAll))
645*288bf522SAndroid Build Coastguard Worker		print("---------------------------------------------------------------")
646*288bf522SAndroid Build Coastguard Worker
647*288bf522SAndroid Build Coastguard Worker		#get average values for build1
648*288bf522SAndroid Build Coastguard Worker		lCItemMap1 = self.getAverageOfDir(buildId1)
649*288bf522SAndroid Build Coastguard Worker		lCItemMap2 = self.getAverageOfDir(buildId2)
650*288bf522SAndroid Build Coastguard Worker		self.compareLCItemMaps(self, lCItemMap1, lCItemMap2)
651*288bf522SAndroid Build Coastguard Worker
652*288bf522SAndroid Build Coastguard Worker
653*288bf522SAndroid Build Coastguard Workerparser = argparse.ArgumentParser()
654*288bf522SAndroid Build Coastguard Workerparser.add_argument("-c", nargs=1, metavar=('<fileName>'), help="convert Logcat output to start from boot with converted timeStamps")
655*288bf522SAndroid Build Coastguard Workerparser.add_argument("-k", nargs=1, metavar=('<fileName>'), help="summary on keywords")
656*288bf522SAndroid Build Coastguard Workerparser.add_argument("-a", nargs=1, metavar=('<fileName>'), help="analyze file")
657*288bf522SAndroid Build Coastguard Workerparser.add_argument("-cmp", nargs=3, metavar=('<fileName1>', '<fileName2>', '<brief/all>'), help="compare logcat files")
658*288bf522SAndroid Build Coastguard Workerparser.add_argument("-cmpd", nargs=3, metavar=('<dirName1>', '<dirName2>', '<brief/all>'), help="compare logcat files")
659*288bf522SAndroid Build Coastguard Workerparser.add_argument("-p", nargs=1, metavar=('<fileName1>'), help="phase report on log files")
660*288bf522SAndroid Build Coastguard Workerargs = parser.parse_args()
661*288bf522SAndroid Build Coastguard Worker
662*288bf522SAndroid Build Coastguard Workerif args.k!=None:
663*288bf522SAndroid Build Coastguard Worker	scanFile = ScanFile()
664*288bf522SAndroid Build Coastguard Worker	scanFile.scanKeyWords(args.k[0])
665*288bf522SAndroid Build Coastguard Worker
666*288bf522SAndroid Build Coastguard Workerif args.a!=None:
667*288bf522SAndroid Build Coastguard Worker	scanFile = ScanFile()
668*288bf522SAndroid Build Coastguard Worker	scanFile.scanTook(args.a[0])
669*288bf522SAndroid Build Coastguard Worker
670*288bf522SAndroid Build Coastguard Workerif args.c!=None:
671*288bf522SAndroid Build Coastguard Worker	scanFile = ScanFile()
672*288bf522SAndroid Build Coastguard Worker	scanFile.convert(args.c[0])
673*288bf522SAndroid Build Coastguard Worker
674*288bf522SAndroid Build Coastguard Workerif args.p!=None:
675*288bf522SAndroid Build Coastguard Worker	scanFile = ScanFile()
676*288bf522SAndroid Build Coastguard Worker	scanFile.phases(args.p[0])
677*288bf522SAndroid Build Coastguard Worker
678*288bf522SAndroid Build Coastguard Workerif args.cmp!=None:
679*288bf522SAndroid Build Coastguard Worker	printAll = False
680*288bf522SAndroid Build Coastguard Worker	compare = Compare()
681*288bf522SAndroid Build Coastguard Worker	if (len(args.cmp)>2):
682*288bf522SAndroid Build Coastguard Worker		if (args.cmp[2].find("all")!=-1):
683*288bf522SAndroid Build Coastguard Worker			printAll = True
684*288bf522SAndroid Build Coastguard Worker	compare.compareFiles(args.cmp[0], args.cmp[1], printAll)
685*288bf522SAndroid Build Coastguard Worker
686*288bf522SAndroid Build Coastguard Workerif args.cmpd!=None:
687*288bf522SAndroid Build Coastguard Worker	printAll = False
688*288bf522SAndroid Build Coastguard Worker	compare = Compare()
689*288bf522SAndroid Build Coastguard Worker	if (len(args.cmpd)>2):
690*288bf522SAndroid Build Coastguard Worker		if (args.cmpd[2].find("all")!=-1):
691*288bf522SAndroid Build Coastguard Worker			printAll = True
692*288bf522SAndroid Build Coastguard Worker	compare.compareDirs(args.cmpd[0], args.cmpd[1], printAll)
693