CTS result readers: refactor common code into utils.py

Bug:
Change-Id: Ifbb6dda89a9250207d385f079e87cfe2b2da4ac9
diff --git a/tools/compare_cts_results.py b/tools/compare_cts_results.py
index 95e29d1..00901ec 100755
--- a/tools/compare_cts_results.py
+++ b/tools/compare_cts_results.py
@@ -9,9 +9,10 @@
 from os.path import basename
 import argparse
 import os
-import re
 import sys
 
+import utils
+
 class Module:
   def __init__(self):
     self.test_cases = {}
@@ -90,35 +91,19 @@
 
 # Read CTS test_result.xml from file and merge into result_tree
 def add_to_result_tree(result_tree, file_xml, file_idx):
-  re_module = re.compile('<Module name="([^"]*)"')
-  re_test_case = re.compile('<TestCase name="([^"]*)"')
-  re_test = re.compile('<Test result="(pass|fail)" name="([^"]*)"')
   module = None
   test_case = None
-  with open(file_xml) as f:
-    for line in f:
-      m = re_module.search(line)
-      if m:
-        module_name = m.groups()[0]
-        module = result_tree.setdefault(module_name, Module())
-        module.set_file_index_present(file_idx)
-        continue
-
-      m = re_test_case.search(line)
-      if m:
-        test_case_name = m.groups()[0]
-        test_case = module.get_test_case_maybe_create(test_case_name)
-        test_case.set_file_index_present(file_idx)
-        continue
-
-      m = re_test.search(line)
-      if m:
-        outcome = m.groups()[0]
-        test_name = m.groups()[1]
-        assert outcome in ["fail", "pass"]
-
-        v = test_case.get_test_maybe_create(test_name)
-        v.set_file_index_outcome(outcome == 'pass', file_idx)
+  for x in utils.read_cts_test_result(file_xml):
+    if type(x) is utils.CtsModule:
+      module = result_tree.setdefault(x.name, Module())
+      module.set_file_index_present(file_idx)
+    elif type(x) is utils.CtsTestCase:
+      test_case = module.get_test_case_maybe_create(x.name)
+      test_case.set_file_index_present(file_idx)
+    else:
+      assert(type(x) is utils.CtsTest)
+      v = test_case.get_test_maybe_create(x.name)
+      v.set_file_index_outcome(x.outcome, file_idx)
 
 # main tree_report function
 def tree_report(result_tree, files, diff_only):
diff --git a/tools/test_android_cts.py b/tools/test_android_cts.py
index 384ce70..7a796b9 100755
--- a/tools/test_android_cts.py
+++ b/tools/test_android_cts.py
@@ -30,6 +30,7 @@
 import os
 import re
 import sys
+import time
 
 import gradle
 import utils
@@ -103,34 +104,19 @@
 #     tree[module_name][testcase_name][test_name] = True|False
 #
 def read_test_result_into_tree(filename):
-  re_module = re.compile('<Module name="([^"]*)"')
-  re_testcase = re.compile('<TestCase name="([^"]*)"')
-  re_test = re.compile('<Test result="(pass|fail)" name="([^"]*)"')
   tree = {}
   module = None
   testcase = None
-  with open(filename) as f:
-    for line in f:
-      m = re_module.search(line)
-      if m:
-        module_name = m.groups()[0]
-        tree[module_name] = {}
-        module = tree[module_name]
-        continue
+  for x in utils.read_cts_test_result(filename):
+    if type(x) is utils.CtsModule:
+      tree[x.name] = {}
+      module = tree[x.name]
+    elif type(x) is utils.CtsTestCase:
+      module[x.name] = {}
+      testcase = module[x.name]
+    else:
+      testcase[x.name] = x.outcome
 
-      m = re_testcase.search(line)
-      if m:
-        testcase_name = m.groups()[0]
-        module[testcase_name] = {}
-        testcase = module[testcase_name]
-        continue
-
-      m = re_test.search(line)
-      if m:
-        outcome = m.groups()[0]
-        test_name = m.groups()[1]
-        assert outcome in ["fail", "pass"]
-        testcase[test_name] = outcome == "pass"
   return tree
 
 # Report the items with the title
diff --git a/tools/utils.py b/tools/utils.py
index 67cac46..7379e16 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -6,6 +6,7 @@
 
 import hashlib
 import os
+import re
 import shutil
 import subprocess
 import sys
@@ -69,3 +70,40 @@
  def __exit__(self, *_):
    print "Enter directory = ", self._old_cwd
    os.chdir(self._old_cwd)
+
+# Reading Android CTS test_result.xml
+
+class CtsModule(object):
+  def __init__(self, module_name):
+    self.name = module_name
+
+class CtsTestCase(object):
+  def __init__(self, test_case_name):
+    self.name = test_case_name
+
+class CtsTest(object):
+  def __init__(self, test_name, outcome):
+    self.name = test_name
+    self.outcome = outcome
+
+# Generator yielding CtsModule, CtsTestCase or CtsTest from
+# reading through a CTS test_result.xml file.
+def read_cts_test_result(file_xml):
+  re_module = re.compile('<Module name="([^"]*)"')
+  re_test_case = re.compile('<TestCase name="([^"]*)"')
+  re_test = re.compile('<Test result="(pass|fail)" name="([^"]*)"')
+  with open(file_xml) as f:
+    for line in f:
+      m = re_module.search(line)
+      if m:
+        yield CtsModule(m.groups()[0])
+        continue
+      m = re_test_case.search(line)
+      if m:
+        yield CtsTestCase(m.groups()[0])
+        continue
+      m = re_test.search(line)
+      if m:
+        outcome = m.groups()[0]
+        assert outcome in ["fail", "pass"]
+        yield CtsTest(m.groups()[1], outcome == 'pass')