Commit | Line | Data |
---|---|---|
94a47083 | 1 | #!/usr/bin/python |
61a87122 TG |
2 | # |
3 | # rt-mutex tester | |
4 | # | |
5 | # (C) 2006 Thomas Gleixner <tglx@linutronix.de> | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License version 2 as | |
9 | # published by the Free Software Foundation. | |
10 | # | |
11 | import os | |
12 | import sys | |
13 | import getopt | |
14 | import shutil | |
15 | import string | |
16 | ||
17 | # Globals | |
18 | quiet = 0 | |
19 | test = 0 | |
20 | comments = 0 | |
21 | ||
22 | sysfsprefix = "/sys/devices/system/rttest/rttest" | |
23 | statusfile = "/status" | |
24 | commandfile = "/command" | |
25 | ||
26 | # Command opcodes | |
27 | cmd_opcodes = { | |
28 | "schedother" : "1", | |
29 | "schedfifo" : "2", | |
30 | "lock" : "3", | |
31 | "locknowait" : "4", | |
32 | "lockint" : "5", | |
33 | "lockintnowait" : "6", | |
34 | "lockcont" : "7", | |
35 | "unlock" : "8", | |
36 | "lockbkl" : "9", | |
37 | "unlockbkl" : "10", | |
38 | "signal" : "11", | |
39 | "resetevent" : "98", | |
40 | "reset" : "99", | |
41 | } | |
42 | ||
43 | test_opcodes = { | |
44 | "prioeq" : ["P" , "eq" , None], | |
45 | "priolt" : ["P" , "lt" , None], | |
46 | "priogt" : ["P" , "gt" , None], | |
47 | "nprioeq" : ["N" , "eq" , None], | |
48 | "npriolt" : ["N" , "lt" , None], | |
49 | "npriogt" : ["N" , "gt" , None], | |
50 | "unlocked" : ["M" , "eq" , 0], | |
51 | "trylock" : ["M" , "eq" , 1], | |
52 | "blocked" : ["M" , "eq" , 2], | |
53 | "blockedwake" : ["M" , "eq" , 3], | |
54 | "locked" : ["M" , "eq" , 4], | |
55 | "opcodeeq" : ["O" , "eq" , None], | |
56 | "opcodelt" : ["O" , "lt" , None], | |
57 | "opcodegt" : ["O" , "gt" , None], | |
58 | "eventeq" : ["E" , "eq" , None], | |
59 | "eventlt" : ["E" , "lt" , None], | |
60 | "eventgt" : ["E" , "gt" , None], | |
61 | } | |
62 | ||
63 | # Print usage information | |
64 | def usage(): | |
65 | print "rt-tester.py <-c -h -q -t> <testfile>" | |
66 | print " -c display comments after first command" | |
67 | print " -h help" | |
68 | print " -q quiet mode" | |
69 | print " -t test mode (syntax check)" | |
70 | print " testfile: read test specification from testfile" | |
71 | print " otherwise from stdin" | |
72 | return | |
73 | ||
74 | # Print progress when not in quiet mode | |
75 | def progress(str): | |
76 | if not quiet: | |
77 | print str | |
78 | ||
79 | # Analyse a status value | |
80 | def analyse(val, top, arg): | |
81 | ||
82 | intval = int(val) | |
83 | ||
84 | if top[0] == "M": | |
85 | intval = intval / (10 ** int(arg)) | |
86 | intval = intval % 10 | |
87 | argval = top[2] | |
88 | elif top[0] == "O": | |
89 | argval = int(cmd_opcodes.get(arg, arg)) | |
90 | else: | |
91 | argval = int(arg) | |
92 | ||
93 | # progress("%d %s %d" %(intval, top[1], argval)) | |
94 | ||
95 | if top[1] == "eq" and intval == argval: | |
96 | return 1 | |
97 | if top[1] == "lt" and intval < argval: | |
98 | return 1 | |
99 | if top[1] == "gt" and intval > argval: | |
100 | return 1 | |
101 | return 0 | |
102 | ||
103 | # Parse the commandline | |
104 | try: | |
105 | (options, arguments) = getopt.getopt(sys.argv[1:],'chqt') | |
106 | except getopt.GetoptError, ex: | |
107 | usage() | |
108 | sys.exit(1) | |
109 | ||
110 | # Parse commandline options | |
111 | for option, value in options: | |
112 | if option == "-c": | |
113 | comments = 1 | |
114 | elif option == "-q": | |
115 | quiet = 1 | |
116 | elif option == "-t": | |
117 | test = 1 | |
118 | elif option == '-h': | |
119 | usage() | |
120 | sys.exit(0) | |
121 | ||
122 | # Select the input source | |
123 | if arguments: | |
124 | try: | |
125 | fd = open(arguments[0]) | |
126 | except Exception,ex: | |
127 | sys.stderr.write("File not found %s\n" %(arguments[0])) | |
128 | sys.exit(1) | |
129 | else: | |
130 | fd = sys.stdin | |
131 | ||
132 | linenr = 0 | |
133 | ||
134 | # Read the test patterns | |
135 | while 1: | |
136 | ||
137 | linenr = linenr + 1 | |
138 | line = fd.readline() | |
139 | if not len(line): | |
140 | break | |
141 | ||
142 | line = line.strip() | |
143 | parts = line.split(":") | |
144 | ||
145 | if not parts or len(parts) < 1: | |
146 | continue | |
147 | ||
148 | if len(parts[0]) == 0: | |
149 | continue | |
150 | ||
151 | if parts[0].startswith("#"): | |
152 | if comments > 1: | |
153 | progress(line) | |
154 | continue | |
155 | ||
156 | if comments == 1: | |
157 | comments = 2 | |
158 | ||
159 | progress(line) | |
160 | ||
161 | cmd = parts[0].strip().lower() | |
162 | opc = parts[1].strip().lower() | |
163 | tid = parts[2].strip() | |
164 | dat = parts[3].strip() | |
165 | ||
166 | try: | |
167 | # Test or wait for a status value | |
168 | if cmd == "t" or cmd == "w": | |
169 | testop = test_opcodes[opc] | |
170 | ||
171 | fname = "%s%s%s" %(sysfsprefix, tid, statusfile) | |
172 | if test: | |
173 | print fname | |
174 | continue | |
175 | ||
176 | while 1: | |
177 | query = 1 | |
178 | fsta = open(fname, 'r') | |
179 | status = fsta.readline().strip() | |
180 | fsta.close() | |
181 | stat = status.split(",") | |
182 | for s in stat: | |
183 | s = s.strip() | |
184 | if s.startswith(testop[0]): | |
185 | # Seperate status value | |
186 | val = s[2:].strip() | |
187 | query = analyse(val, testop, dat) | |
188 | break | |
189 | if query or cmd == "t": | |
190 | break | |
191 | ||
192 | progress(" " + status) | |
193 | ||
194 | if not query: | |
195 | sys.stderr.write("Test failed in line %d\n" %(linenr)) | |
196 | sys.exit(1) | |
197 | ||
198 | # Issue a command to the tester | |
199 | elif cmd == "c": | |
200 | cmdnr = cmd_opcodes[opc] | |
201 | # Build command string and sys filename | |
202 | cmdstr = "%s:%s" %(cmdnr, dat) | |
203 | fname = "%s%s%s" %(sysfsprefix, tid, commandfile) | |
204 | if test: | |
205 | print fname | |
206 | continue | |
207 | fcmd = open(fname, 'w') | |
208 | fcmd.write(cmdstr) | |
209 | fcmd.close() | |
210 | ||
211 | except Exception,ex: | |
212 | sys.stderr.write(str(ex)) | |
213 | sys.stderr.write("\nSyntax error in line %d\n" %(linenr)) | |
214 | if not test: | |
215 | fd.close() | |
216 | sys.exit(1) | |
217 | ||
218 | # Normal exit pass | |
219 | print "Pass" | |
220 | sys.exit(0) | |
221 | ||
222 |