vault-tools 0.3.11 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,6 +4,11 @@ require 'sinatra/base'
4
4
  require 'scrolls'
5
5
  require 'rack/ssl-enforcer'
6
6
  require 'heroku-api'
7
+ require 'honeybadger'
8
+
9
+ Honeybadger.configure do |config|
10
+ config.api_key = ENV['HONEYBADGER_API_KEY']
11
+ end
7
12
 
8
13
  module Vault
9
14
  #require bundler and the proper gems for the ENV
@@ -27,19 +32,26 @@ module Vault
27
32
  end
28
33
 
29
34
  def self.hack_time_class
30
- $stderr.puts "Modifying Time#to_s to use #iso8601"
35
+ $stderr.puts "Modifying Time#to_s to use #iso8601..."
31
36
  # use send to call private method
32
37
  Time.send(:define_method, :to_s) do
33
38
  self.iso8601
34
39
  end
35
40
  end
36
41
 
42
+ def self.override_global_config
43
+ $stderr.puts "Set Config to Vault::Config..."
44
+ Object.send(:remove_const, :Config)
45
+ Object.const_set(:Config, Vault::Config)
46
+ end
47
+
37
48
  # all in one go
38
49
  def self.setup
39
50
  self.require
40
51
  self.load_path
41
52
  self.set_timezones
42
53
  self.hack_time_class
54
+ self.override_global_config
43
55
  end
44
56
  end
45
57
 
@@ -1,62 +1,168 @@
1
1
  module Vault
2
2
  module Config
3
- extend self
3
+ @@defaults = {}
4
4
 
5
- def remote_env(app, env)
5
+ # An environment variable from another app.
6
+ #
7
+ # @param app [String] The name of the app to get the value from.
8
+ # @param name [String] The name of the environment variable to fetch a
9
+ # value for.
10
+ # @return [String] The value of an environment variable from another
11
+ # Heroku app or nil if no match is available.
12
+ def self.remote_env(app, name)
6
13
  heroku = Heroku::API.new
7
- heroku.get_config_vars(app).body[env]
14
+ heroku.get_config_vars(app).body[name]
8
15
  end
9
16
 
10
- def core_follower_url
11
- remote_env('vault-core-follower', 'DATABASE_URL')
17
+ # An environment variable.
18
+ #
19
+ # @param name [String] The name of the environment variable to fetch a
20
+ # value for.
21
+ # @return [String] The value of the environment variable or nil if no
22
+ # match is available.
23
+ def self.env(name)
24
+ self[name]
12
25
  end
13
26
 
14
- def env(key)
15
- ENV[key]
27
+ # Set a default
28
+ # Defaults are supplied when accessing via Config[:varname]
29
+ #
30
+ # @param key [Symbol/String] The lower-case name of the default
31
+ # @return [String] The value of the default
32
+ def self.default(key, value)
33
+ @@defaults[key.to_sym] = value
16
34
  end
17
35
 
18
- def env!(key)
19
- env(key) || raise("missing #{key}")
36
+ # Get all the defaults
37
+ # @return [Hash] The current set of defaults
38
+ def self.defaults
39
+ @@defaults
20
40
  end
21
41
 
22
- def production?
23
- env('RACK_ENV') == 'production'
42
+ # Get a Config value
43
+ # Uses defaults if available. Converts upper-case ENV var names
44
+ # to lower-case default names.
45
+ #
46
+ # Config[:foo] == nil
47
+ #
48
+ # Config.default(:foo, 'bar')
49
+ # Config[:foo] == 'bar'
50
+ #
51
+ # ENV['FOO'] = 'baz'
52
+ # Config[:foo] == 'baz'
53
+ #
54
+ # @param key [Symbol] The lower-case name of the ENV value
55
+ # @return [String] The value of the ENV value or default.
56
+ def self.[](name)
57
+ var_name = name.to_s.upcase
58
+ ENV[var_name] || @@defaults[name]
24
59
  end
25
60
 
26
- def test?
27
- env('RACK_ENV') == 'test'
61
+ # An environment variable.
62
+ #
63
+ # @param name [String] The name of the environment variable to fetch a
64
+ # value for.
65
+ # @raise [RuntimeError] Raised if the environment variable is not defined.
66
+ # @return [String] The value of the environment variable.
67
+ def self.env!(name)
68
+ self[name] || raise("missing #{name}")
28
69
  end
29
70
 
