appsignal 1.4.0.beta.1 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,122 +1,170 @@
1
- require 'appsignal/cli'
1
+ require "appsignal/cli"
2
2
 
3
3
  describe Appsignal::CLI::NotifyOfDeploy do
4
+ include CLIHelpers
5
+
4
6
  let(:out_stream) { StringIO.new }
5
- let(:cli) { Appsignal::CLI::NotifyOfDeploy }
6
- let(:config) { Appsignal::Config.new(project_fixture_path, {}) }
7
- let(:marker_data) { {:revision => 'aaaaa', :user => 'thijs', :environment => 'production'} }
8
- before do
9
- config.stub(:active? => true)
10
- end
7
+ let(:output) { out_stream.string }
11
8
  around do |example|
12
9
  capture_stdout(out_stream) { example.run }
13
10
  end
14
11
 
15
- describe ".run" do
16
- it "should validate that the config has been loaded and all options have been supplied" do
17
- cli.should_receive(:validate_active_config)
18
- cli.should_receive(:validate_required_options).with(
19
- {},
20
- [:revision, :user, :environment]
21
- )
22
- Appsignal::Marker.should_receive(:new).and_return(double(:transmit => true))
23
-
24
- cli.run({}, config)
12
+ define :include_deploy_notification do
13
+ match do |log|
14
+ log.include?("Notifying AppSignal of deploy with: ") &&
15
+ log.include?("AppSignal has been notified of this deploy!")
16
+ end
17
+ end
18
+ define :include_deploy_notification_with do |options|
19
+ match do |log|
20
+ return false unless options
21
+ values = "revision: #{options[:revision]}, user: #{options[:user]}"
22
+ log.include?("Notifying AppSignal of deploy with: #{values}") &&
23
+ log.include?("AppSignal has been notified of this deploy!")
24
+ end
25
+ end
26
+ define :include_config_error do
27
+ match do |log|
28
+ log.include? "Error: No valid config found."
29
+ end
30
+ end
31
+ define :include_missing_options do |options|
32
+ match do |log|
33
+ log.include? "Error: Missing options: #{options.join(", ")}"
25
34
  end
35
+ end
36
+
37
+ def run
38
+ run_cli("notify_of_deploy", options)
39
+ end
26
40
 
27
- it "should notify of a deploy" do
28
- marker = double
29
- Appsignal::Marker.should_receive(:new).with(
30
- {
31
- :revision => 'aaaaa',
32
- :user => 'thijs'
33
- },
34
- kind_of(Appsignal::Config)
35
- ).and_return(marker)
36
- marker.should_receive(:transmit)
37
-
38
- cli.run(marker_data, config)
41
+ context "without config" do
42
+ let(:config) { Appsignal::Config.new(tmp_dir, "production") }
43
+ let(:options) { {} }
44
+ around do |example|
45
+ Dir.chdir tmp_dir do
46
+ example.run
47
+ end
39
48
  end
40
49
 
41
- it "should notify of a deploy with no config file and a name specified" do
42
- ENV['PWD'] = '/nonsense'
43
- ENV['APPSIGNAL_PUSH_API_KEY'] = 'key'
44
-
45
- marker = double
46
- Appsignal::Marker.should_receive(:new).with(
47
- {
48
- :revision => 'aaaaa',
49
- :user => 'thijs'
50
- },
51
- kind_of(Appsignal::Config)
52
- ).and_return(marker)
53
- marker.should_receive(:transmit)
54
-
55
- cli.run(marker_data, config)
50
+ it "prints a config error" do
51
+ expect { run }.to raise_error(SystemExit)
52
+ expect(output).to include_config_error
53
+ expect(output).to_not include_deploy_notification
56
54
  end
57
55
  end
58
56
 
59
- describe "#validate_required_options" do
60
- let(:required_options) { [:option_1, :option_2, :option_3] }
61
-
62
- it "should do nothing with all options supplied" do
63
- cli.send(
64
- :validate_required_options,
65
- {
66
- :option_1 => 1,
67
- :option_2 => 2,
68
- :option_3 => 3
69
- },
70
- required_options
71
- )
72
- out_stream.string.should be_empty
57
+ context "with config" do
58
+ let(:config) { project_fixture_config }
59
+ before do
60
+ config[:name] = options[:name] if options[:name]
61
+ stub_api_request config, "markers", {
62
+ :revision => options[:revision],
63
+ :user => options[:user]
64
+ }
73
65
  end
74
-
75
- it "should print a message with one option missing and exit" do
76
- lambda {
77
- cli.send(
78
- :validate_required_options,
79
- {
80
- :option_1 => 1,
81
- :option_2 => 2
82
- },
83
- required_options
84
- )
85
- }.should raise_error(SystemExit)
86
- out_stream.string.should include('Missing options: option_3')
66
+ around do |example|
67
+ Dir.chdir project_fixture_path do
68
+ example.run
69
+ end
87
70
  end
88
71
 
89
- it "should print a message with multiple options missing and exit" do
90
- lambda {
91
- cli.send(
92
- :validate_required_options,
93
- {
94
- :option_1 => 1,
95
- :option_2 => ''
96
- },
97
- required_options
98
- )
99
- }.should raise_error(SystemExit)
100
- out_stream.string.should include("Missing options: option_2, option_3")
72
+ context "without environment" do
73
+ let(:options) { {:environment => "", :revision => "foo", :user => "thijs"} }
74
+ before do
75
+ # Makes the config "active"
76
+ ENV["APPSIGNAL_PUSH_API_KEY"] = "foo"
77
+ end
78
+
79
+ it "requires environment option" do
80
+ expect { run }.to raise_error(SystemExit)
81
+ expect(output).to include_missing_options(%w(environment))
82
+ expect(output).to_not include_deploy_notification
83
+ end
101
84
  end
102
- end
103
85
 
104
- describe "#validate_active_config" do
105
- context "when config is present" do
106
- it "should do nothing" do
107
- cli.send(:validate_active_config, config)
108
- out_stream.string.should be_empty
86
+ context "without known environment" do
87
+ let(:options) { {:environment => "foo"} }
88
+
89
+ it "prints a config error" do
90
+ expect { run }.to raise_error(SystemExit)
91
+ expect(output).to include_config_error
92
+ expect(output).to_not include_missing_options([])
93
+ expect(output).to_not include_deploy_notification
109
94
  end
110
95
  end
111
96
 
112
- context "when config is not active" do
113
- before { config.stub(:active? => false) }
97
+ context "with known environment" do
98
+ context "without required options" do
99
+ let(:options) { {:environment => "production"} }
100
+
101
+ it "prints a missing required options error" do
102
+ expect { run }.to raise_error(SystemExit)
103
+ expect(output).to_not include_config_error
104
+ expect(output).to include_missing_options(%w(revision user))
105
+ expect(output).to_not include_deploy_notification
106
+ end
107
+
108
+ context "with empty required option" do
109
+ let(:options) { {:environment => "production", :revision => "foo", :user => ""} }
110
+
111
+ it "prints a missing required option error" do
112
+ expect { run }.to raise_error(SystemExit)
113
+ expect(output).to_not include_config_error
114
+ expect(output).to include_missing_options(%w(user))
115
+ expect(output).to_not include_deploy_notification
116
+ end
117
+ end
118
+ end
119
+
120
+ context "with required options" do
121
+ let(:options) { {:environment => "production", :revision => "aaaaa", :user => "thijs"} }
122
+
123
+ it "notifies of a deploy" do
124
+ run
125
+ expect(output).to_not include_config_error
126
+ expect(output).to_not include_missing_options([])
127
+ expect(output).to include_deploy_notification_with(options)
128
+ end
129
+
130
+ context "with no app name configured" do
131
+ before { ENV["APPSIGNAL_APP_NAME"] = "" }
132
+
133
+ context "without name option" do
134
+ let(:options) { {:environment => "production", :revision => "aaaaa", :user => "thijs"} }
135
+
136
+ it "requires name option" do
137
+ expect { run }.to raise_error(SystemExit)
138
+ expect(output).to_not include_config_error
139
+ expect(output).to include_missing_options(%w(name))
140
+ expect(output).to_not include_deploy_notification
141
+ end
142
+ end
143
+
144
+ context "with name option" do
145
+ let(:options) { {:environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo"} }
146
+
147
+ it "notifies of a deploy with a custom name" do
148
+ run
149
+ expect(output).to_not include_config_error
150
+ expect(output).to_not include_missing_options([])
151
+ expect(output).to include_deploy_notification_with(options)
152
+ end
153
+ end
154
+ end
155
+
156
+ context "with name option" do
157
+ let(:options) do
158
+ {:environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo"}
159
+ end
114
160
 
115
- it "should print a message and exit" do
116
- lambda {
117
- cli.send(:validate_active_config, config)
118
- }.should raise_error(SystemExit)
119
- out_stream.string.should include('Exiting: No config file or push api key env var found')
161
+ it "notifies of a deploy with a custom name" do
162
+ run
163
+ expect(output).to_not include_config_error
164
+ expect(output).to_not include_missing_options([])
165
+ expect(output).to include_deploy_notification_with(options)
166
+ end
167
+ end
120
168
  end
121
169
  end
122
170
  end
@@ -35,7 +35,7 @@ describe Appsignal::CLI do
35
35
  cli.run([arg])
36
36
  }.should raise_error(SystemExit)
37
37
 
38
- out_stream.string.should include 'Appsignal'
38
+ out_stream.string.should include 'AppSignal'
39
39
  out_stream.string.should include '.'
40
40
  end
41
41
  end
@@ -72,21 +72,4 @@ describe Appsignal::CLI do
72
72
  ])
73
73
  end
74
74
  end
75
-
76
- describe "notify_of_deploy" do
77
- it "should call Appsignal::Install.install" do
78
- Appsignal::CLI::NotifyOfDeploy.should_receive(:run).with(
79
- {:revision=>"aaaaa", :user=>"thijs", :environment=>"production"},
80
- instance_of(Appsignal::Config)
81
- )
82
-
83
- cli.run([
84
- 'notify_of_deploy',
85
- '--name=project-production',
86
- '--revision=aaaaa',
87
- '--user=thijs',
88
- '--environment=production'
89
- ])
90
- end
91
- end
92
75
  end
@@ -29,6 +29,26 @@ describe Appsignal::Config do
29
29
  end
30
30
  end
31
31
  end
32
+
33
+ describe ":log" do
34
+ subject { config[:log] }
35
+
36
+ context "when running on Heroku" do
37
+ around { |example| recognize_as_heroku { example.run } }
38
+
39
+ it "is set to stdout" do
40
+ expect(subject).to eq("stdout")
41
+ end
42
+ end
43
+
44
+ context "when not running on Heroku" do
45
+ around { |example| recognize_as_container(:none) { example.run } }
46
+
47
+ it "is set to file" do
48
+ expect(subject).to eq("file")
49
+ end
50
+ end
51
+ end
32
52
  end
33
53
 
34
54
  describe "initial config" do
@@ -46,6 +66,7 @@ describe Appsignal::Config do
46
66
  it "merges with the default config" do
