appsignal 2.1.2 → 2.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +14 -0
  3. data/.rubocop_todo.yml +16 -171
  4. data/.travis.yml +14 -1
  5. data/.yardopts +8 -0
  6. data/CHANGELOG.md +21 -3
  7. data/README.md +20 -2
  8. data/Rakefile +60 -62
  9. data/appsignal.gemspec +24 -23
  10. data/ext/agent.yml +11 -11
  11. data/ext/appsignal_extension.c +43 -12
  12. data/ext/extconf.rb +9 -9
  13. data/gemfiles/padrino.gemfile +1 -1
  14. data/lib/appsignal.rb +403 -26
  15. data/lib/appsignal/auth_check.rb +28 -1
  16. data/lib/appsignal/cli.rb +1 -0
  17. data/lib/appsignal/cli/demo.rb +40 -0
  18. data/lib/appsignal/cli/diagnose.rb +345 -89
  19. data/lib/appsignal/cli/helpers.rb +9 -4
  20. data/lib/appsignal/cli/install.rb +6 -6
  21. data/lib/appsignal/cli/notify_of_deploy.rb +58 -0
  22. data/lib/appsignal/config.rb +40 -38
  23. data/lib/appsignal/demo.rb +20 -0
  24. data/lib/appsignal/event_formatter.rb +4 -0
  25. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +1 -0
  26. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +1 -0
  27. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -0
  28. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +1 -0
  29. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +1 -0
  30. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +2 -1
  31. data/lib/appsignal/event_formatter/moped/query_formatter.rb +1 -0
  32. data/lib/appsignal/extension.rb +1 -0
  33. data/lib/appsignal/garbage_collection_profiler.rb +20 -19
  34. data/lib/appsignal/hooks.rb +1 -0
  35. data/lib/appsignal/hooks/active_support_notifications.rb +1 -0
  36. data/lib/appsignal/hooks/celluloid.rb +1 -0
  37. data/lib/appsignal/hooks/data_mapper.rb +1 -0
  38. data/lib/appsignal/hooks/delayed_job.rb +1 -0
  39. data/lib/appsignal/hooks/mongo_ruby_driver.rb +1 -0
  40. data/lib/appsignal/hooks/net_http.rb +1 -0
  41. data/lib/appsignal/hooks/passenger.rb +1 -0
  42. data/lib/appsignal/hooks/puma.rb +1 -0
  43. data/lib/appsignal/hooks/rake.rb +1 -0
  44. data/lib/appsignal/hooks/redis.rb +1 -0
  45. data/lib/appsignal/hooks/sequel.rb +1 -0
  46. data/lib/appsignal/hooks/shoryuken.rb +1 -0
  47. data/lib/appsignal/hooks/sidekiq.rb +1 -0
  48. data/lib/appsignal/hooks/unicorn.rb +1 -0
  49. data/lib/appsignal/hooks/webmachine.rb +1 -0
  50. data/lib/appsignal/integrations/capistrano/appsignal.cap +4 -4
  51. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +2 -0
  52. data/lib/appsignal/integrations/data_mapper.rb +1 -1
  53. data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -0
  54. data/lib/appsignal/integrations/grape.rb +3 -1
  55. data/lib/appsignal/integrations/mongo_ruby_driver.rb +1 -0
  56. data/lib/appsignal/integrations/padrino.rb +36 -21
  57. data/lib/appsignal/integrations/railtie.rb +2 -2
  58. data/lib/appsignal/integrations/resque.rb +1 -0
  59. data/lib/appsignal/integrations/resque_active_job.rb +1 -0
  60. data/lib/appsignal/integrations/webmachine.rb +27 -24
  61. data/lib/appsignal/js_exception_transaction.rb +8 -8
  62. data/lib/appsignal/marker.rb +41 -4
  63. data/lib/appsignal/minutely.rb +1 -0
  64. data/lib/appsignal/rack/generic_instrumentation.rb +3 -2
  65. data/lib/appsignal/rack/js_exception_catcher.rb +55 -15
  66. data/lib/appsignal/rack/rails_instrumentation.rb +2 -1
  67. data/lib/appsignal/rack/sinatra_instrumentation.rb +4 -2
  68. data/lib/appsignal/rack/streaming_listener.rb +4 -2
  69. data/lib/appsignal/system.rb +5 -31
  70. data/lib/appsignal/transaction.rb +71 -6
  71. data/lib/appsignal/transmitter.rb +24 -13
  72. data/lib/appsignal/utils.rb +18 -11
  73. data/lib/appsignal/utils/params_sanitizer.rb +2 -1
  74. data/lib/appsignal/utils/query_params_sanitizer.rb +1 -0
  75. data/lib/appsignal/version.rb +1 -1
  76. data/resources/appsignal.yml.erb +1 -1
  77. data/spec/lib/appsignal/auth_check_spec.rb +64 -22
  78. data/spec/lib/appsignal/cli/diagnose_spec.rb +539 -81
  79. data/spec/lib/appsignal/cli/helpers_spec.rb +74 -2
  80. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  81. data/spec/lib/appsignal/config_spec.rb +38 -72
  82. data/spec/lib/appsignal/demo_spec.rb +2 -2
  83. data/spec/lib/appsignal/event_formatter_spec.rb +2 -2
  84. data/spec/lib/appsignal/extension_spec.rb +4 -0
  85. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +18 -21
  86. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +1 -1
  87. data/spec/lib/appsignal/hooks/redis_spec.rb +34 -44
  88. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -2
  89. data/spec/lib/appsignal/integrations/grape_spec.rb +6 -6
  90. data/spec/lib/appsignal/integrations/padrino_spec.rb +241 -122
  91. data/spec/lib/appsignal/integrations/railtie_spec.rb +34 -16
  92. data/spec/lib/appsignal/integrations/resque_spec.rb +1 -1
  93. data/spec/lib/appsignal/integrations/sinatra_spec.rb +38 -10
  94. data/spec/lib/appsignal/integrations/webmachine_spec.rb +2 -2
  95. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +7 -6
  96. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +95 -58
  97. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +9 -6
  98. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +11 -10
  99. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +20 -13
  100. data/spec/lib/appsignal/system_spec.rb +2 -32
  101. data/spec/lib/appsignal/transaction_spec.rb +48 -7
  102. data/spec/lib/appsignal/transmitter_spec.rb +52 -33
  103. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +3 -1
  104. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +3 -3
  105. data/spec/lib/appsignal/utils_spec.rb +49 -6
  106. data/spec/lib/appsignal_spec.rb +60 -5
  107. data/spec/spec_helper.rb +4 -3
  108. data/spec/support/helpers/api_request_helper.rb +1 -4
  109. data/spec/support/helpers/dependency_helper.rb +4 -0
  110. data/spec/support/helpers/system_helpers.rb +1 -17
  111. data/spec/support/helpers/time_helpers.rb +1 -1
  112. metadata +19 -8
  113. data/spec/lib/appsignal/system/container_spec.rb +0 -67
  114. data/spec/lib/appsignal/utils/gzip_spec.rb +0 -10