30
- def app_name
71
+ # The `RACK_ENV` environment variable is used to determine whether the
72
+ # service is in production mode or not.
73
+ #
74
+ # @return [Bool] True if the service is in production mode.
75
+ def self.production?
76
+ self['RACK_ENV'] == 'production'
77
+ end
78
+
79
+ # The `RACK_ENV` environment variable is used to determine whether the
80
+ # service is in test mode or not.
81
+ #
82
+ # @return [Bool] True if the service is in test mode.
83
+ def self.test?
84
+ self['RACK_ENV'] == 'test'
85
+ end
86
+
87
+ # The `APP_NAME` env var is used to identify which codebase is
88
+ # running in librato. This usually matches the name of the repository.
89
+ #
90
+ # @return [String] The name of the app
91
+ def self.app_name
31
92
  env!("APP_NAME")
32
93
  end
33
94
 
34
- def app_deploy
95
+ # The `APP_DEPLOY` env var is used to identify which deploy of the codebase is
96
+ # running in librato. This usually matches the name of the environment such
97
+ # as local, production, staging, etc.
98
+ #
99
+ # @return [String] The deploy/environment of the app
100
+ def self.app_deploy
35
101
  env!("APP_DEPLOY")
36
102
  end
37
103
 
38
- def port
104
+ # The port to listen on for web requests.
105
+ #
106
+ # @return [Fixnum] The port to listen on for web requests.
107
+ def self.port
39
108
  env!("PORT").to_i
40
109
  end
41
110
 
42
- def database_url(kind = '')
111
+ # The database URL from the environment.
112
+ #
113
+ # @param kind [String] Optionally, the leading name of `*_DATABASE_URL`
114
+ # environment variable. Defaults to `DATABASE_URL`.
115
+ # @raise [RuntimeError] Raised if the environment variable is not defined.
116
+ def self.database_url(kind = '')
43
117
  kind = "#{kind}_".upcase unless kind.empty?
44
118
  env!("#{kind}DATABASE_URL")
45
119
  end
46
120
 
47
- def enable_ssl?
48
- !env('VAULT_TOOLS_DISABLE_SSL')
121
+ # Enforce HTTPS connections in the web API?
122
+ #
123
+ # @return [Bool] True if SSL is enforced, otherwise false.
124
+ def self.enable_ssl?
125
+ !bool?('VAULT_TOOLS_DISABLE_SSL')
126
+ end
127
+
128
+ # An environment variable converted to a Fixnum.
129
+ #
130
+ # @param name [String] The name of the environment variable to fetch a
131
+ # Fixnum for.
132
+ # @return [Fixnum] The number or nil if the value couldn't be coerced to a
133
+ # Fixnum.
134
+ def self.int(name)
135
+ self[name] ? self[name].to_i : nil
136
+ end
137
+
138
+ # Comma-separated words converted to an array.
139
+ #
140
+ # @param name [String] The name of the environment variable to fetch an
141
+ # array for.
142
+ # @raise [RuntimeError] Raised if the environment variable is not defined.
143
+ # @return [Array] An array of values.
144
+ def self.array(name)
145
+ env!(name).split(',')
49
146
  end
50
147
 
51
- def int(key)
52
- env(key) ? env(key).to_i : nil
148
+ # An environment variable converted to a bool.
149
+ #
150
+ # @param name [String] The name of the environment variable to fetch a
151
+ # boolean for.
152
+ # @return [bool] True if the value is `true`, otherwise false.
153
+ def self.bool?(name)
154
+ self[name] == 'true'
53
155
  end
54
156
 
55
- def bool?(key)
56
- ENV[key] == 'true'
157
+ def self.time(name)
158
+ Time.parse(self[name])
57
159
  end
58
160
 
59
- def sidekiq_concurrency
161
+ # The number of threads to use in Sidekiq workers.
162
+ #
163
+ # @return [Fixnum] The number of threads from the `SIDEKIQ_CONCURRENCY`
164
+ # environment variable or 25 if no variable is defined.
165
+ def self.sidekiq_concurrency
60
166
  int('SIDEKIQ_CONCURRENCY') || 25
61
167
  end
62
168
  end
@@ -4,14 +4,14 @@
4
4
  #
5
5
  # require 'vault-tools/core_db_tasks'
6
6
 
7
- desc "Pull db/structure.sql from core HEAD"
7
+ desc "Pull db/structure.sql from api HEAD"
8
8
  task :pull_core do
9
9
  steps = []
10
10
  steps << 'cd contrib/'
11
11
  if File.exists?('contrib/core')
12
12
  steps << 'rm -rf core'
13
13
  end
14
- steps << 'git clone -n git@github.com:heroku/core --depth 1'
14
+ steps << 'git clone -n git@github.com:heroku/api --depth 1'
15
15
  steps << 'cd core'
16
16
  steps << 'git checkout HEAD db/structure.sql'
