^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) from __future__ import print_function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) import os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) import sys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) import glob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) import optparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) import tempfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) import logging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) import shutil
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) import configparser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) except ImportError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) import ConfigParser as configparser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) def data_equal(a, b):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) # Allow multiple values in assignment separated by '|'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) a_list = a.split('|')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) b_list = b.split('|')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) for a_item in a_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) for b_item in b_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (a_item == b_item):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) elif (a_item == '*') or (b_item == '*'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) class Fail(Exception):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) def __init__(self, test, msg):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) self.msg = msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) self.test = test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) def getMsg(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return '\'%s\' - %s' % (self.test.path, self.msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) class Notest(Exception):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) def __init__(self, test, arch):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) self.arch = arch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) self.test = test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) def getMsg(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return '[%s] \'%s\'' % (self.arch, self.test.path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) class Unsup(Exception):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) def __init__(self, test):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) self.test = test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) def getMsg(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return '\'%s\'' % self.test.path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) class Event(dict):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) terms = [
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 'cpu',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 'flags',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 'type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 'size',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 'config',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 'sample_period',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 'sample_type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 'read_format',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 'disabled',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 'inherit',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 'pinned',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 'exclusive',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 'exclude_user',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 'exclude_kernel',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 'exclude_hv',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 'exclude_idle',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 'mmap',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 'comm',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 'freq',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 'inherit_stat',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 'enable_on_exec',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 'task',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 'watermark',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 'precise_ip',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 'mmap_data',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 'sample_id_all',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 'exclude_host',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 'exclude_guest',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 'exclude_callchain_kernel',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 'exclude_callchain_user',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 'wakeup_events',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 'bp_type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 'config1',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 'config2',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 'branch_sample_type',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 'sample_regs_user',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 'sample_stack_user',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) def add(self, data):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) for key, val in data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) log.debug(" %s = %s" % (key, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) self[key] = val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) def __init__(self, name, data, base):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) log.debug(" Event %s" % name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) self.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) self.group = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) self.add(base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) self.add(data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) def equal(self, other):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) for t in Event.terms:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) log.debug(" [%s] %s %s" % (t, self[t], other[t]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if t not in self or t not in other:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if not data_equal(self[t], other[t]):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) def optional(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if 'optional' in self and self['optional'] == '1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) def diff(self, other):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for t in Event.terms:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if t not in self or t not in other:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if not data_equal(self[t], other[t]):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) log.warning("expected %s=%s, got %s" % (t, self[t], other[t]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) # Test file description needs to have following sections:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) # [config]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) # - just single instance in file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) # - needs to specify:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) # 'command' - perf command name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) # 'args' - special command arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) # 'ret' - expected command return value (0 by default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) # 'arch' - architecture specific test (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) # comma separated list, ! at the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) # negates it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) # [eventX:base]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) # - one or multiple instances in file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) # - expected values assignments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) class Test(object):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) def __init__(self, path, options):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) parser = configparser.SafeConfigParser()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) parser.read(path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) log.warning("running '%s'" % path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) self.path = path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) self.test_dir = options.test_dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) self.perf = options.perf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) self.command = parser.get('config', 'command')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) self.args = parser.get('config', 'args')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) self.ret = parser.get('config', 'ret')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) self.ret = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) self.arch = parser.get('config', 'arch')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) log.warning("test limitation '%s'" % self.arch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) self.arch = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) self.expect = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) self.result = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) log.debug(" loading expected events");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) self.load_events(path, self.expect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) def is_event(self, name):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if name.find("event") == -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) def skip_test(self, myarch):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) # If architecture not set always run test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if self.arch == '':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) # log.warning("test for arch %s is ok" % myarch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) # Allow multiple values in assignment separated by ','
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) arch_list = self.arch.split(',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) # Handle negated list such as !s390x,ppc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if arch_list[0][0] == '!':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) arch_list[0] = arch_list[0][1:]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) log.warning("excluded architecture list %s" % arch_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) for arch_item in arch_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) # log.warning("test for %s arch is %s" % (arch_item, myarch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if arch_item == myarch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) for arch_item in arch_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) # log.warning("test for architecture '%s' current '%s'" % (arch_item, myarch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if arch_item == myarch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) def load_events(self, path, events):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) parser_event = configparser.SafeConfigParser()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) parser_event.read(path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) # The event record section header contains 'event' word,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) # optionaly followed by ':' allowing to load 'parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) # event' first as a base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) for section in filter(self.is_event, parser_event.sections()):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) parser_items = parser_event.items(section);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) base_items = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) # Read parent event if there's any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (':' in section):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) base = section[section.index(':') + 1:]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) parser_base = configparser.SafeConfigParser()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) parser_base.read(self.test_dir + '/' + base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) base_items = parser_base.items('event')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) e = Event(section, parser_items, base_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) events[section] = e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) def run_cmd(self, tempdir):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) junk1, junk2, junk3, junk4, myarch = (os.uname())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if self.skip_test(myarch):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) raise Notest(self, myarch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) self.perf, self.command, tempdir, self.args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = os.WEXITSTATUS(os.system(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) log.info(" '%s' ret '%s', expected '%s'" % (cmd, str(ret), str(self.ret)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if not data_equal(str(ret), str(self.ret)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) raise Unsup(self)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) def compare(self, expect, result):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) match = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) log.debug(" compare");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) # For each expected event find all matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) # events in result. Fail if there's not any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for exp_name, exp_event in expect.items():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) exp_list = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) res_event = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) log.debug(" matching [%s]" % exp_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) for res_name, res_event in result.items():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) log.debug(" to [%s]" % res_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (exp_event.equal(res_event)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) exp_list.append(res_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) log.debug(" ->OK")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) log.debug(" ->FAIL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) log.debug(" match: [%s] matches %s" % (exp_name, str(exp_list)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) # we did not any matching event - fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if not exp_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if exp_event.optional():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) log.debug(" %s does not match, but is optional" % exp_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if not res_event:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) log.debug(" res_event is empty");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) exp_event.diff(res_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) raise Fail(self, 'match failure');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) match[exp_name] = exp_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) # For each defined group in the expected events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) # check we match the same group in the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) for exp_name, exp_event in expect.items():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) group = exp_event.group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (group == ''):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) for res_name in match[exp_name]:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) res_group = result[res_name].group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if res_group not in match[group]:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) raise Fail(self, 'group failure')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) log.debug(" group: [%s] matches group leader %s" %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (exp_name, str(match[group])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) log.debug(" matched")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) def resolve_groups(self, events):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for name, event in events.items():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) group_fd = event['group_fd'];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if group_fd == '-1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) for iname, ievent in events.items():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ievent['fd'] == group_fd):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) event.group = iname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) log.debug('[%s] has group leader [%s]' % (name, iname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) def run(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) tempdir = tempfile.mkdtemp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) # run the test script
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) self.run_cmd(tempdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) # load events expectation for the test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) log.debug(" loading result events");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) for f in glob.glob(tempdir + '/event*'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) self.load_events(f, self.result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) # resolve group_fd to event names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) self.resolve_groups(self.expect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) self.resolve_groups(self.result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) # do the expectation - results matching - both ways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) self.compare(self.expect, self.result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) self.compare(self.result, self.expect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) finally:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) # cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) shutil.rmtree(tempdir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) def run_tests(options):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) for f in glob.glob(options.test_dir + '/' + options.test):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) Test(f, options).run()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) except Unsup as obj:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) log.warning("unsupp %s" % obj.getMsg())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) except Notest as obj:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) log.warning("skipped %s" % obj.getMsg())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) def setup_log(verbose):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) global log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) level = logging.CRITICAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if verbose == 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) level = logging.WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if verbose == 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) level = logging.INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if verbose >= 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) level = logging.DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) log = logging.getLogger('test')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) log.setLevel(level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ch = logging.StreamHandler()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ch.setLevel(level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) formatter = logging.Formatter('%(message)s')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ch.setFormatter(formatter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) log.addHandler(ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) USAGE = '''%s [OPTIONS]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) -d dir # tests dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) -p path # perf binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) -t test # single test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) -v # verbose level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ''' % sys.argv[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) def main():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) parser = optparse.OptionParser(usage=USAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) parser.add_option("-t", "--test",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) action="store", type="string", dest="test")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) parser.add_option("-d", "--test-dir",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) action="store", type="string", dest="test_dir")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) parser.add_option("-p", "--perf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) action="store", type="string", dest="perf")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) parser.add_option("-v", "--verbose",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) default=0, action="count", dest="verbose")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) options, args = parser.parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if args:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) parser.error('FAILED wrong arguments %s' % ' '.join(args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) setup_log(options.verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if not options.test_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) print('FAILED no -d option specified')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) sys.exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if not options.test:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) options.test = 'test*'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) run_tests(options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) except Fail as obj:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) print("FAILED %s" % obj.getMsg())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) sys.exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) sys.exit(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if __name__ == '__main__':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) main()