@@ -51,6 +51,7 @@ describe Appsignal::CLI::Helpers do
51
51
  describe ".press_any_key" do
52
52
  before do
53
53
  set_input "a" # a as in any
54
+ prepare_input
54
55
  end
55
56
 
56
57
  it "continues after press" do
@@ -59,12 +60,40 @@ describe Appsignal::CLI::Helpers do
59
60
  end
60
61
  end
61
62
 
63
+ describe ".ask_for_input" do
64
+ it "returns the input" do
65
+ set_input "foo"
66
+ prepare_input
67
+ expect(cli.send(:ask_for_input)).to eq("foo")
68
+ end
69
+
70
+ context "with input ending with a line break" do
71
+ it "returns only the input" do
72
+ set_input "foo\n"
73
+ prepare_input
74
+ expect(cli.send(:ask_for_input)).to eq("foo")
75
+ end
76
+ end
77
+
78
+ context "when user interrupts the program" do
79
+ before do
80
+ expect(cli).to receive(:stdin).and_raise(Interrupt)
81
+ expect(cli).to receive(:exit).with(1)
82
+ capture_stdout(out_stream) { cli.send :ask_for_input }
83
+ end
84
+
85
+ it "exits the process" do
86
+ expect(output).to include("Exiting...")
87
+ end
88
+ end
89
+ end
90
+
62
91
  describe ".yes_or_no" do
