mesa_test 1.1.12 → 1.2.1
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 +60 -0
- data/lib/mesa_test.rb +104 -16
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c01327f74ca824acf8b7cb473561037281255de396cc623c6c636b9c21bb2ed
|
|
4
|
+
data.tar.gz: 52f1c9d09ece9a85bdfc3827249357ec1ada18da6b14d70793df9b082331bbe9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91a42fce1cf44a643b465edf60351448ea863ebd8ac4e5f962733928b9c620c1dafb251c38cbc4bd9267309ee6298d96fb05a12b35847a974025aa8a183f9037
|
|
7
|
+
data.tar.gz: 19aca1c41bc5519d8082f7ee5e85398a3652d9b7455f21b4ecf2b2b767084e3abfe5fd52a2630f4a17a8248879e84375549b954453f3c2c79a1acdf6590cd6cf
|
data/bin/mesa_test
CHANGED
|
@@ -328,8 +328,68 @@ class MesaTest < Thor
|
|
|
328
328
|
force_setup: true)
|
|
329
329
|
end
|
|
330
330
|
|
|
331
|
+
desc 'search "QUERY"', 'retrieve JSON test instances matching QUERY'
|
|
332
|
+
long_desc <<-LONGDESC
|
|
333
|
+
Sends a GET request to the MesaTestHub search API. QUERY should be
|
|
334
|
+
quoted. Credentials are read from your mesa_test config file and sent as
|
|
335
|
+
URL query parameters (HTTPS is mandatory).
|
|
336
|
+
|
|
337
|
+
Query syntax is the same key-value form used by the in-browser search box
|
|
338
|
+
at testhub.mesastar.org/test_instances/search (see the "Query syntax"
|
|
339
|
+
panel on that page). Example:
|
|
340
|
+
|
|
341
|
+
mesa_test search "computer: Hercules; passed: false"
|
|
342
|
+
|
|
343
|
+
The raw JSON response body is written to STDOUT, suitable for piping to
|
|
344
|
+
jq or redirecting to a file. If the server reports any rejected query
|
|
345
|
+
clauses in a `failures` array, those are also echoed to STDERR so they
|
|
346
|
+
aren't silently dropped from downstream pipelines. On a non-success HTTP
|
|
347
|
+
status, an error is written to STDERR and the command exits non-zero.
|
|
348
|
+
LONGDESC
|
|
349
|
+
|
|
350
|
+
def search(query)
|
|
351
|
+
s = create_submitter(force: true)
|
|
352
|
+
emit_search_response(s.search(query))
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
desc 'count "QUERY"', 'count test instances matching QUERY'
|
|
356
|
+
long_desc <<-LONGDESC
|
|
357
|
+
Like `search`, but hits the count endpoint. The response is a small JSON
|
|
358
|
+
object containing the result-set size (and any `failures`). Use this
|
|
359
|
+
before `search` when you don't know how large a result set will be.
|
|
360
|
+
LONGDESC
|
|
361
|
+
|
|
362
|
+
def count(query)
|
|
363
|
+
s = create_submitter(force: true)
|
|
364
|
+
emit_search_response(s.search_count(query))
|
|
365
|
+
end
|
|
366
|
+
|
|
331
367
|
private
|
|
332
368
|
|
|
369
|
+
def emit_search_response(response)
|
|
370
|
+
if response.is_a?(Net::HTTPSuccess)
|
|
371
|
+
puts response.body
|
|
372
|
+
warn_search_failures(response.body)
|
|
373
|
+
else
|
|
374
|
+
$stderr.puts "Search request failed: HTTP #{response.code} "\
|
|
375
|
+
"#{response.message}"
|
|
376
|
+
$stderr.puts response.body unless response.body.nil? || response.body.empty?
|
|
377
|
+
exit 1
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def warn_search_failures(body)
|
|
382
|
+
parsed = JSON.parse(body)
|
|
383
|
+
failures = parsed['failures']
|
|
384
|
+
return unless failures.is_a?(Array) && !failures.empty?
|
|
385
|
+
|
|
386
|
+
$stderr.puts 'Warning: the following query clauses were rejected by '\
|
|
387
|
+
'the server and ignored:'
|
|
388
|
+
failures.each { |f| $stderr.puts " - #{f}" }
|
|
389
|
+
rescue JSON::ParserError
|
|
390
|
+
# Body wasn't JSON; nothing to surface.
|
|
391
|
+
end
|
|
392
|
+
|
|
333
393
|
def work_dir(given, default)
|
|
334
394
|
if given
|
|
335
395
|
File.expand_path('', given)
|
data/lib/mesa_test.rb
CHANGED
|
@@ -18,7 +18,6 @@ GITHUB_HTTPS = 'https://github.com/MESAHub/mesa.git'.freeze
|
|
|
18
18
|
GITHUB_SSH = 'git@github.com:MESAHub/mesa.git'.freeze
|
|
19
19
|
|
|
20
20
|
class MesaTestSubmitter
|
|
21
|
-
# DEFAULT_URI = 'https://mesa-test-hub.herokuapp.com'.freeze
|
|
22
21
|
DEFAULT_URI = 'https://testhub.mesastar.org'.freeze
|
|
23
22
|
|
|
24
23
|
# set up config file for computer
|
|
@@ -52,8 +51,9 @@ e-mail and password will be stored in plain text.'
|
|
|
52
51
|
|
|
53
52
|
# Get API key for submitting failure logs
|
|
54
53
|
response = shell.ask 'What is the logs submission API token associated '\
|
|
55
|
-
"with the email #{s.email} (required;
|
|
56
|
-
"
|
|
54
|
+
"with the email #{s.email} (required; if you don't have one, ask a "\
|
|
55
|
+
"MESA testing maintainer or a representative from Flatiron for a "\
|
|
56
|
+
"key)? (#{s.logs_token})", :blue
|
|
57
57
|
s.logs_token = response unless response.empty?
|
|
58
58
|
|
|
59
59
|
# Determine if we'll use ssh or https to access github
|
|
@@ -330,7 +330,12 @@ e-mail and password will be stored in plain text.'
|
|
|
330
330
|
password: password,
|
|
331
331
|
computer_name: computer_name
|
|
332
332
|
}.to_json
|
|
333
|
-
|
|
333
|
+
response = testhub_request(https, request)
|
|
334
|
+
# if the hub was unreachable, behave as an unverified computer; the
|
|
335
|
+
# network error has already been reported by testhub_request
|
|
336
|
+
return {} if response.nil?
|
|
337
|
+
|
|
338
|
+
JSON.parse(response.body).to_hash
|
|
334
339
|
end
|
|
335
340
|
|
|
336
341
|
# submit entire commit's worth of test cases, OR submit compilation status
|
|
@@ -366,11 +371,15 @@ e-mail and password will be stored in plain text.'
|
|
|
366
371
|
request.body = request_data.to_json
|
|
367
372
|
|
|
368
373
|
# actually do the submission
|
|
369
|
-
response = https
|
|
374
|
+
response = testhub_request(https, request)
|
|
370
375
|
|
|
371
|
-
if
|
|
376
|
+
if response.nil?
|
|
377
|
+
# network failure; testhub_request already explained why
|
|
378
|
+
false
|
|
379
|
+
elsif !response.is_a? Net::HTTPCreated
|
|
372
380
|
shell.say "\nFailed to submit some or all test case instances and/or "\
|
|
373
|
-
|
|
381
|
+
"commit data (server responded #{response.code} "\
|
|
382
|
+
"#{response.message}).", :red
|
|
374
383
|
false
|
|
375
384
|
else
|
|
376
385
|
shell.say "\nSuccessfully submitted commit #{mesa.sha}.", :green
|
|
@@ -427,12 +436,16 @@ e-mail and password will be stored in plain text.'
|
|
|
427
436
|
request.body = request_data.to_json
|
|
428
437
|
|
|
429
438
|
# actually do the submission
|
|
430
|
-
response = https
|
|
439
|
+
response = testhub_request(https, request)
|
|
431
440
|
|
|
432
|
-
if
|
|
441
|
+
if response.nil?
|
|
442
|
+
# network failure; testhub_request already explained why
|
|
443
|
+
return false
|
|
444
|
+
elsif !response.is_a? Net::HTTPCreated
|
|
433
445
|
shell.say "\nFailed to submit #{test_case.test_name} for commit "\
|
|
434
|
-
"#{mesa.sha}"
|
|
435
|
-
|
|
446
|
+
"#{mesa.sha} (server responded #{response.code} "\
|
|
447
|
+
"#{response.message}).", :red
|
|
448
|
+
return false
|
|
436
449
|
else
|
|
437
450
|
shell.say "\nSuccessfully submitted instance of #{test_case.test_name} "\
|
|
438
451
|
"for commit #{mesa.sha}.", :green
|
|
@@ -444,17 +457,50 @@ e-mail and password will be stored in plain text.'
|
|
|
444
457
|
end
|
|
445
458
|
end
|
|
446
459
|
|
|
460
|
+
# Perform an HTTP request against the test hub with bounded connect/read
|
|
461
|
+
# timeouts, so a slow or unreachable server (e.g. while it is under heavy
|
|
462
|
+
# load) fails fast with a clear message instead of hanging on the default
|
|
463
|
+
# 60-second connect timeout and then dumping a raw Ruby backtrace. Returns
|
|
464
|
+
# the Net::HTTPResponse, or +nil+ if the request could not be completed
|
|
465
|
+
# because of a network problem.
|
|
466
|
+
def testhub_request(https, request)
|
|
467
|
+
https.open_timeout = 10
|
|
468
|
+
https.read_timeout = 60
|
|
469
|
+
https.request(request)
|
|
470
|
+
rescue StandardError => e
|
|
471
|
+
shell.say "\nCould not reach the test hub at #{https.address} "\
|
|
472
|
+
"(#{e.class}: #{e.message}).", :red
|
|
473
|
+
nil
|
|
474
|
+
end
|
|
475
|
+
|
|
447
476
|
# make generic request to LOGS server
|
|
448
477
|
# +params+ is a hash of data to be encoded as JSON and sent off
|
|
478
|
+
#
|
|
479
|
+
# Returns the Net::HTTPResponse on success, or +nil+ if the request could
|
|
480
|
+
# not be completed because of a network problem (the LOGS server being
|
|
481
|
+
# unreachable, slow, or refusing connections). The LOGS server only receives
|
|
482
|
+
# diagnostic build/test output, so a failure here must never crash the run or
|
|
483
|
+
# fail a CI build whose actual test results already reached the test hub. We
|
|
484
|
+
# cap the connect/read time so we fail fast instead of hanging on the default
|
|
485
|
+
# 60-second open timeout for every test case.
|
|
449
486
|
def submit_logs(params)
|
|
450
487
|
#uri = URI('https://logs.mesastar.org/uploads')
|
|
451
488
|
uri = URI('https://mesa-logs.flatironinstitute.org/uploads')
|
|
452
489
|
https = Net::HTTP.new(uri.host, uri.port)
|
|
453
490
|
https.use_ssl = true
|
|
491
|
+
https.open_timeout = 10
|
|
492
|
+
https.read_timeout = 30
|
|
454
493
|
req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json',
|
|
455
494
|
'X-Api-Key' => logs_token)
|
|
456
495
|
req.body = params.to_json
|
|
457
|
-
|
|
496
|
+
begin
|
|
497
|
+
https.request(req)
|
|
498
|
+
rescue StandardError => e
|
|
499
|
+
shell.say "\nCould not reach the LOGS server at #{uri.host} "\
|
|
500
|
+
"(#{e.class}: #{e.message}). Skipping log upload; this does "\
|
|
501
|
+
'not affect test results already sent to the test hub.', :yellow
|
|
502
|
+
nil
|
|
503
|
+
end
|
|
458
504
|
end
|
|
459
505
|
|
|
460
506
|
# send build log to the logs server
|
|
@@ -473,9 +519,13 @@ e-mail and password will be stored in plain text.'
|
|
|
473
519
|
res = submit_logs(build_log_params(mesa))
|
|
474
520
|
|
|
475
521
|
# report out results
|
|
476
|
-
if
|
|
522
|
+
if res.nil?
|
|
523
|
+
# network failure; submit_logs already explained why. Don't fail the run.
|
|
524
|
+
false
|
|
525
|
+
elsif !res.is_a? Net::HTTPOK
|
|
477
526
|
shell.say "\nFailed to submit build.log to the LOGS server for commit "\
|
|
478
|
-
"#{mesa.sha}.",
|
|
527
|
+
"#{mesa.sha} (server responded #{res.code} #{res.message}).",
|
|
528
|
+
:red
|
|
479
529
|
false
|
|
480
530
|
else
|
|
481
531
|
shell.say "\nSuccessfully submitted build.log to the LOGS server for "\
|
|
@@ -503,9 +553,13 @@ e-mail and password will be stored in plain text.'
|
|
|
503
553
|
res = submit_logs(test_log_params(test_case))
|
|
504
554
|
|
|
505
555
|
# report out results
|
|
506
|
-
if
|
|
556
|
+
if res.nil?
|
|
557
|
+
# network failure; submit_logs already explained why. Don't fail the run.
|
|
558
|
+
false
|
|
559
|
+
elsif !res.is_a? Net::HTTPOK
|
|
507
560
|
shell.say "Failed to submit logs for test case #{test_case.test_name} "\
|
|
508
|
-
"in commit #{test_case.mesa.sha}
|
|
561
|
+
"in commit #{test_case.mesa.sha} (server responded "\
|
|
562
|
+
"#{res.code} #{res.message}).", :red
|
|
509
563
|
false
|
|
510
564
|
else
|
|
511
565
|
shell.say "Successfully submitted logs for test case "\
|
|
@@ -515,6 +569,40 @@ e-mail and password will be stored in plain text.'
|
|
|
515
569
|
end
|
|
516
570
|
end
|
|
517
571
|
|
|
572
|
+
# GET a search query from the testhub. Credentials and the query string
|
|
573
|
+
# ride in the URL's query parameters (per the testhub search API contract;
|
|
574
|
+
# the controller also accepts session auth, but a CLI sends them in-band).
|
|
575
|
+
# Returns the raw Net::HTTP response.
|
|
576
|
+
def search(query_text)
|
|
577
|
+
get_search('/test_instances/search.json', query_text)
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
# Like #search, but hits the count endpoint. Useful for sizing a result set
|
|
581
|
+
# before pulling the full payload.
|
|
582
|
+
def search_count(query_text)
|
|
583
|
+
get_search('/test_instances/search_count.json', query_text)
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
private
|
|
587
|
+
|
|
588
|
+
def get_search(path, query_text)
|
|
589
|
+
uri = URI.parse(base_uri + path)
|
|
590
|
+
uri.query = URI.encode_www_form(
|
|
591
|
+
email: email,
|
|
592
|
+
password: password,
|
|
593
|
+
query_text: query_text
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
https = Net::HTTP.new(uri.hostname, uri.port)
|
|
597
|
+
https.use_ssl = base_uri.include? 'https'
|
|
598
|
+
|
|
599
|
+
request = Net::HTTP::Get.new(
|
|
600
|
+
uri,
|
|
601
|
+
initheader = { 'Accept' => 'application/json' }
|
|
602
|
+
)
|
|
603
|
+
|
|
604
|
+
https.request(request)
|
|
605
|
+
end
|
|
518
606
|
end
|
|
519
607
|
|
|
520
608
|
class Mesa
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mesa_test
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- William Wolf
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
10
|
+
date: 2026-05-29 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: json
|
|
@@ -66,7 +65,6 @@ homepage: https://github.com/MESAHub/mesa_test
|
|
|
66
65
|
licenses:
|
|
67
66
|
- MIT
|
|
68
67
|
metadata: {}
|
|
69
|
-
post_install_message:
|
|
70
68
|
rdoc_options: []
|
|
71
69
|
require_paths:
|
|
72
70
|
- lib
|
|
@@ -81,8 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
81
79
|
- !ruby/object:Gem::Version
|
|
82
80
|
version: '0'
|
|
83
81
|
requirements: []
|
|
84
|
-
rubygems_version: 3.
|
|
85
|
-
signing_key:
|
|
82
|
+
rubygems_version: 3.7.1
|
|
86
83
|
specification_version: 4
|
|
87
84
|
summary: Command line tool for running and reporting the MESA test suites.
|
|
88
85
|
test_files: []
|