cloudtrapper 0.0.2.pre
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.
- data/CHANGELOG +823 -0
- data/Gemfile +12 -0
- data/Guardfile +6 -0
- data/INSTALL +20 -0
- data/MIT-LICENSE +22 -0
- data/README.md +465 -0
- data/README_FOR_HEROKU_ADDON.md +94 -0
- data/Rakefile +223 -0
- data/SUPPORTED_RAILS_VERSIONS +23 -0
- data/TESTING.md +33 -0
- data/cloudtrapper.gemspec +35 -0
- data/features/metal.feature +18 -0
- data/features/rack.feature +56 -0
- data/features/rails.feature +211 -0
- data/features/rails_with_js_notifier.feature +97 -0
- data/features/rake.feature +27 -0
- data/features/sinatra.feature +29 -0
- data/features/step_definitions/file_steps.rb +10 -0
- data/features/step_definitions/metal_steps.rb +23 -0
- data/features/step_definitions/rack_steps.rb +23 -0
- data/features/step_definitions/rails_application_steps.rb +433 -0
- data/features/step_definitions/rake_steps.rb +17 -0
- data/features/support/airbrake_shim.rb.template +11 -0
- data/features/support/env.rb +18 -0
- data/features/support/matchers.rb +35 -0
- data/features/support/rails.rb +201 -0
- data/features/support/rake/Rakefile +68 -0
- data/features/support/terminal.rb +107 -0
- data/features/user_informer.feature +63 -0
- data/generators/cloudtrapper/airbrake_generator.rb +94 -0
- data/generators/cloudtrapper/lib/insert_commands.rb +34 -0
- data/generators/cloudtrapper/lib/rake_commands.rb +24 -0
- data/generators/cloudtrapper/templates/capistrano_hook.rb +6 -0
- data/generators/cloudtrapper/templates/cloudtrapper_tasks.rake +25 -0
- data/generators/cloudtrapper/templates/initializer.rb +6 -0
- data/install.rb +1 -0
- data/lib/cloudtrapper/backtrace.rb +100 -0
- data/lib/cloudtrapper/capistrano.rb +44 -0
- data/lib/cloudtrapper/configuration.rb +281 -0
- data/lib/cloudtrapper/notice.rb +348 -0
- data/lib/cloudtrapper/rack.rb +55 -0
- data/lib/cloudtrapper/rails/action_controller_catcher.rb +30 -0
- data/lib/cloudtrapper/rails/controller_methods.rb +74 -0
- data/lib/cloudtrapper/rails/error_lookup.rb +33 -0
- data/lib/cloudtrapper/rails/javascript_notifier.rb +48 -0
- data/lib/cloudtrapper/rails/middleware/exceptions_catcher.rb +29 -0
- data/lib/cloudtrapper/rails.rb +40 -0
- data/lib/cloudtrapper/rails3_tasks.rb +85 -0
- data/lib/cloudtrapper/railtie.rb +48 -0
- data/lib/cloudtrapper/rake_handler.rb +66 -0
- data/lib/cloudtrapper/sender.rb +116 -0
- data/lib/cloudtrapper/shared_tasks.rb +36 -0
- data/lib/cloudtrapper/tasks.rb +83 -0
- data/lib/cloudtrapper/user_informer.rb +27 -0
- data/lib/cloudtrapper/version.rb +3 -0
- data/lib/cloudtrapper.rb +155 -0
- data/lib/cloudtrapper_tasks.rb +65 -0
- data/lib/rails/generators/cloudtrapper/cloudtrapper_generator.rb +100 -0
- data/lib/templates/javascript_notifier.erb +15 -0
- data/lib/templates/rescue.erb +91 -0
- data/rails/init.rb +1 -0
- data/resources/README.md +34 -0
- data/resources/ca-bundle.crt +3376 -0
- data/script/integration_test.rb +38 -0
- data/test/backtrace_test.rb +162 -0
- data/test/capistrano_test.rb +34 -0
- data/test/catcher_test.rb +333 -0
- data/test/cloudtrapper_2_2.xsd +78 -0
- data/test/cloudtrapper_tasks_test.rb +170 -0
- data/test/configuration_test.rb +221 -0
- data/test/helper.rb +263 -0
- data/test/javascript_notifier_test.rb +52 -0
- data/test/logger_test.rb +73 -0
- data/test/notice_test.rb +468 -0
- data/test/notifier_test.rb +246 -0
- data/test/rack_test.rb +58 -0
- data/test/rails_initializer_test.rb +36 -0
- data/test/recursion_test.rb +10 -0
- data/test/sender_test.rb +261 -0
- data/test/user_informer_test.rb +29 -0
- metadata +301 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
Feature: Install the Gem in a Rails application and enable the JavaScript notifier
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have built and installed the "cloudtrapper" gem
|
5
|
+
|
6
|
+
Scenario: Include the Javascript notifier when enabled
|
7
|
+
When I generate a new Rails application
|
8
|
+
And I configure the Cloudtrapper shim
|
9
|
+
And I configure my application to require the "cloudtrapper" gem
|
10
|
+
When I configure the notifier to use the following configuration lines:
|
11
|
+
"""
|
12
|
+
config.api_key = "myapikey"
|
13
|
+
"""
|
14
|
+
And I define a response for "TestController#index":
|
15
|
+
"""
|
16
|
+
render :inline => '<html><head profile="http://example.com"><%= cloudtrapper_javascript_notifier %></head><body></body></html>'
|
17
|
+
"""
|
18
|
+
And I route "/test/index" to "test#index"
|
19
|
+
And I perform a request to "http://example.com:123/test/index"
|
20
|
+
Then I should see the notifier JavaScript for the following:
|
21
|
+
| api_key | environment | host |
|
22
|
+
| myapikey | production | api.cloudtrapper.io |
|
23
|
+
And the notifier JavaScript should provide the following errorDefaults:
|
24
|
+
| url | component | action |
|
25
|
+
| http://example.com:123/test/index | test | index |
|
26
|
+
|
27
|
+
Scenario: Include the Javascript notifier when enabled using custom configuration settings
|
28
|
+
When I generate a new Rails application
|
29
|
+
And I configure the Cloudtrapper shim
|
30
|
+
And I configure my application to require the "cloudtrapper" gem
|
31
|
+
When I configure the notifier to use the following configuration lines:
|
32
|
+
"""
|
33
|
+
config.api_key = "myapikey!"
|
34
|
+
config.host = "mycloudtrapper.com"
|
35
|
+
config.port = 3001
|
36
|
+
"""
|
37
|
+
And I define a response for "TestController#index":
|
38
|
+
"""
|
39
|
+
render :inline => '<html><head><%= cloudtrapper_javascript_notifier %></head><body></body></html>'
|
40
|
+
"""
|
41
|
+
And I route "/test/index" to "test#index"
|
42
|
+
And I perform a request to "http://example.com:123/test/index"
|
43
|
+
Then I should see the notifier JavaScript for the following:
|
44
|
+
| api_key | environment | host |
|
45
|
+
| myapikey! | production | mycloudtrapper.com:3001 |
|
46
|
+
|
47
|
+
Scenario: Don't include the Javascript notifier by default
|
48
|
+
When I generate a new Rails application
|
49
|
+
And I configure the Cloudtrapper shim
|
50
|
+
And I configure my application to require the "cloudtrapper" gem
|
51
|
+
When I configure the notifier to use the following configuration lines:
|
52
|
+
"""
|
53
|
+
config.api_key = "myapikey!"
|
54
|
+
"""
|
55
|
+
And I define a response for "TestController#index":
|
56
|
+
"""
|
57
|
+
render :inline => "<html><head></head><body></body></html>"
|
58
|
+
"""
|
59
|
+
And I route "/test/index" to "test#index"
|
60
|
+
And I perform a request to "http://example.com:123/test/index"
|
61
|
+
Then I should not see notifier JavaScript
|
62
|
+
|
63
|
+
Scenario: Don't include the Javascript notifier when enabled in non-public environments
|
64
|
+
When I generate a new Rails application
|
65
|
+
And I configure the Cloudtrapper shim
|
66
|
+
And I configure my application to require the "cloudtrapper" gem
|
67
|
+
When I configure the notifier to use the following configuration lines:
|
68
|
+
"""
|
69
|
+
config.api_key = "myapikey!"
|
70
|
+
config.environment_name = 'test'
|
71
|
+
"""
|
72
|
+
And I define a response for "TestController#index":
|
73
|
+
"""
|
74
|
+
render :inline => '<html><head><%= cloudtrapper_javascript_notifier %></head><body></body></html>'
|
75
|
+
"""
|
76
|
+
And I route "/test/index" to "test#index"
|
77
|
+
And I perform a request to "http://example.com:123/test/index" in the "test" environment
|
78
|
+
Then I should not see notifier JavaScript
|
79
|
+
|
80
|
+
Scenario: Include the Javascript notifier with a custom api key
|
81
|
+
When I generate a new Rails application
|
82
|
+
And I configure the Cloudtrapper shim
|
83
|
+
And I configure my application to require the "cloudtrapper" gem
|
84
|
+
When I configure the notifier to use the following configuration lines:
|
85
|
+
"""
|
86
|
+
config.api_key = "myapikey!"
|
87
|
+
config.js_api_key = "myjsapikey!"
|
88
|
+
"""
|
89
|
+
And I define a response for "TestController#index":
|
90
|
+
"""
|
91
|
+
render :inline => '<html><head><%= cloudtrapper_javascript_notifier %></head><body></body></html>'
|
92
|
+
"""
|
93
|
+
And I route "/test/index" to "test#index"
|
94
|
+
And I perform a request to "http://example.com:123/test/index"
|
95
|
+
Then I should see the notifier JavaScript for the following:
|
96
|
+
| api_key | environment | host |
|
97
|
+
| myjsapikey! | production | api.cloudtrapper.io |
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Use the Gem to catch errors in a Rake application
|
2
|
+
Background:
|
3
|
+
Given I have built and installed the "cloudtrapper" gem
|
4
|
+
|
5
|
+
Scenario: Catching exceptions in Rake
|
6
|
+
When I run rake with cloudtrapper
|
7
|
+
Then Cloudtrapper should catch the exception
|
8
|
+
|
9
|
+
Scenario: Falling back to default handler before Cloudtrapper is configured
|
10
|
+
When I run rake with cloudtrapper not yet configured
|
11
|
+
Then Cloudtrapper should not catch the exception
|
12
|
+
|
13
|
+
Scenario: Disabling Rake exception catcher
|
14
|
+
When I run rake with cloudtrapper disabled
|
15
|
+
Then Cloudtrapper should not catch the exception
|
16
|
+
|
17
|
+
Scenario: Autodetect, running from terminal
|
18
|
+
When I run rake with cloudtrapper autodetect from terminal
|
19
|
+
Then Cloudtrapper should not catch the exception
|
20
|
+
|
21
|
+
Scenario: Autodetect, not running from terminal
|
22
|
+
When I run rake with cloudtrapper autodetect not from terminal
|
23
|
+
Then Cloudtrapper should catch the exception
|
24
|
+
|
25
|
+
Scenario: Sending the correct component name
|
26
|
+
When I run rake with cloudtrapper
|
27
|
+
Then Cloudtrapper should send the rake command line as the component name
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Use the notifier in a Sinatra app
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have built and installed the "cloudtrapper" gem
|
5
|
+
|
6
|
+
Scenario: Rescue an exception in a Sinatra app
|
7
|
+
Given the following Rack app:
|
8
|
+
"""
|
9
|
+
require 'sinatra/base'
|
10
|
+
require 'cloudtrapper'
|
11
|
+
|
12
|
+
Cloudtrapper.configure do |config|
|
13
|
+
config.api_key = 'my_api_key'
|
14
|
+
end
|
15
|
+
|
16
|
+
class FontaneApp < Sinatra::Base
|
17
|
+
use Cloudtrapper::Rack
|
18
|
+
enable :raise_errors
|
19
|
+
|
20
|
+
get "/test/index" do
|
21
|
+
raise "Sinatra has left the building"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
app = FontaneApp
|
26
|
+
"""
|
27
|
+
When I perform a Rack request to "http://example.com:123/test/index?param=value"
|
28
|
+
Then I should receive a Cloudtrapper notification
|
29
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Then /^"([^\"]*)" should not contain text of "([^\"]*)"$/ do |target_file, contents_file|
|
2
|
+
notifier_root = File.join(File.dirname(__FILE__), '..', '..')
|
3
|
+
full_path_contents = File.join(notifier_root, contents_file)
|
4
|
+
contents_text = File.open(full_path_contents).read
|
5
|
+
|
6
|
+
full_path_target = File.join(rails_root, target_file)
|
7
|
+
target_text = File.open(full_path_target).read
|
8
|
+
|
9
|
+
target_text.should_not include(contents_text)
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
When /^I define a Metal endpoint called "([^\"]*)":$/ do |class_name, definition|
|
2
|
+
FileUtils.mkdir_p(File.join(rails_root, 'app', 'metal'))
|
3
|
+
file_name = File.join(rails_root, 'app', 'metal', "#{class_name.underscore}.rb")
|
4
|
+
File.open(file_name, "w") do |file|
|
5
|
+
file.puts "class #{class_name}"
|
6
|
+
file.puts definition
|
7
|
+
file.puts "end"
|
8
|
+
end
|
9
|
+
When %{the metal endpoint "#{class_name}" is mounted in the Rails 3 routes.rb} if rails3?
|
10
|
+
end
|
11
|
+
|
12
|
+
When /^the metal endpoint "([^\"]*)" is mounted in the Rails 3 routes.rb$/ do |class_name|
|
13
|
+
routesrb = File.join(rails_root, "config", "routes.rb")
|
14
|
+
routes = IO.readlines(routesrb)
|
15
|
+
rack_route = "match '/metal(/*other)' => #{class_name}"
|
16
|
+
routes = routes[0..-2] + [rack_route, routes[-1]]
|
17
|
+
File.open(routesrb, "w") do |f|
|
18
|
+
f.puts "require 'app/metal/#{class_name.underscore}'"
|
19
|
+
routes.each do |route_line|
|
20
|
+
f.puts route_line
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Given /^the following Rack app:$/ do |definition|
|
2
|
+
File.open(RACK_FILE, 'w') { |file| file.write(definition) }
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I perform a Rack request to "([^\"]*)"$/ do |url|
|
6
|
+
shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'cloudtrapper_shim.rb.template')
|
7
|
+
request_file = File.join(TEMP_DIR, 'rack_request.rb')
|
8
|
+
File.open(request_file, 'w') do |file|
|
9
|
+
file.puts "require 'rubygems'"
|
10
|
+
file.puts IO.read(shim_file)
|
11
|
+
file.puts IO.read(RACK_FILE)
|
12
|
+
file.puts "env = Rack::MockRequest.env_for(#{url.inspect})"
|
13
|
+
file.puts "status, headers, body = app.call(env)"
|
14
|
+
file.puts %{puts "HTTP \#{status}"}
|
15
|
+
file.puts %{headers.each { |key, value| puts "\#{key}: \#{value}"}}
|
16
|
+
file.puts "body.each { |part| print part }"
|
17
|
+
end
|
18
|
+
@terminal.run("ruby #{request_file}")
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^I should receive a Cloudtrapper notification for rack$/ do
|
22
|
+
Then %{I should see "You have accessed a deleted account."}
|
23
|
+
end
|
@@ -0,0 +1,433 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'active_support/core_ext/string/inflections'
|
3
|
+
|
4
|
+
Given /^I have built and installed the "([^\"]*)" gem$/ do |gem_name|
|
5
|
+
@terminal.build_and_install_gem(File.join(PROJECT_ROOT, "#{gem_name}.gemspec"))
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^I generate a new Rails application$/ do
|
9
|
+
@terminal.cd(TEMP_DIR)
|
10
|
+
|
11
|
+
rails3 = version_string =~ /^3/
|
12
|
+
|
13
|
+
if rails3
|
14
|
+
rails_create_command = 'new'
|
15
|
+
else
|
16
|
+
rails_create_command = ''
|
17
|
+
end
|
18
|
+
|
19
|
+
load_rails = <<-RUBY
|
20
|
+
gem 'rails', '#{version_string}'; \
|
21
|
+
load Gem.bin_path('#{version_string >= "3.2.0" ? "railties" : "rails"}', 'rails', '#{version_string}')
|
22
|
+
RUBY
|
23
|
+
|
24
|
+
@terminal.run(%{ruby -rrubygems -rthread -e "#{load_rails.strip!}" #{rails_create_command} rails_root})
|
25
|
+
if rails_root_exists?
|
26
|
+
@terminal.echo("Generated a Rails #{version_string} application")
|
27
|
+
else
|
28
|
+
raise "Unable to generate a Rails application:\n#{@terminal.output}"
|
29
|
+
end
|
30
|
+
require_thread
|
31
|
+
if version_string >= "3.1.0"
|
32
|
+
When %{I configure my application to require the "therubyracer" gem with version "0.10.1"}
|
33
|
+
elsif version_string == "2.3.14"
|
34
|
+
monkeypatch_old_version
|
35
|
+
end
|
36
|
+
config_gem_dependencies unless rails3
|
37
|
+
end
|
38
|
+
|
39
|
+
When /^I run the cloudtrapper generator with "([^\"]*)"$/ do |generator_args|
|
40
|
+
if rails3?
|
41
|
+
When %{I run "./script/rails generate cloudtrapper #{generator_args}"}
|
42
|
+
else
|
43
|
+
When %{I run "./script/generate cloudtrapper #{generator_args}"}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
When /^I print the console output$/ do
|
48
|
+
puts @terminal.output
|
49
|
+
end
|
50
|
+
|
51
|
+
Given /^I have installed the "([^\"]*)" gem$/ do |gem_name|
|
52
|
+
@terminal.install_gem(gem_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
When /^I configure my application to require the "capistrano" gem if necessary$/ do
|
57
|
+
When %{I configure my application to require the "capistrano" gem} if version_string >= "3.0.0"
|
58
|
+
end
|
59
|
+
|
60
|
+
When /^I configure my application to require the "([^\"]*)" gem(?: with version "(.+)")?$/ do |gem_name, version|
|
61
|
+
if rails_manages_gems?
|
62
|
+
config_gem(gem_name, version)
|
63
|
+
elsif bundler_manages_gems?
|
64
|
+
bundle_gem(gem_name, version)
|
65
|
+
else
|
66
|
+
File.open(environment_path, 'a') do |file|
|
67
|
+
file.puts
|
68
|
+
file.puts("require 'cloudtrapper'")
|
69
|
+
file.puts("require 'cloudtrapper/rails'")
|
70
|
+
end
|
71
|
+
|
72
|
+
unless rails_finds_generators_in_gems?
|
73
|
+
FileUtils.cp_r(File.join(PROJECT_ROOT, 'generators'), File.join(rails_root, 'lib'))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
When /^I run "([^\"]*)"$/ do |command|
|
79
|
+
@terminal.cd(rails_root)
|
80
|
+
@terminal.run(command)
|
81
|
+
end
|
82
|
+
|
83
|
+
Then /^I should receive a Cloudtrapper notification$/ do
|
84
|
+
Then %{I should see "** [Cloudtrapper] Response from Cloudtrapper:"}
|
85
|
+
And %{I should see "b6817316-9c45-ed26-45eb-780dbb86aadb"}
|
86
|
+
And %{I should see "http://cloudtrapper.io/locate/b6817316-9c45-ed26-45eb-780dbb86aadb"}
|
87
|
+
end
|
88
|
+
|
89
|
+
Then /^I should receive two Cloudtrapper notifications$/ do
|
90
|
+
@terminal.output.scan(/\[Cloudtrapper\] Response from Cloudtrapper:/).size.should == 2
|
91
|
+
end
|
92
|
+
|
93
|
+
When /^I configure the Cloudtrapper shim$/ do
|
94
|
+
if bundler_manages_gems?
|
95
|
+
bundle_gem("sham_rack")
|
96
|
+
end
|
97
|
+
|
98
|
+
shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'cloudtrapper_shim.rb.template')
|
99
|
+
if rails_supports_initializers?
|
100
|
+
target = File.join(rails_root, 'config', 'initializers', 'cloudtrapper_shim.rb')
|
101
|
+
FileUtils.cp(shim_file, target)
|
102
|
+
else
|
103
|
+
File.open(environment_path, 'a') do |file|
|
104
|
+
file.puts
|
105
|
+
file.write IO.read(shim_file)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
When /^I configure the notifier to use "([^\"]*)" as an API key$/ do |api_key|
|
111
|
+
steps %{
|
112
|
+
When I configure the notifier to use the following configuration lines:
|
113
|
+
"""
|
114
|
+
config.api_key = #{api_key.inspect}
|
115
|
+
"""
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
When /^I configure the notifier to use the following configuration lines:$/ do |configuration_lines|
|
120
|
+
if rails_manages_gems?
|
121
|
+
requires = ''
|
122
|
+
else
|
123
|
+
requires = "require 'cloudtrapper'"
|
124
|
+
end
|
125
|
+
|
126
|
+
initializer_code = <<-EOF
|
127
|
+
#{requires}
|
128
|
+
Cloudtrapper.configure do |config|
|
129
|
+
#{configuration_lines}
|
130
|
+
end
|
131
|
+
EOF
|
132
|
+
|
133
|
+
if rails_supports_initializers?
|
134
|
+
File.open(rails_initializer_file, 'w') { |file| file.write(initializer_code) }
|
135
|
+
else
|
136
|
+
File.open(environment_path, 'a') do |file|
|
137
|
+
file.puts
|
138
|
+
file.puts initializer_code
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def rails_initializer_file
|
145
|
+
File.join(rails_root, 'config', 'initializers', 'cloudtrapper.rb')
|
146
|
+
end
|
147
|
+
|
148
|
+
def rails_non_initializer_cloudtrapper_config_file
|
149
|
+
File.join(rails_root, 'config', 'cloudtrapper.rb')
|
150
|
+
end
|
151
|
+
|
152
|
+
Then /^I should see "([^\"]*)"$/ do |expected_text|
|
153
|
+
unless @terminal.output.include?(expected_text)
|
154
|
+
raise("Got terminal output:\n#{@terminal.output}\n\nExpected output:\n#{expected_text}")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
Then /^I should not see "([^\"]*)"$/ do |unexpected_text|
|
159
|
+
if @terminal.output.include?(unexpected_text)
|
160
|
+
raise("Got terminal output:\n#{@terminal.output}\n\nDid not expect the following output:\n#{unexpected_text}")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
When /^I uninstall the "([^\"]*)" gem$/ do |gem_name|
|
165
|
+
@terminal.uninstall_gem(gem_name)
|
166
|
+
end
|
167
|
+
|
168
|
+
When /^I unpack the "([^\"]*)" gem$/ do |gem_name|
|
169
|
+
if bundler_manages_gems?
|
170
|
+
@terminal.cd(rails_root)
|
171
|
+
@terminal.run("bundle pack")
|
172
|
+
elsif rails_manages_gems?
|
173
|
+
@terminal.cd(rails_root)
|
174
|
+
@terminal.run("rake gems:unpack GEM=#{gem_name}")
|
175
|
+
else
|
176
|
+
vendor_dir = File.join(rails_root, 'vendor', 'gems')
|
177
|
+
FileUtils.mkdir_p(vendor_dir)
|
178
|
+
@terminal.cd(vendor_dir)
|
179
|
+
@terminal.run("gem unpack #{gem_name}")
|
180
|
+
gem_path =
|
181
|
+
Dir.glob(File.join(rails_root, 'vendor', 'gems', "#{gem_name}-*", 'lib')).first
|
182
|
+
File.open(environment_path, 'a') do |file|
|
183
|
+
file.puts
|
184
|
+
file.puts("$: << #{gem_path.inspect}")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
When /^I install cached gems$/ do
|
190
|
+
if bundler_manages_gems?
|
191
|
+
Then %{I run "bundle install"}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
When /^I install the "([^\"]*)" plugin$/ do |plugin_name|
|
196
|
+
FileUtils.mkdir_p("#{rails_root}/vendor/plugins/#{plugin_name}")
|
197
|
+
end
|
198
|
+
|
199
|
+
When /^I define a response for "([^\"]*)":$/ do |controller_and_action, definition|
|
200
|
+
controller_class_name, action = controller_and_action.split('#')
|
201
|
+
controller_name = controller_class_name.underscore
|
202
|
+
controller_file_name = File.join(rails_root, 'app', 'controllers', "#{controller_name}.rb")
|
203
|
+
File.open(controller_file_name, "w") do |file|
|
204
|
+
file.puts "class #{controller_class_name} < ApplicationController"
|
205
|
+
file.puts "def consider_all_requests_local; false; end"
|
206
|
+
file.puts "def local_request?; false; end"
|
207
|
+
file.puts "def #{action}"
|
208
|
+
file.puts definition
|
209
|
+
file.puts "end"
|
210
|
+
file.puts "end"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
When /^I perform a request to "([^\"]*)"$/ do |uri|
|
215
|
+
perform_request(uri)
|
216
|
+
end
|
217
|
+
|
218
|
+
When /^I perform a request to "([^\"]*)" in the "([^\"]*)" environment$/ do |uri, environment|
|
219
|
+
perform_request(uri, environment)
|
220
|
+
end
|
221
|
+
|
222
|
+
Given /^the response page for a "([^\"]*)" error is$/ do |error, html|
|
223
|
+
File.open(File.join(rails_root, "public", "#{error}.html"), "w") do |file|
|
224
|
+
file.write(html)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
Then /^I should receive the following Cloudtrapper notification:$/ do |table|
|
229
|
+
exceptions = @terminal.output.scan(%r{Recieved the following exception:\n([^\n]*)\n}m)
|
230
|
+
exceptions.should_not be_empty
|
231
|
+
|
232
|
+
xml = exceptions.last[0]
|
233
|
+
doc = Nokogiri::XML.parse(xml)
|
234
|
+
|
235
|
+
hash = table.transpose.hashes.first
|
236
|
+
|
237
|
+
doc.should have_content('//error/message', hash['error message'])
|
238
|
+
doc.should have_content('//error/class', hash['error class'])
|
239
|
+
doc.should have_content('//request/url', hash['url'])
|
240
|
+
|
241
|
+
doc.should have_content('//component', hash['component']) if hash['component']
|
242
|
+
doc.should have_content('//action', hash['action']) if hash['action']
|
243
|
+
doc.should have_content('//server-environment/project-root', hash['project-root']) if hash['project-root']
|
244
|
+
|
245
|
+
if hash['session']
|
246
|
+
session_key, session_value = hash['session'].split(': ')
|
247
|
+
doc.should have_content('//request/session/var/@key', session_key)
|
248
|
+
doc.should have_content('//request/session/var', session_value)
|
249
|
+
end
|
250
|
+
|
251
|
+
if hash['parameters']
|
252
|
+
param_key, param_value = hash['parameters'].split(': ')
|
253
|
+
doc.should have_content('//request/params/var/@key', param_key)
|
254
|
+
doc.should have_content('//request/params/var', param_value)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
Then /^I should see the Rails version$/ do
|
259
|
+
Then %{I should see "[Rails: #{rails_version}]"}
|
260
|
+
end
|
261
|
+
|
262
|
+
Then /^I should see that "([^\"]*)" is not considered a framework gem$/ do |gem_name|
|
263
|
+
Then %{I should not see "[R] #{gem_name}"}
|
264
|
+
end
|
265
|
+
|
266
|
+
Then /^the command should have run successfully$/ do
|
267
|
+
@terminal.status.exitstatus.should == 0
|
268
|
+
end
|
269
|
+
|
270
|
+
When /^I route "([^\"]*)" to "([^\"]*)"$/ do |path, controller_action_pair|
|
271
|
+
route = if rails3?
|
272
|
+
%(match "#{path}", :to => "#{controller_action_pair}")
|
273
|
+
else
|
274
|
+
controller, action = controller_action_pair.split('#')
|
275
|
+
%(map.connect "#{path}", :controller => "#{controller}", :action => "#{action}")
|
276
|
+
end
|
277
|
+
routes_file = File.join(rails_root, "config", "routes.rb")
|
278
|
+
File.open(routes_file, "r+") do |file|
|
279
|
+
content = file.read
|
280
|
+
content.gsub!(/^end$/, " #{route}\nend")
|
281
|
+
file.rewind
|
282
|
+
file.write(content)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
Then /^"([^\"]*)" should not contain "([^\"]*)"$/ do |file_path, text|
|
287
|
+
actual_text = IO.read(File.join(rails_root, file_path))
|
288
|
+
if actual_text.include?(text)
|
289
|
+
raise "Didn't expect text:\n#{actual_text}\nTo include:\n#{text}"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
Then /^my Cloudtrapper configuration should contain the following line:$/ do |line|
|
294
|
+
configuration_file = if rails_supports_initializers?
|
295
|
+
rails_initializer_file
|
296
|
+
else
|
297
|
+
rails_non_initializer_cloudtrapper_config_file
|
298
|
+
# environment_path
|
299
|
+
end
|
300
|
+
|
301
|
+
configuration = File.read(configuration_file)
|
302
|
+
if ! configuration.include?(line.strip)
|
303
|
+
raise "Expected text:\n#{configuration}\nTo include:\n#{line}\nBut it didn't."
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
When /^I set the environment variable "([^\"]*)" to "([^\"]*)"$/ do |environment_variable, value|
|
308
|
+
@terminal.environment_variables[environment_variable] = value
|
309
|
+
end
|
310
|
+
|
311
|
+
When /^I configure the Heroku rake shim$/ do
|
312
|
+
@terminal.invoke_heroku_rake_tasks_locally = true
|
313
|
+
end
|
314
|
+
|
315
|
+
When /^I configure the Heroku gem shim with "([^\"]*)"( and multiple app support)?$/ do |api_key, multi_app|
|
316
|
+
heroku_script_bin = File.join(TEMP_DIR, "bin")
|
317
|
+
FileUtils.mkdir_p(heroku_script_bin)
|
318
|
+
heroku_script = File.join(heroku_script_bin, "heroku")
|
319
|
+
heroku_env_vars = <<-VARS
|
320
|
+
AIRBRAKE_API_KEY => myapikey
|
321
|
+
APP_NAME => cold-moon-2929
|
322
|
+
BUNDLE_WITHOUT => development:test
|
323
|
+
COMMIT_HASH => lj32j42ss9332jfa2
|
324
|
+
DATABASE_URL => postgres://fchovwjcyb:QLPVWmBBbf4hCG_YMrtV@ec3-107-28-193-23.compute-1.amazonaws.com/fhcvojwwcyb
|
325
|
+
LANG => en_US.UTF-8
|
326
|
+
LAST_GIT_BY => kensa
|
327
|
+
RACK_ENV => production
|
328
|
+
SHARED_DATABASE_URL => postgres://fchovwjcyb:QLPVwMbbbF8Hcg_yMrtV@ec2-94-29-181-224.compute-1.amazonaws.com/fhcvojcwwyb
|
329
|
+
STACK => bamboo-mri-1.9.2
|
330
|
+
URL => cold-moon-2929.heroku.com
|
331
|
+
VARS
|
332
|
+
single_app_script = <<-SINGLE
|
333
|
+
#!/bin/bash
|
334
|
+
if [ $1 == 'config' ]
|
335
|
+
then
|
336
|
+
echo "#{heroku_env_vars}"
|
337
|
+
fi
|
338
|
+
SINGLE
|
339
|
+
|
340
|
+
multi_app_script = <<-MULTI
|
341
|
+
#!/bin/bash
|
342
|
+
if [[ $1 == 'config' && $2 == '--app' ]]
|
343
|
+
then
|
344
|
+
echo "#{heroku_env_vars}"
|
345
|
+
fi
|
346
|
+
MULTI
|
347
|
+
|
348
|
+
File.open(heroku_script, "w") do |f|
|
349
|
+
if multi_app
|
350
|
+
f.puts multi_app_script
|
351
|
+
else
|
352
|
+
f.puts single_app_script
|
353
|
+
end
|
354
|
+
end
|
355
|
+
FileUtils.chmod(0755, heroku_script)
|
356
|
+
@terminal.prepend_path(heroku_script_bin)
|
357
|
+
end
|
358
|
+
|
359
|
+
When /^I configure the application to filter parameter "([^\"]*)"$/ do |parameter|
|
360
|
+
if rails3?
|
361
|
+
application_filename = File.join(rails_root, 'config', 'application.rb')
|
362
|
+
application_lines = File.open(application_filename).readlines
|
363
|
+
|
364
|
+
application_definition_line = application_lines.detect { |line| line =~ /Application/ }
|
365
|
+
application_definition_line_index = application_lines.index(application_definition_line)
|
366
|
+
|
367
|
+
application_lines.insert(application_definition_line_index + 1,
|
368
|
+
" config.filter_parameters += [#{parameter.inspect}]")
|
369
|
+
|
370
|
+
File.open(application_filename, "w") do |file|
|
371
|
+
file.puts application_lines.join("\n")
|
372
|
+
end
|
373
|
+
else
|
374
|
+
controller_filename = application_controller_filename
|
375
|
+
controller_lines = File.open(controller_filename).readlines
|
376
|
+
|
377
|
+
controller_definition_line = controller_lines.detect { |line| line =~ /ApplicationController/ }
|
378
|
+
controller_definition_line_index = controller_lines.index(controller_definition_line)
|
379
|
+
|
380
|
+
controller_lines.insert(controller_definition_line_index + 1,
|
381
|
+
" filter_parameter_logging #{parameter.inspect}")
|
382
|
+
|
383
|
+
File.open(controller_filename, "w") do |file|
|
384
|
+
file.puts controller_lines.join("\n")
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
Then /^I should see the notifier JavaScript for the following:$/ do |table|
|
390
|
+
hash = table.hashes.first
|
391
|
+
host = hash['host'] || 'api.cloudtrapper.io'
|
392
|
+
secure = hash['secure'] || false
|
393
|
+
api_key = hash['api_key']
|
394
|
+
environment = hash['environment'] || 'production'
|
395
|
+
|
396
|
+
document_body = '<html>' + @terminal.output.split('<html>').last
|
397
|
+
document_body.should include("#{host}/javascripts/notifier.js")
|
398
|
+
|
399
|
+
response = Nokogiri::HTML.parse(document_body)
|
400
|
+
response.css("script[type='text/javascript']:last-child").each do |element|
|
401
|
+
content = element.content
|
402
|
+
content.should include("Cloudtrapper.setKey('#{api_key}');")
|
403
|
+
content.should include("Cloudtrapper.setHost('#{host}');")
|
404
|
+
content.should include("Cloudtrapper.setEnvironment('#{environment}');")
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
Then "the notifier JavaScript should provide the following errorDefaults:" do |table|
|
409
|
+
hash = table.hashes.first
|
410
|
+
|
411
|
+
document_body = '<html>' + @terminal.output.split('<html>').last
|
412
|
+
|
413
|
+
response = Nokogiri::HTML.parse(document_body)
|
414
|
+
response.css("script[type='text/javascript']:last-child").each do |element|
|
415
|
+
content = element.content
|
416
|
+
|
417
|
+
hash.each do |key, value|
|
418
|
+
content.should =~ %r{Cloudtrapper\.setErrorDefaults.*#{key}: "#{value}}m
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
Then /^I should not see notifier JavaScript$/ do
|
424
|
+
response = Nokogiri::HTML.parse('<html>' + @terminal.output.split('<html>').last)
|
425
|
+
response.at_css("script[type='text/javascript'][src$='/javascripts/notifier.js']").should be_nil
|
426
|
+
end
|
427
|
+
|
428
|
+
|
429
|
+
When /^I configure usage of Cloudtrapper$/ do
|
430
|
+
When %{I configure my application to require the "cloudtrapper" gem}
|
431
|
+
When %{I run the cloudtrapper generator with "-k myapikey"}
|
432
|
+
@terminal.flush! # flush the results of setting up Cloudtrapper (generates notification)
|
433
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
When /I run rake with (.+)/ do |command|
|
2
|
+
@rake_command = "rake #{command.gsub(' ','_')}"
|
3
|
+
@rake_result = `cd features/support/rake && GEM_HOME=#{BUILT_GEM_ROOT} #{@rake_command} 2>&1`
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /Cloudtrapper should (|not) ?catch the exception/ do |condition|
|
7
|
+
if condition=='not'
|
8
|
+
@rake_result.should_not =~ /^cloudtrapper/
|
9
|
+
else
|
10
|
+
@rake_result.should =~ /^cloudtrapper/
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Then /Cloudtrapper should send the rake command line as the component name/ do
|
15
|
+
component = @rake_result.match(/^cloudtrapper (.*)$/)[1]
|
16
|
+
component.should == @rake_command
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'sham_rack'
|
2
|
+
|
3
|
+
ShamRack.at("api.cloudtrapper.io") do |env|
|
4
|
+
response = <<-end_xml
|
5
|
+
<notice>
|
6
|
+
<id>b6817316-9c45-ed26-45eb-780dbb86aadb</id>
|
7
|
+
<url>http://cloudtrapper.io/locate/b6817316-9c45-ed26-45eb-780dbb86aadb</url>
|
8
|
+
</notice>
|
9
|
+
end_xml
|
10
|
+
["200 OK", { "Content-type" => "text/xml" }, [response]]
|
11
|
+
end
|