63
92
  def yes_or_no
64
93
  capture_stdout(out_stream) { cli.send(:yes_or_no, "yes or no?: ") }
65
94
  end
66
95
 
67
- it "takes yes for an answer" do
96
+ it "takes 'y' for an answer" do
68
97
  set_input ""
69
98
  set_input "nonsense"
70
99
  set_input "y"
@@ -73,7 +102,21 @@ describe Appsignal::CLI::Helpers do
73
102
  expect(yes_or_no).to be_truthy
74
103
  end
75
104
 
76
- it "takes no for an answer" do
105
+ it "takes 'Y' for an answer" do
106
+ set_input "Y"
107
+ prepare_input
108
+
109
+ expect(yes_or_no).to be_truthy
110
+ end
111
+
112
+ it "takes 'yes' for an answer" do
113
+ set_input "yes"
114
+ prepare_input
115
+
116
+ expect(yes_or_no).to be_truthy
117
+ end
118
+
119
+ it "takes 'n' for an answer" do
77
120
  set_input ""
78
121
  set_input "nonsense"
79
122
  set_input "n"
@@ -81,6 +124,35 @@ describe Appsignal::CLI::Helpers do
81
124
 
82
125
  expect(yes_or_no).to be_falsy
83
126
  end
127
+
128
+ it "takes 'N' for an answer" do
129
+ set_input "N"
130
+ prepare_input
131
+
132
+ expect(yes_or_no).to be_falsy
133
+ end
134
+
135
+ it "takes 'no' for an answer" do
136
+ set_input "no"
137
+ prepare_input
138
+
139
+ expect(yes_or_no).to be_falsy
140
+ end
141
+
142
+ context "with a default" do
143
+ def yes_or_no
144
+ capture_stdout(out_stream) do
145
+ cli.send(:yes_or_no, "yes or no?: ", :default => "y")
146
+ end
147
+ end
148
+
149
+ it "returns the default if no input is received from the user" do
150
+ set_input ""
151
+ prepare_input
152
+
153
+ expect(yes_or_no).to be_truthy
154
+ end
155
+ end
84
156
  end
85
157
 
86
158
  describe ".required_input" do
@@ -419,7 +419,7 @@ describe Appsignal::CLI::Install do
419
419
  "Installing for Sinatra",
420
420
  "Sinatra requires some manual configuration.",
421
421
  "require 'appsignal/integrations/sinatra'",
422
- "http://docs.appsignal.com/getting-started/supported-frameworks.html#sinatra"
422
+ "http://docs.appsignal.com/ruby/integrations/sinatra.html"
423
423
  ]
424
424
  end
425
425
  let(:app_name) { "Test app" }
@@ -486,7 +486,7 @@ describe Appsignal::CLI::Install do
486
486
  [
487
487
  "Installing for Padrino",
488
488
  "Padrino requires some manual configuration.",
489
- "http://docs.appsignal.com/getting-started/supported-frameworks.html#padrino"
489
+ "http://docs.appsignal.com/ruby/integrations/padrino.html"
490
490
  ]
491
491
  end
492
492
  let(:app_name) { "Test app" }
@@ -553,7 +553,7 @@ describe Appsignal::CLI::Install do
553
553
  [
554
554
  "Installing for Grape",
555
555
  "Manual Grape configuration needed",
556
- "http://docs.appsignal.com/getting-started/supported-frameworks.html#grape"
556
+ "http://docs.appsignal.com/ruby/integrations/grape.html"
557
557
  ]
558
558
  end
559
559
  let(:app_name) { "Test app" }
@@ -50,34 +50,6 @@ describe Appsignal::Config do
50
50
  end
51
51
  end
52
52
 
53
- describe ":running_in_container" do
54
- subject { config[:running_in_container] }
55
-
56
- context "when running on Heroku" do
57
- around { |example| recognize_as_heroku { example.run } }
58
-
59
- it "is set to true" do
60
- expect(subject).to be_truthy
61
- end
62
- end
63
-
64
- context "when running in container" do
65
- around { |example| recognize_as_container(:docker) { example.run } }
66
-
67
- it "is set to true" do
68
- expect(subject).to be_truthy
69
- end
70
- end
71
-
72
- context "when not running in container" do
73
- around { |example| recognize_as_container(:none) { example.run } }
74
-
75
- it "is set to false" do
76
- expect(subject).to be_falsy
77
- end
78
- end
79
- end
80
-
81
53
  describe ":log" do
