mesa_test 2.0.0.rc1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/mesa_test +87 -68
- data/lib/mesa_test.rb +145 -158
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 539c96d3328d28340abaac30b503be321ee9a79742a0efa3fce3e03889c7762c
|
|
4
|
+
data.tar.gz: 885b08d2985ecf74db5d5c492d5a47022e75b58986fb5bb1037b9e6d1126e9a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a6f3271653eb9b93dfa096ae1dfcd226726db72fce4fe5ebfac4acfd860a7a4b5293fedad15cdb85dc8399e7c781477b0290828f123fe42e86d02cbe4f89c0d
|
|
7
|
+
data.tar.gz: c0796ba4b2b7c0e63f95b7b0e8d8def92da1c9aad7a800da896b6c077d56a317e68c3d5ce73ca0fbbfb28e35f9d81c0013bc0ab85b4fc1b878a62240b0dac240
|
data/bin/mesa_test
CHANGED
|
@@ -21,7 +21,7 @@ class MesaTest < Thor
|
|
|
21
21
|
DEVELOPMENT_URI = 'http://localhost:3000'.freeze
|
|
22
22
|
STAGING_URI = 'https://beta-testhub.herokuapp.com'.freeze
|
|
23
23
|
|
|
24
|
-
# Exit status when
|
|
24
|
+
# Exit status when MESATestHub has nothing for this computer to do, so a
|
|
25
25
|
# script can stop instead of re-testing whatever is already in the work
|
|
26
26
|
# directory: mesa_test install best || exit
|
|
27
27
|
NOTHING_TO_DO_EXIT = 3
|
|
@@ -32,7 +32,7 @@ class MesaTest < Thor
|
|
|
32
32
|
|
|
33
33
|
# --claim / --no-claim, shared by every command that starts work.
|
|
34
34
|
def self.claim_option
|
|
35
|
-
option :claim, desc: 'Tell
|
|
35
|
+
option :claim, desc: 'Tell MESATestHub this computer is working on the ' \
|
|
36
36
|
'commit (and its tests) so it shows as pending, not ' \
|
|
37
37
|
'untested. Use --no-claim if something else already ' \
|
|
38
38
|
'claimed it.',
|
|
@@ -90,7 +90,7 @@ class MesaTest < Thor
|
|
|
90
90
|
|
|
91
91
|
#{MesaTestCase.modules.map { |mod| ' ' + mod.to_s }.join(', ')}
|
|
92
92
|
|
|
93
|
-
Each test is claimed on
|
|
93
|
+
Each test is claimed on MESATestHub as it starts, so it shows as pending,
|
|
94
94
|
and its result is submitted as soon as it finishes. This needs an API key
|
|
95
95
|
(see `mesa_test help setup`). --no-submit runs tests locally only:
|
|
96
96
|
nothing is claimed or sent, and no key is needed.
|
|
@@ -109,7 +109,7 @@ class MesaTest < Thor
|
|
|
109
109
|
type: :boolean, default: true, aliases: '-f'
|
|
110
110
|
option 'force-logs', desc: 'Submit logs for test case(s), even if they pass',
|
|
111
111
|
type: :boolean, default: false
|
|
112
|
-
option :submit, desc: 'Submit results (if any) to
|
|
112
|
+
option :submit, desc: 'Submit results (if any) to MESATestHub.',
|
|
113
113
|
type: :boolean, default: true
|
|
114
114
|
option :module, desc: 'Which module to test and/or submit, if applicable.',
|
|
115
115
|
type: :string, default: 'all', aliases: '-m'
|
|
@@ -145,16 +145,10 @@ class MesaTest < Thor
|
|
|
145
145
|
flags: claim_flags(modes), mesa: m)
|
|
146
146
|
end
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
say_step(shell, "Testing #{t.mod}/#{t.test_name}")
|
|
149
149
|
started = Time.now
|
|
150
150
|
t.do_one
|
|
151
|
-
|
|
152
|
-
# bail out if not submitting
|
|
153
|
-
return unless options[:submit]
|
|
154
|
-
|
|
155
|
-
# submit results
|
|
156
|
-
shell.say 'Submitting results to ' + s.base_uri + '... ', :blue
|
|
157
|
-
submit_result(s, m, t, started)
|
|
151
|
+
finish_test(s, m, t, started, submit: options[:submit])
|
|
158
152
|
else
|
|
159
153
|
# Each test is claimed as it starts and submitted as it finishes.
|
|
160
154
|
# (`install` reports the build.)
|
|
@@ -163,7 +157,6 @@ class MesaTest < Thor
|
|
|
163
157
|
end
|
|
164
158
|
end
|
|
165
159
|
end
|
|
166
|
-
shell.say "Done.\n", :green
|
|
167
160
|
end
|
|
168
161
|
|
|
169
162
|
desc 'submit [TEST CASE]', 'submit a test case or commit'
|
|
@@ -175,7 +168,7 @@ class MesaTest < Thor
|
|
|
175
168
|
that test's result. Without it, the build status plus every test with
|
|
176
169
|
results from this build (or with --empty, just the build status), in one
|
|
177
170
|
request. Results left over from an earlier build are skipped, and
|
|
178
|
-
|
|
171
|
+
MESATestHub ignores results it already has, so submitting again is safe.
|
|
179
172
|
Needs an API key (see `mesa_test help setup`). Modules are
|
|
180
173
|
searched/concatenated in this order:
|
|
181
174
|
|
|
@@ -216,10 +209,7 @@ class MesaTest < Thor
|
|
|
216
209
|
mod: options[:module].downcase.to_sym)
|
|
217
210
|
raise Thor::Error, "#{t.mod}/#{t.test_name} has no results to submit." unless t.ran?
|
|
218
211
|
|
|
219
|
-
# submit results
|
|
220
|
-
shell.say 'Submitting results to ' + s.base_uri + '... ', :blue
|
|
221
212
|
s.submit_instance(m, t, force_logs: options['force-logs'])
|
|
222
|
-
shell.say "Done.\n", :green
|
|
223
213
|
else
|
|
224
214
|
# The build status plus (unless --empty) every test with results from
|
|
225
215
|
# this build, in one request. MESATestHub stores it as a build row
|
|
@@ -228,9 +218,8 @@ class MesaTest < Thor
|
|
|
228
218
|
begin
|
|
229
219
|
m.check_installation
|
|
230
220
|
rescue MesaDirError
|
|
231
|
-
shell.say
|
|
232
|
-
|
|
233
|
-
'MESATestHub.', :red
|
|
221
|
+
shell.say "This build didn't finish compiling, so only the failed build " \
|
|
222
|
+
'will be reported.', :yellow
|
|
234
223
|
empty = true
|
|
235
224
|
end
|
|
236
225
|
s.submit_commit(m, empty: empty, force_logs: options['force-logs'])
|
|
@@ -243,7 +232,7 @@ class MesaTest < Thor
|
|
|
243
232
|
Checks out SHA (default: main) into your work directory (mesa_work in
|
|
244
233
|
~/.mesa_test/config.yml, or --mesadir), using git worktrees off the mirror
|
|
245
234
|
so MESA's history isn't downloaded again. Doesn't build, doesn't contact
|
|
246
|
-
|
|
235
|
+
MESATestHub, and doesn't touch your own MESA_DIR or environment.
|
|
247
236
|
LONGDESC
|
|
248
237
|
|
|
249
238
|
option :mesadir, desc: 'Location of mesa dir, if not relying on config data',
|
|
@@ -269,7 +258,7 @@ class MesaTest < Thor
|
|
|
269
258
|
already there and ignores SHA.
|
|
270
259
|
|
|
271
260
|
The build is claimed and its result (pass or fail, with the build log)
|
|
272
|
-
reported to
|
|
261
|
+
reported to MESATestHub, which needs an API key (see `mesa_test help
|
|
273
262
|
setup`). A failed build exits with status 1. --no-submit just builds, for
|
|
274
263
|
local work: nothing is claimed or sent, and no key is needed.
|
|
275
264
|
|
|
@@ -277,7 +266,7 @@ class MesaTest < Thor
|
|
|
277
266
|
the build and recorded in $MESA_DIR/testhub.yml, so later `mesa_test test`
|
|
278
267
|
runs on this build (e.g. cluster array jobs) apply them automatically.
|
|
279
268
|
|
|
280
|
-
If SHA is `best`,
|
|
269
|
+
If SHA is `best`, MESATestHub picks the commit this computer should build
|
|
281
270
|
next, and the run modes come from its request instead: the mode flags then
|
|
282
271
|
say what this computer is *willing* to do (overriding `capabilities` in the
|
|
283
272
|
config file). If nothing needs building, mesa_test exits with status
|
|
@@ -293,7 +282,7 @@ class MesaTest < Thor
|
|
|
293
282
|
option :mesadir, desc: 'Location of mesa dir, if not relying on config data',
|
|
294
283
|
type: :string
|
|
295
284
|
option :submit, desc: 'Report the build (claim it first, then submit its ' \
|
|
296
|
-
'status) to
|
|
285
|
+
'status) to MESATestHub. --no-submit just builds, ' \
|
|
297
286
|
'e.g. for local testing.',
|
|
298
287
|
type: :boolean, default: true
|
|
299
288
|
claim_option
|
|
@@ -367,7 +356,7 @@ class MesaTest < Thor
|
|
|
367
356
|
Run modes (--skip-optional, --fpe, --converge) apply to the build and
|
|
368
357
|
every test; unset ones are left to your shell's environment.
|
|
369
358
|
|
|
370
|
-
If SHA is `best`,
|
|
359
|
+
If SHA is `best`, MESATestHub picks the commit (one this computer hasn't
|
|
371
360
|
tested yet) and the run modes (FPE checks, plus full inlists or a
|
|
372
361
|
convergence run if the commit asks for one); everything else is the
|
|
373
362
|
ordinary run above. The mode flags then say what this computer is
|
|
@@ -385,7 +374,7 @@ class MesaTest < Thor
|
|
|
385
374
|
option :force, desc: 'Use ~/.mesa_test/config.yml as it is. --no-force ' \
|
|
386
375
|
'shows it and asks you to confirm (or fix) it first.',
|
|
387
376
|
type: :boolean, default: true, aliases: '-f'
|
|
388
|
-
option :submit, desc: 'Submit results (if any) to
|
|
377
|
+
option :submit, desc: 'Submit results (if any) to MESATestHub.',
|
|
389
378
|
type: :boolean, default: true
|
|
390
379
|
option :module, desc: 'Which module to test and/or submit, if applicable.',
|
|
391
380
|
type: :string, default: 'all', aliases: '-m'
|
|
@@ -456,9 +445,9 @@ class MesaTest < Thor
|
|
|
456
445
|
end
|
|
457
446
|
end
|
|
458
447
|
|
|
459
|
-
desc 'request_work', 'ask
|
|
448
|
+
desc 'request_work', 'ask MESATestHub what this computer should do next'
|
|
460
449
|
long_desc <<-LONGDESC
|
|
461
|
-
Asks
|
|
450
|
+
Asks MESATestHub which commit this computer should build next (or, with
|
|
462
451
|
--scope=test --sha=SHA, which test to run next on a commit it built) and
|
|
463
452
|
prints the recommendation as JSON on STDOUT, including the run modes to
|
|
464
453
|
use and the reasons it was picked. The mode flags say what this computer
|
|
@@ -488,13 +477,13 @@ class MesaTest < Thor
|
|
|
488
477
|
which is where the other commands look).
|
|
489
478
|
|
|
490
479
|
mesa_test authenticates with a per-computer API key. To get one, log in
|
|
491
|
-
to
|
|
480
|
+
to MESATestHub, open My Computers, open this computer's page (adding the
|
|
492
481
|
computer first if needed; one used only for `search` and `count` is
|
|
493
482
|
fine), and click "Generate key". The key starts with mth_. Paste it when
|
|
494
483
|
the wizard asks, or export MESATESTHUB_API_KEY, which overrides the
|
|
495
484
|
config file (e.g. to keep the key off disk on a cluster).
|
|
496
485
|
|
|
497
|
-
The wizard checks the key with
|
|
486
|
+
The wizard checks the key with MESATestHub, which also supplies this
|
|
498
487
|
computer's name. Then it asks which optional test modes the computer is
|
|
499
488
|
willing to run when a commit asks for them (full_inlists, fpe, converge),
|
|
500
489
|
the logs token, and where the MESA mirror and work directory live.
|
|
@@ -506,7 +495,7 @@ class MesaTest < Thor
|
|
|
506
495
|
|
|
507
496
|
desc 'search "QUERY"', 'retrieve JSON test instances matching QUERY'
|
|
508
497
|
long_desc <<-LONGDESC
|
|
509
|
-
Sends a GET request to the
|
|
498
|
+
Sends a GET request to the MESATestHub search API. QUERY should be
|
|
510
499
|
quoted. Authenticates with your API key; a key for any of your computers
|
|
511
500
|
works, since search is read-only.
|
|
512
501
|
|
|
@@ -542,7 +531,7 @@ class MesaTest < Thor
|
|
|
542
531
|
|
|
543
532
|
private
|
|
544
533
|
|
|
545
|
-
# `install_and_test best`:
|
|
534
|
+
# `install_and_test best`: MESATestHub picks the commit, then each test.
|
|
546
535
|
def install_and_test_best
|
|
547
536
|
unless options[:submit]
|
|
548
537
|
raise Thor::Error, '`install_and_test best` submits as it goes; ' \
|
|
@@ -572,7 +561,7 @@ class MesaTest < Thor
|
|
|
572
561
|
|
|
573
562
|
# Report the build on its own; this also fulfills the build claim.
|
|
574
563
|
build_submitted = submit_build(s, m)
|
|
575
|
-
#
|
|
564
|
+
# MESATestHub chose the commit and its modes; from here it's an ordinary
|
|
576
565
|
# whole-suite run, as `install_and_test SHA` does it: MESA's order,
|
|
577
566
|
# --jobs at a time, each test claimed as it starts and submitted as it
|
|
578
567
|
# finishes.
|
|
@@ -626,9 +615,8 @@ class MesaTest < Thor
|
|
|
626
615
|
"(#{jobs} in all).", :yellow
|
|
627
616
|
else
|
|
628
617
|
idle = budget - each * jobs
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
"(#{source} ÷ #{jobs}#{note}). Use --test-threads to set it yourself.", :blue
|
|
618
|
+
@thread_note = "#{source} split #{jobs} ways#{"; #{idle} left idle" if idle.positive?}; " \
|
|
619
|
+
'--test-threads sets it directly'
|
|
632
620
|
end
|
|
633
621
|
each
|
|
634
622
|
end
|
|
@@ -647,11 +635,9 @@ class MesaTest < Thor
|
|
|
647
635
|
# run's result. Its claim is left to lapse, which tells the hub the work
|
|
648
636
|
# was abandoned. Returns whether a result went through.
|
|
649
637
|
def submit_result(s, m, t, started)
|
|
650
|
-
unless t.ran_since?(started)
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
end
|
|
654
|
-
s.submit_instance(m, t, force_logs: options['force-logs'])
|
|
638
|
+
return false unless t.ran_since?(started)
|
|
639
|
+
|
|
640
|
+
s.submit_instance(m, t, force_logs: options['force-logs'], quiet: true)
|
|
655
641
|
end
|
|
656
642
|
|
|
657
643
|
# Check numeric options before anything is checked out or built, so a
|
|
@@ -699,7 +685,13 @@ class MesaTest < Thor
|
|
|
699
685
|
tests = tests_for(m, mod)
|
|
700
686
|
sha = m.sha
|
|
701
687
|
claiming = submit && options[:claim]
|
|
702
|
-
|
|
688
|
+
if jobs > 1
|
|
689
|
+
threads = test_thread_env['OMP_NUM_THREADS'] || ENV['OMP_NUM_THREADS']
|
|
690
|
+
say_step(shell, "Testing #{tests.size} tests, #{jobs} at a time" \
|
|
691
|
+
"#{", #{threads} thread#{'s' unless threads == '1'} each" if threads}")
|
|
692
|
+
shell.say "(#{@thread_note})" if @thread_note
|
|
693
|
+
shell.say "Each test's output goes to each_test_run.log in its directory."
|
|
694
|
+
end
|
|
703
695
|
lock = Mutex.new
|
|
704
696
|
done = 0
|
|
705
697
|
all_submitted = true
|
|
@@ -710,15 +702,17 @@ class MesaTest < Thor
|
|
|
710
702
|
end
|
|
711
703
|
end
|
|
712
704
|
started = Time.now
|
|
713
|
-
jobs > 1
|
|
705
|
+
if jobs > 1
|
|
706
|
+
t.run_isolated
|
|
707
|
+
else
|
|
708
|
+
say_step(shell, "[#{lock.synchronize { done } + 1}/#{tests.size}] Testing #{t.mod}/#{t.test_name}")
|
|
709
|
+
t.do_one
|
|
710
|
+
end
|
|
714
711
|
lock.synchronize do
|
|
715
712
|
done += 1
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
submitted = submit_result(s, m, t, started)
|
|
720
|
-
all_submitted &&= submitted
|
|
721
|
-
end
|
|
713
|
+
# (not `&&=` on the call: that would skip every later submission)
|
|
714
|
+
submitted = finish_test(s, m, t, started, submit: submit, prefix: "[#{done}/#{tests.size}] ")
|
|
715
|
+
all_submitted &&= submitted
|
|
722
716
|
end
|
|
723
717
|
end
|
|
724
718
|
if jobs > 1
|
|
@@ -729,34 +723,58 @@ class MesaTest < Thor
|
|
|
729
723
|
all_submitted
|
|
730
724
|
end
|
|
731
725
|
|
|
732
|
-
#
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
726
|
+
# Submit a finished test (with +submit+) and print its one progress line:
|
|
727
|
+
# [12/107] star/1M_pre_ms_to_wd passed in 41.2 min, submitted
|
|
728
|
+
# Only the outcome is colored. Returns whether the result went in (true
|
|
729
|
+
# when not submitting).
|
|
730
|
+
def finish_test(s, m, t, started, submit:, prefix: '')
|
|
731
|
+
elapsed = format_duration(Time.now - started)
|
|
732
|
+
unless t.ran_since?(started)
|
|
733
|
+
line = "#{prefix}#{t.mod}/#{t.test_name} #{shell.set_color('wrote no results', :red)} " \
|
|
734
|
+
"after #{elapsed}"
|
|
735
|
+
shell.say(submit ? "#{line}; nothing submitted" : line)
|
|
736
|
+
return !submit
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
passed = begin
|
|
740
|
+
t.passed?
|
|
736
741
|
rescue StandardError
|
|
737
|
-
|
|
742
|
+
false
|
|
743
|
+
end
|
|
744
|
+
outcome = passed ? shell.set_color('passed', :green) : shell.set_color('FAILED', :red)
|
|
745
|
+
submitted = submit ? submit_result(s, m, t, started) : true
|
|
746
|
+
suffix = if !submit then ''
|
|
747
|
+
elsif submitted then ', submitted'
|
|
748
|
+
else ", #{shell.set_color('not submitted', :red)}"
|
|
749
|
+
end
|
|
750
|
+
shell.say "#{prefix}#{t.mod}/#{t.test_name} #{outcome} in #{elapsed}#{suffix}"
|
|
751
|
+
submitted
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
def format_duration(seconds)
|
|
755
|
+
if seconds < 90 then format('%d s', seconds.round)
|
|
756
|
+
elsif seconds < 2 * 3600 then format('%.1f min', seconds / 60.0)
|
|
757
|
+
else format('%.1f h', seconds / 3600.0)
|
|
738
758
|
end
|
|
739
|
-
shell.say format('%s %s/%s: %s (%.1f min)', prefix, t.mod, t.test_name, outcome,
|
|
740
|
-
(Time.now - started) / 60.0), outcome == 'pass' ? :green : :red
|
|
741
759
|
end
|
|
742
760
|
|
|
743
761
|
|
|
744
762
|
# clean + install +m+ with +modes+ in the environment, then record the
|
|
745
763
|
# modes in $MESA_DIR/testhub.yml for later `test`/`submit` runs.
|
|
746
764
|
def build_with_modes(m, modes, raise_on_failure: false)
|
|
765
|
+
say_step(shell, "Building MESA #{short_sha(m.sha)}" \
|
|
766
|
+
"#{" (#{describe_modes(modes)})" unless modes.empty?}")
|
|
747
767
|
with_env(run_mode_env(modes).merge(build_thread_env)) do
|
|
748
768
|
m.clean
|
|
749
769
|
m.install
|
|
750
770
|
end
|
|
751
771
|
rescue MesaDirError
|
|
752
|
-
shell.say "
|
|
772
|
+
shell.say "MESA #{short_sha(m.sha)} failed to build; see #{File.join(m.mesa_dir, 'build.log')}.", :red
|
|
753
773
|
raise if raise_on_failure
|
|
754
774
|
else
|
|
775
|
+
# Recorded so later `mesa_test test` runs on this build use the same modes.
|
|
755
776
|
m.record_run_modes(modes)
|
|
756
|
-
shell.say "
|
|
757
|
-
unless modes.empty?
|
|
758
|
-
shell.say "Recorded run modes for this build: #{describe_modes(modes)}.", :blue
|
|
759
|
-
end
|
|
777
|
+
shell.say "Built MESA #{short_sha(m.sha)}.", :green
|
|
760
778
|
end
|
|
761
779
|
|
|
762
780
|
# Run modes given explicitly on the command line (unset flags omitted).
|
|
@@ -806,8 +824,8 @@ class MesaTest < Thor
|
|
|
806
824
|
shell_factor = ENV['MESA_TEST_SUITE_RESOLUTION_FACTOR']
|
|
807
825
|
if recorded[:resolution_factor] && !explicit.key?(:resolution_factor) && shell_factor &&
|
|
808
826
|
shell_factor.to_f != recorded[:resolution_factor].to_f
|
|
809
|
-
|
|
810
|
-
|
|
827
|
+
warn_yellow "This build was set up for resolution factor #{recorded[:resolution_factor]}; " \
|
|
828
|
+
"using it instead of your MESA_TEST_SUITE_RESOLUTION_FACTOR=#{shell_factor}."
|
|
811
829
|
end
|
|
812
830
|
recorded.merge(explicit)
|
|
813
831
|
end
|
|
@@ -831,7 +849,7 @@ class MesaTest < Thor
|
|
|
831
849
|
end.join(', ')
|
|
832
850
|
end
|
|
833
851
|
|
|
834
|
-
# Optional modes this computer is willing to run for
|
|
852
|
+
# Optional modes this computer is willing to run for MESATestHub: the
|
|
835
853
|
# config file's `capabilities`, overridden by any mode flag given.
|
|
836
854
|
def capabilities_for(s)
|
|
837
855
|
caps = s.capabilities.dup
|
|
@@ -853,11 +871,12 @@ class MesaTest < Thor
|
|
|
853
871
|
def dispatch_or_exit(s, scope:, sha: nil, capabilities: capabilities_for(s))
|
|
854
872
|
rec = s.dispatch(scope: scope, sha: sha, capabilities: capabilities)
|
|
855
873
|
if rec.nil?
|
|
856
|
-
$stderr.puts '
|
|
874
|
+
$stderr.puts 'MESATestHub has nothing for this computer to ' \
|
|
857
875
|
"#{scope == 'build' ? 'build' : 'test on this commit'} right now."
|
|
858
876
|
elsif scope == 'build'
|
|
859
|
-
|
|
860
|
-
|
|
877
|
+
# (the hub's first reason is usually "on <branch>", already said)
|
|
878
|
+
reasons = Array(rec['reasons']) - ["on #{rec['branch']}"]
|
|
879
|
+
$stderr.puts "MESATestHub picked #{rec['short_sha']} on #{rec['branch']}: #{reasons.join('; ')}"
|
|
861
880
|
end
|
|
862
881
|
rec
|
|
863
882
|
rescue TestHubError => e
|
|
@@ -914,7 +933,7 @@ class MesaTest < Thor
|
|
|
914
933
|
end
|
|
915
934
|
end
|
|
916
935
|
|
|
917
|
-
# hub: true for commands that talk to
|
|
936
|
+
# hub: true for commands that talk to MESATestHub, which all need an API
|
|
918
937
|
# key; checked first, before any checkout or build.
|
|
919
938
|
def create_submitter(force: true, hub: false)
|
|
920
939
|
s = case MODE
|
data/lib/mesa_test.rb
CHANGED
|
@@ -16,6 +16,26 @@ InvalidDataType = Class.new(StandardError)
|
|
|
16
16
|
GitHubError = Class.new(StandardError)
|
|
17
17
|
TestHubError = Class.new(StandardError)
|
|
18
18
|
|
|
19
|
+
# Output conventions (CLAUDE.md, "Output"): a bold step heading after one
|
|
20
|
+
# blank line for each phase; green when MESA work succeeded (a build, a
|
|
21
|
+
# passing test, a standalone submission), red when something failed, yellow
|
|
22
|
+
# for a warning (the run continues, but you may want to act), blue only for
|
|
23
|
+
# setup-wizard questions; everything else plain. No color for plumbing.
|
|
24
|
+
def say_step(shell, text)
|
|
25
|
+
shell.say ''
|
|
26
|
+
shell.say text, :bold
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def short_sha(sha)
|
|
30
|
+
sha.to_s[0, 7]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# A warning on STDERR (so `request_work`'s JSON stays clean), yellow on a
|
|
34
|
+
# terminal.
|
|
35
|
+
def warn_yellow(text)
|
|
36
|
+
$stderr.puts($stderr.tty? ? "\e[33m#{text}\e[0m" : text)
|
|
37
|
+
end
|
|
38
|
+
|
|
19
39
|
GITHUB_HTTPS = 'https://github.com/MESAHub/mesa.git'.freeze
|
|
20
40
|
GITHUB_SSH = 'git@github.com:MESAHub/mesa.git'.freeze
|
|
21
41
|
|
|
@@ -36,9 +56,9 @@ class MesaTestSubmitter
|
|
|
36
56
|
def setup
|
|
37
57
|
update do |s|
|
|
38
58
|
shell.say <<~INTRO
|
|
39
|
-
This wizard sets up this computer's profile for MESATestHub.
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
This wizard sets up this computer's profile for MESATestHub. Each
|
|
60
|
+
question shows the current value; press enter to keep it. You can
|
|
61
|
+
review everything at the end.
|
|
42
62
|
|
|
43
63
|
#{API_KEY_HELP}
|
|
44
64
|
(MESATESTHUB_API_KEY, if set, overrides the key saved here.) The key
|
|
@@ -52,37 +72,33 @@ class MesaTestSubmitter
|
|
|
52
72
|
# Optional run modes this computer can serve when MESATestHub asks for
|
|
53
73
|
# them (see `mesa_test request_work` and `install_and_test best`)
|
|
54
74
|
current = s.capabilities.select { |_, on| on }.keys.join(', ')
|
|
55
|
-
response =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
s.capabilities = parse_capabilities(response) unless response.strip.empty?
|
|
75
|
+
response = question('Which optional test modes can this computer run when a ' \
|
|
76
|
+
'commit asks for them? Any of: full_inlists, fpe, converge, ' \
|
|
77
|
+
"separated by commas, or 'none'.", current.empty? ? 'none' : current)
|
|
78
|
+
s.capabilities = parse_capabilities(response) unless response.empty?
|
|
60
79
|
|
|
61
80
|
# Get API key for submitting failure logs
|
|
62
|
-
response =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"(#{s.logs_token}):", :blue
|
|
81
|
+
response = question('What is your token for uploading failure logs to the logs ' \
|
|
82
|
+
"server? (If you don't have one, ask a MESA testing maintainer " \
|
|
83
|
+
'or a representative from Flatiron for a key.)', s.logs_token)
|
|
66
84
|
s.logs_token = response unless response.empty?
|
|
67
85
|
|
|
68
86
|
# Determine if we'll use ssh or https to access github
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
87
|
+
shell.say ''
|
|
88
|
+
shell.say 'When accessing GitHub, which protocol do you want to use?', :blue
|
|
89
|
+
response = shell.ask '>', limited_to: %w[ssh https], default: s.github_protocol.to_s
|
|
72
90
|
s.github_protocol = response.strip.downcase.to_sym
|
|
73
91
|
|
|
74
92
|
# Get location of source MESA repo (the mirror)
|
|
75
|
-
response =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"(#{s.mesa_mirror}):", :blue
|
|
93
|
+
response = question('Where is/should your mirrored MESA repository be? This is ' \
|
|
94
|
+
'where a mirror will be stored from which test repos will be ' \
|
|
95
|
+
"generated. You won't touch this in regular operation.", s.mesa_mirror)
|
|
79
96
|
s.mesa_mirror = response unless response.empty?
|
|
80
97
|
|
|
81
98
|
# Get location of source MESA work (where testing happens)
|
|
82
|
-
response =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"(#{s.mesa_work}):", :blue
|
|
99
|
+
response = question('Where is/should your working directory for testing be? This ' \
|
|
100
|
+
'is where testing actually occurs, but all files it uses are ' \
|
|
101
|
+
'cached in the mirror repo to save time later.', s.mesa_work)
|
|
86
102
|
s.mesa_work = response unless response.empty?
|
|
87
103
|
end
|
|
88
104
|
|
|
@@ -90,11 +106,23 @@ class MesaTestSubmitter
|
|
|
90
106
|
if confirm_computer_data
|
|
91
107
|
save_computer_data
|
|
92
108
|
else
|
|
93
|
-
shell.say
|
|
109
|
+
shell.say 'Starting over.'
|
|
94
110
|
setup
|
|
95
111
|
end
|
|
96
112
|
end
|
|
97
113
|
|
|
114
|
+
# Ask one wizard question; returns the stripped answer, '' to keep
|
|
115
|
+
# +current+. The question goes out through `say`, which the terminal
|
|
116
|
+
# wraps normally; the prompt that Readline draws stays a short, plain
|
|
117
|
+
# "> ". Readline counts color codes as visible characters, so a long or
|
|
118
|
+
# colored prompt garbles at the terminal's edge (the start of the line
|
|
119
|
+
# repeats before it wraps).
|
|
120
|
+
def question(text, current = nil)
|
|
121
|
+
shell.say ''
|
|
122
|
+
shell.say(current.to_s.empty? ? text : "#{text} (current: #{current})", :blue)
|
|
123
|
+
shell.ask('>').to_s.strip
|
|
124
|
+
end
|
|
125
|
+
|
|
98
126
|
# Ask for the API key until MESATestHub accepts one, and take the computer
|
|
99
127
|
# name from it, since a key belongs to exactly one computer. If the hub
|
|
100
128
|
# can't be reached, keep the key and ask for the name instead.
|
|
@@ -104,9 +132,9 @@ class MesaTestSubmitter
|
|
|
104
132
|
shell.say "Using the API key in MESATESTHUB_API_KEY (#{s.masked_api_key}). " \
|
|
105
133
|
'Unset it to enter one here.', :yellow
|
|
106
134
|
else
|
|
107
|
-
response =
|
|
108
|
-
|
|
109
|
-
s.api_key = response
|
|
135
|
+
response = question('What is the MESATestHub API key for this computer?',
|
|
136
|
+
s.masked_api_key || 'none')
|
|
137
|
+
s.api_key = response unless response.empty?
|
|
110
138
|
next shell.say('An API key is required.', :red) unless s.api_key
|
|
111
139
|
end
|
|
112
140
|
|
|
@@ -117,8 +145,7 @@ class MesaTestSubmitter
|
|
|
117
145
|
return
|
|
118
146
|
elsif check['reachable'] == false
|
|
119
147
|
shell.say 'Saving the key unverified.', :yellow
|
|
120
|
-
response =
|
|
121
|
-
"MESATestHub? (#{s.computer_name}):", :blue
|
|
148
|
+
response = question('What is the name of this computer on MESATestHub?', s.computer_name)
|
|
122
149
|
s.computer_name = response unless response.empty?
|
|
123
150
|
return
|
|
124
151
|
end
|
|
@@ -235,21 +262,20 @@ class MesaTestSubmitter
|
|
|
235
262
|
end
|
|
236
263
|
|
|
237
264
|
def confirm_computer_data
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
response.strip.casecmp('y').zero?
|
|
265
|
+
modes = capabilities.select { |_, on| on }.keys.join(', ')
|
|
266
|
+
say_step(shell, "This computer's settings")
|
|
267
|
+
[['Computer', computer_name],
|
|
268
|
+
['API key', masked_api_key || 'none'],
|
|
269
|
+
['Optional test modes', modes.empty? ? 'none' : modes],
|
|
270
|
+
['Logs token', logs_token.to_s.empty? ? 'none' : logs_token],
|
|
271
|
+
['GitHub protocol', github_protocol],
|
|
272
|
+
['MESA mirror', mesa_mirror],
|
|
273
|
+
['Work directory', mesa_work],
|
|
274
|
+
['OS (detected)', platform_version]].each do |label, value|
|
|
275
|
+
shell.say format(' %-20s %s', label, value)
|
|
276
|
+
end
|
|
277
|
+
shell.say ''
|
|
278
|
+
shell.ask('Save these settings? [y/N]').to_s.strip.casecmp('y').zero?
|
|
253
279
|
end
|
|
254
280
|
|
|
255
281
|
def save_computer_data
|
|
@@ -397,8 +423,8 @@ class MesaTestSubmitter
|
|
|
397
423
|
'build (left over from an earlier one).', :yellow
|
|
398
424
|
end
|
|
399
425
|
unless unread.empty?
|
|
400
|
-
shell.say '
|
|
401
|
-
|
|
426
|
+
shell.say "Couldn't read the results of #{unread.map(&:test_name).join(', ')}; " \
|
|
427
|
+
'not submitting them.', :red
|
|
402
428
|
end
|
|
403
429
|
tests
|
|
404
430
|
end
|
|
@@ -525,39 +551,39 @@ class MesaTestSubmitter
|
|
|
525
551
|
# network failure; testhub_request already explained why
|
|
526
552
|
false
|
|
527
553
|
elsif !response.is_a? Net::HTTPCreated
|
|
528
|
-
shell.say "
|
|
529
|
-
"
|
|
530
|
-
"#{response.message}).", :red
|
|
554
|
+
shell.say "MESATestHub refused the results for #{short_sha(mesa.sha)} " \
|
|
555
|
+
"(HTTP #{response.code}: #{error_message(response)}).", :red
|
|
531
556
|
false
|
|
532
557
|
else
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
558
|
+
if !mesa.installed?
|
|
559
|
+
shell.say "Reported the failed build of #{short_sha(mesa.sha)} to MESATestHub."
|
|
560
|
+
elsif empty || tests.empty?
|
|
561
|
+
shell.say "Reported the build of #{short_sha(mesa.sha)} to MESATestHub."
|
|
562
|
+
else
|
|
563
|
+
shell.say "Submitted the build and #{tests.size} test result#{'s' unless tests.size == 1} " \
|
|
564
|
+
"for #{short_sha(mesa.sha)}.", :green
|
|
565
|
+
end
|
|
566
|
+
# Upload the build log if compilation failed. A logs-server problem is
|
|
567
|
+
# only a warning: the results are already in.
|
|
536
568
|
unless mesa.installed?
|
|
537
|
-
|
|
569
|
+
submit_build_log(mesa)
|
|
570
|
+
return true
|
|
538
571
|
end
|
|
539
572
|
|
|
540
|
-
# compilation succeded, so submit any logs for failing tests
|
|
541
|
-
res = true
|
|
542
573
|
# logs for the failing tests just submitted (or all, with force_logs)
|
|
543
574
|
tests.each do |test_case|
|
|
544
|
-
if !test_case.passed? || force_logs
|
|
545
|
-
# (not `res &&= submit_test_log(...)`: after one failed upload that
|
|
546
|
-
# would skip every remaining test's logs)
|
|
547
|
-
sent = submit_test_log(test_case, skip_passing: !force_logs)
|
|
548
|
-
res &&= sent
|
|
549
|
-
end
|
|
575
|
+
submit_test_log(test_case, skip_passing: !force_logs) if !test_case.passed? || force_logs
|
|
550
576
|
end
|
|
551
|
-
|
|
552
|
-
# a true return value means that any and all log submission were
|
|
553
|
-
# successful
|
|
554
|
-
res
|
|
577
|
+
true
|
|
555
578
|
end
|
|
556
579
|
end
|
|
557
580
|
|
|
558
581
|
# submit results for a single test case instance. Does *not* report overall
|
|
559
|
-
# compilation status to testhub. Use an empty commit submission for that
|
|
560
|
-
|
|
582
|
+
# compilation status to testhub. Use an empty commit submission for that.
|
|
583
|
+
# +quiet+ leaves the success line to the caller (a test run's progress
|
|
584
|
+
# line says "submitted"). Returns whether the result went in; a log
|
|
585
|
+
# upload problem is only a warning.
|
|
586
|
+
def submit_instance(mesa, test_case, force_logs: false, quiet: false)
|
|
561
587
|
unless mesa.install_attempted?
|
|
562
588
|
raise MesaDirError, 'No testhub.yml file found in installation; '\
|
|
563
589
|
'must attempt to install before subitting.'
|
|
@@ -587,17 +613,13 @@ class MesaTestSubmitter
|
|
|
587
613
|
# network failure; testhub_request already explained why
|
|
588
614
|
return false
|
|
589
615
|
elsif !response.is_a? Net::HTTPCreated
|
|
590
|
-
shell.say "
|
|
591
|
-
"#{
|
|
592
|
-
"#{response.message}).", :red
|
|
616
|
+
shell.say "MESATestHub refused #{test_case.mod}/#{test_case.test_name} " \
|
|
617
|
+
"(HTTP #{response.code}: #{error_message(response)}).", :red
|
|
593
618
|
return false
|
|
594
619
|
else
|
|
595
|
-
shell.say "
|
|
596
|
-
"for commit #{mesa.sha}.", :green
|
|
620
|
+
shell.say "Submitted #{test_case.mod}/#{test_case.test_name}.", :green unless quiet
|
|
597
621
|
# submit logs if test failed
|
|
598
|
-
if !test_case.passed? || force_logs
|
|
599
|
-
return submit_test_log(test_case, skip_passing: !force_logs)
|
|
600
|
-
end
|
|
622
|
+
submit_test_log(test_case, skip_passing: !force_logs) if !test_case.passed? || force_logs
|
|
601
623
|
true
|
|
602
624
|
end
|
|
603
625
|
end
|
|
@@ -613,8 +635,7 @@ class MesaTestSubmitter
|
|
|
613
635
|
https.read_timeout = 60
|
|
614
636
|
https.request(request)
|
|
615
637
|
rescue StandardError => e
|
|
616
|
-
shell.say "
|
|
617
|
-
"(#{e.class}: #{e.message}).", :red
|
|
638
|
+
shell.say "Could not reach MESATestHub at #{https.address} (#{e.class}: #{e.message}).", :red
|
|
618
639
|
nil
|
|
619
640
|
end
|
|
620
641
|
|
|
@@ -641,9 +662,8 @@ class MesaTestSubmitter
|
|
|
641
662
|
begin
|
|
642
663
|
https.request(req)
|
|
643
664
|
rescue StandardError => e
|
|
644
|
-
shell.say "
|
|
645
|
-
|
|
646
|
-
'not affect test results already sent to the test hub.', :yellow
|
|
665
|
+
shell.say "Could not reach the logs server at #{uri.host} (#{e.class}: #{e.message}); " \
|
|
666
|
+
'skipping the log upload. The results themselves are in.', :yellow
|
|
647
667
|
nil
|
|
648
668
|
end
|
|
649
669
|
end
|
|
@@ -653,12 +673,7 @@ class MesaTestSubmitter
|
|
|
653
673
|
# intercept and don't send if mesa was properly installed
|
|
654
674
|
return true if mesa.installed?
|
|
655
675
|
|
|
656
|
-
|
|
657
|
-
unless logs_token
|
|
658
|
-
shell.say 'Cannot submit to logs server; need to set mesa_logs_token '\
|
|
659
|
-
'in the mesa_test config file.'
|
|
660
|
-
return false
|
|
661
|
-
end
|
|
676
|
+
return false unless logs_token?
|
|
662
677
|
|
|
663
678
|
# do submission
|
|
664
679
|
res = submit_logs(build_log_params(mesa))
|
|
@@ -668,13 +683,10 @@ class MesaTestSubmitter
|
|
|
668
683
|
# network failure; submit_logs already explained why. Don't fail the run.
|
|
669
684
|
false
|
|
670
685
|
elsif !res.is_a? Net::HTTPOK
|
|
671
|
-
shell.say "
|
|
672
|
-
"#{mesa.sha} (server responded #{res.code} #{res.message}).",
|
|
673
|
-
:red
|
|
686
|
+
shell.say "The logs server refused the build log (HTTP #{res.code} #{res.message}).", :yellow
|
|
674
687
|
false
|
|
675
688
|
else
|
|
676
|
-
shell.say
|
|
677
|
-
"#{mesa.sha}.", :green
|
|
689
|
+
shell.say 'Uploaded the build log to the logs server.'
|
|
678
690
|
true
|
|
679
691
|
end
|
|
680
692
|
end
|
|
@@ -687,13 +699,8 @@ class MesaTestSubmitter
|
|
|
687
699
|
return true
|
|
688
700
|
end
|
|
689
701
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
shell.say 'Cannot submit to logs server; need to set mesa_logs_token '\
|
|
693
|
-
'in the mesa_test config file..'
|
|
694
|
-
return false
|
|
695
|
-
end
|
|
696
|
-
|
|
702
|
+
return false unless logs_token?
|
|
703
|
+
|
|
697
704
|
# do submission
|
|
698
705
|
res = submit_logs(test_log_params(test_case))
|
|
699
706
|
|
|
@@ -702,18 +709,27 @@ class MesaTestSubmitter
|
|
|
702
709
|
# network failure; submit_logs already explained why. Don't fail the run.
|
|
703
710
|
false
|
|
704
711
|
elsif !res.is_a? Net::HTTPOK
|
|
705
|
-
shell.say "
|
|
706
|
-
"
|
|
707
|
-
"#{res.code} #{res.message}).", :red
|
|
712
|
+
shell.say "The logs server refused the logs for #{test_case.test_name} " \
|
|
713
|
+
"(HTTP #{res.code} #{res.message}).", :yellow
|
|
708
714
|
false
|
|
709
715
|
else
|
|
710
|
-
shell.say "
|
|
711
|
-
"#{test_case.test_name} in commit #{test_case.mesa.sha}.",
|
|
712
|
-
:green
|
|
716
|
+
shell.say "Uploaded the logs for #{test_case.test_name} to the logs server."
|
|
713
717
|
true
|
|
714
718
|
end
|
|
715
719
|
end
|
|
716
720
|
|
|
721
|
+
# Whether failure logs can be uploaded; says why not once per run.
|
|
722
|
+
def logs_token?
|
|
723
|
+
return true if logs_token && !logs_token.to_s.empty?
|
|
724
|
+
|
|
725
|
+
unless @warned_no_logs_token
|
|
726
|
+
shell.say 'No logs token is set, so failure logs are not being uploaded ' \
|
|
727
|
+
'(add one with `mesa_test setup`).', :yellow
|
|
728
|
+
@warned_no_logs_token = true
|
|
729
|
+
end
|
|
730
|
+
false
|
|
731
|
+
end
|
|
732
|
+
|
|
717
733
|
# GET a search query from the testhub. The query rides in the URL's
|
|
718
734
|
# query_text parameter; the API key in the Authorization header.
|
|
719
735
|
# Returns the raw Net::HTTP response.
|
|
@@ -876,35 +892,29 @@ class Mesa
|
|
|
876
892
|
end
|
|
877
893
|
|
|
878
894
|
def checkout(new_sha: 'HEAD')
|
|
895
|
+
# A branch name is worth showing; a SHA is shown with its subject below.
|
|
896
|
+
say_step(shell, new_sha =~ /\A\h{40}\z/ ? 'Checking out MESA' : "Checking out #{new_sha}")
|
|
879
897
|
# before anything confirm that git-lfs has been installed
|
|
880
|
-
shell.say "\nEnsuring that git-lfs is installed... ", :blue
|
|
881
898
|
command = 'git lfs help >> /dev/null 2>&1'
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
shell.say "no", :red
|
|
886
|
-
raise(GitHubError, "The command #{command} returned with an error "\
|
|
887
|
-
'status, indicating that git-lfs is not installed. '\
|
|
888
|
-
'Make sure it is installed and try again.')
|
|
899
|
+
unless bash_execute(command)
|
|
900
|
+
raise(GitHubError, 'git-lfs is not installed (`git lfs help` failed); ' \
|
|
901
|
+
'MESA needs it. Install it and try again.')
|
|
889
902
|
end
|
|
890
903
|
|
|
891
904
|
# set up mirror if it doesn't exist
|
|
892
905
|
unless dir_or_symlink_exists?(mirror_dir)
|
|
893
|
-
shell.say "
|
|
894
|
-
'
|
|
906
|
+
shell.say "Creating a mirror of MESA in #{mirror_dir} (first time only; " \
|
|
907
|
+
'this can take a while).'
|
|
895
908
|
FileUtils.mkdir_p mirror_dir
|
|
896
909
|
case github_protocol
|
|
897
910
|
when :ssh
|
|
898
911
|
command = "git clone --mirror #{GITHUB_SSH} #{mirror_dir}"
|
|
899
|
-
shell.say command
|
|
900
912
|
# fail loudly if this doesn't work
|
|
901
913
|
unless bash_execute(command)
|
|
902
914
|
# nuke the mirror directory since it is probably bogus (make this
|
|
903
915
|
# code fire off the next time checkout is done)
|
|
904
|
-
shell.say
|
|
905
|
-
|
|
906
|
-
shell.say command
|
|
907
|
-
bash_execute(command)
|
|
916
|
+
shell.say 'Cloning failed; removing the partial mirror.', :red
|
|
917
|
+
bash_execute("rm -rf #{mirror_dir}")
|
|
908
918
|
|
|
909
919
|
raise(GitHubError, 'Error while executing the following command:'\
|
|
910
920
|
"#{command}. Perhaps you haven't set up "\
|
|
@@ -912,15 +922,12 @@ class Mesa
|
|
|
912
922
|
end
|
|
913
923
|
when :https
|
|
914
924
|
command = "git clone --mirror #{GITHUB_HTTPS} #{mirror_dir}"
|
|
915
|
-
shell.say command
|
|
916
925
|
# fail loudly if this doesn't work
|
|
917
926
|
unless bash_execute(command)
|
|
918
927
|
# nuke the mirror directory since it is probably bogus (make this
|
|
919
928
|
# code fire off the next time checkout is done)
|
|
920
|
-
shell.say
|
|
921
|
-
|
|
922
|
-
shell.say command
|
|
923
|
-
bash_execute(command)
|
|
929
|
+
shell.say 'Cloning failed; removing the partial mirror.', :red
|
|
930
|
+
bash_execute("rm -rf #{mirror_dir}")
|
|
924
931
|
|
|
925
932
|
raise(GitHubError, 'Error while executing the following command: '\
|
|
926
933
|
"#{command}. Perhaps you need to configure "\
|
|
@@ -938,20 +945,19 @@ class Mesa
|
|
|
938
945
|
update_mirror
|
|
939
946
|
|
|
940
947
|
# create "work" directory with proper commit
|
|
941
|
-
shell.say "\nSetting up worktree repo...", :blue
|
|
942
948
|
FileUtils.mkdir_p mesa_dir
|
|
943
|
-
command = "git -C #{mirror_dir} worktree add #{mesa_dir} #{new_sha}"
|
|
944
|
-
|
|
945
|
-
|
|
949
|
+
command = "git -C #{mirror_dir} worktree add --quiet #{mesa_dir} #{new_sha}"
|
|
950
|
+
if bash_execute(command)
|
|
951
|
+
shell.say "#{bashticks("git -C #{mesa_dir} log -1 --format='%h %s'")} (in #{mesa_dir})"
|
|
952
|
+
return
|
|
953
|
+
end
|
|
946
954
|
|
|
947
955
|
raise(GitHubError, 'Failed while executing the following command: '\
|
|
948
956
|
"\"#{command}\".")
|
|
949
957
|
end
|
|
950
958
|
|
|
951
959
|
def update_mirror
|
|
952
|
-
|
|
953
|
-
command = "git -C #{mirror_dir} fetch origin --prune"
|
|
954
|
-
shell.say command
|
|
960
|
+
command = "git -C #{mirror_dir} fetch origin --prune --quiet"
|
|
955
961
|
# fail loudly
|
|
956
962
|
return if bash_execute(command)
|
|
957
963
|
|
|
@@ -961,15 +967,11 @@ class Mesa
|
|
|
961
967
|
|
|
962
968
|
def remove
|
|
963
969
|
return unless File.exist? mesa_dir
|
|
964
|
-
shell.say "\nRemoving work directory from worktree (clearing old data)...",
|
|
965
|
-
:blue
|
|
966
970
|
command = "git -C #{mirror_dir} worktree remove --force #{mesa_dir}"
|
|
967
|
-
shell.say command
|
|
968
971
|
return if bash_execute(command)
|
|
969
972
|
|
|
970
|
-
|
|
973
|
+
# Not a worktree of this mirror (or git refused): just delete it.
|
|
971
974
|
command = "rm -rf #{mesa_dir}"
|
|
972
|
-
shell.say command
|
|
973
975
|
# fail loudly (the "true" tells bash_execute to raise an exception if
|
|
974
976
|
# the command fails)
|
|
975
977
|
bash_execute(command, true)
|
|
@@ -987,8 +989,6 @@ class Mesa
|
|
|
987
989
|
with_mesa_dir do
|
|
988
990
|
visit_and_check mesa_dir, MesaDirError, 'E\countered a problem in ' \
|
|
989
991
|
"running `clean` in #{mesa_dir}." do
|
|
990
|
-
shell.say('MESA_DIR = ' + ENV['MESA_DIR'])
|
|
991
|
-
shell.say './clean'
|
|
992
992
|
bash_execute('./clean')
|
|
993
993
|
end
|
|
994
994
|
end
|
|
@@ -999,8 +999,6 @@ class Mesa
|
|
|
999
999
|
with_mesa_dir do
|
|
1000
1000
|
visit_and_check mesa_dir, MesaDirError, 'Encountered a problem in ' \
|
|
1001
1001
|
"running `install` in #{mesa_dir}." do
|
|
1002
|
-
shell.say('MESA_DIR = ' + ENV['MESA_DIR'])
|
|
1003
|
-
shell.say './install'
|
|
1004
1002
|
bash_execute('./install')
|
|
1005
1003
|
end
|
|
1006
1004
|
end
|
|
@@ -1114,7 +1112,7 @@ class Mesa
|
|
|
1114
1112
|
@names_to_numbers[mod] = {}
|
|
1115
1113
|
@test_case_names[mod] = []
|
|
1116
1114
|
@test_cases[mod] = {}
|
|
1117
|
-
visit_dir(test_suite_dir(mod: mod)
|
|
1115
|
+
visit_dir(test_suite_dir(mod: mod)) do
|
|
1118
1116
|
bashticks('./list_tests').split("\n").each do |line|
|
|
1119
1117
|
num, tc_name = line.strip.split
|
|
1120
1118
|
@names_to_numbers[mod][tc_name.strip] = num.to_i
|
|
@@ -1127,7 +1125,7 @@ class Mesa
|
|
|
1127
1125
|
mesa: self
|
|
1128
1126
|
)
|
|
1129
1127
|
rescue TestCaseDirError
|
|
1130
|
-
shell.say "
|
|
1128
|
+
shell.say "do1_test_source lists #{tc_name.strip}, but it has no directory; skipping it.", :yellow
|
|
1131
1129
|
end
|
|
1132
1130
|
end
|
|
1133
1131
|
end
|
|
@@ -1196,15 +1194,13 @@ class Mesa
|
|
|
1196
1194
|
# change MESA_DIR, holding on to old value
|
|
1197
1195
|
orig_mesa_dir = ENV['MESA_DIR']
|
|
1198
1196
|
ENV['MESA_DIR'] = mesa_dir
|
|
1199
|
-
|
|
1200
|
-
|
|
1197
|
+
|
|
1201
1198
|
# do the stuff
|
|
1202
1199
|
begin
|
|
1203
1200
|
yield
|
|
1204
1201
|
# make sure we undo MESA_DIR change
|
|
1205
1202
|
ensure
|
|
1206
1203
|
ENV['MESA_DIR'] = orig_mesa_dir
|
|
1207
|
-
shell.say "Changed MESA_DIR back to #{ENV['MESA_DIR']}.", :blue
|
|
1208
1204
|
end
|
|
1209
1205
|
end
|
|
1210
1206
|
|
|
@@ -1380,7 +1376,6 @@ class MesaTestCase
|
|
|
1380
1376
|
# just punt to +each_test_run+ in the test_suite directory. It's your problem
|
|
1381
1377
|
# now, sucker!
|
|
1382
1378
|
def do_one
|
|
1383
|
-
shell.say("Testing #{test_name}", :yellow)
|
|
1384
1379
|
visit_dir(test_suite_dir) do
|
|
1385
1380
|
bash_execute("./each_test_run #{position}")
|
|
1386
1381
|
end
|
|
@@ -1478,12 +1473,8 @@ end
|
|
|
1478
1473
|
# exception if the block failed (returned false or nil)
|
|
1479
1474
|
def visit_and_check(new_dir, exception, message)
|
|
1480
1475
|
cwd = Dir.getwd
|
|
1481
|
-
shell.say "Leaving #{cwd}", :blue
|
|
1482
|
-
shell.say "\nEntering #{new_dir}.", :blue
|
|
1483
1476
|
Dir.chdir(new_dir)
|
|
1484
1477
|
success = yield if block_given?
|
|
1485
|
-
shell.say "Leaving #{new_dir}", :blue
|
|
1486
|
-
shell.say "\nEntering #{cwd}.", :blue
|
|
1487
1478
|
Dir.chdir(cwd)
|
|
1488
1479
|
return if success
|
|
1489
1480
|
raise exception, message
|
|
@@ -1491,19 +1482,15 @@ end
|
|
|
1491
1482
|
|
|
1492
1483
|
# cd into a new directory, execute a block, then cd back into original
|
|
1493
1484
|
# directory
|
|
1494
|
-
def visit_dir(new_dir
|
|
1485
|
+
def visit_dir(new_dir)
|
|
1495
1486
|
cwd = Dir.getwd
|
|
1496
|
-
shell.say "Leaving #{cwd}\n", :blue unless quiet
|
|
1497
|
-
shell.say "\nEntering #{new_dir}.", :blue unless quiet
|
|
1498
1487
|
Dir.chdir(new_dir)
|
|
1499
1488
|
yield if block_given?
|
|
1500
|
-
shell.say "Leaving #{new_dir}\n", :blue unless quiet
|
|
1501
|
-
shell.say "\nRe-entering #{cwd}.", :blue unless quiet
|
|
1502
1489
|
Dir.chdir(cwd)
|
|
1503
1490
|
end
|
|
1504
1491
|
|
|
1505
1492
|
# the next function probalby doesn't belong here, but keep it anyway, please
|
|
1506
|
-
# create seed data for test cases for
|
|
1493
|
+
# create seed data for test cases for MESATestHub of a given mesa version
|
|
1507
1494
|
def generate_seeds_rb(mesa_dir, outfile)
|
|
1508
1495
|
m = Mesa.new(mesa_dir: mesa_dir)
|
|
1509
1496
|
m.load_test_source_data
|
|
@@ -1602,8 +1589,8 @@ def dispatch_run_modes(rec, preferred: nil, preferred_source: nil)
|
|
|
1602
1589
|
if requested
|
|
1603
1590
|
factor = requested.to_s
|
|
1604
1591
|
if preferred && preferred.to_f != requested.to_f
|
|
1605
|
-
|
|
1606
|
-
|
|
1592
|
+
warn_yellow "MESATestHub asked for resolution factor #{factor} ([ci converge #{factor}]); " \
|
|
1593
|
+
"using it instead of your #{preferred_source}=#{preferred}."
|
|
1607
1594
|
end
|
|
1608
1595
|
modes[:resolution_factor] = factor
|
|
1609
1596
|
else
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mesa_test
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- William Wolf
|
|
@@ -78,9 +78,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
78
78
|
version: 2.7.0
|
|
79
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
requirements:
|
|
81
|
-
- - "
|
|
81
|
+
- - ">="
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
|
-
version:
|
|
83
|
+
version: '0'
|
|
84
84
|
requirements: []
|
|
85
85
|
rubygems_version: 3.4.17
|
|
86
86
|
signing_key:
|