source: test/pyregfi-smoketest.py @ 218

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

converted hive's .get_root() method into the 'root' property which is cached and better validated for user friendliness

  • Property svn:executable set to *
File size: 4.8 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.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.data_raw
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
135if len(sys.argv) < 2:
136    usage()
137    sys.exit(1)
138
139
140#tests = [("iterTallyNames",iterTallyNames),("iterParentWalk",iterParentWalk),("iterTallyData",iterTallyData),]
141tests = [("recurseKeyTally",recurseKeyTally),("iterParentWalk",iterParentWalk),]
142
143files = []
144for f in sys.argv[1:]:
145    files.append((f, open(f,"r+b")))
146
147
148start_time = time.time()
149for hname,fh in files:
150    hive = pyregfi.Hive(fh)
151    for tname,t in tests:
152        teststart = time.time()
153        tstr = "'%s' on '%s'" % (tname,hname)
154        print("##BEGIN %s:" % tstr)
155        t(hive)
156        print("##END %s; runtime=%f; messages:" % (tstr, time.time() - teststart))
157        print(pyregfi.GetLogMessages())
158        print
159        sys.stdout.flush()
160
161hive = None
162files = None
163tests = None
164gc.collect()
165print("### Tests Completed, runtime: %f ###" % (time.time() -  start_time))
166#print(gc.garbage)
Note: See TracBrowser for help on using the repository browser.