17
17
  # make sure we don't submodule it
@@ -19,13 +19,13 @@ task :pull_core do
19
19
  sh steps.join(' && ')
20
20
  end
21
21
 
22
- desc "Drop and create vault-usage-test, core-test and shushu-test databases"
22
+ desc "Drop and recreate the core-test database"
23
23
  task :create_core_db => [:drop_core_db, :pull_core] do
24
24
  sh 'createdb core-test'
25
25
  sh 'psql core-test -f contrib/core/db/structure.sql'
26
26
  end
27
27
 
28
- desc "Drop the vault-usage-test, core-test and shushu-test databases"
28
+ desc "Drop the core-test database"
29
29
  task :drop_core_db do
30
30
  sh 'dropdb core-test || true'
31
31
  end
@@ -42,10 +42,10 @@ module Vault
42
42
  # @param duration [Fixnum] The duration to record, in milliseconds.
43
43
  def self.time(name, duration)
44
44
  if name
45
- name.gsub(/\/:\w+/, ''). # Remove param names from path.
46
- gsub("/", "-"). # Replace slash with dash.
47
- gsub(/[^A-Za-z0-9\-\_]/, ''). # Only keep subset of chars.
48
- sub(/^-/, ""). # Strip the leading dash.
45
+ name.gsub(/\/:\w+/, ''). # Remove param names from path.
46
+ gsub(/[\/_]+/, "-"). # Replace slash with dash.
47
+ gsub(/[^A-Za-z0-9\-\_]/, ''). # Only keep subset of chars.
48
+ sub(/^-+/, ""). # Strip the leading dashes.
49
49
  tap { |name| measure(name, "#{duration}ms") }
50
50
  end
51
51
  end
@@ -13,13 +13,13 @@ task :pull_payments do
13
13
  sh steps.join(' && ')
14
14
  end
15
15
 
16
- desc "Drop and create vault-usage-test, payments-test and shushu-test databases"
16
+ desc "Drop and recreate payments-test database"
17
17
  task :create_payments_db => [:drop_payments_db, :pull_payments] do
18
18
  sh 'createdb payments-test'
19
19
  sh 'psql payments-test -f contrib/payments/db/structure.sql'
20
20
  end
21
21
 
22
- desc "Drop the vault-usage-test, payments-test and shushu-test databases"
22
+ desc "Drop the payments-test database"
23
23
  task :drop_payments_db do
24
24
  sh 'dropdb payments-test || true'
25
25
  end
@@ -1,5 +1,5 @@
1
1
  module Vault
2
2
  module Tools
3
- VERSION = '0.3.11'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end
@@ -23,7 +23,7 @@ module Vault
23
23
  # Check request for HTTP Basic creds and
24
24
  # password matches settings.basic_password
25
25
  def authorized?
26
- @auth ||= Rack::Auth::Basic::Request.new(request.env)
26
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
27
27
  @auth.provided? && @auth.basic? && @auth.credentials &&
28
28
  @auth.credentials[1] == settings.basic_password
29
29
  end
@@ -51,6 +51,7 @@ module Vault
51
51
  # body for easy debugging of errors.
52
52
  error do
53
53
  e = env['sinatra.error']
54
+ Honeybadger.notify(e, rack_env: env)
54
55
  content = "#{e.class}: #{e.message}\n\n"
55
56
  content << e.backtrace.join("\n")
56
57
  [500, content]
@@ -2,107 +2,180 @@ require 'helper'
2
2
  require 'minitest/mock'
3
3
 
4
4
  class ConfigTest < Vault::TestCase
5
- # Config.production? is true when RACK_ENV=production
5
+ include Vault::Test::EnvironmentHelpers
6
+
7
+ # Config.remote_env uses the Heroku API to read config vars from
8
+ # other apps.
9
+ def test_remote_env
10
+ api_mock = MiniTest::Mock.new
11
+ api_response = OpenStruct.new(body: {'DATABASE_URL' => 'postgres:///foo'})
12
+ Heroku::API.stub(:new, api_mock) do
13
+ api_mock.expect(:get_config_vars, api_response, ['app'])
14
+ assert_equal('postgres:///foo',
15
+ Config.remote_env('app', 'DATABASE_URL'))
16
+ end
17
+ end
18
+
19
+ # Config.env returns the value matching the specified environment
20
+ # variable name.
21
+ def test_env
22
+ set_env('VALUE', 'value')
23
+ assert_equal(Config.env('VALUE'), 'value')
24
+ end
25
+
26
+ # Config[] returns the value matching the specified environment
27
+ # variable name.
28
+ def test_brackets
29
+ set_env('VALUE', 'value')
30
+ assert_equal(Config[:value], 'value')
31
+ end
32
+
33
+ # Config.env return nil if an unknown environment variable is
34
+ # requested.
35
+ def test_env_with_unknown_name
36
+ assert_equal(Config.env('UNKNOWN'), nil)
37
+ end
38
+
39
+ # Config.env! returns the value matching the specified environment
40
+ # variable name.
41
+ def test_env!
42
+ set_env('VALUE', 'value')
43
+ assert_equal(Config.env!('VALUE'), 'value')
44
+ end
45
+
46
+ # Config.env! raises a RuntimeError if an unknown environment
47
+ # variable is requested.
48
+ def test_env_with_unknown_name!
49
+ error = assert_raises RuntimeError do
50
+ Config.env!('UNKNOWN')
51
+ end
52
+ assert_equal(error.message, 'missing UNKNOWN')
53
+ end
54
+
55
+ # Config.production? is true when RACK_ENV=production.
6
56
  def test_production_mode
7
57
  set_env 'RACK_ENV', nil
8
- refute Vault::Config.production?
58
+ refute Config.production?
9
59
  set_env 'RACK_ENV', 'production'
10
- assert Vault::Config.production?
60
+ assert Config.production?
11
61
  end
12
62
 
13
- # Config.test? is true when RACK_ENV=test
63
+ # Config.test? is true when RACK_ENV=test.
14
64
  def test_test_mode
15
65
  set_env 'RACK_ENV', nil
16
- refute Vault::Config.test?
66
+ refute Config.test?
17
67
  set_env 'RACK_ENV', 'test'
18
- assert Vault::Config.test?
68
+ assert Config.test?
19
69
  end
20
70
 
21
- # Returns DATABASE_URL with no params
71
+ # Returns DATABASE_URL with no params.
22
72
  def test_database_url
23
73
  set_env 'DATABASE_URL', "postgres:///foo"
24
- Vault::Config.database_url.must_equal 'postgres:///foo'
74
+ assert_equal(Config.database_url, 'postgres:///foo')
25
75
  end
26
76
 
27
77
  # Returns #{kind}_DATABASE_URL with one param
28
78
  def test_database_url_takes_and_capitalizes_params
29
79
  set_env 'FOO_DATABASE_URL', "postgres:///foo"
30
- Vault::Config.database_url('foo').must_equal 'postgres:///foo'
80
+ assert_equal(Config.database_url('foo'), 'postgres:///foo')
31
81
  end
32
82
 
83
+ # Config.database_url raises a RuntimeError if no DATABASE_URL
84
+ # environment variables is defined.
33
85
  def test_database_url_raises_when_not_found
34
86
  assert_raises RuntimeError do
35
- Vault::Config.database_url('foo')
87
+ Config.database_url('foo')
36
88
  end
37
89
  end
38
90
 
39
- # Vault::Config.app_name returns the value of the APP_NAME environment
91
+ # Config.app_name returns the value of the APP_NAME environment
40
92
  # variable.
41
93
  def test_app_name
42
94
  set_env 'APP_NAME', "my-app"
43
- Vault::Config.app_name.must_equal 'my-app'
95
+ Config.app_name.must_equal 'my-app'
44
96
  end
45
97
 
98
+ # Config.app_deploy returns the value of the APP_DEPLOY environment
99
+ # variable.
46
100
  def test_app_deploy
47
101
  set_env 'APP_DEPLOY', "test"
48
- Vault::Config.app_deploy.must_equal 'test'
102
+ Config.app_deploy.must_equal 'test'
49
103
  end
50
104
 
105
+ # Config.port raises a RuntimeError if no `PORT` environment variable
106
+ # is defined.
51
107
  def test_port_raises
52
108
  assert_raises RuntimeError do
53
- Vault::Config.port
109
+ Config.port
54
110
  end
55
111
  end
56
112
 
113
+ # Config.port converts the value from the environment to a Fixnum
57
114
  def test_port_convert_to_int
58
115
  set_env 'PORT', "3000"
59
- Vault::Config.port.must_equal 3000
116
+ assert_equal(3000, Config.port)
60
117
  end
61
118
 
62
- # Config.int(VAR) returns nil or VAR as integer
119
+ # Config.enable_ssl? is true unless VAULT_TOOLS_DISABLE_SSL is set.
120
+ def test_enable_ssl
121
+ set_env 'VAULT_TOOLS_DISABLE_SSL', nil
122
+ assert Config.enable_ssl?
123
+ set_env 'VAULT_TOOLS_DISABLE_SSL', 'true'
124
+ refute Config.enable_ssl?
125
+ set_env 'VAULT_TOOLS_DISABLE_SSL', 'false'
126
+ assert Config.enable_ssl?
127
+ end
128
+
129
+ # Config.int(VAR) returns nil or VAR as integer.
63
130
  def test_int
