| Thomas Gleixner | 61a8712 | 2006-06-27 02:54:56 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python | 
|  | 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 |  |