82
54
  subject { config[:log] }
83
55
 
@@ -90,8 +62,6 @@ describe Appsignal::Config do
90
62
  end
91
63
 
92
64
  context "when not running on Heroku" do
93
- around { |example| recognize_as_container(:none) { example.run } }
94
-
95
65
  it "is set to file" do
96
66
  expect(subject).to eq("file")
97
67
  end
@@ -109,7 +79,6 @@ describe Appsignal::Config do
109
79
  :active => true
110
80
  )
111
81
  end
112
- around { |example| recognize_as_container(:none) { example.run } }
113
82
 
114
83
  it "merges with the default config" do
115
84
  expect(config.config_hash).to eq(
@@ -131,11 +100,11 @@ describe Appsignal::Config do
131
100
  :frontend_error_catching_path => "/appsignal_error_catcher",
132
101
  :enable_allocation_tracking => true,
133
102
  :enable_gc_instrumentation => false,
134
- :running_in_container => false,
135
103
  :enable_host_metrics => true,
136
104
  :enable_minutely_probes => false,
137
105
  :hostname => Socket.gethostname,
138
- :ca_file_path => File.join(resources_dir, "cacert.pem")
106
+ :ca_file_path => File.join(resources_dir, "cacert.pem"),
107
+ :dns_servers => []
139
108
  )
140
109
  end
141
110
 
@@ -216,7 +185,6 @@ describe Appsignal::Config do
216
185
  :debug => true
217
186
  )
218
187
  end
219
- around { |example| recognize_as_container(:none) { example.run } }
220
188
 
221
189
  it "overrides system detected and defaults config" do
222
190
  expect(config[:running_in_container]).to be_truthy
@@ -315,7 +283,6 @@ describe Appsignal::Config do
315
283
  ENV["APPSIGNAL_INSTRUMENT_REDIS"] = "false"
316
284
  ENV["APPSIGNAL_INSTRUMENT_SEQUEL"] = "false"
317
285
  end
318
- around { |example| recognize_as_container(:none) { example.run } }
319
286
 
320
287
  it "overrides config with environment values" do
321
288
  expect(config.valid?).to be_truthy
@@ -326,7 +293,7 @@ describe Appsignal::Config do
326
293
  expect(config[:active]).to be_truthy
327
294
  expect(config[:name]).to eq "App name"
328
295
  expect(config[:debug]).to be_truthy
329
- expect(config[:ignore_actions]).to eq ["action1", "action2"]
296
+ expect(config[:ignore_actions]).to eq %w(action1 action2)
330
297
  expect(config[:instrument_net_http]).to be_falsey
331
298
  expect(config[:instrument_redis]).to be_falsey
332
299
  expect(config[:instrument_sequel]).to be_falsey
@@ -397,39 +364,43 @@ describe Appsignal::Config do
397
364
  let(:config) { project_fixture_config(:production) }
398
365
  before do
399
366
  config[:http_proxy] = "http://localhost"
400
- config[:ignore_actions] = ["action1", "action2"]
401
- config[:ignore_errors] = ["VerySpecificError", "AnotherError"]
367
+ config[:ignore_actions] = %w(action1 action2)
368
+ config[:ignore_errors] = %w(VerySpecificError AnotherError)
369
+ config[:log] = "stdout"
402
370
  config[:log_path] = "/tmp"
403
371
  config[:hostname] = "app1.local"
404
372
  config[:filter_parameters] = %w(password confirm_password)
405
373
  config[:running_in_container] = false
374
+ config[:dns_servers] = ["8.8.8.8", "8.8.4.4"]
406
375
  config.write_to_environment
407
376
  end
408
377
 
409
378
  it "writes the current config to environment variables" do
