bugsnag-maze-runner 7.23.0 → 7.24.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 278a8086385e122760909cdb546fe9a15d76e24d5d13948c45bb097d86427f4a
4
- data.tar.gz: 56a21399890869570fa4acffdbe962714fb423307e3b7575edc3bee14358d315
3
+ metadata.gz: f07c9dfdaab73bc584bf02c73a553e949851c700d2d1b54411b1886e936f9b3d
4
+ data.tar.gz: 8894d62125f81610660c6df39a05ad73c03b21cb12d8bff69888e9bc1bec3d1e
5
5
  SHA512:
6
- metadata.gz: bc3bca3a7e2471c755ec2e3ba6c7479fd62dc1cdcb46a503332ed31c148554f4c2bd664e43038af537930eedc1f322656baf718905242088fcaaa1f37e134e35
7
- data.tar.gz: 716512518c9dd9124137bd4e1a867c8799dbfdbfc9ae87eec12d38a9da0835e8e34d128999afe24020863cc6bfbb7ae1170ae9d60bd587e7ce973921a70c3420
6
+ metadata.gz: fe3934ed47df9f0c0c921f66802b8cccdd8aa06af1e17005079850009bc797107d13f612a4dcdb708868215ffd5bd3ab7b97a08f2e333f04feb9bf70d8728144
7
+ data.tar.gz: 59bf8a127529f30624586d86493f8db88c5b142ef42841dc58082890229925e7cf4e17946855222d0f10c7fd7a6845622d872f2de829c8d5bbcaa321fdaa3e7a
data/bin/maze-runner CHANGED
@@ -26,6 +26,7 @@ require_relative '../lib/maze/client/selenium/base_client'
26
26
  require_relative '../lib/maze/client/selenium/bb_client'
27
27
  require_relative '../lib/maze/client/selenium/bs_client'
28
28
  require_relative '../lib/maze/client/selenium/local_client'
29
+
29
30
  require_relative '../lib/maze/aws_public_ip'
30
31
  require_relative '../lib/maze/compare'
31
32
  require_relative '../lib/maze/docker'
@@ -82,6 +83,7 @@ require_relative '../lib/maze/plugins/bugsnag_reporting_plugin'
82
83
  require_relative '../lib/maze/plugins/cucumber_report_plugin'
83
84
  require_relative '../lib/maze/plugins/error_code_plugin'
84
85
  require_relative '../lib/maze/plugins/global_retry_plugin'
86
+ require_relative '../lib/maze/plugins/datadog_metrics_plugin'
85
87
 
86
88
  # Require monkey-patches after everything else
87
89
  require_relative '../lib/utils/selenium_money_patch'
data/bin/upload-app CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  require_relative '../lib/maze'
5
5
  require_relative '../lib/maze/client/bs_client_utils'
6
+ require_relative '../lib/maze/client/bb_client_utils'
6
7
  require_relative '../lib/maze/logger'
7
8
  require_relative '../lib/maze/helper'
8
9
  require 'optimist'
@@ -11,45 +12,70 @@ require 'net/http'
11
12
 
12
13
  class UploadAppEntry
13
14
  def start(args)
14
- p = Optimist::Parser.new do
15
- text 'Upload app files to BrowserStack'
16
- text ''
17
- text 'Requires BROWSER_STACK_USERNAME and BROWSER_STACK_ACCESS_KEY'
15
+ parser = Optimist::Parser.new do
16
+ text 'Upload app files to a device farm'
18
17
  text ''
19
18
  text 'Usage [OPTIONS]'
20
19
  text ''
21
20
  opt :help,
22
- 'Print this help.'
21
+ 'Print this help.'
23
22
  opt :app,
24
- 'The app to upload.',
25
- :type => :string
23
+ 'The app to upload.',
24
+ type: :string,
25
+ required: true
26
26
  opt :app_id_file,
27
- 'The file to write the uploaded app ID back to',
28
- :type => :string
27
+ 'The file to write the uploaded app ID back to',
28
+ type: :string
29
+ opt :farm,
30
+ 'The device farm to upload the app to, one of bb (BitBar) or bs (BrowserStack) (default)',
31
+ type: :string,
32
+ default: 'bs'
33
+ opt :username,
34
+ 'Device farm username. Defaults to BROWSER_STACK_DEVICES_USERNAME variable (required for BrowserStack)',
35
+ type: :string
36
+ opt :access_key,
37
+ 'Device farm access key. Defaults to BROWSER_STACK_DEVICES_ACCESS_KEY or BITBAR_ACCESS_KEY environment variables (required)',
38
+ type: :string
29
39
  end
30
40
 
31
- opts = Optimist::with_standard_exception_handling p do
41
+ options = Optimist::with_standard_exception_handling parser do
32
42
  raise Optimist::HelpNeeded if ARGV.empty? # show help screen
