source: test/pyregfi-smoketest.py @ 219

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

updated time conversion to return a double for more precision
added modified attribute to keys to obtain user friendly time value
added accessor for key classnames
converted data attributes to functions to make workload more explicit

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