mesa_test 1.0.3 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mesa_test +10 -3
  3. data/lib/mesa_test.rb +211 -19
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 872e80292cb3ab8bdbe1be17b0dfc082528ad1014010fc2be36257d111481370
4
- data.tar.gz: 8450ccf061a543ec47fcfae07a50fbda80f417efa9f28d8f4d9e20f84ed03b8f
3
+ metadata.gz: 6ef2c5c38af03ad5ebdf41472063fd0d1255de221e7402befc392d0f94d9d683
4
+ data.tar.gz: 35afaaa02352b6a9a60759dfff51ad8312c756bdaa92fc7a480ff728a5d71660
5
5
  SHA512:
6
- metadata.gz: 37aaad6d044957344a18205cbbf4b834d1b0e3000ff6e6c8f33fd17e6f4d2414d01bec923481ae563b173e64e76a057afddbcb138fbce0cbeafa97edcef4d439
7
- data.tar.gz: 6dd6a997f7ec1e5faa0c11755938f6b4213e0c8fd2005f60a88f4dbd63c1c238f71e0323955ac4e17828be6b4646a80918ee0001363fa6204c7fcfd19d9ff6c8
6
+ metadata.gz: d7538fe20d847d901733db1a40dccb6426e5d5b66ee3b727f5394c45babb2baf082ab9576873447e5a25cec46972add717825a27e1a156bf31565d5b569f967d
7
+ data.tar.gz: 10a7b0356b8b84f7f4e8df45f3d0b18a38f1ef30c71bd12b02947b83c6c23b29c778b3cbb9dfa04087fbf4454bf90bb92ecf7ecf9b2c02abf7bf0dfb765a3a70
data/bin/mesa_test CHANGED
@@ -138,7 +138,8 @@ class MesaTest < Thor
138
138
  m.check_installation
139
139
  rescue MesaDirError
140
140
  shell.say %q{This MESA installation doesn't seem to be compiled } \
141
- 'properly. Submitting a compilation failure to MESATestHub.', :red
141
+ 'properly. Attempting to submit a compilation failure to '\
142
+ 'MESATestHub.', :red
142
143
  empty = true
143
144
  ensure
144
145
  # submit all tests
@@ -209,8 +210,14 @@ class MesaTest < Thor
209
210
  github_protocol: s.github_protocol
210
211
  )
211
212
  end
212
- m.clean
213
- m.install
213
+ begin
214
+ m.clean
215
+ m.install
216
+ rescue MesaDirError
217
+ shell.say "\nFailed in compiling MESA.", :red
218
+ else
219
+ shell.say "\nSuccessfully compiled MESA commit #{m.sha}.", :green
220
+ end
214
221
  end
215
222
 
216
223
  desc 'install_and_test [SHA]', 'Install, test, and submit an entire commit.'
data/lib/mesa_test.rb CHANGED
@@ -7,6 +7,7 @@ require 'net/http'
7
7
  require 'net/https'
8
8
  require 'thor'
9
9
  require 'json'
10
+ require 'base64'
10
11
 
11
12
  MesaDirError = Class.new(StandardError)
12
13
  TestCaseDirError = Class.new(StandardError)
@@ -48,9 +49,15 @@ e-mail and password will be stored in plain text.'
48
49
  "#{s.email} (required)? (#{s.password})", :blue
49
50
  s.password = response unless response.empty?
50
51
 
52
+ # Get API key for submitting failure logs
53
+ response = shell.ask 'What is the logs submission API token associated '\
54
+ "with the email #{s.email} (required; contact Josiah Schwab if you "\
55
+ "need a key)? (#{s.logs_token})", :blue
56
+ s.logs_token = response unless response.empty?
57
+
51
58
  # Determine if we'll use ssh or https to access github
52
59
  response = shell.ask 'When accessing GitHub, which protocol do you '\
53
- 'want to use? ', :blue, limited_to: %w[ssh https]
60
+ 'want to use?', :blue, limited_to: %w[ssh https]
54
61
  s.github_protocol = response.strip.downcase.to_sym
55
62
 
56
63
  # Get location of source MESA repo (the mirror)
@@ -110,7 +117,7 @@ e-mail and password will be stored in plain text.'
110
117
 
111
118
  attr_accessor :computer_name, :user_name, :email, :password, :platform,
112
119
  :mesa_mirror, :mesa_work, :platform_version, :processor,
113
- :config_file, :base_uri, :last_tested, :github_protocol
120
+ :config_file, :base_uri, :github_protocol, :logs_token
114
121
 
115
122
  attr_reader :shell
116
123
 
@@ -118,7 +125,7 @@ e-mail and password will be stored in plain text.'
118
125
  def initialize(
119
126
  computer_name: nil, user_name: nil, email: nil, github_protocol: nil,
120
127
  mesa_mirror: nil, platform: nil, platform_version: nil, processor: nil,
121
- config_file: nil, base_uri: nil, last_tested: nil
128
+ config_file: nil, base_uri: nil, logs_token: nil
122
129
  )