410
- expect(ENV["APPSIGNAL_ACTIVE"]).to eq "true"
411
- expect(ENV["APPSIGNAL_APP_PATH"]).to end_with("spec/support/project_fixture")
412
- expect(ENV["APPSIGNAL_AGENT_PATH"]).to end_with("/ext")
413
- expect(ENV["APPSIGNAL_DEBUG_LOGGING"]).to eq "false"
414
- expect(ENV["APPSIGNAL_LOG_FILE_PATH"]).to end_with("/tmp/appsignal.log")
415
- expect(ENV["APPSIGNAL_PUSH_API_ENDPOINT"]).to eq "https://push.appsignal.com"
416
- expect(ENV["APPSIGNAL_PUSH_API_KEY"]).to eq "abc"
417
- expect(ENV["APPSIGNAL_APP_NAME"]).to eq "TestApp"
418
- expect(ENV["APPSIGNAL_ENVIRONMENT"]).to eq "production"
419
- expect(ENV["APPSIGNAL_AGENT_VERSION"]).to eq Appsignal::Extension.agent_version
420
- expect(ENV["APPSIGNAL_LANGUAGE_INTEGRATION_VERSION"]).to eq "ruby-#{Appsignal::VERSION}"
421
- expect(ENV["APPSIGNAL_HTTP_PROXY"]).to eq "http://localhost"
422
- expect(ENV["APPSIGNAL_IGNORE_ACTIONS"]).to eq "action1,action2"
423
- expect(ENV["APPSIGNAL_IGNORE_ERRORS"]).to eq "VerySpecificError,AnotherError"
424
- expect(ENV["APPSIGNAL_FILTER_PARAMETERS"]).to eq "password,confirm_password"
425
- expect(ENV["APPSIGNAL_SEND_PARAMS"]).to eq "true"
426
- expect(ENV["APPSIGNAL_RUNNING_IN_CONTAINER"]).to eq "false"
427
- expect(ENV["APPSIGNAL_ENABLE_HOST_METRICS"]).to eq "true"
428
- expect(ENV["APPSIGNAL_ENABLE_MINUTELY_PROBES"]).to eq "false"
429
- expect(ENV["APPSIGNAL_HOSTNAME"]).to eq "app1.local"
430
- expect(ENV["APPSIGNAL_PROCESS_NAME"]).to include "rspec"
431
- expect(ENV["APPSIGNAL_CA_FILE_PATH"]).to eq File.join(resources_dir, "cacert.pem")
432
- expect(ENV).to_not have_key("APPSIGNAL_WORKING_DIR_PATH")
379
+ expect(ENV["_APPSIGNAL_ACTIVE"]).to eq "true"
380
+ expect(ENV["_APPSIGNAL_APP_PATH"]).to end_with("spec/support/project_fixture")
381
+ expect(ENV["_APPSIGNAL_AGENT_PATH"]).to end_with("/ext")
382
+ expect(ENV["_APPSIGNAL_DEBUG_LOGGING"]).to eq "false"
383
+ expect(ENV["_APPSIGNAL_LOG"]).to eq "stdout"
384
+ expect(ENV["_APPSIGNAL_LOG_FILE_PATH"]).to end_with("/tmp/appsignal.log")
385
+ expect(ENV["_APPSIGNAL_PUSH_API_ENDPOINT"]).to eq "https://push.appsignal.com"
386
+ expect(ENV["_APPSIGNAL_PUSH_API_KEY"]).to eq "abc"
387
+ expect(ENV["_APPSIGNAL_APP_NAME"]).to eq "TestApp"
388
+ expect(ENV["_APPSIGNAL_ENVIRONMENT"]).to eq "production"
389
+ expect(ENV["_APPSIGNAL_AGENT_VERSION"]).to eq Appsignal::Extension.agent_version
390
+ expect(ENV["_APPSIGNAL_LANGUAGE_INTEGRATION_VERSION"]).to eq "ruby-#{Appsignal::VERSION}"
391
+ expect(ENV["_APPSIGNAL_HTTP_PROXY"]).to eq "http://localhost"
392
+ expect(ENV["_APPSIGNAL_IGNORE_ACTIONS"]).to eq "action1,action2"
393
+ expect(ENV["_APPSIGNAL_IGNORE_ERRORS"]).to eq "VerySpecificError,AnotherError"
394
+ expect(ENV["_APPSIGNAL_FILTER_PARAMETERS"]).to eq "password,confirm_password"
395
+ expect(ENV["_APPSIGNAL_SEND_PARAMS"]).to eq "true"
396
+ expect(ENV["_APPSIGNAL_RUNNING_IN_CONTAINER"]).to eq "false"
397
+ expect(ENV["_APPSIGNAL_ENABLE_HOST_METRICS"]).to eq "true"
398
+ expect(ENV["_APPSIGNAL_ENABLE_MINUTELY_PROBES"]).to eq "false"
399
+ expect(ENV["_APPSIGNAL_HOSTNAME"]).to eq "app1.local"
400
+ expect(ENV["_APPSIGNAL_PROCESS_NAME"]).to include "rspec"
401
+ expect(ENV["_APPSIGNAL_CA_FILE_PATH"]).to eq File.join(resources_dir, "cacert.pem")
402
+ expect(ENV["_APPSIGNAL_DNS_SERVERS"]).to eq "8.8.8.8,8.8.4.4"
403
+ expect(ENV).to_not have_key("_APPSIGNAL_WORKING_DIR_PATH")
433
404
  end
