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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mesa_test +87 -68
  3. data/lib/mesa_test.rb +145 -158
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80dc6d76445d3a3b8e24e4de42bc561471583897452faa29cdf9f6d767c99a1c
4
- data.tar.gz: 353ee970f820241963bde503b86a3a5444ae6a793060433938ba122fbcc8d2e2
3
+ metadata.gz: 539c96d3328d28340abaac30b503be321ee9a79742a0efa3fce3e03889c7762c
4
+ data.tar.gz: 885b08d2985ecf74db5d5c492d5a47022e75b58986fb5bb1037b9e6d1126e9a3
5
5
  SHA512:
6
- metadata.gz: 3eacb6b20929997ac9bfea5e555edb219927de877dae78fdd062c28c216ebc894e356e72f336b533a7c4b302cb958116318a784d9a500f7afc35be77ef3cea89
7
- data.tar.gz: d7734eede0dde268ec1a97a24bf0ef90a83efea839bf88c615364f4b5034c18d834b1a0273df2899da483d17e1440af568e8b75564dab7d31092af3313262954
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 MesaTestHub has nothing for this computer to do, so a
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 MesaTestHub this computer is working on the ' \
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 MesaTestHub as it starts, so it shows as pending,
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 MesaTestHub.',
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
- # run test
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
- MesaTestHub ignores results it already has, so submitting again is safe.
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 %q{This MESA installation doesn't seem to be compiled } \
232
- 'properly. Attempting to submit a compilation failure to '\
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
- MesaTestHub, and doesn't touch your own MESA_DIR or environment.
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 MesaTestHub, which needs an API key (see `mesa_test help
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`, MesaTestHub picks the commit this computer should build
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 MesaTestHub. --no-submit just builds, ' \
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`, MesaTestHub picks the commit (one this computer hasn't
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 MesaTestHub.',
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 MesaTestHub what this computer should do next'
448
+ desc 'request_work', 'ask MESATestHub what this computer should do next'
460
449
  long_desc <<-LONGDESC
461
- Asks MesaTestHub which commit this computer should build next (or, with
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 MesaTestHub, open My Computers, open this computer's page (adding the
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 MesaTestHub, which also supplies this
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 MesaTestHub search API. QUERY should be
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`: MesaTestHub picks the commit, then each test.
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
- # MesaTestHub chose the commit and its modes; from here it's an ordinary
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
- note = idle.positive? ? "; #{idle} left idle" : ''
630
- shell.say "Up to #{jobs} tests at a time, #{each} thread#{'s' unless each == 1} each " \
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
- shell.say "#{t.mod}/#{t.test_name} wrote no results; nothing submitted.", :red
652
- return false
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
- shell.say "Running #{tests.size} tests, #{jobs} at a time.", :blue if jobs > 1
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 ? t.run_isolated : t.do_one
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
- report_test(t, started, "[#{done}/#{tests.size}]")
717
- if submit
718
- # (not `&&=` on the call: that would skip every later submission)
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
- # One progress line for a finished test, from its testhub.yml.
733
- def report_test(t, started, prefix)
734
- outcome = begin
735
- t.ran? ? (t.passed? ? 'pass' : 'FAIL') : 'no result'
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
- 'no result'
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 "\nFailed in compiling MESA.", :red
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 "\nSuccessfully compiled MESA commit #{m.sha}.", :green
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
- warn "This build was set up for resolution factor #{recorded[:resolution_factor]}; " \
810
- "using it instead of your MESA_TEST_SUITE_RESOLUTION_FACTOR=#{shell_factor}."
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 MesaTestHub: the
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 'MesaTestHub has nothing more for this computer to ' \
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
- $stderr.puts "MesaTestHub suggests #{rec['short_sha']} on #{rec['branch']}: " \
860
- "#{Array(rec['reasons']).join('; ')}"
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 MesaTestHub, which all need an API
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. Current
40
- values are shown in parentheses; press enter to keep them. You can
41
- confirm everything at the end.
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 = shell.ask 'Which optional test modes can this computer ' \
56
- 'run when a commit asks for them? Any of: full_inlists, fpe, ' \
57
- "converge, separated by commas, or 'none'. " \
58
- "(#{current.empty? ? 'none' : current}):", :blue
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 = shell.ask 'What is your token for uploading failure logs to ' \
63
- "the logs server? (if you don't have one, ask a MESA testing " \
64
- 'maintainer or a representative from Flatiron for a key) ' \
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
- response = shell.ask 'When accessing GitHub, which protocol do you '\
70
- 'want to use?', :blue, limited_to: %w[ssh https],
71
- default: s.github_protocol.to_s
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 = shell.ask "Where is/should your mirrored MESA repository " \
76
- "located? This is where a mirror will be stored from which test " \
77
- "repos will be generated. You won't touch this in regular operation. " \
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 = shell.ask "Where is/should your working directory for "\
83
- "testing be located? This is where testing actually occurs, but all "\
84
- "files it uses are cached in the mirror repo to save time later. " \
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 "Restarting wizard.\n"
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 = shell.ask 'What is the MESATestHub API key for this ' \
108
- "computer? (#{s.masked_api_key || 'none'}):", :blue
109
- s.api_key = response.strip unless response.strip.empty?
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 = shell.ask 'What is the name of this computer on ' \
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
- puts "This computer's mesa_test settings:"
239
- puts '-------------------------------------------------------'
240
- puts "Computer Name #{computer_name}"
241
- puts "API key #{masked_api_key || 'none'}"
242
- puts "Optional test modes #{capabilities.select { |_, on| on }.keys.join(', ').then { |c| c.empty? ? 'none' : c }}"
243
- puts "logs API token #{logs_token}"
244
- puts "GitHub Protocol #{github_protocol}"
245
- puts "MESA Mirror Location #{mesa_mirror}"
246
- puts "MESA Work Location #{mesa_work}"
247
- puts "OS (detected each run) #{platform_version}"
248
- # puts "Config location #{config_file}"
249
- puts '-------------------------------------------------------'
250
- puts ''
251
- response = shell.ask 'Is this correct? (y/Y = Yes, anything else = No):'
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 'The following test cases could NOT be read for submission:', :red
401
- unread.each { |test_case| shell.say "- #{test_case.test_name}", :red }
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 "\nFailed to submit some or all test case instances and/or "\
529
- "commit data (server responded #{response.code} "\
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
- shell.say "\nSuccessfully submitted commit #{mesa.sha}.", :green
534
- # commit submitted to testhub, now submit build log if compilation failed
535
- # and exit
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
- return submit_build_log(mesa)
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
- def submit_instance(mesa, test_case, force_logs: false)
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 "\nFailed to submit #{test_case.test_name} for commit "\
591
- "#{mesa.sha} (server responded #{response.code} "\
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 "\nSuccessfully submitted instance of #{test_case.test_name} "\
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 "\nCould not reach the test hub at #{https.address} "\
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 "\nCould not reach the LOGS server at #{uri.host} "\
645
- "(#{e.class}: #{e.message}). Skipping log upload; this does "\
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
- # don't even try unless we have a logs token set
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 "\nFailed to submit build.log to the LOGS server for commit "\
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 "\nSuccessfully submitted build.log to the LOGS server for "\
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
- # don't even try unless we have a logs token set
691
- unless logs_token
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 "Failed to submit logs for test case #{test_case.test_name} "\
706
- "in commit #{test_case.mesa.sha} (server responded "\
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 "Successfully submitted logs for test case "\
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
- if bash_execute(command)
883
- shell.say "yes", :green
884
- else
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 "\nCreating initial mirror at #{mirror_dir}. "\
894
- 'This might take awhile...', :blue
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 "Failed. Removing the [potentially corrupted] mirror.", :red
905
- command = "rm -rf #{mirror_dir}"
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 "Failed. Removing the [potentially corrupted] mirror.", :red
921
- command = "rm -rf #{mirror_dir}"
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
- shell.say command
945
- return if bash_execute(command)
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
- shell.say "\nFetching MESA history...", :blue
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
- shell.say "Failed. Simply trying to remove the directory.", :red
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), quiet: true) do
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 "No such test case #{tc_name.strip}. Skipping loading it.", :red
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
- shell.say "Temporarily changed MESA_DIR to #{ENV['MESA_DIR']}.", :blue
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, quiet: false)
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 MesaTestHub of a given mesa version
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
- warn "MESATestHub asked for resolution factor #{factor} ([ci converge #{factor}]); " \
1606
- "using it instead of your #{preferred_source}=#{preferred}."
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.rc1
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: 1.3.1
83
+ version: '0'
84
84
  requirements: []
85
85
  rubygems_version: 3.4.17
86
86
  signing_key: