diff paraspace/tests/injection_test.py @ 111:3820379b34e8

Add dexfile_insert_class_relative()
author Thinker K.F. Li <thinker@codemud.net>
date Mon, 01 Aug 2011 22:23:55 +0800
parents 6380730a80b4
children ee13c86d84f2
line wrap: on
line diff
--- a/paraspace/tests/injection_test.py	Mon Aug 01 15:00:29 2011 +0800
+++ b/paraspace/tests/injection_test.py	Mon Aug 01 22:23:55 2011 +0800
@@ -213,3 +213,76 @@
     typeid_name = DEXFile_linked.get_typeid_name(typeid)
     assert typeid_name == 'Ljava/io/File;'
     pass
+
+
+def dexfile_insert_class_relative_test():
+    from paraspace.dex_deptracker import prepare_dep_decls
+    from paraspace.injection import dexfile_insert_class_relative
+    
+    _install_dexfile_4_deptracker()
+    
+    all_dep_decls = prepare_dep_decls()
+    
+    srcdir = os.path.dirname(__file__)
+    srcroot = os.path.join(srcdir, '..', '..')
+    
+    helloworld_fn = os.path.join(srcroot, 'data', 'helloworld.dex')
+    helloworld_dex = dexfile.DEXFile.open(helloworld_fn)
+
+    classdef_map = _find_map(helloworld_dex, 0x0006)
+    saved_classdef_map_sz = classdef_map.size
+    saved_methodids_sz = len(helloworld_dex.methodIds.items)
+    
+    codeitems_map = _find_map(helloworld_dex, 0x2001)
+    saved_codeitems_sz = codeitems_map.size
+
+    helloworld_linked = \
+        dexfile.DEXFile_linked.build_dependencies(helloworld_dex,
+                                                  all_dep_decls)
+
+    fakefile_fn = os.path.join(srcroot, 'data', 'fakefile.dex')
+    fakefile_dex = dexfile.DEXFile.open(fakefile_fn)
+    fakefile_linked = \
+        dexfile.DEXFile_linked. \
+        build_dependencies(fakefile_dex, all_dep_decls)
+    
+    fakefile_def = fakefile_linked. \
+        find_class_name('Lcom/codemud/fakefile/fakefile;')
+
+    fakefile_data = fakefile_def.classDataOffRef.value
+    assert len(fakefile_data.directMethods.items) == 1
+    assert len(fakefile_data.virtualMethods.items) == 0
+    fakefile_dataheader = fakefile_data.header
+    assert fakefile_dataheader.directMethodsSize == 1
+    assert fakefile_dataheader.virtualMethodsSize == 0
+
+    clone = dexfile_insert_class_relative(helloworld_linked,
+                                          fakefile_linked, fakefile_def)
+    assert clone
+    assert clone != fakefile_def
+
+    helloworld_unlinked = helloworld_linked.get_unlinked()
+    assert helloworld_unlinked
+
+    # map size for classdef must be increased by 1
+    classdef_map = _find_map(helloworld_unlinked, 0x0006)
+    assert classdef_map.size == saved_classdef_map_sz + 1
+
+    classdata_map = _find_map(helloworld_unlinked, 0x2000)
+    assert classdata_map.size == classdef_map.size
+
+    # Check strings
+    strdatas = helloworld_unlinked.stringDataItems.items
+    strs = sorted([strdata.data.data for strdata in strdatas])
+    assert len(strs) == len(set(strs)) # uniquely
+    assert 'Lcom/codemud/fakefile/fakefile;' in strs
+
+    # Check Method List
+    methodids_map = _find_map(helloworld_unlinked, 0x0005) # method ids
+    assert methodids_map.size == len(helloworld_unlinked.methodIds.items)
+    assert methodids_map.size == saved_methodids_sz + 1
+
+    # Check Code item List
+    codeitems_map = _find_map(helloworld_unlinked, 0x2001)
+    assert codeitems_map.size == saved_codeitems_sz + 1
+    pass