64
- assert_equal(nil, Vault::Config.int('FOO'))
131
+ assert_equal(nil, Config.int('FOO'))
65
132
  set_env 'FOO', "3000"
66
- assert_equal(3000, Vault::Config.int('FOO'))
133
+ assert_equal(3000, Config.int('FOO'))
67
134
  end
68
135
 
69
- # Config.enable_ssl? is true unless VAULT_TOOLS_DISABLE_SSL
70
- # is set
71
- def test_enable_ssl
72
- set_env 'VAULT_TOOLS_DISABLE_SSL', nil
73
- assert Vault::Config.enable_ssl?
74
- set_env 'VAULT_TOOLS_DISABLE_SSL', '1'
75
- refute Vault::Config.enable_ssl?
76
- set_env 'VAULT_TOOLS_DISABLE_SSL', 'foo'
77
- refute Vault::Config.enable_ssl?
136
+ # Config.array loads a comma-separated list of words into an array of
137
+ # strings.
138
+ def test_array
139
+ set_env 'ARRAY', ''
140
+ assert_equal([], Config.array('ARRAY'))
141
+ set_env 'ARRAY', 'apple'
142
+ assert_equal(['apple'], Config.array('ARRAY'))
143
+ set_env 'ARRAY', 'apple,orange,cherry'
144
+ assert_equal(['apple', 'orange', 'cherry'], Config.array('ARRAY'))
78
145
  end
79
146
 
80
- # Config.remote_env uses Heroku API to read config
81
- # vars from apps
82
- def test_remote_env
83
- api_mock = MiniTest::Mock.new
84
- api_response = OpenStruct.new(body: {'DATABASE_URL' => 'postgres:///foo'})
85
- Heroku::API.stub(:new, api_mock) do
86
- api_mock.expect(:get_config_vars, api_response, ['app'])
87
- assert_equal('postgres:///foo', Vault::Config.remote_env('app', 'DATABASE_URL'))
147
+ # Config.array raises a RuntimeError if the environment variable
148
+ # doesn't exist.
149
+ def test_array_with_unknown_environment_variable
150
+ assert_raises RuntimeError do
151
+ Config.array('UNKNOWN')
88
152
  end
89
153
  end
90
154
 
91
- def test_sidekiq_concurrency
92
- assert_equal(25, Vault::Config.sidekiq_concurrency)
93
- set_env 'SIDEKIQ_CONCURRENCY', '10'
94
- assert_equal(10, Vault::Config.sidekiq_concurrency)
95
- end
96
-
97
- # Config.bool?(var) is only true if the value of var is the string 'true'.
98
- # If the var is absent or any other value, it evaluates to false.
155
+ # Config.bool?(var) is only true if the value of var is the string
156
+ # 'true'. If the var is absent or any other value, it evaluates to false.
99
157
  def test_bool_returns_true
100
- assert_equal(false, Vault::Config.bool?('VAULT_BOOLEAN_VAR'))
158
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
101
159
  set_env 'VAULT_BOOLEAN_VAR', 'true'
102
- assert_equal(true, Vault::Config.bool?('VAULT_BOOLEAN_VAR'))
160
+ assert_equal(true, Config.bool?('VAULT_BOOLEAN_VAR'))
161
+ end
162
+
163
+ # Config.bool?(var) is false if the value of var is anything other
164
+ # than the string 'true'.
165
+ def test_bool_returns_false
103
166
  set_env 'VAULT_BOOLEAN_VAR', 'false'
104
- assert_equal(false, Vault::Config.bool?('VAULT_BOOLEAN_VAR'))
167
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
105
168
  set_env 'VAULT_BOOLEAN_VAR', 'foo'
106
- assert_equal(false, Vault::Config.bool?('VAULT_BOOLEAN_VAR'))
169
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
170
+ set_env 'VAULT_BOOLEAN_VAR', '1'
171
+ assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
172
+ end
173
+
174
+ # Config.sidekiq_concurrency returns the value of the
175
+ # `SIDEKIQ_CONCURRENCY` environment variable or 25 if one isn't defined.
176
+ def test_sidekiq_concurrency
177
+ assert_equal(25, Config.sidekiq_concurrency)
178
+ set_env 'SIDEKIQ_CONCURRENCY', '10'
179
+ assert_equal(10, Config.sidekiq_concurrency)
107
180
  end