434
405
 
435
406
  context "with :working_dir_path" do
@@ -439,7 +410,7 @@ describe Appsignal::Config do
439
410
  end
440
411
 
441
412
  it "sets the modified :working_dir_path" do
442
- expect(ENV["APPSIGNAL_WORKING_DIR_PATH"]).to eq "/tmp/appsignal2"
413
+ expect(ENV["_APPSIGNAL_WORKING_DIR_PATH"]).to eq "/tmp/appsignal2"
443
414
  end
444
415
  end
445
416
  end
@@ -449,15 +420,10 @@ describe Appsignal::Config do
449
420
  let(:output) { out_stream.read }
450
421
  let(:config) { project_fixture_config("production", :log_path => log_path) }
451
422
  subject { capture_stdout(out_stream) { config.log_file_path } }
452
- around do |example|
453
- recognize_as_container(:none) do
454
- example.run
455
- end
456
- end
457
423
 
458
424
  context "when path is writable" do
459
425
  let(:log_path) { File.join(tmp_dir, "writable-path") }
460
- before { FileUtils.mkdir_p(log_path, :mode => 0755) }
426
+ before { FileUtils.mkdir_p(log_path, :mode => 0o755) }
461
427
  after { FileUtils.rm_rf(log_path) }
462
428
 
463
429
  it "returns log file path" do
@@ -476,7 +442,7 @@ describe Appsignal::Config do
476
442
  after { FileUtils.rm_rf(system_tmp_dir) }
477
443
 
478
444
  context "when the /tmp fallback path is writable" do
479
- before { FileUtils.chmod(0777, system_tmp_dir) }
445
+ before { FileUtils.chmod(0o777, system_tmp_dir) }
480
446
 
481
447
  it "returns returns the tmp location" do
482
448
  expect(subject).to eq(File.join(system_tmp_dir, "appsignal.log"))
@@ -490,7 +456,7 @@ describe Appsignal::Config do
490
456
  end
491
457
 
492
458
  context "when the /tmp fallback path is not writable" do
493
- before { FileUtils.chmod(0555, system_tmp_dir) }
459
+ before { FileUtils.chmod(0o555, system_tmp_dir) }
494
460
 
495
461
  it "returns nil" do
496
462
  expect(subject).to be_nil
@@ -533,7 +499,7 @@ describe Appsignal::Config do
533
499
 
534
500
  context "when path is not writable" do
535
501
  let(:log_path) { File.join(tmp_dir, "not-writable-path") }
536
- before { FileUtils.mkdir_p(log_path, :mode => 0555) }
502
+ before { FileUtils.mkdir_p(log_path, :mode => 0o555) }
537
503
  after { FileUtils.rm_rf(log_path) }
538
504
 
539
505
  include_examples "#log_file_path: tmp path"
@@ -555,7 +521,7 @@ describe Appsignal::Config do
555
521
  let(:log_path) { File.join(tmp_dir, "symlink-path") }
556
522
  before do
557
523
  FileUtils.mkdir_p(real_path)
558
- FileUtils.chmod(0444, real_path)
524
+ FileUtils.chmod(0o444, real_path)
559
525
  File.symlink(real_path, log_path)
560
526
  end
561
527
  after do
@@ -11,7 +11,7 @@ describe Appsignal::Demo do
11
11
 
12
12
  context "without config" do
13
13
  it "returns false" do
14
- expect(silence { subject }).to be_falsy
14
+ expect(silence { subject }).to eq(false)
15
15
  end
