appsignal 2.5.0.alpha.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +66 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.travis.yml +72 -0
  7. data/.yardopts +8 -0
  8. data/CHANGELOG.md +639 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +20 -0
  11. data/README.md +264 -0
  12. data/Rakefile +214 -0
  13. data/appsignal.gemspec +42 -0
  14. data/benchmark.rake +77 -0
  15. data/bin/appsignal +13 -0
  16. data/ext/Rakefile +27 -0
  17. data/ext/agent.yml +64 -0
  18. data/ext/appsignal_extension.c +692 -0
  19. data/ext/base.rb +79 -0
  20. data/ext/extconf.rb +35 -0
  21. data/gemfiles/capistrano2.gemfile +7 -0
  22. data/gemfiles/capistrano3.gemfile +7 -0
  23. data/gemfiles/grape.gemfile +7 -0
  24. data/gemfiles/no_dependencies.gemfile +5 -0
  25. data/gemfiles/padrino.gemfile +7 -0
  26. data/gemfiles/que.gemfile +5 -0
  27. data/gemfiles/rails-3.2.gemfile +6 -0
  28. data/gemfiles/rails-4.0.gemfile +6 -0
  29. data/gemfiles/rails-4.1.gemfile +6 -0
  30. data/gemfiles/rails-4.2.gemfile +10 -0
  31. data/gemfiles/rails-5.0.gemfile +5 -0
  32. data/gemfiles/rails-5.1.gemfile +5 -0
  33. data/gemfiles/resque.gemfile +12 -0
  34. data/gemfiles/sequel-435.gemfile +11 -0
  35. data/gemfiles/sequel.gemfile +11 -0
  36. data/gemfiles/sinatra.gemfile +6 -0
  37. data/gemfiles/webmachine.gemfile +5 -0
  38. data/lib/appsignal.rb +804 -0
  39. data/lib/appsignal/auth_check.rb +65 -0
  40. data/lib/appsignal/capistrano.rb +10 -0
  41. data/lib/appsignal/cli.rb +108 -0
  42. data/lib/appsignal/cli/demo.rb +63 -0
  43. data/lib/appsignal/cli/diagnose.rb +500 -0
  44. data/lib/appsignal/cli/helpers.rb +72 -0
  45. data/lib/appsignal/cli/install.rb +277 -0
  46. data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
  47. data/lib/appsignal/config.rb +287 -0
  48. data/lib/appsignal/demo.rb +107 -0
  49. data/lib/appsignal/event_formatter.rb +74 -0
  50. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
  51. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
  52. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
  53. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
  54. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
  55. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
  56. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  57. data/lib/appsignal/extension.rb +63 -0
  58. data/lib/appsignal/extension/jruby.rb +460 -0
  59. data/lib/appsignal/garbage_collection_profiler.rb +48 -0
  60. data/lib/appsignal/hooks.rb +105 -0
  61. data/lib/appsignal/hooks/action_cable.rb +113 -0
  62. data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
  63. data/lib/appsignal/hooks/celluloid.rb +30 -0
  64. data/lib/appsignal/hooks/data_mapper.rb +18 -0
  65. data/lib/appsignal/hooks/delayed_job.rb +19 -0
  66. data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
  67. data/lib/appsignal/hooks/net_http.rb +29 -0
  68. data/lib/appsignal/hooks/passenger.rb +22 -0
  69. data/lib/appsignal/hooks/puma.rb +35 -0
  70. data/lib/appsignal/hooks/que.rb +21 -0
  71. data/lib/appsignal/hooks/rake.rb +39 -0
  72. data/lib/appsignal/hooks/redis.rb +30 -0
  73. data/lib/appsignal/hooks/sequel.rb +60 -0
  74. data/lib/appsignal/hooks/shoryuken.rb +43 -0
  75. data/lib/appsignal/hooks/sidekiq.rb +144 -0
  76. data/lib/appsignal/hooks/unicorn.rb +40 -0
  77. data/lib/appsignal/hooks/webmachine.rb +23 -0
  78. data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
  79. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
  80. data/lib/appsignal/integrations/data_mapper.rb +33 -0
  81. data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
  82. data/lib/appsignal/integrations/grape.rb +53 -0
  83. data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
  84. data/lib/appsignal/integrations/object.rb +35 -0
  85. data/lib/appsignal/integrations/padrino.rb +84 -0
  86. data/lib/appsignal/integrations/que.rb +43 -0
  87. data/lib/appsignal/integrations/railtie.rb +41 -0
  88. data/lib/appsignal/integrations/rake.rb +2 -0
  89. data/lib/appsignal/integrations/resque.rb +20 -0
  90. data/lib/appsignal/integrations/resque_active_job.rb +30 -0
  91. data/lib/appsignal/integrations/sinatra.rb +17 -0
  92. data/lib/appsignal/integrations/webmachine.rb +38 -0
  93. data/lib/appsignal/js_exception_transaction.rb +54 -0
  94. data/lib/appsignal/marker.rb +63 -0
  95. data/lib/appsignal/minutely.rb +42 -0
  96. data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
  97. data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
  98. data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
  99. data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
  100. data/lib/appsignal/rack/streaming_listener.rb +73 -0
  101. data/lib/appsignal/system.rb +81 -0
  102. data/lib/appsignal/transaction.rb +498 -0
  103. data/lib/appsignal/transmitter.rb +107 -0
  104. data/lib/appsignal/utils.rb +127 -0
  105. data/lib/appsignal/utils/params_sanitizer.rb +59 -0
  106. data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
  107. data/lib/appsignal/version.rb +3 -0
  108. data/lib/sequel/extensions/appsignal_integration.rb +3 -0
  109. data/resources/appsignal.yml.erb +39 -0
  110. data/resources/cacert.pem +3866 -0
  111. data/spec/.rubocop.yml +7 -0
  112. data/spec/lib/appsignal/auth_check_spec.rb +80 -0
  113. data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
  114. data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
  115. data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
  116. data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
  117. data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
  118. data/spec/lib/appsignal/cli/install_spec.rb +632 -0
  119. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
  120. data/spec/lib/appsignal/cli_spec.rb +56 -0
  121. data/spec/lib/appsignal/config_spec.rb +637 -0
  122. data/spec/lib/appsignal/demo_spec.rb +87 -0
  123. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
  124. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
  125. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
  126. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
  127. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
  128. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
  129. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
  130. data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
  131. data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
  132. data/spec/lib/appsignal/extension_spec.rb +137 -0
  133. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
  134. data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
  135. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
  136. data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
  137. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
  138. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
  139. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
  140. data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
  141. data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
  142. data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
  143. data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
  144. data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
  145. data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
  146. data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
  147. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
  148. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
  149. data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
  150. data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
  151. data/spec/lib/appsignal/hooks_spec.rb +195 -0
  152. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
  153. data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
  154. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
  155. data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
  156. data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
  157. data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
  158. data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
  159. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
  160. data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
  161. data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
  162. data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
  163. data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
  164. data/spec/lib/appsignal/marker_spec.rb +51 -0
  165. data/spec/lib/appsignal/minutely_spec.rb +50 -0
  166. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
  167. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
  168. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
  169. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
  170. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
  171. data/spec/lib/appsignal/system_spec.rb +131 -0
  172. data/spec/lib/appsignal/transaction_spec.rb +1146 -0
  173. data/spec/lib/appsignal/transmitter_spec.rb +152 -0
  174. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
  175. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
  176. data/spec/lib/appsignal/utils_spec.rb +150 -0
  177. data/spec/lib/appsignal_spec.rb +1049 -0
  178. data/spec/spec_helper.rb +116 -0
  179. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  180. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  181. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  182. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  183. data/spec/support/fixtures/containers/cgroups/none +1 -0
  184. data/spec/support/fixtures/generated_config.yml +24 -0
  185. data/spec/support/fixtures/uploaded_file.txt +0 -0
  186. data/spec/support/helpers/api_request_helper.rb +19 -0
  187. data/spec/support/helpers/cli_helpers.rb +26 -0
  188. data/spec/support/helpers/config_helpers.rb +21 -0
  189. data/spec/support/helpers/dependency_helper.rb +73 -0
  190. data/spec/support/helpers/directory_helper.rb +27 -0
  191. data/spec/support/helpers/env_helpers.rb +33 -0
  192. data/spec/support/helpers/example_exception.rb +13 -0
  193. data/spec/support/helpers/example_standard_error.rb +13 -0
  194. data/spec/support/helpers/log_helpers.rb +22 -0
  195. data/spec/support/helpers/std_streams_helper.rb +66 -0
  196. data/spec/support/helpers/system_helpers.rb +8 -0
  197. data/spec/support/helpers/time_helpers.rb +11 -0
  198. data/spec/support/helpers/transaction_helpers.rb +37 -0
  199. data/spec/support/matchers/contains_log.rb +7 -0
  200. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  201. data/spec/support/mocks/mock_extension.rb +6 -0
  202. data/spec/support/project_fixture/config/application.rb +0 -0
  203. data/spec/support/project_fixture/config/appsignal.yml +32 -0
  204. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  205. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  206. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  207. data/spec/support/project_fixture/log/.gitkeep +0 -0
  208. data/spec/support/rails/my_app.rb +6 -0
  209. data/spec/support/shared_examples/instrument.rb +43 -0
  210. data/spec/support/stubs/delayed_job.rb +0 -0
  211. metadata +483 -0
