1515import tempfile
1616from pathlib import Path
1717import shutil
18+ import traceback
1819
1920def check_docker ():
2021 docker_ps = smoketests .run_cmd ("docker" , "ps" , "--format=json" )
@@ -57,6 +58,15 @@ def _convert_select_pattern(pattern):
5758
5859
5960TESTPREFIX = "smoketests.tests."
61+
62+ def _iter_all_tests (suite_or_case ):
63+ """Yield all individual tests from possibly nested TestSuite structures."""
64+ if isinstance (suite_or_case , unittest .TestSuite ):
65+ for t in suite_or_case :
66+ yield from _iter_all_tests (t )
67+ else :
68+ yield suite_or_case
69+
6070def main ():
6171 tests = [fname .removesuffix (".py" ) for fname in os .listdir (TEST_DIR / "tests" ) if fname .endswith (".py" ) and fname != "__init__.py" ]
6272
@@ -79,6 +89,51 @@ def main():
7989 parser .add_argument ("--spacetime-login" , action = "store_true" , help = "Use `spacetime login` for these tests (and disable tests that don't work with that)" )
8090 args = parser .parse_args ()
8191
92+ if args .docker :
93+ # have docker logs print concurrently with the test output
94+ if args .compose_file :
95+ smoketests .COMPOSE_FILE = args .compose_file
96+ if not args .no_docker_logs :
97+ if args .compose_file :
98+ subprocess .Popen (["docker" , "compose" , "-f" , args .compose_file , "logs" , "-f" ])
99+ else :
100+ docker_container = check_docker ()
101+ subprocess .Popen (["docker" , "logs" , "-f" , docker_container ])
102+ smoketests .HAVE_DOCKER = True
103+
104+ if not args .skip_dotnet :
105+ smoketests .HAVE_DOTNET = check_dotnet ()
106+ if not smoketests .HAVE_DOTNET :
107+ print ("no suitable dotnet installation found" )
108+ exit (1 )
109+
110+ add_prefix = lambda testlist : [TESTPREFIX + test for test in testlist ]
111+ import fnmatch
112+ excludelist = add_prefix (args .exclude )
113+ testlist = add_prefix (args .test )
114+
115+ loader = ExclusionaryTestLoader (excludelist )
116+ loader .testNamePatterns = args .testNamePatterns
117+
118+ tests = loader .loadTestsFromNames (testlist )
119+ if args .list :
120+ failed_cls = getattr (unittest .loader , "_FailedTest" , None )
121+ any_failed = False
122+ for test in _iter_all_tests (tests ):
123+ name = test .id ()
124+ if isinstance (test , failed_cls ):
125+ any_failed = True
126+ print ('' )
127+ print ("Failed to construct %s:" % test .id ())
128+ exc = getattr (test , "_exception" , None )
129+ if exc is not None :
130+ tb = '' .join (traceback .format_exception (exc ))
131+ print (tb .rstrip ())
132+ print ('' )
133+ else :
134+ print (f"{ name } " )
135+ exit (1 if any_failed else 0 )
136+
82137 if not args .no_build_cli :
83138 logging .info ("Compiling spacetime cli..." )
84139 smoketests .run_cmd ("cargo" , "build" , cwd = TEST_DIR .parent , capture_stderr = False )
@@ -100,18 +155,6 @@ def main():
100155
101156 os .environ ["SPACETIME_SKIP_CLIPPY" ] = "1"
102157
103- if args .docker :
104- # have docker logs print concurrently with the test output
105- if args .compose_file :
106- smoketests .COMPOSE_FILE = args .compose_file
107- if not args .no_docker_logs :
108- if args .compose_file :
109- subprocess .Popen (["docker" , "compose" , "-f" , args .compose_file , "logs" , "-f" ])
110- else :
111- docker_container = check_docker ()
112- subprocess .Popen (["docker" , "logs" , "-f" , docker_container ])
113- smoketests .HAVE_DOCKER = True
114-
115158 with tempfile .NamedTemporaryFile (mode = "w+b" , suffix = ".toml" , buffering = 0 , delete_on_close = False ) as config_file :
116159 with BASE_STDB_CONFIG_PATH .open ("rb" ) as src , config_file .file as dst :
117160 shutil .copyfileobj (src , dst )
@@ -130,28 +173,6 @@ def main():
130173 smoketests .STDB_CONFIG = Path (config_file .name ).read_text ()
131174
132175 build_template_target ()
133-
134- if not args .skip_dotnet :
135- smoketests .HAVE_DOTNET = check_dotnet ()
136- if not smoketests .HAVE_DOTNET :
137- print ("no suitable dotnet installation found" )
138- exit (1 )
139-
140- add_prefix = lambda testlist : [TESTPREFIX + test for test in testlist ]
141- import fnmatch
142- excludelist = add_prefix (args .exclude )
143- testlist = add_prefix (args .test )
144-
145- loader = ExclusionaryTestLoader (excludelist )
146- loader .testNamePatterns = args .testNamePatterns
147-
148- tests = loader .loadTestsFromNames (testlist )
149- if args .list :
150- print ("Selected tests:\n " )
151- for test in itertools .chain (* itertools .chain (* tests )):
152- print (f"{ test } " )
153- exit (0 )
154-
155176 buffer = not args .show_all_output
156177 verbosity = 2
157178
0 commit comments