source: test/pyregfi-smoketest.py @ 224

Last change on this file since 224 was 224, checked in by tim, 13 years ago

added new regfi API function to help manage memory better
fixed reference loop problems in pyregfi

  • Property svn:executable set to *
File size: 6.4 KB
Line 
1#!/usr/bin/env python3
2
3import sys
4import gc
5import time
6import pyregfi
7
8def usage():
9    sys.stderr.write("USAGE: pyregfi-smoketest.py hive1 [hive2 ...]\n")
10
11
12
13
14# Uses the HiveIterator to walk all keys
15# Gathers various (meaningless) statistics to exercise simple attribute access
16# and to hopefully smoke out any bugs that can be identified by changing stats
17def iterTallyNames(hive):
18    key_count = 0
19    key_lens = 0
20    key_rawlens = 0
21    value_count = 0
22    value_lens = 0
23    value_rawlens = 0
24
25    for k in hive:
26        key_count += 1
27        if k.name != None:
28            key_lens += len(k.name)
29        if k.name_raw != None:
30            key_rawlens += len(k.name_raw)
31
32        for v in k.values:
33            value_count += 1
34            if v.name != None:
35                value_lens += len(v.name)
36            if v.name_raw != None:
37                value_rawlens += len(v.name_raw)
38
39    print("  Counts: keys=%d, values=%d" % (key_count, value_count))
40    print("  Total name length: keys=%d, values=%d" % (key_lens, value_lens))
41    print("  Total raw name lengths: keys=%d, values=%d" % (key_rawlens, value_rawlens))
42
43
44# helper function
45def getCurrentPath(key):
46    if key == None:
47        return ''
48    path = []
49    p = key
50    while p != None:
51        path.append(p.name)
52        p = p.get_parent()
53    path.reverse()
54    del path[0]
55
56    return path
57
58# For each key in the hive, this traverses the parent links up to the root,
59# recording the path as it goes, and then uses the subtree/descend method
60# to find the same key again, verifying it is the same.  This test is currently
61# very slow because no key caching is used.
62def iterParentWalk(hive):
63    i = 1
64    for k in hive:
65        path = getCurrentPath(k)
66        try:
67            hive_iter = hive.subtree(path)
68            if hive_iter.current_key() != k:
69                print("WARNING: k != current_key for path '%s'." % path)
70            else:
71                i += 1
72        except Exception as e:
73            print("WARNING: Could not decend to path '%s'.\nError:\n %s\n%s" % (path,e.args,e))
74    print("   Successfully tested paths on %d keys." % i)
75
76
77# Uses the HiveIterator to walk all keys
78# Gathers various (meaningless) statistics about data/data_raw attributes
79def iterTallyData(hive):
80    data_stat = 0.0
81    dataraw_stat = 0.0
82   
83    for k in hive:
84        for v in k.values:
85            d = v.fetch_data()
86            if d == None:
87                data_stat += 0.1
88            elif hasattr(d, "__len__"):
89                data_stat += len(d)
90            else:
91                data_stat += d/2.0**64
92
93            d = v.fetch_raw_data()
94            if d == None:
95                dataraw_stat += 0.1
96            else:
97                dataraw_stat += len(d)
98
99    print("  Data stat: %f" % data_stat)
100    print("  Raw data stat: %f" % dataraw_stat)
101
102
103recurseKey_stat = 0.0
104recurseValue_stat = 0.0
105def checkValues(key):
106    global recurseKey_stat
107    global recurseValue_stat
108    recurseKey_stat += (key.mtime.low^key.mtime.high - key.max_bytes_subkeyname) * key.flags
109    for v in key.values:
110        recurseValue_stat += (v.data_off - v.data_size) / (1.0 + v.flags) + v.data_in_offset
111        value = key.values[v.name]
112        if v != value:
113            print("WARNING: iterator value '%s' does not match dictionary value '%s'." 
114                  % (v.name, value.name))
115
116def recurseTree(cur, operation):
117    for k in cur.subkeys:
118        key = cur.subkeys[k.name]
119        if k != key:
120            print("WARNING: iterator subkey '%s' does not match dictionary subkey '%s'." 
121                  % (k.name, key.name))
122        del key
123        operation(k)
124        recurseTree(k, operation)
125
126# Retrieves all keys by recursion, rather than the iterator, and validates
127# list dictionary access.  Also builds nonsensical statistics as an excuse
128# to access various base structure attributes.
129def recurseKeyTally(hive):
130    checkValues(hive.root)
131    recurseTree(hive.root, checkValues)
132    print("  Key stat: %f" % recurseKey_stat)
133    print("  Value stat: %f" % recurseValue_stat)
134
135
136# Iterates hive gathering stats about security and classname records
137def iterFetchRelated(hive):
138    security_stat = 0.0
139    classname_stat = 0.0
140    modified_stat = 0.0
141
142    for k in hive:
143        cn = k.fetch_classname()
144        if cn == None:
145            classname_stat += 0.000001
146        elif type(cn) == bytearray:
147            classname_stat += len(cn)/2**32
148        else:
149            classname_stat += len(cn)
150
151        modified_stat += k.modified
152       
153    print("  Security stat: %f" % security_stat)
154    print("  Classname stat: %f" % classname_stat)
155    print("  Modified stat: %f" % modified_stat)
156
157
158
159def iterIterWalk(hive):
160    sk_stat = 0.0
161    v_stat = 0.0
162    iter = pyregfi.HiveIterator(hive)
163    for k in iter:
164        path = getCurrentPath(k)
165        try:
166            hive_iter = hive.subtree(path)
167            sk = hive_iter.first_subkey()
168            while sk != None:
169                ssk = hive_iter.find_subkey(sk.name)
170                sk_stat += len(ssk.name)
171                sk = hive_iter.next_subkey()
172
173            v = hive_iter.first_value()
174            while v != None:
175                vv = hive_iter.find_value(v.name)
176                v_stat += len(vv.name)
177                v = hive_iter.next_value()
178
179        except Exception as e:
180            print("WARNING: Could not decend to path '%s'.\nError:\n %s\n%s" % (path,e.args,e))
181    print("   Subkey stat: %f" % sk_stat)
182    print("   Value stat: %f" % v_stat)
183
184
185
186if len(sys.argv) < 2:
187    usage()
188    sys.exit(1)
189
190
191tests = [("iterTallyNames",iterTallyNames),
192         ("iterParentWalk",iterParentWalk),
193         ("iterTallyData",iterTallyData),
194         ("recurseKeyTally",recurseKeyTally),
195         ("iterFetchRelated",iterFetchRelated),
196         ("iterIterWalk",iterIterWalk),]
197
198tests = [("iterIterWalk",iterIterWalk),]
199
200
201files = []
202for f in sys.argv[1:]:
203    files.append((f, open(f,"rb")))
204
205
206start_time = time.time()
207for hname,fh in files:
208    hive = pyregfi.Hive(fh)
209    for tname,t in tests:
210        teststart = time.time()
211        tstr = "'%s' on '%s'" % (tname,hname)
212        print("##BEGIN %s:" % tstr)
213        t(hive)
214        print("##END %s; runtime=%f; messages:" % (tstr, time.time() - teststart))
215        print(pyregfi.GetLogMessages())
216        print
217        sys.stdout.flush()
218    fh.close()
219
220hive = None
221files = None
222tests = None
223gc.collect()
224print("### Tests Completed, runtime: %f ###" % (time.time() -  start_time))
225#print(gc.garbage)
Note: See TracBrowser for help on using the repository browser.