108
181
  end
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+
3
+ class DefaultsTest < Vault::TestCase
4
+ include Vault::Test::EnvironmentHelpers
5
+
6
+ def setup
7
+ Config.defaults.clear
8
+ end
9
+
10
+ def test_default_when_no_value
11
+ assert_equal(Config[:max_connections], nil)
12
+ Config.default(:max_connections, 10)
13
+ assert_equal(Config[:max_connections], 10)
14
+ end
15
+
16
+ def test_default_with_int
17
+ assert_equal(Config[:max_connections], nil)
18
+ Config.default(:max_connections, '10')
19
+ assert_equal('10', Config[:max_connections])
20
+ assert_equal(10, Config.int(:max_connections))
21
+ set_env 'MAX_CONNECTIONS', '100'
22
+ assert_equal(100, Config.int(:max_connections))
23
+ end
24
+
25
+ def test_default_with_time
26
+ assert_equal(Config[:date], nil)
27
+ Config.default(:date, '2013-01-01')
28
+ assert_equal('2013-01-01', Config[:date])
29
+ assert_equal(Time.utc(2013), Config.time(:date))
30
+ set_env 'DATE', '2014-01-01'
31
+ assert_equal('2014-01-01', Config[:date])
32
+ assert_equal(Time.utc(2014), Config.time(:date))
33
+ end
34
+
35
+ def test_default_with_array
36
+ assert_equal(Config[:array], nil)
37
+ Config.default(:array, '10')
38
+ assert_equal('10', Config[:array])
39
+ assert_equal(['10'], Config.array(:array))
40
+ Config.default(:array, '1,0')
41
+ assert_equal('1,0', Config[:array])
42
+ assert_equal(['1','0'], Config.array(:array))
43
+ set_env 'ARRAY', '1,2'
44
+ assert_equal('1,2', Config[:array])
45
+ assert_equal(['1','2'], Config.array(:array))
46
+ end
47
+ end
@@ -1,12 +1,40 @@
1
1
  require 'vault-test-tools'
2
2
  require 'vault-tools'
3
- ENV['RACK_ENV'] = 'test'
4
- Vault.setup
5
3
 
6
- class Vault::TestCase
7
- include Vault::Test::EnvironmentHelpers
4
+ ENV['RACK_ENV'] = 'test'
8
5
 
6
+ module LoggedDataHelper
9
7
  def logged_data
10
8
  Hash[Scrolls.stream.string.split(/\s+/).map {|p| p.split('=') }]
11
9
  end
12
10
  end
11
+
12
+ # Overwrite the Honeybadger module
13
+ module Honeybadger
14
+ # A place to store the exceptions
15
+ def self.exceptions
16
+ @exceptions ||= []
17
+ end
18
+
19
+ # Store calls to notify in an array instead
20
+ # of calling out to the Honeybadger service
21
+ def self.notify(exception, opts = {})
22
+ self.exceptions << [exception, opts]
23
+ end
24
+ end
25
+
26
+ # Clear the stored exceptions in Honeybadger
27
+ # so each test starts w. a clean slate
28
+ module HoneybadgerHelper
29
+ def setup
30
+ super
31
+ Honeybadger.exceptions.clear
32
+ end
33
+ end
34
+
35
+ class Vault::TestCase
36
+ include Vault::Test::EnvironmentHelpers
37
+ include HoneybadgerHelper
38
+ end
39
+
40
+ Vault.setup
@@ -1,6 +1,9 @@
1
1
  require 'helper'
2
2
 
3
3
  class LogTest < Vault::TestCase
4
+ include Vault::Test::EnvironmentHelpers
5
+ include LoggedDataHelper
6
+
4
7
  def setup
5
8
  super
6
9
  set_env('APP_NAME', 'test-app')
@@ -64,6 +67,11 @@ class LogTest < Vault::TestCase
64
67
  assert_equal '123.4ms', logged_data['measure#test-app.some-web-path']
65
68
  end
66
69
 
70
+ def test_time_replaces_underscore_with_dash
71
+ Vault::Log.time('/some/web_path', 123.4)
72
+ assert_equal '123.4ms', logged_data['measure#test-app.some-web-path']
73
+ end
74
+
67
75
  # Vault::Log.time removes parameters.
68
76
  def test_time_removes_parameters
69
77
  Vault::Log.time('/some/:web/path', 123.4)
@@ -1,6 +1,8 @@
1
1
  require 'helper'
2
2
 
3
3
  class TextProcessorTest < Vault::TestCase
4
+ include Vault::Test::EnvironmentHelpers
5
+
4
6
  def setup
5
7
  set_env 'FERNET_SECRET', 'Mcdej7RFV/yHDrs1P8mrYP9zcw4JxSyReqYyELDrRPY='