47
67
  expect(config.config_hash).to eq(
48
68
  :debug => false,
69
+ :log => 'file',
49
70
  :ignore_errors => [],
50
71
  :ignore_actions => [],
51
72
  :filter_parameters => [],
@@ -319,7 +340,7 @@ describe Appsignal::Config do
319
340
  expect(ENV['APPSIGNAL_APP_NAME']).to eq 'TestApp'
320
341
  expect(ENV['APPSIGNAL_ENVIRONMENT']).to eq 'production'
321
342
  expect(ENV['APPSIGNAL_AGENT_VERSION']).to eq Appsignal::Extension.agent_version
322
- expect(ENV['APPSIGNAL_LANGUAGE_INTEGRATION_VERSION']).to eq Appsignal::VERSION
343
+ expect(ENV['APPSIGNAL_LANGUAGE_INTEGRATION_VERSION']).to eq "ruby-#{Appsignal::VERSION}"
323
344
  expect(ENV['APPSIGNAL_HTTP_PROXY']).to eq 'http://localhost'
324
345
  expect(ENV['APPSIGNAL_IGNORE_ACTIONS']).to eq 'action1,action2'
325
346
  expect(ENV['APPSIGNAL_FILTER_PARAMETERS']).to eq 'password,confirm_password'
@@ -349,7 +370,11 @@ describe Appsignal::Config do
349
370
  let(:stdout) { StringIO.new }
350
371
  let(:config) { project_fixture_config('production', :log_path => log_path) }
351
372
  subject { config.log_file_path }
352
- around { |example| capture_stdout(stdout) { example.run } }
373
+ around do |example|
374
+ recognize_as_container(:none) do
375
+ capture_stdout(stdout) { example.run }
376
+ end
377
+ end
353
378
 
354
379
  context "when path is writable" do
355
380
  let(:log_path) { File.join(tmp_dir, 'writable-path') }
@@ -1,72 +1,55 @@
1
1
  require 'rake'
2
2
 
3
3
  describe Appsignal::Hooks::RakeHook do
4
- let(:app) { double(:current_scope => nil) }
5
- let(:task) { Rake::Task.new('task', app) }
6
- before do
7
- task.stub(
8
- :name => 'task:name',
9
- :execute_without_appsignal => true
10
- )
11
- end
12
- before :all do
13
- Appsignal::Hooks::RakeHook.new.install
4
+ let(:task) { Rake::Task.new('task:name', Rake::Application.new) }
5
+ before(:all) do
6
+ Appsignal.config = project_fixture_config
7
+ expect(Appsignal.active?).to be_true
8
+ Appsignal::Hooks.load_hooks
14
9
  end
15
10
 
16
11
  describe "#execute" do
17
- context "with transaction" do
18
- let!(:transaction) { background_job_transaction }
19
- let!(:agent) { double('Agent', :send_queue => true) }
20
- before do
21
- transaction.stub(:set_action)
22
- transaction.stub(:set_error)
23
- transaction.stub(:complete)
24
- SecureRandom.stub(:uuid => '123')
25
- Appsignal::Transaction.stub(:create => transaction)
26
- Appsignal.stub(:active? => true)
27
- end
28
-
29
- it "should call the original task" do
30
- expect( task ).to receive(:execute_without_appsignal).with('foo')
12
+ context "without error" do
13
+ it "creates no transaction" do
14
+ expect(Appsignal::Transaction).to_not receive(:create)
31
15
  end
32
16
 
33
- it "should not create a transaction" do
34
- expect( Appsignal::Transaction ).not_to receive(:create)
17
+ it "calls the original task" do
18
+ expect(task).to receive(:execute_without_appsignal).with('foo')
35
19
  end
36
20
 
37
- context "with an exception" do
38
- let(:exception) { VerySpecificError.new }
21
+ after { task.execute('foo') }
22
+ end
39
23
 
40
- before do
41
- task.stub(:execute_without_appsignal).and_raise(exception)
42
- end
24
+ context "with error" do
25
+ let(:error) { VerySpecificError.new }
26
+ let(:transaction) { background_job_transaction }
27
+ before do
28
+ task.enhance { raise error }
43
29
 
44
- it "should create a transaction" do
45
- expect( Appsignal::Transaction ).to receive(:create).with(
46
- '123',
47
- Appsignal::Transaction::BACKGROUND_JOB,
48
- kind_of(Appsignal::Transaction::GenericRequest)
49
- )
50
- end
30
+ expect(Appsignal::Transaction).to receive(:create).with(
31
+ kind_of(String),
32
+ Appsignal::Transaction::BACKGROUND_JOB,
33
+ kind_of(Appsignal::Transaction::GenericRequest)
34
+ ).and_return(transaction)
35
+ end
51
36
 
52
- it "should set the action on the transaction" do
53
- expect( transaction ).to receive(:set_action).with('task:name')
54
- end
37
+ it "sets the action" do
38
+ expect(transaction).to receive(:set_action).with('task:name')
39
+ end
55
40
 
56
- it "should add the exception to the transaction" do
57
- expect( transaction ).to receive(:set_error).with(exception)
58
- end
41
+ it "sets the error" do
42
+ expect(transaction).to receive(:set_error).with(error)
43
+ end
59
44
 
60
- it "should call complete! on the transaction" do
61
- expect( transaction ).to receive(:complete)
62
- end
45
+ it "completes the transaction and stops" do
46
+ expect(transaction).to receive(:complete).ordered
47
+ expect(Appsignal).to receive(:stop).with('rake').ordered
48
+ end
63
49
 
64
- it "should stop appsignal" do
65
- expect( Appsignal ).to receive(:stop)
66
- end
50
+ after do
51
+ expect { task.execute('foo') }.to raise_error VerySpecificError
67
52
  end
68
53
  end
69
-
70
- after { task.execute('foo') rescue VerySpecificError }
71
54
  end
72
55
  end