Don't require private types in mapping file.

Private types are not visible to vendor/odm policy, so we don't need mapping
entries for them.

We build platform-only public policy .cil file and give it as input to
treble_sepolicy_tests. Using this public policy the test can now figure out if
the newly added type in public or private.

Bug: 116344577
Test: adding public type triggers mapping test failure, adding private type does
not.
Change-Id: I421f335e37274b24aa73109e260653d7b73788b5
diff --git a/tests/mini_parser.py b/tests/mini_parser.py
index 5dfda06..9182c5d 100644
--- a/tests/mini_parser.py
+++ b/tests/mini_parser.py
@@ -9,12 +9,23 @@
 # get the text in the next matching parens
 
 class MiniCilParser:
-    types = set() # types declared in mapping
-    pubtypes = set()
-    typeattributes = set() # attributes declared in mapping
-    typeattributesets = {} # sets defined in mapping
-    rTypeattributesets = {} # reverse mapping of above sets
-    apiLevel = None
+    def __init__(self, policyFile):
+        self.types = set() # types declared in mapping
+        self.pubtypes = set()
+        self.typeattributes = set() # attributes declared in mapping
+        self.typeattributesets = {} # sets defined in mapping
+        self.rTypeattributesets = {} # reverse mapping of above sets
+        self.apiLevel = None
+
+        with open(policyFile, 'r') as infile:
+            s = self._getNextStmt(infile)
+            while s:
+                self._parseStmt(s)
+                s = self._getNextStmt(infile)
+        fn = basename(policyFile)
+        m = re.match(r"(\d+\.\d+).+\.cil", fn)
+        if m:
+            self.apiLevel = m.group(1)
 
     def _getNextStmt(self, infile):
         parens = 0
@@ -77,27 +88,8 @@
             self._parseTypeattribute(stmt)
         elif re.match(r"typeattributeset\s+.+", stmt):
             self._parseTypeattributeset(stmt)
-        elif re.match(r"expandtypeattribute\s+.+", stmt):
-            # To silence the build warnings.
-            pass
-        else:
-            m = re.match(r"(\w+)\s+.+", stmt)
-            ret = "Warning: Unknown statement type (" + m.group(1) + ") in "
-            ret += "mapping file, perhaps consider adding support for it in "
-            ret += "system/sepolicy/tests/mini_parser.py!\n"
-            print ret
         return
 
-    def __init__(self, policyFile):
-        with open(policyFile, 'r') as infile:
-            s = self._getNextStmt(infile)
-            while s:
-                self._parseStmt(s)
-                s = self._getNextStmt(infile)
-        fn = basename(policyFile)
-        m = re.match(r"(\d+\.\d+).+\.cil", fn)
-        self.apiLevel = m.group(1)
-
 if __name__ == '__main__':
     f = sys.argv[1]
     p = MiniCilParser(f)
diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py
index 6e9eb6a..05549a1 100644
--- a/tests/treble_sepolicy_tests.py
+++ b/tests/treble_sepolicy_tests.py
@@ -76,6 +76,7 @@
 alltypes = set()
 oldalltypes = set()
 compatMapping = None
+pubtypes = set()
 
 # Distinguish between PRODUCT_FULL_TREBLE and PRODUCT_FULL_TREBLE_OVERRIDE
 FakeTreble = False
@@ -170,11 +171,13 @@
     GetCoreDomains()
 
 # setup for the policy compatibility tests
-def compatSetup(pol, oldpol, mapping):
+def compatSetup(pol, oldpol, mapping, types):
     global compatMapping
+    global pubtypes
 
     GetAllTypes(pol, oldpol)
     compatMapping = mapping
+    pubtypes = types
 
 def DomainsWithAttribute(attr):
     global alldomains
@@ -219,24 +222,25 @@
     return ret
 
 ###
-# Make sure that any new type introduced in the new policy that was not present
-# in the old policy has been recorded in the mapping file.
+# Make sure that any new public type introduced in the new policy that was not
+# present in the old policy has been recorded in the mapping file.
 def TestNoUnmappedNewTypes():
     global alltypes
     global oldalltypes
     global compatMapping
+    global pubtypes
     newt = alltypes - oldalltypes
     ret = ""
     violators = []
 
     for n in newt:
-        if compatMapping.rTypeattributesets.get(n) is None:
+        if n in pubtypes and compatMapping.rTypeattributesets.get(n) is None:
             violators.append(n)
 
     if len(violators) > 0:
-        ret += "SELinux: The following types were found added to the policy "
-        ret += "without an entry into the compatibility mapping file(s) found "
-        ret += "in private/compat/" + compatMapping.apiLevel + "/"
+        ret += "SELinux: The following public types were found added to the "
+        ret += "policy without an entry into the compatibility mapping file(s) "
+        ret += "found in private/compat/" + compatMapping.apiLevel + "/"
         ret +=  compatMapping.apiLevel + "[.ignore].cil\n"
         ret += " ".join(str(x) for x in sorted(violators)) + "\n"
     return ret
@@ -322,6 +326,8 @@
     usage +="-m mapping file [--test test] [--help]"
     parser = OptionParser(option_class=MultipleOption, usage=usage)
     parser.add_option("-b", "--basepolicy", dest="basepolicy", metavar="FILE")
+    parser.add_option("-u", "--base-pub-policy", dest="base_pub_policy",
+                      metavar="FILE")
     parser.add_option("-f", "--file_contexts", dest="file_contexts",
             metavar="FILE", action="extend", type="string")
     parser.add_option("-l", "--library-path", dest="libpath", metavar="FILE")
@@ -352,19 +358,26 @@
             sys.exit("Error: File_contexts file " + f + " does not exist\n" +
                     parser.usage)
 
-    # Mapping files are only necessary for the TrebleCompatMapping test
+    # Mapping files and public platform policy are only necessary for the
+    # TrebleCompatMapping test.
     if options.tests is None or options.tests is "TrebleCompatMapping":
         if not options.basepolicy:
-            sys.exit("Must specify the current platform-only policy file\n" + parser.usage)
+            sys.exit("Must specify the current platform-only policy file\n"
+                     + parser.usage)
         if not options.mapping:
-            sys.exit("Must specify a compatibility mapping file\n" + parser.usage)
+            sys.exit("Must specify a compatibility mapping file\n"
+                     + parser.usage)
         if not options.oldpolicy:
-            sys.exit("Must specify the previous monolithic policy file\n" + parser.usage)
+            sys.exit("Must specify the previous monolithic policy file\n"
+                     + parser.usage)
+        if not options.base_pub_policy:
+            sys.exit("Must specify the current platform-only public policy "
+                     + ".cil file\n" + parser.usage)
         basepol = policy.Policy(options.basepolicy, None, options.libpath)
         oldpol = policy.Policy(options.oldpolicy, None, options.libpath)
         mapping = mini_parser.MiniCilParser(options.mapping)
-        compatSetup(basepol, oldpol, mapping)
-
+        pubpol = mini_parser.MiniCilParser(options.base_pub_policy)
+        compatSetup(basepol, oldpol, mapping, pubpol.types)
 
     if options.faketreble:
         FakeTreble = True