diff --git a/Android.mk b/Android.mk
index 8ec1ebf2b5d65f973edd82067a5974f835235ba6..0503b55444096021e296d374636ffb47a05e4ae7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1155,30 +1155,121 @@ LOCAL_MODULE_TAGS := tests
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-# 26.0_compat - the current plat_sepolicy.cil built
-# with the compatibility file targeting the 26.0
-# SELinux release.
+# 26.0_plat - the platform policy shipped as part of the 26.0 release.  This is
+# built to enable us to determine the diff between the current policy and the
+# 26.0 policy, which will be used in tests to make sure that compatibility has
+# been maintained by our mapping files.
+26.0_PLAT_PUBLIC_POLICY := $(LOCAL_PATH)/prebuilts/api/26.0/public
+26.0_PLAT_PRIVATE_POLICY := $(LOCAL_PATH)/prebuilts/api/26.0/private
+26.0_plat_policy.conf := $(intermediates)/26.0_plat_policy.conf
+$(26.0_plat_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(26.0_plat_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(26.0_plat_policy.conf): PRIVATE_TGT_ARCH := $(my_target_arch)
+$(26.0_plat_policy.conf): PRIVATE_TGT_WITH_ASAN := $(with_asan)
+$(26.0_plat_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(26.0_plat_policy.conf): PRIVATE_FULL_TREBLE := true
+$(26.0_plat_policy.conf): $(call build_policy, $(sepolicy_build_files), \
+$(26.0_PLAT_PUBLIC_POLICY) $(26.0_PLAT_PRIVATE_POLICY))
+	$(transform-policy-to-conf)
+	$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
+
+built_26.0_plat_sepolicy := $(intermediates)/built_26.0_plat_sepolicy
+$(built_26.0_plat_sepolicy): PRIVATE_ADDITIONAL_CIL_FILES := \
+  $(call build_policy, technical_debt.cil , $(26.0_PLAT_PRIVATE_POLICY))
+$(built_26.0_plat_sepolicy): $(26.0_plat_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy \
+  $(HOST_OUT_EXECUTABLES)/secilc \
+  $(call build_policy, technical_debt.cil, $(26.0_PLAT_PRIVATE_POLICY))
+	@mkdir -p $(dir $@)
+	$(hide) $(CHECKPOLICY_ASAN_OPTIONS) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -C -c \
+		$(POLICYVERS) -o $@ $<
+	$(hide) cat $(PRIVATE_ADDITIONAL_CIL_FILES) >> $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/secilc -M true -G -c $(POLICYVERS) $@ -o $@ -f /dev/null
+
+26.0_plat_policy.conf :=
+
+
+# 26.0_compat - the current plat_sepolicy.cil built with the compatibility file
+# targeting the 26.0 SELinux release.  This ensures that our policy will build
+# when used on a device that has non-platform policy targetting the 26.0 release.
 26.0_compat := $(intermediates)/26.0_compat
-26.0_mapping_cil := $(LOCAL_PATH)/prebuilts/api/26.0/26.0.cil
+26.0_mapping.cil := $(LOCAL_PATH)/prebuilts/api/26.0/26.0.cil
+26.0_mapping.ignore.cil := $(LOCAL_PATH)/prebuilts/api/26.0/26.0.ignore.cil
 26.0_nonplat := $(LOCAL_PATH)/prebuilts/api/26.0/nonplat_sepolicy.cil
 $(26.0_compat): PRIVATE_CIL_FILES := \
-$(built_plat_cil) $(26.0_mapping_cil) $(26.0_nonplat)
+$(built_plat_cil) $(26.0_mapping.cil) $(26.0_nonplat)
 $(26.0_compat): $(HOST_OUT_EXECUTABLES)/secilc \
-$(built_plat_cil) $(26.0_mapping_cil) $(26.0_nonplat)
+$(built_plat_cil) $(26.0_mapping.cil) $(26.0_nonplat)
 	$(hide) $(HOST_OUT_EXECUTABLES)/secilc -M true -G -N -c $(POLICYVERS) \
 		$(PRIVATE_CIL_FILES) -o $@ -f /dev/null
 
+# 26.0_mapping.combined.cil - a combination of the mapping file used when
+# combining the current platform policy with nonplatform policy based on the
+# 26.0 policy release and also a special ignored file that exists purely for
+# these tests.
+26.0_mapping.combined.cil := $(intermediates)/26.0_mapping.combined.cil
+$(26.0_mapping.combined.cil): $(26.0_mapping.cil) $(26.0_mapping.ignore.cil)
+	mkdir -p $(dir $@)
+	cat $^ > $@
+
+# plat_sepolicy - the current platform policy only, built into a policy binary.
+# TODO - this currently excludes partner extensions, but support should be added
+# to enable partners to add their own compatibility mapping
+BASE_PLAT_PUBLIC_POLICY := $(filter-out $(BOARD_PLAT_PUBLIC_SEPOLICY_DIR), $(PLAT_PUBLIC_POLICY))
+BASE_PLAT_PRIVATE_POLICY := $(filter-out $(BOARD_PLAT_PRIVATE_SEPOLICY_DIR), $(PLAT_PRIVATE_POLICY))
+base_plat_policy.conf := $(intermediates)/base_plat_policy.conf
+$(base_plat_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(base_plat_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(base_plat_policy.conf): PRIVATE_TGT_ARCH := $(my_target_arch)
+$(base_plat_policy.conf): PRIVATE_TGT_WITH_ASAN := $(with_asan)
+$(base_plat_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(base_plat_policy.conf): PRIVATE_FULL_TREBLE := true
+$(base_plat_policy.conf): $(call build_policy, $(sepolicy_build_files), \
+$(BASE_PLAT_PUBLIC_POLICY) $(BASE_PLAT_PRIVATE_POLICY))
+	$(transform-policy-to-conf)
+	$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
+
+built_plat_sepolicy := $(intermediates)/built_plat_sepolicy
+$(built_plat_sepolicy): PRIVATE_ADDITIONAL_CIL_FILES := \
+  $(call build_policy, $(sepolicy_build_cil_workaround_files), $(BASE_PLAT_PRIVATE_POLICY))
+$(built_plat_sepolicy): $(base_plat_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy \
+$(HOST_OUT_EXECUTABLES)/secilc \
+$(call build_policy, $(sepolicy_build_cil_workaround_files), $(BASE_PLAT_PRIVATE_POLICY))
+	@mkdir -p $(dir $@)
+	$(hide) $(CHECKPOLICY_ASAN_OPTIONS) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -C -c \
+		$(POLICYVERS) -o $@ $<
+	$(hide) cat $(PRIVATE_ADDITIONAL_CIL_FILES) >> $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/secilc -M true -G -c $(POLICYVERS) $@ -o $@ -f /dev/null
+
 treble_sepolicy_tests := $(intermediates)/treble_sepolicy_tests
 $(treble_sepolicy_tests): PRIVATE_PLAT_FC := $(built_plat_fc)
 $(treble_sepolicy_tests): PRIVATE_NONPLAT_FC := $(built_nonplat_fc)
 $(treble_sepolicy_tests): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(treble_sepolicy_tests): PRIVATE_SEPOLICY_OLD := $(built_26.0_plat_sepolicy)
+$(treble_sepolicy_tests): PRIVATE_COMBINED_MAPPING := $(26.0_mapping.combined.cil)
+$(treble_sepolicy_tests): PRIVATE_PLAT_SEPOLICY := $(built_plat_sepolicy)
 $(treble_sepolicy_tests): $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests.py \
-$(built_plat_fc) $(built_nonplat_fc) $(built_sepolicy) $(26.0_compat)
+$(built_plat_fc) $(built_nonplat_fc) $(built_sepolicy) $(built_plat_sepolicy) \
+$(built_26.0_plat_sepolicy) $(26.0_compat) $(26.0_mapping.combined.cil)
 	@mkdir -p $(dir $@)
-	$(hide) python $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests.py -l $(HOST_OUT)/lib64 -f $(PRIVATE_PLAT_FC) -f $(PRIVATE_NONPLAT_FC) -p $(PRIVATE_SEPOLICY)
+	$(hide) python $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests.py -l \
+		$(HOST_OUT)/lib64 -f $(PRIVATE_PLAT_FC) -f $(PRIVATE_NONPLAT_FC) \
+		-b $(PRIVATE_PLAT_SEPOLICY) -m $(PRIVATE_COMBINED_MAPPING) \
+		-o $(PRIVATE_SEPOLICY_OLD) -p $(PRIVATE_SEPOLICY)
 	$(hide) touch $@
 
+26.0_PLAT_PUBLIC_POLICY :=
+26.0_PLAT_PRIVATE_POLICY :=
 26.0_compat :=
+26.0_mapping.cil :=
+26.0_mapping.combined.cil :=
+26.0_mapping.ignore.cil :=
+26.0_nonplat :=
+BASE_PLAT_PUBLIC_POLICY :=
+BASE_PLAT_PRIVATE_POLICY :=
+base_plat_policy.conf :=
+built_26.0_plat_sepolicy :=
+plat_sepolicy :=
+
 endif # ($(PRODUCT_FULL_TREBLE),true)
 #################################
 
diff --git a/tests/Android.bp b/tests/Android.bp
index e875497d5d22054105b9debbba4a86733de07f8c..19aca9ccd6b4ff060487c375d0dd9bcd0b70559c 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -6,6 +6,12 @@ cc_library_host_shared {
     export_include_dirs: ["include"],
 }
 
+cc_prebuilt_binary {
+    name: "mini_parser.py",
+    srcs: ["mini_parser.py"],
+    host_supported: true,
+}
+
 cc_prebuilt_binary {
     name: "policy.py",
     srcs: ["policy.py"],
@@ -17,7 +23,7 @@ cc_prebuilt_binary {
     name: "treble_sepolicy_tests.py",
     srcs: ["treble_sepolicy_tests.py"],
     host_supported: true,
-    required: ["policy.py"],
+    required: ["mini_parser.py", "policy.py"],
 }
 
 cc_prebuilt_binary {
diff --git a/tests/mini_parser.py b/tests/mini_parser.py
new file mode 100644
index 0000000000000000000000000000000000000000..57b3d59f82cd628b3a48a8b16c70aaf171267a6a
--- /dev/null
+++ b/tests/mini_parser.py
@@ -0,0 +1,100 @@
+from os.path import basename
+import re
+import sys
+
+# A very limited parser whose job is to process the compatibility mapping
+# files and retrieve type and attribute information until proper support is
+# built into libsepol
+
+# 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 _getNextStmt(self, infile):
+        parens = 0
+        s = ""
+        c = infile.read(1)
+        # get to first statement
+        while c and c != "(":
+            c = infile.read(1)
+
+        parens += 1
+        c = infile.read(1)
+        while c and parens != 0:
+            s += c
+            c = infile.read(1)
+            if c == ';':
+                # comment, get rid of rest of the line
+                while c != '\n':
+                    c = infile.read(1)
+            elif c == '(':
+                parens += 1
+            elif c == ')':
+                parens -= 1
+        return s
+
+    def _parseType(self, stmt):
+        m = re.match(r"type\s+(.+)", stmt)
+        self.types.update(set(m.group(1)))
+        return
+
+    def _parseTypeattribute(self, stmt):
+        m = re.match(r"typeattribute\s+(.+)", stmt)
+        self.typeattributes.update(set(m.group(1)))
+        return
+
+    def _parseTypeattributeset(self, stmt):
+        m = re.match(r"typeattributeset\s+(.+?)\s+\((.+?)\)", stmt, flags = re.M |re.S)
+        ta = m.group(1)
+        # this isn't proper expression parsing, but will do for our
+        # current use
+        tas = m.group(2).split()
+
+        if self.typeattributesets.get(ta) is None:
+            self.typeattributesets[ta] = set()
+        self.typeattributesets[ta].update(set(tas))
+        for t in tas:
+            if self.rTypeattributesets.get(t) is None:
+                self.rTypeattributesets[t] = set()
+            self.rTypeattributesets[t].update(set(ta))
+
+        # check to see if this typeattributeset is a versioned public type
+        pub = re.match(r"(\w+)_\d+_\d+", ta)
+        if pub is not None:
+            self.pubtypes.update(set(pub.group(1)))
+        return
+
+    def _parseStmt(self, stmt):
+        if re.match(r"type\s+.+", stmt):
+            self._parseType(stmt)
+        elif re.match(r"typeattribute\s+.+", stmt):
+            self._parseTypeattribute(stmt)
+        elif re.match(r"typeattributeset\s+.+", stmt):
+            self._parseTypeattributeset(stmt)
+        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/policy.py b/tests/policy.py
index b70b836d0c8df3cfc9e1a2c16bb3b67969ee79bf..15a537ec39bcb00b08fd2925965401b25c6ca162 100644
--- a/tests/policy.py
+++ b/tests/policy.py
@@ -123,6 +123,26 @@ class Policy:
                 continue
             yield Rule
 
+
+    def GetAllTypes(self):
+        TypeIterP = self.__libsepolwrap.init_type_iter(self.__policydbP, None, False)
+        if (TypeIterP == None):
+            sys.exit("Failed to initialize type iterator")
+        buf = create_string_buffer(self.__BUFSIZE)
+        AllTypes = set()
+        while True:
+            ret = self.__libsepolwrap.get_type(buf, self.__BUFSIZE,
+                    self.__policydbP, TypeIterP)
+            if ret == 0:
+                AllTypes.add(buf.value)
+                continue
+            if ret == 1:
+                break;
+            # We should never get here.
+            sys.exit("Failed to import policy")
+        self.__libsepolwrap.destroy_type_iter(TypeIterP)
+        return AllTypes
+
     def __GetTypesByFilePathPrefix(self, MatchPrefixes, DoNotMatchPrefixes):
         Types = set()
         for Type in self.__FcDict:
@@ -203,6 +223,8 @@ class Policy:
 
     # load file_contexts
     def __InitFC(self, FcPaths):
+        if FcPaths is None:
+            return
         fc = []
         for path in FcPaths:
             if not os.path.exists(path):
diff --git a/tests/sepol_wrap.cpp b/tests/sepol_wrap.cpp
index a12d4383df986b13b56972ccea8d9dcd1ee660ee..cd5336795e49315aed9ad690060a634af75e75da 100644
--- a/tests/sepol_wrap.cpp
+++ b/tests/sepol_wrap.cpp
@@ -17,8 +17,11 @@
 #include <android-base/strings.h>
 #include <sepol_wrap.h>
 
-
+#define TYPE_ITER_LOOKUP   0
+#define TYPE_ITER_ALLTYPES 1
+#define TYPE_ITER_ALLATTRS 2
 struct type_iter {
+    unsigned int alltypes;
     type_datum *d;
     ebitmap_node *n;
     unsigned int length;
@@ -36,23 +39,33 @@ void *init_type_iter(void *policydbp, const char *type, bool is_attr)
         return NULL;
     }
 
-    out->d = static_cast<type_datum *>(hashtab_search(db->p_types.table, type));
-    if (is_attr && out->d->flavor != TYPE_ATTRIB) {
-        std::cerr << "\"" << type << "\" MUST be an attribute in the policy" << std::endl;
-        free(out);
-        return NULL;
-    } else if (!is_attr && out->d->flavor !=TYPE_TYPE) {
-        std::cerr << "\"" << type << "\" MUST be a type in the policy" << std::endl;
-        free(out);
-        return NULL;
-    }
-
-    if (is_attr) {
-        out->bit = ebitmap_start(&db->attr_type_map[out->d->s.value - 1], &out->n);
-        out->length = ebitmap_length(&db->attr_type_map[out->d->s.value - 1]);
+    if (type == NULL) {
+        out->length = db->p_types.nprim;
+        out->bit = 0;
+        if (is_attr)
+            out->alltypes = TYPE_ITER_ALLATTRS;
+        else
+            out->alltypes = TYPE_ITER_ALLTYPES;
     } else {
-        out->bit = ebitmap_start(&db->type_attr_map[out->d->s.value - 1], &out->n);
-        out->length = ebitmap_length(&db->type_attr_map[out->d->s.value - 1]);
+        out->alltypes = TYPE_ITER_LOOKUP;
+        out->d = static_cast<type_datum *>(hashtab_search(db->p_types.table, type));
+        if (is_attr && out->d->flavor != TYPE_ATTRIB) {
+            std::cerr << "\"" << type << "\" MUST be an attribute in the policy" << std::endl;
+            free(out);
+            return NULL;
+        } else if (!is_attr && out->d->flavor !=TYPE_TYPE) {
+            std::cerr << "\"" << type << "\" MUST be a type in the policy" << std::endl;
+            free(out);
+            return NULL;
+        }
+
+        if (is_attr) {
+            out->bit = ebitmap_start(&db->attr_type_map[out->d->s.value - 1], &out->n);
+            out->length = ebitmap_length(&db->attr_type_map[out->d->s.value - 1]);
+        } else {
+            out->bit = ebitmap_start(&db->type_attr_map[out->d->s.value - 1], &out->n);
+            out->length = ebitmap_length(&db->type_attr_map[out->d->s.value - 1]);
+        }
     }
 
     return static_cast<void *>(out);
@@ -65,7 +78,7 @@ void destroy_type_iter(void *type_iterp)
 }
 
 /*
- * print allow rule into *out buffer.
+ * print type into *out buffer.
  *
  * Returns -1 on error.
  * Returns 0 on successfully reading an avtab entry.
@@ -77,20 +90,28 @@ int get_type(char *out, size_t max_size, void *policydbp, void *type_iterp)
     policydb_t *db = static_cast<policydb_t *>(policydbp);
     struct type_iter *i = static_cast<struct type_iter *>(type_iterp);
 
-    for (; i->bit < i->length; i->bit = ebitmap_next(&i->n, i->bit)) {
-        if (!ebitmap_node_get_bit(i->n, i->bit)) {
-            continue;
-        }
-        len = snprintf(out, max_size, "%s", db->p_type_val_to_name[i->bit]);
-        if (len >= max_size) {
-               std::cerr << "type name exceeds buffer size." << std::endl;
-               return -1;
+    if (!i->alltypes) {
+        for (; i->bit < i->length; i->bit = ebitmap_next(&i->n, i->bit)) {
+            if (!ebitmap_node_get_bit(i->n, i->bit)) {
+                continue;
+            }
+            break;
         }
-        i->bit = ebitmap_next(&i->n, i->bit);
-        return 0;
     }
-
-    return 1;
+    if (i->bit >= i->length)
+        return 1;
+    while ((i->alltypes == TYPE_ITER_ALLATTRS
+            && db->type_val_to_struct[i->bit]->flavor != TYPE_ATTRIB)
+            || (i->alltypes == TYPE_ITER_ALLTYPES
+            && db->type_val_to_struct[i->bit]->flavor != TYPE_TYPE))
+        i->bit++;
+    len = snprintf(out, max_size, "%s", db->p_type_val_to_name[i->bit]);
+    if (len >= max_size) {
+        std::cerr << "type name exceeds buffer size." << std::endl;
+        return -1;
+    }
+    i->alltypes ? i->bit++ : i->bit = ebitmap_next(&i->n, i->bit);
+    return 0;
 }
 
 void *load_policy(const char *policy_path)
diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py
index b358a14e12cb96a9c2bd19659ddf98b5212393db..7584cab5a6adcbddcf3fba265de20138820f63a0 100644
--- a/tests/treble_sepolicy_tests.py
+++ b/tests/treble_sepolicy_tests.py
@@ -1,6 +1,7 @@
 from optparse import OptionParser
 from optparse import Option, OptionValueError
 import os
+import mini_parser
 import policy
 from policy import MatchPathPrefix
 import re
@@ -70,6 +71,11 @@ coredomains = set()
 appdomains = set()
 vendordomains = set()
 
+# compat vars
+alltypes = set()
+oldalltypes = set()
+compatMapping = None
+
 def GetAllDomains(pol):
     global alldomains
     for result in pol.QueryTypeAttribute("domain", True):
@@ -87,7 +93,6 @@ def GetAppDomains():
             alldomains[d].appdomain = True
             appdomains.add(d)
 
-
 def GetCoreDomains():
     global alldomains
     global coredomains
@@ -147,6 +152,12 @@ def GetAttributes(pol):
         for result in pol.QueryTypeAttribute(domain, False):
             alldomains[domain].attributes.add(result)
 
+def GetAllTypes(pol, oldpol):
+    global alltypes
+    global oldalltypes
+    alltypes = pol.GetAllTypes()
+    oldalltypes = oldpol.GetAllTypes()
+
 def setup(pol):
     GetAllDomains(pol)
     GetAttributes(pol)
@@ -154,6 +165,13 @@ def setup(pol):
     GetAppDomains()
     GetCoreDomains()
 
+# setup for the policy compatibility tests
+def compatSetup(pol, oldpol, mapping):
+    global compatMapping
+
+    GetAllTypes(pol, oldpol)
+    compatMapping = mapping
+
 #############################################################
 # Tests
 #############################################################
@@ -189,6 +207,30 @@ def TestCoredomainViolations():
     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.
+def TestNoUnmappedNewTypes():
+    global alltypes
+    global oldalltypes
+    newt = alltypes - oldalltypes
+    ret = ""
+    violators = []
+
+    for n in newt:
+        if 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 prebuilts/api/" + compatMapping.apiLevel + "/\n"
+        ret += " ".join(str(x) for x in sorted(violators)) + "\n"
+    return ret
+
+def TestTrebleCompatMapping():
+    ret = TestNoUnmappedNewTypes()
+    return ret
+###
 # extend OptionParser to allow the same option flag to be used multiple times.
 # This is used to allow multiple file_contexts files and tests to be
 # specified.
@@ -205,17 +247,23 @@ class MultipleOption(Option):
         else:
             Option.take_action(self, action, dest, opt, value, values, parser)
 
-Tests = ["CoredomainViolations"]
+Tests = {"CoredomainViolations": TestCoredomainViolations,
+         "TrebleCompatMapping": TestTrebleCompatMapping }
 
 if __name__ == '__main__':
     usage = "treble_sepolicy_tests.py -f nonplat_file_contexts -f "
-    usage +="plat_file_contexts -p policy [--test test] [--help]"
+    usage +="plat_file_contexts -p curr_policy -b base_policy -o old_policy "
+    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("-f", "--file_contexts", dest="file_contexts",
             metavar="FILE", action="extend", type="string")
-    parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
     parser.add_option("-l", "--library-path", dest="libpath", metavar="FILE")
+    parser.add_option("-m", "--mapping", dest="mapping", metavar="FILE")
+    parser.add_option("-o", "--oldpolicy", dest="oldpolicy", metavar="FILE")
+    parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
     parser.add_option("-t", "--test", dest="tests", action="extend",
+
             help="Test options include "+str(Tests))
 
     (options, args) = parser.parse_args()
@@ -225,9 +273,14 @@ if __name__ == '__main__':
     if not os.path.exists(options.libpath):
         sys.exit("Error: library-path " + options.libpath + " does not exist\n"
                 + parser.usage)
-
+    if not options.basepolicy:
+        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)
+    if not options.oldpolicy:
+        sys.exit("Must specify the previous monolithic policy file\n" + parser.usage)
     if not options.policy:
-        sys.exit("Must specify monolithic policy file\n" + parser.usage)
+        sys.exit("Must specify current monolithic policy file\n" + parser.usage)
     if not os.path.exists(options.policy):
         sys.exit("Error: policy file " + options.policy + " does not exist\n"
                 + parser.usage)
@@ -241,17 +294,30 @@ if __name__ == '__main__':
 
     pol = policy.Policy(options.policy, options.file_contexts, options.libpath)
     setup(pol)
+    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)
 
     if DEBUG:
         PrintScontexts()
 
     results = ""
     # If an individual test is not specified, run all tests.
-    if ( options.tests is None
-        or ("CoredomainViolations" in options.tests and len(options.tests) == 1)):
-        results += TestCoredomainViolations()
+    if options.tests is None:
+        for t in Tests.values():
+            results += t()
     else:
-        sys.exit("Error: unknown test(s): " + str(options.tests))
+        for tn in options.tests:
+            t = Tests.get(tn)
+            if t:
+                results += t()
+            else:
+                err = "Error: unknown test: " + tn + "\n"
+                err += "Available tests:\n"
+                for tn in Tests.keys():
+                    err += tn + "\n"
+                sys.exit(err)
 
     if len(results) > 0:
         sys.exit(results)