1*da0073e9SAndroid Build Coastguard Worker# Owner(s): ["oncall: package/deploy"] 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Workerfrom io import BytesIO 4*da0073e9SAndroid Build Coastguard Worker 5*da0073e9SAndroid Build Coastguard Workerfrom torch.package import PackageExporter, PackageImporter 6*da0073e9SAndroid Build Coastguard Workerfrom torch.package._mangling import ( 7*da0073e9SAndroid Build Coastguard Worker demangle, 8*da0073e9SAndroid Build Coastguard Worker get_mangle_prefix, 9*da0073e9SAndroid Build Coastguard Worker is_mangled, 10*da0073e9SAndroid Build Coastguard Worker PackageMangler, 11*da0073e9SAndroid Build Coastguard Worker) 12*da0073e9SAndroid Build Coastguard Workerfrom torch.testing._internal.common_utils import run_tests 13*da0073e9SAndroid Build Coastguard Worker 14*da0073e9SAndroid Build Coastguard Worker 15*da0073e9SAndroid Build Coastguard Workertry: 16*da0073e9SAndroid Build Coastguard Worker from .common import PackageTestCase 17*da0073e9SAndroid Build Coastguard Workerexcept ImportError: 18*da0073e9SAndroid Build Coastguard Worker # Support the case where we run this file directly. 19*da0073e9SAndroid Build Coastguard Worker from common import PackageTestCase 20*da0073e9SAndroid Build Coastguard Worker 21*da0073e9SAndroid Build Coastguard Worker 22*da0073e9SAndroid Build Coastguard Workerclass TestMangling(PackageTestCase): 23*da0073e9SAndroid Build Coastguard Worker def test_unique_manglers(self): 24*da0073e9SAndroid Build Coastguard Worker """ 25*da0073e9SAndroid Build Coastguard Worker Each mangler instance should generate a unique mangled name for a given input. 26*da0073e9SAndroid Build Coastguard Worker """ 27*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 28*da0073e9SAndroid Build Coastguard Worker b = PackageMangler() 29*da0073e9SAndroid Build Coastguard Worker self.assertNotEqual(a.mangle("foo.bar"), b.mangle("foo.bar")) 30*da0073e9SAndroid Build Coastguard Worker 31*da0073e9SAndroid Build Coastguard Worker def test_mangler_is_consistent(self): 32*da0073e9SAndroid Build Coastguard Worker """ 33*da0073e9SAndroid Build Coastguard Worker Mangling the same name twice should produce the same result. 34*da0073e9SAndroid Build Coastguard Worker """ 35*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 36*da0073e9SAndroid Build Coastguard Worker self.assertEqual(a.mangle("abc.def"), a.mangle("abc.def")) 37*da0073e9SAndroid Build Coastguard Worker 38*da0073e9SAndroid Build Coastguard Worker def test_roundtrip_mangling(self): 39*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 40*da0073e9SAndroid Build Coastguard Worker self.assertEqual("foo", demangle(a.mangle("foo"))) 41*da0073e9SAndroid Build Coastguard Worker 42*da0073e9SAndroid Build Coastguard Worker def test_is_mangled(self): 43*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 44*da0073e9SAndroid Build Coastguard Worker b = PackageMangler() 45*da0073e9SAndroid Build Coastguard Worker self.assertTrue(is_mangled(a.mangle("foo.bar"))) 46*da0073e9SAndroid Build Coastguard Worker self.assertTrue(is_mangled(b.mangle("foo.bar"))) 47*da0073e9SAndroid Build Coastguard Worker 48*da0073e9SAndroid Build Coastguard Worker self.assertFalse(is_mangled("foo.bar")) 49*da0073e9SAndroid Build Coastguard Worker self.assertFalse(is_mangled(demangle(a.mangle("foo.bar")))) 50*da0073e9SAndroid Build Coastguard Worker 51*da0073e9SAndroid Build Coastguard Worker def test_demangler_multiple_manglers(self): 52*da0073e9SAndroid Build Coastguard Worker """ 53*da0073e9SAndroid Build Coastguard Worker PackageDemangler should be able to demangle name generated by any PackageMangler. 54*da0073e9SAndroid Build Coastguard Worker """ 55*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 56*da0073e9SAndroid Build Coastguard Worker b = PackageMangler() 57*da0073e9SAndroid Build Coastguard Worker 58*da0073e9SAndroid Build Coastguard Worker self.assertEqual("foo.bar", demangle(a.mangle("foo.bar"))) 59*da0073e9SAndroid Build Coastguard Worker self.assertEqual("bar.foo", demangle(b.mangle("bar.foo"))) 60*da0073e9SAndroid Build Coastguard Worker 61*da0073e9SAndroid Build Coastguard Worker def test_mangle_empty_errors(self): 62*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 63*da0073e9SAndroid Build Coastguard Worker with self.assertRaises(AssertionError): 64*da0073e9SAndroid Build Coastguard Worker a.mangle("") 65*da0073e9SAndroid Build Coastguard Worker 66*da0073e9SAndroid Build Coastguard Worker def test_demangle_base(self): 67*da0073e9SAndroid Build Coastguard Worker """ 68*da0073e9SAndroid Build Coastguard Worker Demangling a mangle parent directly should currently return an empty string. 69*da0073e9SAndroid Build Coastguard Worker """ 70*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 71*da0073e9SAndroid Build Coastguard Worker mangled = a.mangle("foo") 72*da0073e9SAndroid Build Coastguard Worker mangle_parent = mangled.partition(".")[0] 73*da0073e9SAndroid Build Coastguard Worker self.assertEqual("", demangle(mangle_parent)) 74*da0073e9SAndroid Build Coastguard Worker 75*da0073e9SAndroid Build Coastguard Worker def test_mangle_prefix(self): 76*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 77*da0073e9SAndroid Build Coastguard Worker mangled = a.mangle("foo.bar") 78*da0073e9SAndroid Build Coastguard Worker mangle_prefix = get_mangle_prefix(mangled) 79*da0073e9SAndroid Build Coastguard Worker self.assertEqual(mangle_prefix + "." + "foo.bar", mangled) 80*da0073e9SAndroid Build Coastguard Worker 81*da0073e9SAndroid Build Coastguard Worker def test_unique_module_names(self): 82*da0073e9SAndroid Build Coastguard Worker import package_a.subpackage 83*da0073e9SAndroid Build Coastguard Worker 84*da0073e9SAndroid Build Coastguard Worker obj = package_a.subpackage.PackageASubpackageObject() 85*da0073e9SAndroid Build Coastguard Worker obj2 = package_a.PackageAObject(obj) 86*da0073e9SAndroid Build Coastguard Worker f1 = BytesIO() 87*da0073e9SAndroid Build Coastguard Worker with PackageExporter(f1) as pe: 88*da0073e9SAndroid Build Coastguard Worker pe.intern("**") 89*da0073e9SAndroid Build Coastguard Worker pe.save_pickle("obj", "obj.pkl", obj2) 90*da0073e9SAndroid Build Coastguard Worker f1.seek(0) 91*da0073e9SAndroid Build Coastguard Worker importer1 = PackageImporter(f1) 92*da0073e9SAndroid Build Coastguard Worker loaded1 = importer1.load_pickle("obj", "obj.pkl") 93*da0073e9SAndroid Build Coastguard Worker f1.seek(0) 94*da0073e9SAndroid Build Coastguard Worker importer2 = PackageImporter(f1) 95*da0073e9SAndroid Build Coastguard Worker loaded2 = importer2.load_pickle("obj", "obj.pkl") 96*da0073e9SAndroid Build Coastguard Worker 97*da0073e9SAndroid Build Coastguard Worker # Modules from loaded packages should not shadow the names of modules. 98*da0073e9SAndroid Build Coastguard Worker # See mangling.md for more info. 99*da0073e9SAndroid Build Coastguard Worker self.assertNotEqual(type(obj2).__module__, type(loaded1).__module__) 100*da0073e9SAndroid Build Coastguard Worker self.assertNotEqual(type(loaded1).__module__, type(loaded2).__module__) 101*da0073e9SAndroid Build Coastguard Worker 102*da0073e9SAndroid Build Coastguard Worker def test_package_mangler(self): 103*da0073e9SAndroid Build Coastguard Worker a = PackageMangler() 104*da0073e9SAndroid Build Coastguard Worker b = PackageMangler() 105*da0073e9SAndroid Build Coastguard Worker a_mangled = a.mangle("foo.bar") 106*da0073e9SAndroid Build Coastguard Worker # Since `a` mangled this string, it should demangle properly. 107*da0073e9SAndroid Build Coastguard Worker self.assertEqual(a.demangle(a_mangled), "foo.bar") 108*da0073e9SAndroid Build Coastguard Worker # Since `b` did not mangle this string, demangling should leave it alone. 109*da0073e9SAndroid Build Coastguard Worker self.assertEqual(b.demangle(a_mangled), a_mangled) 110*da0073e9SAndroid Build Coastguard Worker 111*da0073e9SAndroid Build Coastguard Worker 112*da0073e9SAndroid Build Coastguard Workerif __name__ == "__main__": 113*da0073e9SAndroid Build Coastguard Worker run_tests() 114