@@ -24,140 +24,6 @@ def abort_now():
2424 else :
2525 os .kill (0 , 9 )
2626
27- ###
28- # Test Execution Implementation
29-
30- class LockedValue (object ):
31- def __init__ (self , value ):
32- self .lock = threading .Lock ()
33- self ._value = value
34-
35- def _get_value (self ):
36- self .lock .acquire ()
37- try :
38- return self ._value
39- finally :
40- self .lock .release ()
41-
42- def _set_value (self , value ):
43- self .lock .acquire ()
44- try :
45- self ._value = value
46- finally :
47- self .lock .release ()
48-
49- value = property (_get_value , _set_value )
50-
51- class TestProvider (object ):
52- def __init__ (self , queue_impl , canceled_flag ):
53- self .canceled_flag = canceled_flag
54-
55- # Create a shared queue to provide the test indices.
56- self .queue = queue_impl ()
57-
58- def queue_tests (self , tests , num_jobs ):
59- for i in range (len (tests )):
60- self .queue .put (i )
61- for i in range (num_jobs ):
62- self .queue .put (None )
63-
64- def cancel (self ):
65- self .canceled_flag .value = 1
66-
67- def get (self ):
68- # Check if we are canceled.
69- if self .canceled_flag .value :
70- return None
71-
72- # Otherwise take the next test.
73- return self .queue .get ()
74-
75- class Tester (object ):
76- def __init__ (self , run_instance , provider , consumer ):
77- self .run_instance = run_instance
78- self .provider = provider
79- self .consumer = consumer
80-
81- def run (self ):
82- while True :
83- item = self .provider .get ()
84- if item is None :
85- break
86- self .run_test (item )
87- self .consumer .task_finished ()
88-
89- def run_test (self , test_index ):
90- test = self .run_instance .tests [test_index ]
91- try :
92- execute_test (test , self .run_instance .lit_config ,
93- self .run_instance .parallelism_semaphores )
94- except KeyboardInterrupt :
95- # This is a sad hack. Unfortunately subprocess goes
96- # bonkers with ctrl-c and we start forking merrily.
97- print ('\n Ctrl-C detected, goodbye.' )
98- abort_now ()
99- self .consumer .update (test_index , test )
100-
101- class ThreadResultsConsumer (object ):
102- def __init__ (self , display ):
103- self .display = display
104- self .lock = threading .Lock ()
105-
106- def update (self , test_index , test ):
107- self .lock .acquire ()
108- try :
109- self .display .update (test )
110- finally :
111- self .lock .release ()
112-
113- def task_finished (self ):
114- pass
115-
116- def handle_results (self ):
117- pass
118-
119- class MultiprocessResultsConsumer (object ):
120- def __init__ (self , run , display , num_jobs ):
121- self .run = run
122- self .display = display
123- self .num_jobs = num_jobs
124- self .queue = multiprocessing .Queue ()
125-
126- def update (self , test_index , test ):
127- # This method is called in the child processes, and communicates the
128- # results to the actual display implementation via an output queue.
129- self .queue .put ((test_index , test .result ))
130-
131- def task_finished (self ):
132- # This method is called in the child processes, and communicates that
133- # individual tasks are complete.
134- self .queue .put (None )
135-
136- def handle_results (self ):
137- # This method is called in the parent, and consumes the results from the
138- # output queue and dispatches to the actual display. The method will
139- # complete after each of num_jobs tasks has signalled completion.
140- completed = 0
141- while completed != self .num_jobs :
142- # Wait for a result item.
143- item = self .queue .get ()
144- if item is None :
145- completed += 1
146- continue
147-
148- # Update the test result in the parent process.
149- index ,result = item
150- test = self .run .tests [index ]
151- test .result = result
152-
153- self .display .update (test )
154-
155- def run_one_tester (run , provider , display ):
156- tester = Tester (run , provider , display )
157- tester .run ()
158-
159- ###
160-
16127class _Display (object ):
16228 def __init__ (self , display , provider , maxFailures ):
16329 self .display = display
@@ -170,47 +36,6 @@ def update(self, test):
17036 if self .failedCount == self .maxFailures :
17137 self .provider .cancel ()
17238
173- def handleFailures (provider , consumer , maxFailures ):
174- consumer .display = _Display (consumer .display , provider , maxFailures )
175-
176- def execute_test (test , lit_config , parallelism_semaphores ):
177- """Execute one test"""
178- pg = test .config .parallelism_group
179- if callable (pg ):
180- pg = pg (test )
181-
182- result = None
183- semaphore = None
184- try :
185- if pg :
186- semaphore = parallelism_semaphores [pg ]
187- if semaphore :
188- semaphore .acquire ()
189- start_time = time .time ()
190- result = test .config .test_format .execute (test , lit_config )
191- # Support deprecated result from execute() which returned the result
192- # code and additional output as a tuple.
193- if isinstance (result , tuple ):
194- code , output = result
195- result = lit .Test .Result (code , output )
196- elif not isinstance (result , lit .Test .Result ):
197- raise ValueError ("unexpected result from test execution" )
198- result .elapsed = time .time () - start_time
199- except KeyboardInterrupt :
200- raise
201- except :
202- if lit_config .debug :
203- raise
204- output = 'Exception during script execution:\n '
205- output += traceback .format_exc ()
206- output += '\n '
207- result = lit .Test .Result (lit .Test .UNRESOLVED , output )
208- finally :
209- if semaphore :
210- semaphore .release ()
211-
212- test .setResult (result )
213-
21439class Run (object ):
21540 """
21641 This class represents a concrete, configured testing run.
@@ -221,7 +46,8 @@ def __init__(self, lit_config, tests):
22146 self .tests = tests
22247
22348 def execute_test (self , test ):
224- return execute_test (test , self .lit_config , self .parallelism_semaphores )
49+ return _execute_test_impl (test , self .lit_config ,
50+ self .parallelism_semaphores )
22551
22652 def execute_tests (self , display , jobs , max_time = None ):
22753 """
@@ -350,6 +176,44 @@ def consume_test_result(self, pool_result):
350176 self .failure_count == self .lit_config .maxFailures :
351177 self .hit_max_failures = True
352178
179+ def _execute_test_impl (test , lit_config , parallelism_semaphores ):
180+ """Execute one test"""
181+ pg = test .config .parallelism_group
182+ if callable (pg ):
183+ pg = pg (test )
184+
185+ result = None
186+ semaphore = None
187+ try :
188+ if pg :
189+ semaphore = parallelism_semaphores [pg ]
190+ if semaphore :
191+ semaphore .acquire ()
192+ start_time = time .time ()
193+ result = test .config .test_format .execute (test , lit_config )
194+ # Support deprecated result from execute() which returned the result
195+ # code and additional output as a tuple.
196+ if isinstance (result , tuple ):
197+ code , output = result
198+ result = lit .Test .Result (code , output )
199+ elif not isinstance (result , lit .Test .Result ):
200+ raise ValueError ("unexpected result from test execution" )
201+ result .elapsed = time .time () - start_time
202+ except KeyboardInterrupt :
203+ raise
204+ except :
205+ if lit_config .debug :
206+ raise
207+ output = 'Exception during script execution:\n '
208+ output += traceback .format_exc ()
209+ output += '\n '
210+ result = lit .Test .Result (lit .Test .UNRESOLVED , output )
211+ finally :
212+ if semaphore :
213+ semaphore .release ()
214+
215+ test .setResult (result )
216+
353217child_lit_config = None
354218child_parallelism_semaphores = None
355219
@@ -375,7 +239,7 @@ def worker_run_one_test(test_index, test):
375239 the display.
376240 """
377241 try :
378- execute_test (test , child_lit_config , child_parallelism_semaphores )
242+ _execute_test_impl (test , child_lit_config , child_parallelism_semaphores )
379243 return (test_index , test )
380244 except KeyboardInterrupt as e :
381245 # If a worker process gets an interrupt, abort it immediately.
0 commit comments