123
130
  @computer_name = computer_name || Socket.gethostname.scan(/^[^\.]+\.?/)[0]
124
131
  @computer_name.chomp!('.') if @computer_name
@@ -146,6 +153,7 @@ e-mail and password will be stored in plain text.'
146
153
  @config_file = config_file || File.join(ENV['HOME'], '.mesa_test',
147
154
  'config.yml')
148
155
  @base_uri = base_uri
156
+ @logs_token = logs_token || ENV['MESA_LOGS_TOKEN']
149
157
 
150
158
  # set up thor-proof way to get responses from user. Thor hijacks the
151
159
  # gets command, so we have to use its built-in "ask" method, which is
@@ -166,6 +174,7 @@ e-mail and password will be stored in plain text.'
166
174
  puts "Computer Name #{computer_name}"
167
175
  puts "User email #{email}"
168
176
  puts 'Password ***********'
177
+ puts "logs API token #{logs_token}"
169
178
  puts "GitHub Protocol #{github_protocol}"
170
179
  puts "MESA Mirror Location #{mesa_mirror}"
171
180
  puts "MESA Work Location #{mesa_work}"
@@ -188,6 +197,7 @@ e-mail and password will be stored in plain text.'
188
197
  'computer_name' => computer_name,
189
198
  'email' => email,
190
199
  'password' => password,
200
+ 'logs_token' => logs_token,
191
201
  'github_protocol' => github_protocol,
192
202
  'mesa_mirror' => mesa_mirror,
193
203
  'mesa_work' => mesa_work,
@@ -206,6 +216,7 @@ e-mail and password will be stored in plain text.'
206
216
  @computer_name = data_hash['computer_name']
207
217
  @email = data_hash['email']
208
218
  @password = data_hash['password']
219
+ @logs_token = data_hash['logs_token']
209
220
  @github_protocol = data_hash['github_protocol'].to_sym
210
221
  @mesa_mirror = data_hash['mesa_mirror']
211
222
  @mesa_work = data_hash['mesa_work']
@@ -273,6 +284,28 @@ e-mail and password will be stored in plain text.'
273
284
  res
274
285
  end
275
286
 
287
+ # Parameters for reporting a failed compilation to the logs server
288
+ def build_log_params(mesa)
289
+ {
290
+ 'computer_name' => computer_name,
291
+ 'commit' => mesa.sha,
292
+ 'build.log' => mesa.build_log_64
293
+ }
294
+ end
295
+
296
+ # Parameters for reporting a failed test to the logs server
297
+ def test_log_params(test_case)
298
+ res = {
299
+ 'computer_name' => computer_name,
300
+ 'commit' => test_case.mesa.sha,
301
+ 'test_case' => test_case.test_name
302
+ }
303
+ res['mk.txt'] = test_case.mk_64 unless test_case.mk_64.empty?
304
+ res['out.txt'] = test_case.out_64 unless test_case.out_64.empty?
305
+ res['err.txt'] = test_case.err_64 unless test_case.err_64.empty?
306
+ res
307
+ end
308
+
276
309
  # Parameters for a single test case. +mesa+ is an instance of +Mesa+, and
277
310
  # +test_case+ is an instance of MesaTestCase representing the test case to
278
311
  # be submitted
@@ -302,6 +335,10 @@ e-mail and password will be stored in plain text.'
302
335
  # submit entire commit's worth of test cases, OR submit compilation status
303
336
  # and NO test cases
304
337
  def submit_commit(mesa, empty: false)
338
+ unless mesa.install_attempted?
339
+ raise MesaDirError, 'No testhub.yml file found in installation; '\
340
+ 'must attempt to install before subitting.'
341
+ end
305
342
  uri = URI.parse(base_uri + '/submissions/create.json')
306
343
  https = Net::HTTP.new(uri.hostname, uri.port)
307
344
  https.use_ssl = true if base_uri.include? 'https'
@@ -315,7 +352,9 @@ e-mail and password will be stored in plain text.'
315
352
  #
316
353
  # if we have an empty submission, then it is necessarily not entire.
317
354
  # Similarly, a non-empty submission is necessarily entire (otherwise one
318
- # would use +submit_instance+)
355
+ # would use +submit_instance+). Also, make a "nonempty" submission be
356
+ # empty if there was an overall build error
357
+ empty ||= !mesa.installed?
319
358
  request_data = {submitter: submitter_params,
320
359
  commit: commit_params(mesa, empty: empty, entire: !empty)}
321
360
  # don't need test instances if it's an empty submission or if compilation
@@ -334,13 +373,40 @@ e-mail and password will be stored in plain text.'
334
373
  false
