vault-tools 0.3.11 → 0.4.0

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.
@@ -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