16
16
  end
17
17
 
@@ -20,7 +20,7 @@ describe Appsignal::Demo do
20
20
  before { Appsignal.config = config }
21
21
 
22
22
  it "returns true" do
23
- expect(subject).to be_truthy
23
+ expect(subject).to eq(true)
24
24
  end
25
25
 
26
26
  it "creates demonstration samples" do
@@ -8,12 +8,12 @@ class MockFormatter < Appsignal::EventFormatter
8
8
  end
9
9
 
10
10
  def format(_payload)
11
- ["title", @body]
11
+ ["title", body]
12
12
  end
13
13
  end
14
14
 
15
15
  class MissingFormatMockFormatter < Appsignal::EventFormatter
16
- def transform(payload)
16
+ def transform(_payload)
17
17
  end
18
18
  end
19
19
 
@@ -63,6 +63,10 @@ describe "extension loading and operation" do
63
63
  subject.set_action("value")
64
64
  end
65
65
 
66
+ it "should have a set_namespace method" do
67
+ subject.set_namespace("value")
68
+ end
69
+
66
70
  it "should have a set_queue_start method" do
67
71
  subject.set_queue_start(10)
68
72
  end
@@ -1,44 +1,41 @@
1
1
  describe Appsignal::GarbageCollectionProfiler do
2
2
  let(:internal_profiler) { FakeGCProfiler.new }
3
+ let(:profiler) { described_class.new }
3
4
 
4
5
  before do
5
- allow_any_instance_of(Appsignal::GarbageCollectionProfiler)
6
+ allow_any_instance_of(described_class)
6
7
  .to receive(:internal_profiler)
7
8
  .and_return(internal_profiler)
8
9
  end
9
10
 
10
- it "should have a total time of 0" do
11
- expect(Appsignal::GarbageCollectionProfiler.new.total_time).to eq(0)
11
+ context "on initialization" do
12
+ it "has a total time of 0" do
13
+ expect(profiler.total_time).to eq(0)
14
+ end
12
15
  end
13
16
 
14
- describe "after a GC run" do
15
- before do
16
- internal_profiler.total_time = 0.12345
17
- @profiler = Appsignal::GarbageCollectionProfiler.new
18
- end
17
+ context "when the GC has run" do
18
+ before { internal_profiler.total_time = 0.12345 }
19
19
 
20
- it "should take the total time from Ruby's GC::Profiler" do
21
- expect(@profiler.total_time).to eq(123)
20
+ it "fetches the total time from Ruby's GC::Profiler" do
21
+ expect(profiler.total_time).to eq(123)
22
22
  end
23
23
 
24
- it "should clear Ruby's GC::Profiler" do
24
+ it "clears Ruby's GC::Profiler afterward" do
25
25
  expect(internal_profiler).to receive(:clear)
26
- @profiler.total_time
26
+ profiler.total_time
27
27
  end
28
28
  end
29
29
 
30
- describe "when the total GC time becomes too high" do
31
- it "should reset" do
32
- profiler = Appsignal::GarbageCollectionProfiler.new
30
+ context "when the total GC time becomes too high" do
31
+ it "resets the total time" do
33
32
  internal_profiler.total_time = 2_147_483_647
34
33
  expect(profiler.total_time).to eq(0)
35
34
  end
36
35
  end
37
36
 
38
- describe "after multiple GC runs" do
39
- it "should add all times from Ruby's GC::Profiler together" do
40
- profiler = Appsignal::GarbageCollectionProfiler.new
41
-
37
+ context "when the GC has run multiple times" do
38
+ it "adds all times from Ruby's GC::Profiler together" do
42
39
  2.times do
43
40
  internal_profiler.total_time = 0.12345
44
41
  profiler.total_time
@@ -48,8 +45,8 @@ describe Appsignal::GarbageCollectionProfiler do
48
45
  end
49
46
  end
50
47
 
51
- describe "in multiple threads, with a slow GC::Profiler" do
52
- it "should not count garbage collection times twice" do
48
+ context "when in multiple threads and with a slow GC::Profiler" do
49
+ it "does not count garbage collection times twice" do
53
50
  threads = []
54
51
  results = []
55
52
  internal_profiler.clear_delay = 0.001