335
374
  else
336
375
  shell.say "\nSuccessfully submitted commit #{mesa.sha}.", :green
337
- true
376
+ # commit submitted to testhub, now submit build log if compilation failed
377
+ # and exit
378
+ unless mesa.installed?
379
+ return submit_build_log(mesa)
380
+ end
381
+
382
+ # compilation succeded, so submit any logs for failing tests
383
+ res = true
384
+ unless empty
385
+ mesa.test_cases.each do |mod, test_case_hash|
386
+ test_case_hash.each do |tc_name, test_case|
387
+ # get at each individual test case, see if it failed, and if it
388
+ # did, submit its log files
389
+ unless test_case.passed?
390
+ res &&= submit_test_log(test_case)
391
+ end
392
+ end
393
+ end
394
+ end
395
+
396
+ # a true return value means that any and all log submission were
397
+ # successful
398
+ res
338
399
  end
339
400
  end
340
401
 
341
402
  # submit results for a single test case instance. Does *not* report overall
342
403
  # compilation status to testhub. Use an empty commit submission for that
343
404
  def submit_instance(mesa, test_case)
405
+ unless mesa.install_attempted?
406
+ raise MesaDirError, 'No testhub.yml file found in installation; '\
407
+ 'must attempt to install before subitting.'
408
+ end
409
+
344
410
  uri = URI.parse(base_uri + '/submissions/create.json')
345
411
  https = Net::HTTP.new(uri.hostname, uri.port)
346
412
  https.use_ssl = true if base_uri.include? 'https'
@@ -369,9 +435,80 @@ e-mail and password will be stored in plain text.'
369
435
  else
370
436
  shell.say "\nSuccessfully submitted instance of #{test_case.test_name} "\
371
437
  "for commit #{mesa.sha}.", :green
438
+ # submit logs if test failed
439
+ return submit_test_log(test_case) unless test_case.passed?
440
+ true
441
+ end
442
+ end
443
+
444
+ # make generic request to LOGS server
445
+ # +params+ is a hash of data to be encoded as JSON and sent off
446
+ def submit_logs(params)
447
+ uri = URI('https://logs.mesastar.org/uploads')
448
+ https = Net::HTTP.new(uri.host, uri.port)
449
+ https.use_ssl = true
450
+ req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json',
451
+ 'X-Api-Key' => logs_token)
452
+ req.body = params.to_json
453
+ https.request(req)
454
+ end
455
+
456
+ # send build log to the logs server
457
+ def submit_build_log(mesa)
458
+ # intercept and don't send if mesa was properly installed
459
+ return true if mesa.installed?
460
+
461
+ # don't even try unless we have a logs token set
462
+ unless logs_token
463
+ shell.say 'Cannot submit to logs server; need to set mesa_logs_token '\
464
+ 'in the mesa_test config file.'
465
+ return false
466
+ end
467
+
468
+ # do submission
469
+ res = submit_logs(build_log_params(mesa))
470
+
471
+ # report out results
472
+ if !res.is_a? Net::HTTPOK
473
+ shell.say "\nFailed to submit build.log to the LOGS server for commit "\
474
+ "#{mesa.sha}.", :red
475
+ false
476
+ else
477
+ shell.say "\nSuccessfully submitted build.log to the LOGS server for "\
478
+ "#{mesa.sha}.", :green
372
479
  true
373
480
  end
374
481
  end
482
+
483
+ # send build log to the logs server
484
+ def submit_test_log(test_case)
485
+ # skip submission if mesa was never installed or if the test passed
486
+ return true if !test_case.mesa.installed? || test_case.passed?
487
+
488
+ # don't even try unless we have a logs token set
489
+ unless logs_token
490
+ shell.say 'Cannot submit to logs server; need to set mesa_logs_token '\
491
+ 'in the mesa_test config file..'
492
+ return false
493
+ end
494
+
495
+ # do submission
496
+ res = submit_logs(test_log_params(test_case))
497
+
498
+ # report out results
499
+ if !res.is_a? Net::HTTPOK
500
+ shell.say "Failed to submit out.txt and mk.txt to the LOGS server for "\
501
+ "test case #{test_case.test_name} in commit "\
502
+ "#{test_case.mesa.sha}.", :red
503
+ false
504
+ else
505
+ shell.say "Successfully submitted out.txt and mk.txt to the LOGS "\
506
+ "server for test case #{test_case.test_name} in commit "\
507
+ "#{test_case.mesa.sha}.", :green
508
+ true
509
+ end
510
+ end
511
+
375
512
  end
376
513
 
377
514
  class Mesa
@@ -553,18 +690,29 @@ class Mesa
553
690
  'show a successful installation).'
554
691
  end
555
692
 
