mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-19 19:07:48 +02:00
SetFontPixel refused to write any pixel whose x fell outside bytesPerLine, so a glyph drawn into a buffer with a bytesPerLine narrower than its rows came out mostly blank. The hardware doesn't bound it that way - it works out an address and writes, so the rows overlap and the glyph smears across them. The declared bufWidth and bufHeight, plus the address check, are what keep it in bounds. Cache invalidation now covers the wider of bytesPerLine * bufHeight and where the last row actually ends, since those are no longer the same thing when the rows overlap. Fixes font/charglyphimage and font/charglyphimageclip, moved from tests_next to tests_good. The other font tests are unaffected, so whatever ails them is something else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JvJR8oJNSCimCM9KXVLjfq
608 lines
16 KiB
Python
Executable File
608 lines
16 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Automated script to run the pspautotests test suite in PPSSPP.
|
|
|
|
import sys
|
|
import os
|
|
import subprocess
|
|
import threading
|
|
import glob
|
|
|
|
|
|
PPSSPP_EXECUTABLES = [
|
|
# Windows
|
|
"Windows\\Debug\\PPSSPPHeadless.exe",
|
|
"Windows\\Release\\PPSSPPHeadless.exe",
|
|
"Windows\\x64\\Debug\\PPSSPPHeadless.exe",
|
|
"Windows\\x64\\Release\\PPSSPPHeadless.exe",
|
|
"build*/PPSSPPHeadless.exe",
|
|
"./PPSSPPHeadless.exe",
|
|
# Mac
|
|
"build*/Debug/PPSSPPHeadless",
|
|
"build*/Release/PPSSPPHeadless",
|
|
"build*/RelWithDebInfo/PPSSPPHeadless",
|
|
"build*/MinSizeRel/PPSSPPHeadless",
|
|
# Linux
|
|
"build*/PPSSPPHeadless",
|
|
"./PPSSPPHeadless",
|
|
# CI
|
|
"ppsspp/PPSSPPHeadless",
|
|
"ppsspp\\PPSSPPHeadless.exe",
|
|
]
|
|
|
|
PPSSPP_EXE = None
|
|
TEST_ROOT = "pspautotests/tests/"
|
|
TIMEOUT = 5
|
|
|
|
class Command(object):
|
|
def __init__(self, cmd, data = None):
|
|
self.cmd = cmd
|
|
self.data = data
|
|
self.process = None
|
|
self.output = None
|
|
self.timeout = False
|
|
|
|
def run(self, timeout):
|
|
def target():
|
|
self.process = subprocess.Popen(self.cmd, stdin=subprocess.PIPE, stdout=sys.stdout, stderr=subprocess.STDOUT)
|
|
self.process.stdin.write(self.data.encode('utf-8'))
|
|
self.process.stdin.close()
|
|
self.process.communicate()
|
|
|
|
thread = threading.Thread(target=target)
|
|
thread.start()
|
|
|
|
thread.join(timeout)
|
|
if thread.is_alive():
|
|
self.timeout = True
|
|
if sys.version_info < (2, 6):
|
|
os.kill(self.process.pid, signal.SIGKILL)
|
|
else:
|
|
self.process.terminate()
|
|
thread.join()
|
|
|
|
return self.process.returncode
|
|
|
|
# Test names are the C files without the .c extension.
|
|
# These have worked and should keep working always - regression tests.
|
|
# -g flag runs these.
|
|
tests_good = [
|
|
"cpu/cpu_alu/cpu_alu",
|
|
"cpu/cpu_alu/cpu_branch",
|
|
"cpu/cpu_alu/cpu_branch2",
|
|
"cpu/vfpu/colors",
|
|
"cpu/vfpu/convert",
|
|
"cpu/vfpu/gum",
|
|
"cpu/vfpu/matrix",
|
|
"cpu/vfpu/vavg",
|
|
"cpu/icache/icache",
|
|
"cpu/lsu/lsu",
|
|
"cpu/fpu/fpu",
|
|
|
|
"audio/atrac/addstreamdata",
|
|
"audio/atrac/atractest",
|
|
"audio/atrac/decode",
|
|
"audio/atrac/getremainframe",
|
|
"audio/atrac/getsoundsample",
|
|
"audio/atrac/ids",
|
|
"audio/atrac/resetpos",
|
|
"audio/atrac/resetting",
|
|
"audio/atrac/replay",
|
|
"audio/atrac/stream",
|
|
"audio/atrac/reset2",
|
|
"audio/atrac/second/resetting",
|
|
"audio/atrac/second/getinfo",
|
|
"audio/atrac/second/needed",
|
|
"audio/atrac/second/setbuffer",
|
|
"audio/atrac/setdata",
|
|
"audio/atrac/sas",
|
|
"audio/mp3/checkneeded",
|
|
"audio/mp3/getbitrate",
|
|
"audio/mp3/getchannel",
|
|
"audio/mp3/getframenum",
|
|
"audio/mp3/getloopnum",
|
|
"audio/mp3/getmaxoutput",
|
|
"audio/mp3/getmpegversion",
|
|
"audio/mp3/getsamplerate",
|
|
"audio/mp3/getsumdecoded",
|
|
"audio/mp3/initresource",
|
|
"audio/mp3/mp3test",
|
|
"audio/mp3/release",
|
|
"audio/mp3/reserve",
|
|
"audio/mp3/setloopnum",
|
|
"audio/output2/changelength",
|
|
"audio/output2/reserve",
|
|
"audio/output2/threads",
|
|
"audio/reverb/basic",
|
|
"audio/reverb/volume",
|
|
"audio/sascore/sascore",
|
|
"audio/sascore/adsrcurve",
|
|
"audio/sascore/getheight",
|
|
"audio/sascore/keyoff",
|
|
"audio/sascore/keyon",
|
|
"audio/sascore/noise",
|
|
"audio/sascore/outputmode",
|
|
"audio/sascore/pause",
|
|
"audio/sascore/pcm",
|
|
"audio/sascore/pitch",
|
|
"audio/sascore/vag",
|
|
"ctrl/ctrl",
|
|
"ctrl/idle/idle",
|
|
"ctrl/sampling/sampling",
|
|
"ctrl/sampling2/sampling2",
|
|
"ctrl/vblank",
|
|
"display/display",
|
|
"display/vblankmulti",
|
|
"display/isstate",
|
|
"display/setframebuf",
|
|
"display/setmode",
|
|
"dmac/dmactest",
|
|
"font/altcharcode",
|
|
"font/charglyphimage",
|
|
"font/charglyphimageclip",
|
|
"font/charimagerect",
|
|
"font/find",
|
|
"font/fontinfo",
|
|
"font/fontinfobyindex",
|
|
"font/fontlist",
|
|
"font/optimum",
|
|
"font/resolution",
|
|
"font/shadowimagerect",
|
|
"gpu/bounding/count",
|
|
"gpu/bounding/planes",
|
|
"gpu/bounding/vertexaddr",
|
|
"gpu/bounding/viewport",
|
|
"gpu/callbacks/ge_callbacks",
|
|
"gpu/clipping/homogeneous",
|
|
"gpu/clut/address",
|
|
"gpu/clut/masks",
|
|
"gpu/clut/offset",
|
|
"gpu/clut/shifts",
|
|
"gpu/commands/basic",
|
|
"gpu/commands/blend",
|
|
"gpu/commands/blend565",
|
|
"gpu/commands/blocktransfer",
|
|
"gpu/commands/cull",
|
|
"gpu/commands/fog",
|
|
"gpu/commands/material",
|
|
"gpu/complex/complex",
|
|
"gpu/displaylist/alignment",
|
|
"gpu/dither/dither",
|
|
"gpu/filtering/mipmaplinear",
|
|
"gpu/ge/break",
|
|
"gpu/ge/context",
|
|
"gpu/ge/edram",
|
|
"gpu/ge/enqueueparam",
|
|
"gpu/ge/queue",
|
|
"gpu/primitives/indices",
|
|
"gpu/primitives/invalidprim",
|
|
"gpu/primitives/points",
|
|
"gpu/primitives/rectangles",
|
|
"gpu/primitives/trianglefan",
|
|
"gpu/primitives/trianglestrip",
|
|
"gpu/primitives/triangles",
|
|
"gpu/rendertarget/copy",
|
|
"gpu/rendertarget/depal",
|
|
"gpu/signals/pause",
|
|
"gpu/signals/pause2",
|
|
"gpu/signals/suspend",
|
|
"gpu/signals/sync",
|
|
"gpu/texcolors/dxt1",
|
|
"gpu/texcolors/dxt3",
|
|
"gpu/texcolors/dxt5",
|
|
"gpu/texcolors/rgb565",
|
|
"gpu/texcolors/rgba4444",
|
|
"gpu/texcolors/rgba5551",
|
|
"gpu/texfunc/add",
|
|
"gpu/texfunc/blend",
|
|
"gpu/texfunc/decal",
|
|
"gpu/texfunc/modulate",
|
|
"gpu/texfunc/replace",
|
|
"gpu/textures/mipmap",
|
|
"gpu/textures/rotate",
|
|
"gpu/transfer/invalid",
|
|
"gpu/transfer/mirrors",
|
|
"gpu/transfer/overlap",
|
|
"gpu/vertices/colors",
|
|
"gpu/vertices/morph",
|
|
# "gpu/vertices/texcoords", # See issue #19093
|
|
"hash/hash",
|
|
"hle/check_not_used_uids",
|
|
"intr/intr",
|
|
"intr/enablesub",
|
|
"intr/suspended",
|
|
"intr/vblank/vblank",
|
|
"io/cwd/cwd",
|
|
"io/file/rename",
|
|
"io/directory/directory",
|
|
"io/open/badparent",
|
|
"jpeg/create",
|
|
"jpeg/delete",
|
|
"jpeg/finish",
|
|
"jpeg/init",
|
|
"loader/bss/bss",
|
|
"malloc/malloc",
|
|
"misc/dcache",
|
|
"misc/deadbeef",
|
|
"misc/libc",
|
|
"misc/sdkver",
|
|
"misc/testgp",
|
|
"misc/timeconv",
|
|
"misc/reg",
|
|
"mstick/mstick",
|
|
"power/cpu",
|
|
"power/power",
|
|
"power/volatile/lock",
|
|
"power/volatile/trylock",
|
|
"power/volatile/unlock",
|
|
"rtc/rtc",
|
|
"rtc/arithmetic",
|
|
"rtc/lookup",
|
|
"rtc/convert",
|
|
"string/string",
|
|
"sysmem/freesize",
|
|
"sysmem/memblock",
|
|
"sysmem/sysmem",
|
|
"sysmem/volatile",
|
|
"threads/alarm/alarm",
|
|
"threads/alarm/cancel/cancel",
|
|
"threads/alarm/refer/refer",
|
|
"threads/alarm/set/set",
|
|
"threads/callbacks/callbacks",
|
|
"threads/callbacks/check",
|
|
"threads/callbacks/create",
|
|
"threads/callbacks/delete",
|
|
"threads/callbacks/exit",
|
|
"threads/callbacks/refer",
|
|
"threads/events/events",
|
|
"threads/events/cancel/cancel",
|
|
"threads/events/clear/clear",
|
|
"threads/events/create/create",
|
|
"threads/events/delete/delete",
|
|
"threads/events/poll/poll",
|
|
"threads/events/refer/refer",
|
|
"threads/events/set/set",
|
|
"threads/events/wait/wait",
|
|
"threads/fpl/fpl",
|
|
"threads/fpl/allocate",
|
|
"threads/fpl/cancel",
|
|
"threads/fpl/create",
|
|
"threads/fpl/delete",
|
|
"threads/fpl/free",
|
|
"threads/fpl/priority",
|
|
"threads/fpl/refer",
|
|
"threads/fpl/tryallocate",
|
|
"threads/k0/k0",
|
|
"threads/lwmutex/create",
|
|
"threads/lwmutex/delete",
|
|
"threads/lwmutex/lock",
|
|
"threads/lwmutex/priority",
|
|
"threads/lwmutex/refer",
|
|
"threads/lwmutex/try",
|
|
"threads/lwmutex/try600",
|
|
"threads/lwmutex/unlock",
|
|
"threads/mbx/mbx",
|
|
"threads/mbx/cancel/cancel",
|
|
"threads/mbx/create/create",
|
|
"threads/mbx/delete/delete",
|
|
"threads/mbx/poll/poll",
|
|
"threads/mbx/priority/priority",
|
|
"threads/mbx/receive/receive",
|
|
"threads/mbx/refer/refer",
|
|
"threads/mbx/send/send",
|
|
"threads/msgpipe/msgpipe",
|
|
"threads/msgpipe/cancel",
|
|
"threads/msgpipe/create",
|
|
"threads/msgpipe/data",
|
|
"threads/msgpipe/delete",
|
|
"threads/msgpipe/receive",
|
|
"threads/msgpipe/refer",
|
|
"threads/msgpipe/send",
|
|
"threads/msgpipe/tryreceive",
|
|
"threads/msgpipe/trysend",
|
|
"threads/mutex/cancel",
|
|
"threads/mutex/create",
|
|
"threads/mutex/delete",
|
|
"threads/mutex/lock",
|
|
"threads/mutex/mutex",
|
|
"threads/mutex/priority",
|
|
"threads/mutex/refer",
|
|
"threads/mutex/try",
|
|
"threads/mutex/unlock",
|
|
"threads/mutex/unlock2",
|
|
"threads/semaphores/semaphores",
|
|
"threads/semaphores/cancel",
|
|
"threads/semaphores/create",
|
|
"threads/semaphores/delete",
|
|
"threads/semaphores/fifo",
|
|
"threads/semaphores/poll",
|
|
"threads/semaphores/priority",
|
|
"threads/semaphores/refer",
|
|
"threads/semaphores/signal",
|
|
"threads/semaphores/wait",
|
|
"threads/threads/change",
|
|
"threads/threads/exitstatus",
|
|
"threads/threads/extend",
|
|
"threads/threads/refer",
|
|
"threads/threads/release",
|
|
"threads/threads/rotate",
|
|
"threads/threads/stackfree",
|
|
"threads/threads/start",
|
|
"threads/threads/suspend",
|
|
"threads/threads/threadend",
|
|
"threads/threads/threadmanidlist",
|
|
"threads/threads/threadmanidtype",
|
|
"threads/threads/threads",
|
|
"threads/tls/create",
|
|
"threads/tls/delete",
|
|
"threads/tls/get",
|
|
"threads/tls/free",
|
|
"threads/tls/priority",
|
|
"threads/tls/refer",
|
|
"threads/vpl/allocate",
|
|
"threads/vpl/cancel",
|
|
"threads/vpl/delete",
|
|
"threads/vpl/fifo",
|
|
"threads/vpl/free",
|
|
"threads/vpl/order",
|
|
"threads/vpl/priority",
|
|
"threads/vpl/refer",
|
|
"threads/vpl/try",
|
|
"threads/vpl/vpl",
|
|
"threads/vtimers/vtimer",
|
|
"threads/vtimers/cancelhandler",
|
|
"threads/vtimers/create",
|
|
"threads/vtimers/delete",
|
|
"threads/vtimers/getbase",
|
|
"threads/vtimers/gettime",
|
|
"threads/vtimers/interrupt",
|
|
"threads/vtimers/refer",
|
|
"threads/vtimers/sethandler",
|
|
"threads/vtimers/settime",
|
|
"threads/vtimers/start",
|
|
"threads/vtimers/stop",
|
|
"threads/wakeup/wakeup",
|
|
"utility/msgdialog/abort",
|
|
"utility/savedata/autosave",
|
|
"utility/savedata/filelist",
|
|
"utility/savedata/makedata",
|
|
"utility/systemparam/systemparam",
|
|
"umd/callbacks/umd",
|
|
"umd/register",
|
|
"video/mpeg/ringbuffer/avail",
|
|
"video/mpeg/ringbuffer/construct",
|
|
"video/mpeg/ringbuffer/destruct",
|
|
"video/mpeg/ringbuffer/memsize",
|
|
"video/mpeg/ringbuffer/packnum",
|
|
"video/psmfplayer/break",
|
|
"video/psmfplayer/create",
|
|
"video/psmfplayer/delete",
|
|
"video/psmfplayer/getaudiodata",
|
|
"video/psmfplayer/getaudiooutsize",
|
|
"video/psmfplayer/getcurrentpts",
|
|
"video/psmfplayer/getcurrentstatus",
|
|
"video/psmfplayer/getcurrentstream",
|
|
"video/psmfplayer/getpsmfinfo",
|
|
"video/psmfplayer/releasepsmf",
|
|
"video/psmfplayer/selectspecific",
|
|
"video/psmfplayer/setpsmf",
|
|
"video/psmfplayer/settempbuf",
|
|
"video/psmfplayer/stop",
|
|
]
|
|
|
|
# Broken tests
|
|
# -b flag runs these.
|
|
tests_next = [
|
|
# These are the next tests up for fixing. These run by default.
|
|
"cpu/fpu/fcr",
|
|
"cpu/vfpu/prefixes",
|
|
"cpu/vfpu/vector",
|
|
"cpu/vfpu/vregs",
|
|
"audio/sceaudio/datalen",
|
|
"audio/sceaudio/output",
|
|
"audio/sceaudio/reserve",
|
|
"audio/sascore/setadsr",
|
|
"audio/mp3/infotoadd",
|
|
"audio/mp3/init",
|
|
"audio/mp3/notifyadd",
|
|
"audio/output2/frequency",
|
|
"audio/output2/release",
|
|
"audio/output2/rest",
|
|
"ccc/convertstring",
|
|
"display/hcount",
|
|
"font/fonttest",
|
|
"font/charinfo",
|
|
"font/newlib",
|
|
"font/open",
|
|
"font/openfile",
|
|
"font/openmem",
|
|
"font/shadowglyphimage",
|
|
"font/shadowglyphimageclip",
|
|
"font/shadowinfo",
|
|
"gpu/clipping/guardband",
|
|
"gpu/commands/light",
|
|
"gpu/depth/precision",
|
|
"gpu/displaylist/state",
|
|
"gpu/filtering/linear",
|
|
"gpu/filtering/nearest",
|
|
"gpu/filtering/precisionlinear2d",
|
|
"gpu/filtering/precisionlinear3d",
|
|
"gpu/filtering/precisionnearest2d",
|
|
"gpu/filtering/precisionnearest3d",
|
|
"gpu/ge/edramswizzle",
|
|
"gpu/ge/get",
|
|
"gpu/primitives/bezier",
|
|
"gpu/primitives/continue",
|
|
"gpu/primitives/immediate",
|
|
"gpu/primitives/lines",
|
|
"gpu/primitives/linestrip",
|
|
"gpu/primitives/spline",
|
|
"gpu/reflection/reflection",
|
|
"gpu/rendertarget/rendertarget",
|
|
"gpu/signals/continue",
|
|
"gpu/signals/jumps",
|
|
"gpu/signals/simple",
|
|
"gpu/simple/simple",
|
|
"gpu/texmtx/normals",
|
|
"gpu/texmtx/prims",
|
|
"gpu/texmtx/source",
|
|
"gpu/texmtx/uvs",
|
|
"gpu/textures/size",
|
|
"gpu/triangle/triangle",
|
|
"intr/registersub",
|
|
"intr/releasesub",
|
|
"intr/waits",
|
|
"io/file/file",
|
|
"io/io/io",
|
|
"io/iodrv/iodrv",
|
|
"io/open/tty0",
|
|
"jpeg/csc",
|
|
"jpeg/decode",
|
|
"jpeg/decodes",
|
|
"jpeg/decodeycbcr",
|
|
"jpeg/decodeycbcrs",
|
|
"jpeg/getoutputinfo",
|
|
"jpeg/mjpegcsc",
|
|
# Doesn't work on a PSP for security reasons, hangs in PPSSPP currently.
|
|
# Commented out to make tests run much faster.
|
|
#"modules/loadexec/loader",
|
|
"net/http/http",
|
|
"net/primary/ether",
|
|
"power/freq",
|
|
"sysmem/partition",
|
|
"threads/callbacks/cancel",
|
|
"threads/callbacks/count",
|
|
"threads/callbacks/notify",
|
|
# These two mbx tests only appeared to work because they papered over bugs
|
|
|
|
|
|
"threads/scheduling/dispatch",
|
|
"threads/scheduling/scheduling",
|
|
"threads/threads/create",
|
|
"threads/threads/terminate",
|
|
"threads/vpl/create",
|
|
"umd/io/umd_io",
|
|
"umd/raw_access/raw_access",
|
|
"umd/wait/wait",
|
|
"utility/msgdialog/dialog",
|
|
"utility/savedata/getsize",
|
|
"utility/savedata/idlist",
|
|
# These tests appear to be broken and just hang.
|
|
#"utility/savedata/deletebroken",
|
|
#"utility/savedata/deletedata",
|
|
#"utility/savedata/deleteemptyfilename",
|
|
#"utility/savedata/loadbroken",
|
|
#"utility/savedata/loaddata",
|
|
#"utility/savedata/loademptyfilename",
|
|
#"utility/savedata/saveemptyfilename",
|
|
"utility/savedata/secureversion",
|
|
"utility/savedata/sizes",
|
|
"video/mpeg/basic",
|
|
"video/pmf/pmf",
|
|
"video/pmf_simple/pmf_simple",
|
|
"video/psmfplayer/basic",
|
|
"video/psmfplayer/configplayer",
|
|
"video/psmfplayer/getvideodata",
|
|
"video/psmfplayer/playmode",
|
|
"video/psmfplayer/selectstream",
|
|
"video/psmfplayer/setpsmfoffset",
|
|
"video/psmfplayer/start",
|
|
"video/psmfplayer/update",
|
|
]
|
|
|
|
|
|
# These are the tests we ignore (not important, or impossible to run)
|
|
tests_ignored = [
|
|
"kirk/kirk",
|
|
"me/me",
|
|
]
|
|
|
|
|
|
|
|
def init():
|
|
global PPSSPP_EXE, TEST_ROOT
|
|
if not os.path.exists("pspautotests"):
|
|
if os.path.exists(os.path.dirname(__file__) + "/pspautotests"):
|
|
TEST_ROOT = os.path.dirname(__file__) + "/pspautotests/tests/";
|
|
else:
|
|
print("Please run git submodule init; git submodule update;")
|
|
sys.exit(1)
|
|
|
|
if not os.path.exists(TEST_ROOT + "cpu/cpu_alu/cpu_alu.prx"):
|
|
print("Please install the pspsdk and run make in common/ and in all the tests")
|
|
print("(checked for existence of cpu/cpu_alu/cpu_alu.prx)")
|
|
sys.exit(1)
|
|
|
|
possible_exes = [glob.glob(f) for f in PPSSPP_EXECUTABLES]
|
|
possible_exes = [x for sublist in possible_exes for x in sublist]
|
|
existing = filter(os.path.exists, possible_exes)
|
|
if existing:
|
|
PPSSPP_EXE = max((os.path.getmtime(f), f) for f in existing)[1]
|
|
else:
|
|
PPSSPP_EXE = None
|
|
|
|
if not PPSSPP_EXE:
|
|
print("PPSSPPHeadless executable missing, please build one.")
|
|
sys.exit(1)
|
|
|
|
def run_tests(test_list, args):
|
|
global PPSSPP_EXE, TIMEOUT
|
|
returncode = 0
|
|
|
|
test_filenames = []
|
|
for test in test_list:
|
|
# Try prx first
|
|
elf_filename = TEST_ROOT + test + ".prx"
|
|
if not os.path.exists(elf_filename):
|
|
print("WARNING: no prx, trying elf")
|
|
elf_filename = TEST_ROOT + test + ".elf"
|
|
|
|
test_filenames.append(elf_filename)
|
|
|
|
if len(test_filenames):
|
|
# TODO: Maybe --compare should detect --graphics?
|
|
cmdline = [PPSSPP_EXE, '--root', TEST_ROOT + '../', '--compare', '--timeout=' + str(TIMEOUT), '@-']
|
|
cmdline.extend([i for i in args if i not in ['-g', '-m', '-b']])
|
|
|
|
c = Command(cmdline, '\n'.join(test_filenames))
|
|
returncode = c.run(TIMEOUT * len(test_filenames))
|
|
|
|
print("Ran " + ' '.join(cmdline))
|
|
|
|
return returncode
|
|
|
|
def main():
|
|
init()
|
|
tests = []
|
|
args = []
|
|
teamcity = False
|
|
for arg in sys.argv[1:]:
|
|
if arg == '--teamcity':
|
|
args.append(arg)
|
|
teamcity = True
|
|
elif arg[0] == '-':
|
|
args.append(arg)
|
|
else:
|
|
tests.append(arg)
|
|
|
|
if not tests:
|
|
if '-g' in args:
|
|
tests = tests_good
|
|
elif '-b' in args:
|
|
tests = tests_next
|
|
else:
|
|
tests = tests_next + tests_good
|
|
elif '-m' in args and '-g' in args:
|
|
tests = [i for i in tests_good if i.startswith(tests[0])]
|
|
elif '-m' in args and '-b' in args:
|
|
tests = [i for i in tests_next if i.startswith(tests[0])]
|
|
elif '-m' in args:
|
|
tests = [i for i in tests_next + tests_good if i.startswith(tests[0])]
|
|
|
|
returncode = run_tests(tests, args)
|
|
if teamcity:
|
|
return 0
|
|
return returncode
|
|
|
|
exit(main())
|