mesa_test 1.0.2 → 1.1.1

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