693
+ # base 64-encoded contents of build.log
694
+ def build_log_64
695
+ build_log = File.join(mesa_dir, 'build.log')
696
+ return '' unless File.exist?(build_log)
697
+
698
+ b64_file(build_log)
699
+ end
700
+
556
701
  # sourced from $MESA_DIR/testhub.yml, which should be created after
557
702
  # installation
558
703
  def compiler_hash
559
704
  data_file = File.join(mesa_dir, 'testhub.yml')
560
- unless File.exist? data_file
561
- raise(MesaDirError, "Could not find file testhub.yml in #{mesa_dir}.")
705
+ res = {
706
+ compiler: 'Unknown',
707
+ sdk_version: 'Unknown',
708
+ math_backend: 'Unknown'
709
+ }
710
+ if File.exist? data_file
711
+ res = res.merge(YAML.safe_load(File.read(data_file)) || {})
712
+ # currently version_number is reported, but we don't need that in Git land
713
+ res.delete('version_number') # returns the value, not the updated hash
714
+ res
562
715
  end
563
-
564
- res = YAML.safe_load(File.read(data_file))
565
- # currently version_number is reported, but we don't need that in Git land
566
- res.delete('version_number') # returns the value, not the updated hash
567
- res
568
716
  end
569
717
 
570
718
  ## TEST SUITE METHODS
@@ -602,12 +750,16 @@ class Mesa
602
750
  num, tc_name = line.strip.split
603
751
  @names_to_numbers[mod][tc_name.strip] = num.to_i
604
752
  @test_case_names[mod] << tc_name.strip
605
- @test_cases[mod][tc_name.strip] = MesaTestCase.new(
606
- test: tc_name.strip,
607
- mod: mod,
608
- position: num.to_i,
609
- mesa: self
610
- )
753
+ begin
754
+ @test_cases[mod][tc_name.strip] = MesaTestCase.new(
755
+ test: tc_name.strip,
756
+ mod: mod,
757
+ position: num.to_i,
758
+ mesa: self
759
+ )
760
+ rescue TestCaseDirError
761
+ shell.say "No such test case #{tc_name.strip}. Skipping loading it.", :red
762
+ end
611
763
  end
612
764
  end
613
765
  end
@@ -647,11 +799,16 @@ class Mesa
647
799
  def installed?
648
800
  # assume build log reflects installation status; does not account for
649
801
  # mucking with modules after the fact
650
- downloaded? && File.read(File.join(mesa_dir, 'build.log')).include?(
802
+ build_log = File.join(mesa_dir, 'build.log')
803
+ downloaded? && File.exist?(build_log) && File.read(build_log).include?(
651
804
  'MESA installation was successful'
652
805
  )
653
806
  end
654
807
 
808
+ def install_attempted?
809
+ File.exist? File.join(mesa_dir, 'testhub.yml')
810
+ end
811
+
655
812
  private
656
813
 
657
814
  # verify that mesa_dir is valid by checking for existence of test_suite
@@ -836,6 +993,36 @@ class MesaTestCase
836
993
  YAML.safe_load(File.read(testhub_file), [Symbol])
837
994
  end
838
995
 
996
+ # whether or not a test case has passed; only has meaning
997
+ # if we can load the results hash, though
998
+ def passed?
999
+ results_hash['outcome'] == :pass
1000
+ end
1001
+
1002
+ # Base-64 encoded contents of mk.txt file
1003
+ def mk_64
1004
+ mk_file = File.join(test_case_dir, 'mk.txt')
1005
+ return '' unless File.exist?(mk_file)
1006
+
1007
+ b64_file(mk_file)
1008
+ end
1009
+
1010
+ # Base-64 encoded contents of err.txt file
1011
+ def err_64
1012
+ err_file = File.join(test_case_dir, 'err.txt')
1013
+ return '' unless File.exist?(err_file)
1014
+
1015
+ b64_file(err_file)
1016
+ end
1017
+
1018
+ # Base-64 encoded contents of out.txt file
1019
+ def out_64
1020
+ out_file = File.join(test_case_dir, 'out.txt')
1021
+ return '' unless File.exist?(out_file)
1022
+
1023
+ b64_file(out_file)
1024
+ end
1025
+
839
1026
  private
840
1027
 
841
1028
  # cd into the test case directory, do something in a block, then cd back
@@ -934,3 +1121,8 @@ end
934
1121
  def bashticks(command)
935
1122
  `bash -c "#{command}"`.chomp
936
1123
  end
1124
+
1125
+ # encode the contents of a file as base-64
1126
+ def b64_file(filename)
1127
+ Base64.encode64(File.open(filename).read)
1128
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mesa_test
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Wolf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2021-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubygems_version: 3.0.4
84
+ rubygems_version: 3.2.3
85
85
  signing_key:
86
86
  specification_version: 4
87
87
  summary: Command line tool for running and reporting the MESA test suites.