@@ -0,0 +1,171 @@
1
+ require "appsignal/cli/helpers"
2
+
3
+ describe Appsignal::CLI::Helpers do
4
+ include CLIHelpers
5
+
6
+ let(:out_stream) { std_stream }
7
+ let(:output) { out_stream.read }
8
+ let(:cli) do
9
+ Class.new do
10
+ extend Appsignal::CLI::Helpers
11
+ end
12
+ end
13
+ before do
14
+ # Speed up tests
15
+ allow(cli).to receive(:sleep)
16
+ end
17
+ around do |example|
18
+ original_stdin = $stdin
19
+ $stdin = StringIO.new
20
+ example.run
21
+ $stdin = original_stdin
22
+ end
23
+
24
+ describe ".colorize" do
25
+ subject { cli.send(:colorize, "text", :green) }
26
+
27
+ context "on windows" do
28
+ before { allow(Gem).to receive(:win_platform?).and_return(true) }
29
+
30
+ it "outputs plain string" do
31
+ expect(subject).to eq "text"
32
+ end
33
+ end
34
+
35
+ context "not on windows" do
36
+ before { allow(Gem).to receive(:win_platform?).and_return(false) }
37
+
38
+ it "wraps text in color tags" do
39
+ expect(subject).to eq "\e[32mtext\e[0m"
40
+ end
41
+ end
42
+ end
43
+
44
+ describe ".periods" do
45
+ it "prints three periods" do
46
+ capture_stdout(out_stream) { cli.send :periods }
47
+ expect(output).to include("...")
48
+ end
49
+ end
50
+
51
+ describe ".press_any_key" do
52
+ before do
53
+ set_input "a" # a as in any
54
+ prepare_input
55
+ end
56
+
57
+ it "continues after press" do
58
+ capture_stdout(out_stream) { cli.send :press_any_key }
59
+ expect(output).to include("Press any key")
60
+ end
61
+ end
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
+
91
+ describe ".yes_or_no" do
92
+ def yes_or_no
93
+ capture_stdout(out_stream) { cli.send(:yes_or_no, "yes or no?: ") }
94
+ end
95
+
96
+ it "takes 'y' for an answer" do
97
+ set_input ""
98
+ set_input "nonsense"
99
+ set_input "y"
100
+ prepare_input
101
+
102
+ expect(yes_or_no).to be_truthy
103
+ end
104
+
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
120
+ set_input ""
121
+ set_input "nonsense"
122
+ set_input "n"
123
+ prepare_input
124
+
125
+ expect(yes_or_no).to be_falsy
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
156
+ end
157
+
158
+ describe ".required_input" do
159
+ def required_input
160
+ capture_stdout(out_stream) { cli.send(:required_input, "provide: ") }
161
+ end
162
+
163
+ it "collects required input" do
164
+ set_input ""
165
+ set_input "value"
166
+ prepare_input
167
+
168
+ expect(required_input).to eq("value")
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,632 @@
1
+ require "appsignal/cli"
2
+
3
+ describe Appsignal::CLI::Install do
4
+ include CLIHelpers
5
+
6
+ let(:out_stream) { std_stream }
7
+ let(:output) { out_stream.read }
8
+ let(:push_api_key) { "my_key" }
9
+ let(:config) { Appsignal::Config.new(tmp_dir, "") }
10
+ let(:config_file_path) { File.join(tmp_dir, "config", "appsignal.yml") }
11
+ let(:config_file) { File.read(config_file_path) }
12
+ before do
13
+ stub_api_validation_request
14
+ # Stub calls to speed up tests
15
+ allow(described_class).to receive(:sleep)
16
+ allow(described_class).to receive(:press_any_key)
17
+ allow(Appsignal::Demo).to receive(:transmit).and_return(true)
18
+ end
19
+ around do |example|
20
+ original_stdin = $stdin
21
+ $stdin = StringIO.new
22
+ example.run
23
+ $stdin = original_stdin
24
+ end
25
+
26
+ define :include_complete_install do
27
+ match do |actual|
28
+ actual.include?("AppSignal installation complete")
29
+ end
30
+ end
31
+
32
+ define :include_env_push_api_key do |key|
33
+ match do |actual|
34
+ actual.include?("export APPSIGNAL_PUSH_API_KEY=#{key}")
35
+ end
36
+ end
37
+ define :include_env_app_name do |name|
38
+ match do |actual|
39
+ actual.include?("export APPSIGNAL_APP_NAME=#{name}")
40
+ end
41
+ end
42
+
43
+ define :configure_app_name do |name|
44
+ match do |file_contents|
45
+ file_contents =~ /^ name: "#{name}"/
46
+ end
47
+ end
48
+ define :configure_push_api_key do |key|
49
+ match do |file_contents|
50
+ file_contents =~ /^ push_api_key: "#{key}"/
51
+ end
52
+ end
53
+ define :configure_environment do |env|
54
+ match do |file_contents|
55
+ file_contents =~ /^#{env}:$/
56
+ end
57
+ end
58
+ define :include_file_config do
59
+ match do |log|
60
+ log.include?("Config file written to config/appsignal.yml")
61
+ end
62
+ end
63
+
64
+ define :include_demo_transmission do
65
+ match do |log|
66
+ log.include?("Sending example data to AppSignal") &&
67
+ log.include?("Example data sent!")
68
+ end
69
+ end
70
+
71
+ def stub_api_validation_request
72
+ config[:push_api_key] = push_api_key
73
+ stub_api_request config, "auth"
74
+ end
75
+
76
+ alias_method :enter_app_name, :set_input
77
+
78
+ def choose_config_file
79
+ set_input "1"
80
+ end
81
+
82
+ def choose_environment_config
83
+ set_input "2"
84
+ end
85
+
86
+ def run
87
+ Dir.chdir tmp_dir do
88
+ prepare_input
89
+ capture_stdout(out_stream) do
90
+ run_cli(["install", push_api_key])
91
+ end
92
+ end
93
+ end
94
+
95
+ shared_examples "push_api_key validation" do
96
+ context "without key" do
97
+ let(:push_api_key) {}
98
+
99
+ it "does not install" do
100
+ run
101
+
102
+ expect(output).to include "Problem encountered:",
103
+ "No push API key entered"
104
+ end
105
+ end
106
+
107
+ context "with key" do
108
+ let(:push_api_key) { "my_key" }
109
+
110
+ context "when the key is valid" do
111
+ before { stub_api_validation_request.to_return(:status => 200) }
112
+
113
+ it "continues with the installer" do
114
+ enter_app_name "Test App"
115
+ choose_environment_config
116
+ run
117
+
118
+ expect(output).to include("Validating API key...", "API key valid")
119
+ end
120
+ end
121
+
122
+ context "when the key is invalid" do
123
+ before { stub_api_validation_request.to_return(:status => 402) }
124
+
125
+ it "prints an error" do
126
+ run
127
+ expect(output).to include "API key 'my_key' is not valid"
128
+ end
129
+ end
130
+
131
+ context "when there is an error validating" do
132
+ before do
133
+ expect(Appsignal::AuthCheck).to receive(:new).and_raise(StandardError)
134
+ end
135
+
136
+ it "prints an error" do
137
+ run
138
+ expect(output).to include "There was an error validating your API key"
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ shared_examples "requires an application name" do
145
+ before do
146
+ enter_app_name ""
147
+ enter_app_name "Test app"
148
+ choose_environment_config
149
+ run
150
+ end
151
+
152
+ it "requires an application name" do
153
+ expect(output.scan(/Enter application name:/).length).to eq(2)
154
+ end
155
+ end
156
+
157
+ shared_examples "capistrano install" do
158
+ let(:capfile) { File.join(tmp_dir, "Capfile") }
159
+ before do
160
+ FileUtils.mkdir_p(tmp_dir)
161
+
162
+ enter_app_name "foo"
163
+ set_input "n"
164
+ choose_environment_config
165
+ end
166
+ after do
167
+ FileUtils.rm_rf(tmp_dir)
168
+ FileUtils.mkdir_p(tmp_dir)
169
+ end
170
+
171
+ context "without Capfile" do
172
+ it "does nothing" do
173
+ run
174
+
175
+ expect(output).to_not include "Adding AppSignal integration to Capfile"
176
+ expect(File.exist?(capfile)).to be_falsy
177
+ end
178
+ end
179
+
180
+ context "with Capfile" do
181
+ context "when already installed" do
182
+ before { File.open(capfile, "w") { |f| f.write("require 'appsignal/capistrano'") } }
183
+
184
+ it "does not add another require to Capfile" do
185
+ run
186
+
187
+ expect(output).to_not include "Adding AppSignal integration to Capfile"
188
+ expect(File.read(capfile).scan(/appsignal/).count).to eq(1)
189
+ end
190
+ end
191
+
192
+ context "when not installed" do
193
+ before { FileUtils.touch(capfile) }
194
+
195
+ it "adds a require to Capfile" do
196
+ run
197
+
198
+ expect(output).to include "Adding AppSignal integration to Capfile"
199
+ expect(File.read(capfile)).to include "require 'appsignal/capistrano'"
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ shared_examples "windows installation" do
206
+ before do
207
+ allow(Gem).to receive(:win_platform?).and_return(true)
208
+ expect(Appsignal::Demo).to_not receive(:transmit)
209
+ run
210
+ end
211
+
212
+ it "prints a warning for windows" do
213
+ expect(output).to include("The AppSignal agent currently does not work on Microsoft Windows")
214
+ expect(output).to include("staging/production environment")
215
+ end
216
+ end
217
+
218
+ shared_examples "demo data" do
219
+ context "with demo data sent" do
220
+ before do
221
+ expect(Appsignal::Demo).to receive(:transmit).and_return(true)
222
+ run
223
+ end
224
+
225
+ it "prints sending demo data" do
226
+ expect(output).to include "Sending example data to AppSignal", "Example data sent!"
227
+ end
228
+ end
229
+
230
+ context "without demo data being sent" do
231
+ before do
232
+ expect(Appsignal::Demo).to receive(:transmit).and_return(false)
233
+ run
234
+ end
235
+
236
+ it "prints that it couldn't send the demo data" do
237
+ expect(output).to include "Sending example data to AppSignal",
238
+ "Couldn't start the AppSignal agent and send example data",
239
+ "`appsignal diagnose`"
240
+ end
241
+ end
242
+ end
243
+
244
+ if rails_present?
245
+ context "with rails" do
246
+ let(:installation_instructions) { ["Installing for Ruby on Rails"] }
247
+ let(:app_name) { "MyApp" }
248
+ let(:config_dir) { File.join(tmp_dir, "config") }
249
+ let(:environments_dir) { File.join(config_dir, "environments") }
250
+ before do
251
+ # Fake Rails directory
252
+ FileUtils.mkdir_p(config_dir)
253
+ FileUtils.mkdir_p(environments_dir)
254
+ FileUtils.touch(File.join(config_dir, "application.rb"))
255
+ FileUtils.touch(File.join(environments_dir, "development.rb"))
256
+ FileUtils.touch(File.join(environments_dir, "staging.rb"))
257
+ FileUtils.touch(File.join(environments_dir, "production.rb"))
258
+ enter_app_name app_name
259
+ end
260
+
261
+ describe "environments" do
262
+ before do
263
+ File.delete(File.join(environments_dir, "development.rb"))
264
+ File.delete(File.join(environments_dir, "staging.rb"))
265
+ set_input "n"
266
+ choose_config_file
267
+ end
268
+
269
+ it "only configures the available environments" do
270
+ run
271
+
272
+ expect(output).to include_file_config
273
+ expect(config_file).to configure_app_name(app_name)
274
+ expect(config_file).to configure_push_api_key(push_api_key)
275
+ expect(config_file).to_not configure_environment("development")
276
+ expect(config_file).to_not configure_environment("staging")
277
+ expect(config_file).to configure_environment("production")
278
+
279
+ expect(output).to include(*installation_instructions)
280
+ expect(output).to include_complete_install
281
+ expect(output).to include_demo_transmission
282
+ end
283
+ end
284
+
285
+ context "without custom name" do
286
+ before { set_input "n" }
287
+
288
+ it_behaves_like "push_api_key validation"
289
+
290
+ context "with configuration using environment variables" do
291
+ before { choose_environment_config }
292
+
293
+ it_behaves_like "windows installation"
294
+ it_behaves_like "capistrano install"
295
+ it_behaves_like "demo data"
296
+
297
+ it "prints environment variables" do
298
+ run
299
+
300
+ expect(output).to include_env_push_api_key(push_api_key)
301
+ expect(output).to_not include_env_app_name
302
+ end
303
+
304
+ it "completes the installation" do
305
+ run
306
+
307
+ expect(output).to include(*installation_instructions)
308
+ expect(output).to include_complete_install
309
+ end
310
+ end
311
+
312
+ context "with configuration using a configuration file" do
313
+ before { choose_config_file }
314
+
315
+ it_behaves_like "windows installation"
316
+ it_behaves_like "capistrano install"
317
+ it_behaves_like "demo data"
318
+
319
+ it "writes configuration to file" do
320
+ run
321
+
322
+ expect(output).to include_file_config
323
+ expect(config_file).to configure_app_name(app_name)
324
+ expect(config_file).to configure_push_api_key(push_api_key)
325
+ expect(config_file).to configure_environment("development")
326
+ expect(config_file).to configure_environment("staging")
327
+ expect(config_file).to configure_environment("production")
328
+ end
329
+
330
+ it "completes the installation" do
331
+ run
332
+
333
+ expect(output).to include(*installation_instructions)
334
+ expect(output).to include_complete_install
335
+ end
336
+ end
337
+ end
338
+
339
+ context "with custom name" do
340
+ let(:app_name) { "Custom name" }
341
+ before { set_input "y" }
342
+
343
+ it_behaves_like "push_api_key validation"
344
+
345
+ it "requires the custom name" do
346
+ enter_app_name ""
347
+ enter_app_name app_name
348
+ choose_environment_config
349
+ run
350
+
351
+ expect(output.scan(/Choose app's display name:/).length).to eq(2)
352
+ end
353
+
354
+ context "with configuration using environment variables" do
355
+ before do
356
+ enter_app_name app_name
357
+ choose_environment_config
358
+ end
359
+
360
+ it_behaves_like "windows installation"
361
+ it_behaves_like "capistrano install"
362
+ it_behaves_like "demo data"
363
+
364
+ it "prints environment variables" do
365
+ run
366
+
367
+ expect(output).to include_env_push_api_key(push_api_key)
368
+ expect(output).to include_env_app_name(app_name)
369
+ end
370
+
371
+ it "completes the installation" do
372
+ run
373
+
374
+ expect(output).to include(*installation_instructions)
375
+ expect(output).to include_complete_install
376
+ end
377
+ end
378
+
379
+ context "with configuration using a configuration file" do
380
+ before do
381
+ enter_app_name app_name
382
+ choose_config_file
383
+ end
384
+
385
+ it_behaves_like "windows installation"
386
+ it_behaves_like "capistrano install"
387
+ it_behaves_like "demo data"
388
+
389
+ it "writes configuration to file" do
390
+ run
391
+
392
+ expect(output).to include_file_config
393
+ expect(config_file).to configure_app_name(app_name)
394
+ expect(config_file).to configure_push_api_key(push_api_key)
395
+ expect(config_file).to configure_environment("development")
396
+ expect(config_file).to configure_environment("staging")
397
+ expect(config_file).to configure_environment("production")
398
+ end
399
+
400
+ it "completes the installation" do
401
+ run
402
+
403
+ expect(output).to include(*installation_instructions)
404
+ expect(output).to include_complete_install
405
+ end
406
+ end
407
+ end
408
+ end
409
+ end
410
+
411
+ if sinatra_present? && !padrino_present? && !rails_present?
412
+ context "with sinatra" do
413
+ it_behaves_like "push_api_key validation"
414
+ it_behaves_like "requires an application name"
415
+
416
+ describe "sinatra specific tests" do
417
+ let(:installation_instructions) do
418
+ [
419
+ "Installing for Sinatra",
420
+ "Sinatra requires some manual configuration.",
421
+ "require 'appsignal/integrations/sinatra'",
422
+ "http://docs.appsignal.com/ruby/integrations/sinatra.html"
423
+ ]
424
+ end
425
+ let(:app_name) { "Test app" }
426
+ before { enter_app_name app_name }
427
+
428
+ describe "configuration with environment variables" do
429
+ before { choose_environment_config }
430
+
431
+ it_behaves_like "windows installation"
432
+ it_behaves_like "capistrano install"
433
+ it_behaves_like "demo data"
434
+
435
+ it "prints environment variables" do
436
+ run
437
+
438
+ expect(output).to include_env_push_api_key(push_api_key)
439
+ expect(output).to include_env_app_name(app_name)
440
+ end
441
+
442
+ it "completes the installation" do
443
+ run
444
+
445
+ expect(output).to include(*installation_instructions)
446
+ expect(output).to include_complete_install
447
+ end
448
+ end
449
+
450
+ describe "configure with a configuration file" do
451
+ before { choose_config_file }
452
+
453
+ it_behaves_like "windows installation"
454
+ it_behaves_like "capistrano install"
455
+ it_behaves_like "demo data"
456
+
457
+ it "writes configuration to file" do
458
+ run
459
+
460
+ expect(output).to include_file_config
461
+ expect(config_file).to configure_app_name(app_name)
462
+ expect(config_file).to configure_push_api_key(push_api_key)
463
+ expect(config_file).to configure_environment("development")
464
+ expect(config_file).to configure_environment("staging")
465
+ expect(config_file).to configure_environment("production")
466
+ end
467
+
468
+ it "completes the installation" do
469
+ run
470
+
471
+ expect(output).to include(*installation_instructions)
472
+ expect(output).to include_complete_install
473
+ end
474
+ end
475
+ end
476
+ end
477
+ end
478
+
479
+ if padrino_present?
480
+ context "with padrino" do
481
+ it_behaves_like "push_api_key validation"
482
+ it_behaves_like "requires an application name"
483
+
484
+ describe "padrino specific tests" do
485
+ let(:installation_instructions) do
486
+ [
487
+ "Installing for Padrino",
488
+ "Padrino requires some manual configuration.",
489
+ "http://docs.appsignal.com/ruby/integrations/padrino.html"
490
+ ]
491
+ end
492
+ let(:app_name) { "Test app" }
493
+ before { enter_app_name app_name }
494
+
495
+ describe "configuration with environment variables" do
496
+ before { choose_environment_config }
497
+
498
+ it_behaves_like "windows installation"
499
+ it_behaves_like "capistrano install"
500
+ it_behaves_like "demo data"
501
+
502
+ it "prints environment variables" do
503
+ run
504
+
505
+ expect(output).to include_env_push_api_key(push_api_key)
506
+ expect(output).to include_env_app_name(app_name)
507
+ end
508
+
509
+ it "completes the installation" do
510
+ run
511
+
512
+ expect(output).to include(*installation_instructions)
513
+ expect(output).to include_complete_install
514
+ end
515
+ end
516
+
517
+ describe "configure with a configuration file" do
518
+ before { choose_config_file }
519
+
520
+ it_behaves_like "windows installation"
521
+ it_behaves_like "capistrano install"
522
+ it_behaves_like "demo data"
523
+
524
+ it "writes configuration to file" do
525
+ run
526
+
527
+ expect(output).to include_file_config
528
+ expect(config_file).to configure_app_name(app_name)
529
+ expect(config_file).to configure_push_api_key(push_api_key)
530
+ expect(config_file).to configure_environment("development")
531
+ expect(config_file).to configure_environment("staging")
532
+ expect(config_file).to configure_environment("production")
533
+ end
534
+
535
+ it "completes the installation" do
536
+ run
537
+
538
+ expect(output).to include(*installation_instructions)
539
+ expect(output).to include_complete_install
540
+ end
541
+ end
542
+ end
543
+ end
544
+ end
545
+
546
+ if grape_present?
547
+ context "with grape" do
548
+ it_behaves_like "push_api_key validation"
549
+ it_behaves_like "requires an application name"
550
+
551
+ describe "grape specific tests" do
552
+ let(:installation_instructions) do
553
+ [
554
+ "Installing for Grape",
555
+ "Manual Grape configuration needed",
556
+ "http://docs.appsignal.com/ruby/integrations/grape.html"
557
+ ]
558
+ end
559
+ let(:app_name) { "Test app" }
560
+ before { enter_app_name app_name }
561
+
562
+ describe "configuration with environment variables" do
563
+ before { choose_environment_config }
564
+
565
+ it_behaves_like "windows installation"
566
+ it_behaves_like "capistrano install"
567
+ it_behaves_like "demo data"
568
+
569
+ it "prints environment variables" do
570
+ run
571
+
572
+ expect(output).to include_env_push_api_key(push_api_key)
573
+ expect(output).to include_env_app_name(app_name)
574
+ end
575
+
576
+ it "completes the installation" do
577
+ run
578
+
579
+ expect(output).to include(*installation_instructions)
580
+ expect(output).to include_complete_install
581
+ end
582
+ end
583
+
584
+ describe "configure with a configuration file" do
585
+ before { choose_config_file }
586
+
587
+ it_behaves_like "windows installation"
588
+ it_behaves_like "capistrano install"
589
+ it_behaves_like "demo data"
590
+
591
+ it "writes configuration to file" do
592
+ run
593
+
594
+ expect(output).to include_file_config
595
+ expect(config_file).to configure_app_name(app_name)
596
+ expect(config_file).to configure_push_api_key(push_api_key)
597
+ expect(config_file).to configure_environment("development")
598
+ expect(config_file).to configure_environment("staging")
599
+ expect(config_file).to configure_environment("production")
600
+ end
601
+
602
+ it "completes the installation" do
603
+ run
604
+
605
+ expect(output).to include(*installation_instructions)
606
+ expect(output).to include_complete_install
607
+ end
608
+ end
609
+ end
610
+ end
611
+ end
612
+
613
+ if !rails_present? && !sinatra_present? && !padrino_present? && !grape_present?
614
+ context "with unknown framework" do
615
+ let(:push_api_key) { "my_key" }
616
+
617
+ it_behaves_like "windows installation"
618
+ it_behaves_like "push_api_key validation"
619
+ it_behaves_like "demo data"
620
+
621
+ it "prints a message about unknown framework" do
622
+ run
623
+
624
+ expect(output).to include \
625
+ "\e[31mWarning:\e[0m We could not detect which framework you are using."
626
+ expect(output).to_not include_env_push_api_key
627
+ expect(output).to_not include_env_app_name
628
+ expect(File.exist?(config_file_path)).to be_falsy
629
+ end
630
+ end
631
+ end
632
+ end