33
- p.parse ARGV
43
+ parser.parse ARGV
34
44
  end
35
45
 
36
- # Get browserstack username and access key from the environment
37
- username = ENV['BROWSER_STACK_USERNAME']
38
- access_key = ENV['BROWSER_STACK_ACCESS_KEY']
46
+ # Get username and access key from the environment
47
+ case options[:farm]
48
+ when 'bs'
49
+ options[:username] ||= ENV['BROWSER_STACK_DEVICES_USERNAME'] || ENV['BROWSER_STACK_USERNAME']
50
+ options[:access_key] ||= ENV['BROWSER_STACK_DEVICES_ACCESS_KEY'] ||ENV['BROWSER_STACK_ACCESS_KEY']
51
+ if options[:username].nil?
52
+ $logger.warn 'Browserstack requires username option to be set'
53
+ Optimist::with_standard_exception_handling parser do
54
+ raise Optimist::HelpNeeded
55
+ end
56
+ end
57
+ when 'bb'
58
+ options[:access_key] ||= ENV['BITBAR_ACCESS_KEY']
59
+ end
39
60
 
40
- # Check if BROWSER_STACK_USERNAME or BROWSER_STACK_ACCESS_KEY has been set
41
- if username.nil? || access_key.nil?
42
- $logger.warn "BROWSER_STACK_USERNAME or BROWSER_STACK_ACCESS_KEY has not been set"
43
- Optimist::with_standard_exception_handling p do
61
+ if options[:access_key].nil?
62
+ $logger.warn 'An access_key is required to upload the app'
63
+ Optimist::with_standard_exception_handling parser do
44
64
  raise Optimist::HelpNeeded
45
65
  end
46
66
  end
47
67
 
48
- Maze::Client::BrowserStackClientUtils.upload_app username,
49
- access_key,
50
- opts[:app],
51
- opts[:app_id_file]
52
-
68
+ case options[:farm]
69
+ when 'bs'
70
+ Maze::Client::BrowserStackClientUtils.upload_app options[:username],
71
+ options[:access_key],
72
+ options[:app],
73
+ options[:app_id_file]
74
+ when 'bb'
75
+ Maze::Client::BitBarClientUtils.upload_app options[:access_key],
76
+ options[:app],
77
+ options[:app_id_file]
78
+ end
53
79
  end
54
80
  end
55
81
 
@@ -103,7 +103,7 @@ end
103
103
  # @step_input url [String] The URL to open.
104
104
  When('I open the URL {string}') do |url|
105
105
  begin
106
- open(url, &:read)
106
+ URI.open(url, &:read)
107
107
  rescue OpenURI::HTTPError
108
108
  $logger.debug $!.inspect
109
109
  end
@@ -148,6 +148,12 @@ Then('a span field {string} equals {string}') do |key, expected|
148
148
  Maze.check.includes selected_keys, expected
149
149
  end
150
150
 
151
+ Then('a span field {string} equals {int}') do |key, expected|
152
+ spans = spans_from_request_list(Maze::Server.list_for('traces'))
153
+ selected_keys = spans.map { |span| span[key] }
154
+ Maze.check.includes selected_keys, expected
155
+ end
156
+
151
157
  Then('a span field {string} matches the regex {string}') do |attribute, pattern|
152
158
  regex = Regexp.new pattern
153
159
  spans = spans_from_request_list(Maze::Server.list_for('traces'))
@@ -65,6 +65,9 @@ BeforeAll do
65
65
  # Start document server, if asked for
66
66
  # This must happen after any client hooks have run, so that they can set the server root
67
67
  Maze::DocumentServer.start unless Maze.config.document_server_root.nil?
68
+
69
+ # An initial setup for total success status
70
+ $success = true
68
71
  end
69
72
 
70
73
  # @param config The Cucumber config
@@ -141,6 +144,9 @@ After do |scenario|
141
144
  output_received_requests('invalid requests')
142
145
  end
143
146
 
147
+ # Keep a global record of the total test status for reporting purposes
148
+ $success = !scenario.failed?
149
+
144
150
  # Log all received requests to file
145
151
  Maze::MazeOutput.new(scenario).write_requests if Maze.config.file_log
146
152
 
@@ -70,25 +70,37 @@ module Maze
70
70
  #
71
71
  # @return [Hash] A hash containing the capabilities.
72
72
  def dashboard_capabilities
73
- # Attempt to use the current git repo as the project name
74
- output, status = Maze::Runner.run_command('git rev-parse --show-toplevel')
75
- if status == 0
76
- project = File.basename(output[0].strip)
73
+
74
+ # Determine project name
75
+ if ENV['BUILDKITE']
76
+ $logger.info 'Using BUILDKITE_PIPELINE_SLUG for BitBar project name'
77
+ project = ENV['BUILDKITE_PIPELINE_SLUG']
77
78
  else