6
8
  end
@@ -2,6 +2,8 @@ require 'helper'
2
2
 
3
3
  class WebTest < Vault::TestCase
4
4
  include Rack::Test::Methods
5
+ include Vault::Test::EnvironmentHelpers
6
+ include LoggedDataHelper
5
7
 
6
8
  # Anonymous Web Frontend
7
9
  def app
@@ -20,7 +22,7 @@ class WebTest < Vault::TestCase
20
22
  app.set :basic_password, 'password'
21
23
  app.get '/protected' do
22
24
  protected!
23
- 'OKIE'
25
+ 'You may pass'
24
26
  end
25
27
 
26
28
  get '/protected'
@@ -28,7 +30,7 @@ class WebTest < Vault::TestCase
28
30
  authorize('','password')
29
31
  get '/protected'
30
32
  assert_equal 200, last_response.status
31
- assert_equal 'OKIE', last_response.body
33
+ assert_equal 'You may pass', last_response.body
32
34
  end
33
35
 
34
36
  # Middleware is attached at load time, so we have to delete the Vault::Web
@@ -68,8 +70,9 @@ class WebTest < Vault::TestCase
68
70
  assert_equal(404, last_response.status)
69
71
  end
70
72
 
71
- # An internal server error causes a `web-50` log entry to be written. A
72
- # traceback is also written to the response body to ease debugging.
73
+ # An `http_500` and an `http_5xx` log metric is written when an internal
74
+ # server error occurs. A traceback is written to the response body to ease
75
+ # debugging.
73
76
  def test_error_logs_500
74
77
  get '/boom'
75
78
  assert_equal '1', logged_data['count#test-app.http.500']
@@ -79,6 +82,15 @@ class WebTest < Vault::TestCase
79
82
  assert_equal(500, last_response.status)
80
83
  end
81
84
 
85
+ # Test we register errors with Honeybadger when they happen
86
+ def test_error_with_honeybadger
87
+ assert_equal(0, Honeybadger.exceptions.size)
88
+ get '/boom'
89
+ assert_equal(1, Honeybadger.exceptions.size)
90
+ error, opts = Honeybadger.exceptions.first
91
+ assert_equal(RuntimeError, error.class)
92
+ end
93
+
82
94
  # SSL is enforced when we are in production mode
83
95
  def test_ssl_enforced_in_production_mode
84
96
  set_env 'RACK_ENV', 'production'
@@ -89,11 +101,22 @@ class WebTest < Vault::TestCase
89
101
  assert_match(/^https/, last_response.headers['Location'])
90
102
  end
91
103
 
92
- # SSL isn't enforced when the VAULT_TOOLS_DISABLE_SSL environment variable
93
- # has a true value.
94
- def test_ssl_can_be_disabled
104
+ # SSL is explicitly enforced when we're in production mode and the
105
+ # `VAULT_TOOLS_DISABLE_SSL` environment variable is set to `false`.
106
+ def test_ssl_explicitly_enforced_in_production_mode
107
+ set_env 'RACK_ENV', 'production'
108
+ set_env 'VAULT_TOOLS_DISABLE_SSL', 'false'
109
+ reload_web!
110
+ get '/health'
111
+ assert_equal(301, last_response.status)
112
+ assert_match(/^https/, last_response.headers['Location'])
113
+ end
114
+
115
+ # SSL isn't enforced when the `VAULT_TOOLS_DISABLE_SSL` environment variable
116
+ # is set to `true`.
117
+ def test_ssl_can_be_disabled_in_production_mode
95
118
  set_env 'RACK_ENV', 'production'
96
- set_env 'VAULT_TOOLS_DISABLE_SSL', '1'
119
+ set_env 'VAULT_TOOLS_DISABLE_SSL', 'true'
97
120
  reload_web!
98
121
  get '/health'
99
122
  assert_equal(200, last_response.status)
@@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_dependency 'rack-ssl-enforcer'
24
24
  gem.add_dependency 'heroku-api'
25
25
  gem.add_dependency 'fernet', '2.0.rc2'
26
+ gem.add_dependency 'honeybadger'
26
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vault-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.11
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-10-24 00:00:00.000000000Z
13
+ date: 2013-11-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: scrolls
17
- requirement: &2156169280 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2156169280
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: sinatra
28
- requirement: &2156168860 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ! '>='
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: '0'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *2156168860
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: uuidtools
39
- requirement: &2156168440 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ! '>='
@@ -44,10 +54,15 @@ dependencies:
44
54
  version: '0'
45
55
  type: :runtime
46
56
  prerelease: false
47
- version_requirements: *2156168440
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
48
63
  - !ruby/object:Gem::Dependency