78
- if ENV['BUILDKITE']
79
- project = ENV['BUILDKITE_PIPELINE_SLUG']
79
+ # Attempt to use the current git repo
80
+ output, status = Maze::Runner.run_command('git rev-parse --show-toplevel')
81
+ if status == 0
82
+ project = File.basename(output[0].strip)
80
83
  else
81
84
  $logger.warn 'Unable to determine project name, consider running Maze Runner from within a Git repository'
82
85
  project = 'Unknown'
83
86
  end
84
87
  end
85
88
 
89
+ # Test run
86
90
  if ENV['BUILDKITE']
87
- test_run = "#{ENV['BUILDKITE_BUILD_NUMBER']} - #{ENV['BUILDKITE_LABEL']}"
91
+ bk_retry = ENV['BUILDKITE_RETRY_COUNT']
92
+ retry_string = if !bk_retry.nil? && bk_retry.to_i > 1
93
+ " (#{bk_retry})"
94
+ else
95
+ ''
96
+ end
97
+ test_run = "#{ENV['BUILDKITE_BUILD_NUMBER']} - #{ENV['BUILDKITE_LABEL']}#{retry_string}"
88
98
  else
89
99
  test_run = Maze.run_uuid
90
100
  end
91
101
 
102
+ $logger.info "BitBar project name: #{project}"
103
+ $logger.info "BitBar test run: #{test_run}"
92
104
  {
93
105
  'bitbar:options' => {
94
106
  bitbar_project: project,
@@ -41,7 +41,9 @@ module Maze
41
41
  all_devices = query_api(path, query)
42
42
 
43
43
  $logger.debug "All available devices in group #{device_group_id}: #{JSON.pretty_generate(all_devices)}"
44
+ Maze::Plugins::DatadogMetricsPlugin.send_gauge('bitbar.device.available', all_devices['data'].size, [Maze.config.device])
44
45
  filtered_devices = all_devices['data'].reject { |device| device['locked'] }
46
+ Maze::Plugins::DatadogMetricsPlugin.send_gauge('bitbar.device.unlocked', filtered_devices.size, [Maze.config.device])
45
47
  return filtered_devices.size, filtered_devices.sample
46
48
  end
47
49
 
@@ -17,7 +17,8 @@ module Maze
17
17
  # Uploads an app to BitBar for later consumption
18
18
  # @param api_key [String] The BitBar API key
19
19
  # @param app [String] A path to the application file
20
- def upload_app(api_key, app)
20
+ # @param app_id_file [String] the file to write the uploaded app url to BitBar
21
+ def upload_app(api_key, app, app_id_file=nil)
21
22
  uuid_regex = /\A[0-9]+\z/
22
23
 
23
24
  if uuid_regex.match? app
@@ -53,6 +54,12 @@ module Maze
53
54
  raise
54
55
  end
55
56
  end
57
+
58
+ unless app_id_file.nil?
59
+ $logger.info "Writing uploaded app id to #{app_id_file}"
60
+ File.write(Maze::Helper.expand_path(app_id_file), app_uuid)
61
+ end
62
+
56
63
  app_uuid
57
64
  end
58
65
 
@@ -6,6 +6,10 @@ module Maze
6
6
  raise 'Method not implemented by this class'
7
7
  end
8
8
 
9
+ def log_run_outro
10
+ raise 'Method not implemented by this class'
11
+ end
12
+
9
13
  def stop_session
10
14
  Maze.driver&.driver_quit
11
15
  end
@@ -27,6 +27,15 @@ module Maze
27
27
  Maze.driver.start_driver
28
28
  end
29
29
 
30
+ def log_run_outro
31
+ api_client = BitBarApiClient.new(Maze.config.access_key)
32
+
33
+ $logger.info 'Selenium session created:'
34
+ id = Maze.driver.session_id
35
+ link = api_client.get_device_session_ui_link(id)
36
+ $logger.info Maze::LogUtil.linkify link, 'BitBar session(s)' if link
37
+ end
38
+
30
39
  def stop_session
31
40
  super
32
41
  Maze::Client::BitBarClientUtils.stop_local_tunnel
@@ -59,6 +59,10 @@ module Maze
59
59
  Maze::Client::BrowserStackClientUtils.stop_local_tunnel
60
60
  end
61
61
 
62
+ def log_run_outro
63
+ log_session_info
64
+ end
65
+
62
66
  private
63
67
 
64
68
  # Determines and returns sensible project and build capabilities
@@ -92,6 +92,13 @@ module Maze
92
92
  end
93
93
  end
94
94
 
95
+ # Returns the driver session ID
96
+ #
97
+ # @returns [String] The session ID of the selenium session
98
+ def session_id
99
+ @driver.session_id
100
+ end
101
+
95
102
  private
96
103
 
97
104
  # Creates and starts the selenium driver
@@ -6,6 +6,7 @@ module Maze
6
6
  @client
7
7
 
8
8
  def before_all
9
+ Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_started')
9
10
  @client = Maze::Client::Appium.start
10
11
  end
11
12
 
@@ -30,6 +31,11 @@ module Maze
30
31
 
31
32
  def after_all
32
33
  @client&.log_run_outro
34
+ if $success
35
+ Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_succeeded')
36
+ else
37
+ Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_failed')
38
+ end
33
39
  end
34
40
 
35
41
  def at_exit
@@ -7,8 +7,12 @@ module Maze
7
7
  @client = Maze::Client::Selenium.start
8
8
  end
9
9
 
10
+ def after_all
11
+ @client&.log_run_outro
12
+ end
13
+
10
14
  def at_exit
11
- @client.stop_session
15
+ @client&.stop_session
12
16
  end
13
17
  end
14
18
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'datadog/statsd'
4
+
5
+ module Maze
6
+ module Plugins
7
+ # Enables metrics to be reported to Datadog via a StatsD proxy
8
+ class DatadogMetricsPlugin
9
+
10
+ class << self
11
+ # Sends a gauge metric to Datadog
12
+ #
13
+ # @param metric [String] The identifier of the metric
14
+ # @param value [Integer] The value of the metric
15
+ # @param tags [Array] An array of strings with which to tag the metric
16
+ def send_gauge(metric, value, tags=[])
17
+ return unless logging?
18
+ stats_dog.gauge(metric, value, tags: tags)
19
+ end
20
+
21
+ # Sends an increment metric to Datadog
22
+ #
23
+ # @param metric [String] The identifier of the metric
24
+ # @param tags [Array] An array of strings with which to tag the metric
25
+ def send_increment(metric, tags=[])
26
+ return unless logging?
27
+ stats_dog.increment(metric, tags: tags)
28
+ end
29
+
30
+ private
31
+
32
+ # Whether metrics should be delivered to Datadog
33
+ #
34
+ # @returns [Boolean] Whether metrics should be sent
35
+ def logging?
36
+ ENV['BUILDKITE']
37
+ end
38
+
39
+ # Returns or initialises the DogStatsD instance
40
+ #
41
+ # @returns [Datadog::Statsd] The DogStatsD instance
42
+ def stats_dog
43
+ @stats_dog ||= initialize_stats_dog
44
+ end
45
+
46
+ # Initializes the DogStatsD instance, connecting to the buildkite agent Datadog agent
47
+ #
48
+ # @returns [Datadog::Statsd] The newly created DogStatsD instance
49
+ def initialize_stats_dog
50
+ tags = []
51
+ tags << Maze.config.device.to_s if Maze.config.device
52
+ tags << Maze.config.farm.to_s if Maze.config.farm
53
+ @stats_dog = Datadog::Statsd.new(aws_instance_ip, 8125, tags: tags, namespace: 'maze-runner')
54
+
55
+ at_exit do
56
+ @stats_dog.close
57
+ end
58
+
59
+ @stats_dog
60
+ end
61
+
62
+ # Retrieves the internal ipv4 address of the AWS buildkite instance the maze-runner container is run upon
63
+ #
64
+ # @returns [String] The local ipv4 address the Datadog agent is running on
65
+ def aws_instance_ip
66
+ `curl --silent -XGET http://169.254.169.254/latest/meta-data/local-ipv4`
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/maze.rb CHANGED
@@ -7,7 +7,7 @@ require_relative 'maze/timers'
7
7
  # Glues the various parts of MazeRunner together that need to be accessed globally,
8
8
  # providing an alternative to the proliferation of global variables or singletons.
9
9
  module Maze
10
- VERSION = '7.23.0'
10
+ VERSION = '7.24.0'
11
11
 
12
12
  class << self
13
13
  attr_accessor :check, :driver, :internal_hooks, :mode, :start_time, :dynamic_retry, :public_address, :run_uuid
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag-maze-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.23.0
4
+ version: 7.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Kirkland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-20 00:00:00.000000000 Z
11
+ date: 2023-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 0.9.6
167
+ - !ruby/object:Gem::Dependency
168
+ name: dogstatsd-ruby
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 5.5.0
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 5.5.0
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: optimist
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -401,6 +415,7 @@ files:
401
415
  - lib/maze/option/validator.rb
402
416
  - lib/maze/plugins/bugsnag_reporting_plugin.rb
403
417
  - lib/maze/plugins/cucumber_report_plugin.rb
418
+ - lib/maze/plugins/datadog_metrics_plugin.rb
404
419
  - lib/maze/plugins/error_code_plugin.rb
405
420
  - lib/maze/plugins/global_retry_plugin.rb
406
421
  - lib/maze/proxy.rb