49
64
  name: rack-ssl-enforcer
50
- requirement: &2156168020 !ruby/object:Gem::Requirement
65
+ requirement: !ruby/object:Gem::Requirement
51
66
  none: false
52
67
  requirements:
53
68
  - - ! '>='
@@ -55,10 +70,15 @@ dependencies:
55
70
  version: '0'
56
71
  type: :runtime
57
72
  prerelease: false
58
- version_requirements: *2156168020
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
59
79
  - !ruby/object:Gem::Dependency
60
80
  name: heroku-api
61
- requirement: &2156167600 !ruby/object:Gem::Requirement
81
+ requirement: !ruby/object:Gem::Requirement
62
82
  none: false
63
83
  requirements:
64
84
  - - ! '>='
@@ -66,18 +86,44 @@ dependencies:
66
86
  version: '0'
67
87
  type: :runtime
68
88
  prerelease: false
69
- version_requirements: *2156167600
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
70
95
  - !ruby/object:Gem::Dependency
71
96
  name: fernet
72
- requirement: &2156167100 !ruby/object:Gem::Requirement
97
+ requirement: !ruby/object:Gem::Requirement
73
98
  none: false
74
99
  requirements:
75
- - - =
100
+ - - '='
76
101
  - !ruby/object:Gem::Version
77
102
  version: 2.0.rc2
78
103
  type: :runtime
79
104
  prerelease: false
80
- version_requirements: *2156167100
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 2.0.rc2
111
+ - !ruby/object:Gem::Dependency
112
+ name: honeybadger
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
81
127
  description: Basic tools for Heroku Vault's Ruby projects
82
128
  email:
83
129
  - christopher.continanza@gmail.com
@@ -104,7 +150,6 @@ files:
104
150
  - lib/vault-tools/payments_db_tasks.rb
105
151
  - lib/vault-tools/pipeline.rb
106
152
  - lib/vault-tools/product.rb
107
- - lib/vault-tools/shushu_db_tasks.rb
108
153
  - lib/vault-tools/sinatra_helpers/html_serializer.rb
109
154
  - lib/vault-tools/text_processor.rb
110
155
  - lib/vault-tools/user.rb
@@ -112,6 +157,7 @@ files:
112
157
  - lib/vault-tools/web.rb
113
158
  - test/app_test.rb
114
159
  - test/config_test.rb
160
+ - test/defaults_test.rb
115
161
  - test/helper.rb
116
162
  - test/hid_test.rb
117
163
  - test/log_test.rb
@@ -134,15 +180,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
180
  - - ! '>='
135
181
  - !ruby/object:Gem::Version
136
182
  version: '0'
183
+ segments:
184
+ - 0
185
+ hash: 24233614407525305
137
186
  required_rubygems_version: !ruby/object:Gem::Requirement
138
187
  none: false
139
188
  requirements:
140
189
  - - ! '>='
141
190
  - !ruby/object:Gem::Version
142
191
  version: '0'
192
+ segments:
193
+ - 0
194
+ hash: 24233614407525305
143
195
  requirements: []
144
196
  rubyforge_project:
145
- rubygems_version: 1.8.9
197
+ rubygems_version: 1.8.23
146
198
  signing_key:
147
199
  specification_version: 3
148
200
  summary: Test classes, base web classes, and helpers - oh my!
@@ -1,31 +0,0 @@
1
- # Rake tasks for Shushu DB
2
- #
3
- # include in Rakefile via:
4
- #
5
- # require 'vault-tools/shushu_db_tasks'
6
-
7
- desc "Pull db/structure.sql from shushu HEAD"
8
- task :pull_shushu do
9
- steps = []
10
- steps << 'cd contrib/'
11
- if File.exists?('contrib/shushu')
12
- steps << 'rm -rf shushu'
13
- end
14
- steps << 'git clone -n git@github.com:heroku/shushud shushu --depth 1'
15
- steps << 'cd shushu'
16
- steps << 'git checkout HEAD db/*'
17
- # make sure we don't submodule it
18
- steps << 'rm -rf .git'
19
- sh steps.join(' && ')
20
- end
21
-
22
- desc "Drop and create shushu-test database"
23
- task :create_shushu_db => [:drop_shushu_db, :pull_shushu] do
24
- sh 'createdb shushu-test'
25
- sh 'cd contrib/shushu && ../../vendor/bin/sequel postgres:///shushu-test -m db/migrations'
26
- end
27
-
28
- desc "Drop the vault-usage-test, core-test and shushu-test databases"
29
- task :drop_shushu_db do
30
- sh 'dropdb shushu-test || true'
31
- end