service_template 0.5.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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +23 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +64 -0
- data/Gemfile +4 -0
- data/LICENSE +24 -0
- data/README.md +217 -0
- data/Rakefile +9 -0
- data/bin/service_template +5 -0
- data/lib/service_template.rb +55 -0
- data/lib/service_template/active_record_extensions/notifications_subscriber.rb +17 -0
- data/lib/service_template/active_record_extensions/seeder.rb +14 -0
- data/lib/service_template/active_record_extensions/stats.rb +37 -0
- data/lib/service_template/authentication.rb +8 -0
- data/lib/service_template/cli.rb +111 -0
- data/lib/service_template/deploy.rb +98 -0
- data/lib/service_template/gem_dependency.rb +37 -0
- data/lib/service_template/generators.rb +3 -0
- data/lib/service_template/generators/api_generator.rb +30 -0
- data/lib/service_template/generators/readme_generator.rb +47 -0
- data/lib/service_template/generators/scaffold_generator.rb +29 -0
- data/lib/service_template/generators/templates/api/app/apis/%name_tableize%_api.rb.tt +40 -0
- data/lib/service_template/generators/templates/api/app/models/%name_underscore%.rb.tt +2 -0
- data/lib/service_template/generators/templates/api/app/representers/%name_underscore%_representer.rb.tt +4 -0
- data/lib/service_template/generators/templates/api/spec/apis/%name_tableize%_api_spec.rb.tt +16 -0
- data/lib/service_template/generators/templates/api/spec/models/%name_underscore%_spec.rb.tt +9 -0
- data/lib/service_template/generators/templates/readme/README.md.tt +55 -0
- data/lib/service_template/generators/templates/readme/spec/docs/readme_spec.rb +7 -0
- data/lib/service_template/generators/templates/scaffold/.env.development.tt +9 -0
- data/lib/service_template/generators/templates/scaffold/.env.test.tt +10 -0
- data/lib/service_template/generators/templates/scaffold/.gitignore.tt +13 -0
- data/lib/service_template/generators/templates/scaffold/.rubocop.yml +24 -0
- data/lib/service_template/generators/templates/scaffold/.ruby-version.tt +1 -0
- data/lib/service_template/generators/templates/scaffold/Gemfile.tt +29 -0
- data/lib/service_template/generators/templates/scaffold/README.md +3 -0
- data/lib/service_template/generators/templates/scaffold/Rakefile +21 -0
- data/lib/service_template/generators/templates/scaffold/app.rb +19 -0
- data/lib/service_template/generators/templates/scaffold/app/apis/application_api.rb +9 -0
- data/lib/service_template/generators/templates/scaffold/app/apis/hello_api.rb.tt +10 -0
- data/lib/service_template/generators/templates/scaffold/config.ru.tt +21 -0
- data/lib/service_template/generators/templates/scaffold/config/database.yml.tt +19 -0
- data/lib/service_template/generators/templates/scaffold/config/initializers/active_record.rb +5 -0
- data/lib/service_template/generators/templates/scaffold/db/schema.rb +11 -0
- data/lib/service_template/generators/templates/scaffold/lib/.keep +0 -0
- data/lib/service_template/generators/templates/scaffold/log/.keep +0 -0
- data/lib/service_template/generators/templates/scaffold/spec/apis/hello_api_spec.rb.tt +17 -0
- data/lib/service_template/generators/templates/scaffold/spec/factories/.gitkeep +0 -0
- data/lib/service_template/generators/templates/scaffold/spec/spec_helper.rb +47 -0
- data/lib/service_template/grape_extenders.rb +30 -0
- data/lib/service_template/grape_extensions/error_formatter.rb +18 -0
- data/lib/service_template/grape_extensions/grape_helpers.rb +27 -0
- data/lib/service_template/identity.rb +45 -0
- data/lib/service_template/json_error.rb +24 -0
- data/lib/service_template/logger/log_transaction.rb +17 -0
- data/lib/service_template/logger/logger.rb +42 -0
- data/lib/service_template/logger/parseable.rb +37 -0
- data/lib/service_template/middleware/app_monitor.rb +17 -0
- data/lib/service_template/middleware/authentication.rb +32 -0
- data/lib/service_template/middleware/database_stats.rb +15 -0
- data/lib/service_template/middleware/logger.rb +67 -0
- data/lib/service_template/middleware/request_stats.rb +42 -0
- data/lib/service_template/output_formatters/entity.rb +15 -0
- data/lib/service_template/output_formatters/include_nil.rb +16 -0
- data/lib/service_template/output_formatters/json_api_representer.rb +9 -0
- data/lib/service_template/param_sanitizer.rb +30 -0
- data/lib/service_template/rspec_extensions/response_helpers.rb +46 -0
- data/lib/service_template/setup.rb +36 -0
- data/lib/service_template/sortable_api.rb +17 -0
- data/lib/service_template/stats.rb +43 -0
- data/lib/service_template/stats_d_timer.rb +26 -0
- data/lib/service_template/version.rb +45 -0
- data/lib/tasks/deploy.rake +11 -0
- data/lib/tasks/routes.rake +11 -0
- data/service_template.gemspec +42 -0
- data/spec/active_record_extensions/filter_by_hash_spec.rb +23 -0
- data/spec/active_record_extensions/seeder_spec.rb +13 -0
- data/spec/authentication_spec.rb +17 -0
- data/spec/deprecations/application_api_spec.rb +19 -0
- data/spec/deprecations/entity_spec.rb +9 -0
- data/spec/deprecations/filter_by_hash_spec.rb +9 -0
- data/spec/deprecations/napa_setup_spec.rb +52 -0
- data/spec/generators/api_generator_spec.rb +63 -0
- data/spec/generators/migration_generator_spec.rb +105 -0
- data/spec/generators/readme_generator_spec.rb +35 -0
- data/spec/generators/scaffold_generator_spec.rb +90 -0
- data/spec/grape_extenders_spec.rb +50 -0
- data/spec/grape_extensions/error_formatter_spec.rb +29 -0
- data/spec/grape_extensions/include_nil_spec.rb +23 -0
- data/spec/identity_spec.rb +50 -0
- data/spec/json_error_spec.rb +33 -0
- data/spec/logger/log_transaction_spec.rb +34 -0
- data/spec/logger/logger_spec.rb +14 -0
- data/spec/logger/parseable_spec.rb +16 -0
- data/spec/middleware/authentication_spec.rb +54 -0
- data/spec/middleware/database_stats_spec.rb +64 -0
- data/spec/middleware/request_stats_spec.rb +21 -0
- data/spec/sortable_api_spec.rb +56 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/stats_d_timer_spec.rb +23 -0
- data/spec/stats_spec.rb +66 -0
- data/spec/version_spec.rb +40 -0
- data/tasks/spec.rake +9 -0
- data/tasks/version.rake +51 -0
- metadata +456 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/logger/logger'
|
|
3
|
+
|
|
4
|
+
describe ServiceTemplate::Logger do
|
|
5
|
+
context '#response' do
|
|
6
|
+
it 'returns response in the expected format' do
|
|
7
|
+
response = ServiceTemplate::Logger.response('foo', 'bar', 'baz')
|
|
8
|
+
|
|
9
|
+
expect(response[:response][:status]).to eq('foo')
|
|
10
|
+
expect(response[:response][:headers]).to eq('bar')
|
|
11
|
+
expect(response[:response][:response]).to eq('baz')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/logger/parseable'
|
|
3
|
+
|
|
4
|
+
describe Logging::Layouts::Parseable do
|
|
5
|
+
context '#format_obj' do
|
|
6
|
+
it 'formats text as an object' do
|
|
7
|
+
p = Logging::Layouts::Parseable.new
|
|
8
|
+
expect(p.format_obj('foobar')).to eq({ text: 'foobar' })
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'does not reformat objects' do
|
|
12
|
+
p = Logging::Layouts::Parseable.new
|
|
13
|
+
expect(p.format_obj({ foo: :bar })).to eq({ foo: :bar })
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/middleware/authentication'
|
|
3
|
+
require 'pry'
|
|
4
|
+
|
|
5
|
+
describe ServiceTemplate::Identity do
|
|
6
|
+
before do
|
|
7
|
+
ENV['HEADER_PASSWORDS'] = 'foo'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'Authenticated Request' do
|
|
11
|
+
it 'allows the request to continue if given a correct password header' do
|
|
12
|
+
app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
|
|
13
|
+
middleware = ServiceTemplate::Middleware::Authentication.new(app)
|
|
14
|
+
env = Rack::MockRequest.env_for('/test', {'HTTP_PASSWORD' => 'foo'})
|
|
15
|
+
status, headers, body = middleware.call(env)
|
|
16
|
+
|
|
17
|
+
expect(status).to eq(200)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'Failed Authentication Request' do
|
|
22
|
+
it 'returns an error message if the Password header is not supplied' do
|
|
23
|
+
app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
|
|
24
|
+
middleware = ServiceTemplate::Middleware::Authentication.new(app)
|
|
25
|
+
env = Rack::MockRequest.env_for('/test')
|
|
26
|
+
status, headers, body = middleware.call(env)
|
|
27
|
+
|
|
28
|
+
expect(status).to eq(401)
|
|
29
|
+
expect(body).to eq([ServiceTemplate::JsonError.new('bad_password', 'bad password').to_json])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'returns an error message if an incorrect Password header is supplied' do
|
|
33
|
+
app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
|
|
34
|
+
middleware = ServiceTemplate::Middleware::Authentication.new(app)
|
|
35
|
+
env = Rack::MockRequest.env_for('/test', {'HTTP_PASSWORD' => 'incorrect'})
|
|
36
|
+
status, headers, body = middleware.call(env)
|
|
37
|
+
|
|
38
|
+
expect(status).to eq(401)
|
|
39
|
+
expect(body).to eq([ServiceTemplate::JsonError.new('bad_password', 'bad password').to_json])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'returns an error message if HEADER_PASSWORDS is not configured' do
|
|
43
|
+
ENV['HEADER_PASSWORDS'] = nil
|
|
44
|
+
|
|
45
|
+
app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
|
|
46
|
+
middleware = ServiceTemplate::Middleware::Authentication.new(app)
|
|
47
|
+
env = Rack::MockRequest.env_for('/test', {'HTTP_PASSWORD' => 'incorrect'})
|
|
48
|
+
status, headers, body = middleware.call(env)
|
|
49
|
+
|
|
50
|
+
expect(status).to eq(401)
|
|
51
|
+
expect(body).to eq([ServiceTemplate::JsonError.new('not_configured', 'password not configured').to_json])
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'service_template/active_record_extensions/stats'
|
|
4
|
+
|
|
5
|
+
# Delete any prevous instantiations of the emitter and set valid statsd env vars
|
|
6
|
+
ServiceTemplate::Stats.emitter = nil
|
|
7
|
+
ENV['STATSD_HOST'] = 'localhost'
|
|
8
|
+
ENV['STATSD_PORT'] = '8125'
|
|
9
|
+
|
|
10
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
|
11
|
+
|
|
12
|
+
ActiveRecord::Schema.define(version: 1) do
|
|
13
|
+
create_table :foos do |t|
|
|
14
|
+
t.string :word
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Foo < ActiveRecord::Base
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe ServiceTemplate::Middleware::DatabaseStats do
|
|
22
|
+
before do
|
|
23
|
+
# Delete any prevous instantiations of the emitter and set valid statsd env vars
|
|
24
|
+
ServiceTemplate::Stats.emitter = nil
|
|
25
|
+
ENV['STATSD_HOST'] = 'localhost'
|
|
26
|
+
ENV['STATSD_PORT'] = '8125'
|
|
27
|
+
|
|
28
|
+
@foo = Foo.create(word: 'bar')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
after do
|
|
32
|
+
middleware = ServiceTemplate::Middleware::DatabaseStats.new(@app)
|
|
33
|
+
env = Rack::MockRequest.env_for('/test/path')
|
|
34
|
+
middleware.call(env)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should send a query_time for an insert' do
|
|
38
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.query_time', an_instance_of(Float))
|
|
39
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.table.foos.insert.query_time', an_instance_of(Float))
|
|
40
|
+
|
|
41
|
+
@app = lambda { |env| [200, { 'Content-Type' => 'application/json' }, Foo.create(word: 'baz')] }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should send a query_time for a select' do
|
|
45
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.query_time', an_instance_of(Float))
|
|
46
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.table.foos.select.query_time', an_instance_of(Float))
|
|
47
|
+
|
|
48
|
+
@app = lambda { |env| [200, { 'Content-Type' => 'application/json' }, Foo.first] }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should send a query_time for a delete' do
|
|
52
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.query_time', an_instance_of(Float))
|
|
53
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.table.foos.delete.query_time', an_instance_of(Float))
|
|
54
|
+
|
|
55
|
+
@app = lambda { |env| [200, { 'Content-Type' => 'application/json' }, @foo.delete ] }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'should send a query_time for an update' do
|
|
59
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.query_time', an_instance_of(Float))
|
|
60
|
+
allow(ServiceTemplate::Stats.emitter).to receive(:timing).with('sql.table.foos.update.query_time', an_instance_of(Float))
|
|
61
|
+
|
|
62
|
+
@app = lambda { |env| [200, { 'Content-Type' => 'application/json' }, @foo.update_attributes(word: 'baz') ] }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/middleware/request_stats'
|
|
3
|
+
|
|
4
|
+
describe ServiceTemplate::Middleware::RequestStats do
|
|
5
|
+
before do
|
|
6
|
+
# Delete any prevous instantiations of the emitter and set valid statsd env vars
|
|
7
|
+
ServiceTemplate::Stats.emitter = nil
|
|
8
|
+
ENV['STATSD_HOST'] = 'localhost'
|
|
9
|
+
ENV['STATSD_PORT'] = '8125'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should send the api_response_time' do
|
|
13
|
+
expect(ServiceTemplate::Stats.emitter).to receive(:timing).with('response_time', an_instance_of(Float))
|
|
14
|
+
expect(ServiceTemplate::Stats.emitter).to receive(:timing).with('path.get.test.path.response_time', an_instance_of(Float))
|
|
15
|
+
app = lambda { |env| [200, { 'Content-Type' => 'application/json'}, Array.new] }
|
|
16
|
+
middleware = ServiceTemplate::Middleware::RequestStats.new(app)
|
|
17
|
+
env = Rack::MockRequest.env_for('/test/path')
|
|
18
|
+
middleware.call(env)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'service_template/sortable_api'
|
|
4
|
+
|
|
5
|
+
describe "SortableApi" do
|
|
6
|
+
describe "#sort_from_params" do
|
|
7
|
+
before do
|
|
8
|
+
build_model :foos do
|
|
9
|
+
integer :param1
|
|
10
|
+
integer :param2
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
@object1 = Foo.create(param1: 2, param2: 1)
|
|
14
|
+
@object2 = Foo.create(param1: 2, param2: 3)
|
|
15
|
+
@object3 = Foo.create(param1: 3, param2: 5)
|
|
16
|
+
@object4 = Foo.create(param1: 1, param2: 3)
|
|
17
|
+
@object5 = Foo.create(param1: 1, param2: 1)
|
|
18
|
+
|
|
19
|
+
@api = Object.new
|
|
20
|
+
@api.extend(ServiceTemplate::SortableApi)
|
|
21
|
+
@foos = Foo.scoped
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "returns the sortable objects if sort_param is nil" do
|
|
25
|
+
expect(@api.sort_from_params(@foos, nil)).to eq(@foos)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "sorts by a given parameter" do
|
|
29
|
+
sorted = @api.sort_from_params(@foos, "param1")
|
|
30
|
+
expect(sorted.last).to eq(@object3)
|
|
31
|
+
expect(sorted.to_sql).to end_with("ORDER BY param1")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "sorts by a given parameter descending if preceded by -" do
|
|
35
|
+
sorted = @api.sort_from_params(@foos, "-param1")
|
|
36
|
+
expect(sorted.first).to eq(@object3)
|
|
37
|
+
expect(sorted.to_sql).to end_with("ORDER BY param1 DESC")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "sorts by multiple parameters in order" do
|
|
41
|
+
sorted = @api.sort_from_params(@foos, "param2,param1")
|
|
42
|
+
expect(sorted.to_a).to eq([@object5, @object1, @object4, @object2, @object3])
|
|
43
|
+
expect(sorted.to_sql).to end_with("ORDER BY param2, param1")
|
|
44
|
+
|
|
45
|
+
alt_sorted = @api.sort_from_params(@foos, "param1,param2")
|
|
46
|
+
expect(alt_sorted.to_a).to eq([@object5, @object4, @object1, @object2, @object3])
|
|
47
|
+
expect(alt_sorted.to_sql).to end_with("ORDER BY param1, param2")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "sorts by multiple parameters, even if descending" do
|
|
51
|
+
sorted = @api.sort_from_params(@foos, "-param2,param1")
|
|
52
|
+
expect(sorted.to_a).to eq([@object3, @object4, @object2, @object5, @object1])
|
|
53
|
+
expect(sorted.to_sql).to end_with("ORDER BY param2 DESC, param1")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
|
2
|
+
|
|
3
|
+
require 'service_template/setup'
|
|
4
|
+
require 'acts_as_fu'
|
|
5
|
+
|
|
6
|
+
require "codeclimate-test-reporter"
|
|
7
|
+
CodeClimate::TestReporter.start
|
|
8
|
+
|
|
9
|
+
ServiceTemplate.skip_initialization = true
|
|
10
|
+
|
|
11
|
+
require 'service_template'
|
|
12
|
+
require 'service_template/rspec_extensions/response_helpers'
|
|
13
|
+
|
|
14
|
+
# from https://gist.github.com/adamstegman/926858
|
|
15
|
+
RSpec.configure do |config|
|
|
16
|
+
config.include ServiceTemplate::RspecExtensions::ResponseHelpers
|
|
17
|
+
|
|
18
|
+
config.before(:all) { silence_output }
|
|
19
|
+
config.after(:all) { enable_output }
|
|
20
|
+
|
|
21
|
+
config.include ActsAsFu
|
|
22
|
+
|
|
23
|
+
config.before(:each) do
|
|
24
|
+
allow(ServiceTemplate).to receive(:initialize)
|
|
25
|
+
allow(ServiceTemplate::Logger).to receive_message_chain('logger.info').with(:service_template_deprecation_warning)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Redirects stderr and stdout to /dev/null.
|
|
30
|
+
def silence_output
|
|
31
|
+
@orig_stderr = $stderr
|
|
32
|
+
@orig_stdout = $stdout
|
|
33
|
+
|
|
34
|
+
# redirect stderr and stdout to /dev/null
|
|
35
|
+
$stderr = File.new('/dev/null', 'w')
|
|
36
|
+
$stdout = File.new('/dev/null', 'w')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Replace stdout and stderr so anything else is output correctly.
|
|
40
|
+
def enable_output
|
|
41
|
+
$stderr = @orig_stderr
|
|
42
|
+
$stdout = @orig_stdout
|
|
43
|
+
@orig_stderr = nil
|
|
44
|
+
@orig_stdout = nil
|
|
45
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/stats_d_timer'
|
|
3
|
+
|
|
4
|
+
class FooTimer
|
|
5
|
+
include ServiceTemplate::StatsDTimer
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe ServiceTemplate::StatsDTimer do
|
|
9
|
+
before do
|
|
10
|
+
# Delete any prevous instantiations of the emitter
|
|
11
|
+
ServiceTemplate::Stats.emitter = nil
|
|
12
|
+
# Stub out logging since there is no log to output to
|
|
13
|
+
allow(ServiceTemplate::Logger).to receive_message_chain(:logger, :warn)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'logs a timing event based on how long the block takes' do
|
|
17
|
+
expect(ServiceTemplate::Stats.emitter).to receive(:timing).with('foo', an_instance_of(Float))
|
|
18
|
+
FooTimer.report_time('foo') do
|
|
19
|
+
sleep(0.1)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
data/spec/stats_spec.rb
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/stats'
|
|
3
|
+
|
|
4
|
+
describe ServiceTemplate::Stats do
|
|
5
|
+
before do
|
|
6
|
+
# Delete any prevous instantiations of the emitter
|
|
7
|
+
ServiceTemplate::Stats.emitter = nil
|
|
8
|
+
# Stub out logging since there is no log to output to
|
|
9
|
+
allow(ServiceTemplate::Logger).to receive_message_chain(:logger, :warn)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should log an error if StatsD env variables are not configured' do
|
|
13
|
+
ENV['STATSD_HOST'] = nil
|
|
14
|
+
ENV['STATSD_PORT'] = nil
|
|
15
|
+
message = 'StatsD host and port not configured in environment variables, using default settings'
|
|
16
|
+
expect(ServiceTemplate::Logger.logger).to receive(:warn).with(message)
|
|
17
|
+
ServiceTemplate::Stats.emitter
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should default statsd to localhost port 8125 if env vars are not specified' do
|
|
21
|
+
ENV['STATSD_HOST'] = nil
|
|
22
|
+
ENV['STATSD_PORT'] = nil
|
|
23
|
+
expect(ServiceTemplate::Stats.emitter.host).to eq('127.0.0.1')
|
|
24
|
+
expect(ServiceTemplate::Stats.emitter.port).to eq(8125)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should return a StatsD client object' do
|
|
28
|
+
expect(ServiceTemplate::Stats.emitter.class.name).to eq('Statsd')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'the namespace of the StatsD client object should equal the service name' do
|
|
32
|
+
ENV['SERVICE_NAME'] = 'my-service'
|
|
33
|
+
expect(ServiceTemplate::Stats.emitter.namespace).to eq("my-service.test")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should use env variables to set statsd host and port' do
|
|
37
|
+
ENV['STATSD_HOST'] = 'localhost'
|
|
38
|
+
ENV['STATSD_PORT'] = '9000'
|
|
39
|
+
expect(ServiceTemplate::Stats.emitter.host).to eq('localhost')
|
|
40
|
+
expect(ServiceTemplate::Stats.emitter.port).to eq('9000')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '#namespace' do
|
|
44
|
+
it 'prepends the namespace with the STATSD_API_KEY if present' do
|
|
45
|
+
ENV['STATSD_API_KEY'] = 'foo'
|
|
46
|
+
expect(ServiceTemplate::Stats.namespace).to eq("#{ENV['STATSD_API_KEY']}.#{ServiceTemplate::Identity.name}.test")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'does not include the STATSD_API_KEY if empty' do
|
|
50
|
+
ENV['STATSD_API_KEY'] = nil
|
|
51
|
+
expect(ServiceTemplate::Stats.namespace).to eq("#{ServiceTemplate::Identity.name}.test")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe '#path_to_key' do
|
|
56
|
+
it 'returns the key string with ids removed and parts joined with dots' do
|
|
57
|
+
method = 'GET'
|
|
58
|
+
path = '/foo/123/bar'
|
|
59
|
+
expect(ServiceTemplate::Stats.path_to_key(method, path)).to eq('get.foo._.bar')
|
|
60
|
+
|
|
61
|
+
method = 'POST'
|
|
62
|
+
path = '/foo'
|
|
63
|
+
expect(ServiceTemplate::Stats.path_to_key(method, path)).to eq('post.foo')
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'service_template/version'
|
|
3
|
+
|
|
4
|
+
describe ServiceTemplate::Version do
|
|
5
|
+
context '#major_bump' do
|
|
6
|
+
it 'should set the major revision value, and the rest should be 0' do
|
|
7
|
+
stub_const('ServiceTemplate::VERSION', '1.2.3')
|
|
8
|
+
expect(ServiceTemplate::Version.next_major).to eq('2.0.0')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'should set the major revision value, and the rest should be 0' do
|
|
12
|
+
stub_const('ServiceTemplate::VERSION', '5.0.0')
|
|
13
|
+
expect(ServiceTemplate::Version.next_major).to eq('6.0.0')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context '#minor_bump' do
|
|
18
|
+
it 'should set the minor revision value, leaving the major value unchanged and the patch value to 0' do
|
|
19
|
+
stub_const('ServiceTemplate::VERSION', '1.2.3')
|
|
20
|
+
expect(ServiceTemplate::Version.next_minor).to eq('1.3.0')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should set the minor revision value, leaving the major value unchanged and the patch value to 0' do
|
|
24
|
+
stub_const('ServiceTemplate::VERSION', '0.5.0')
|
|
25
|
+
expect(ServiceTemplate::Version.next_minor).to eq('0.6.0')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'patch_bump' do
|
|
30
|
+
it 'should set the patch revision value, leaving the major and minor values unchanged' do
|
|
31
|
+
stub_const('ServiceTemplate::VERSION', '1.2.3')
|
|
32
|
+
expect(ServiceTemplate::Version.next_patch).to eq('1.2.4')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should set the patch revision value, leaving the major and minor values unchanged' do
|
|
36
|
+
stub_const('ServiceTemplate::VERSION', '5.5.5')
|
|
37
|
+
expect(ServiceTemplate::Version.next_patch).to eq('5.5.6')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/tasks/spec.rake
ADDED
data/tasks/version.rake
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
desc "bump the gem version"
|
|
2
|
+
namespace :version do
|
|
3
|
+
namespace :bump do
|
|
4
|
+
|
|
5
|
+
task :major do
|
|
6
|
+
@new_version = ServiceTemplate::Version.next_major
|
|
7
|
+
execute_version_bump
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
task :minor do
|
|
11
|
+
@new_version = ServiceTemplate::Version.next_minor
|
|
12
|
+
execute_version_bump
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
task :patch do
|
|
16
|
+
@new_version = ServiceTemplate::Version.next_patch
|
|
17
|
+
execute_version_bump
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def execute_version_bump
|
|
21
|
+
if !clean_staging_area?
|
|
22
|
+
system "git status"
|
|
23
|
+
raise "Unclean staging area! Be sure to commit or .gitignore everything first. See `git status` above."
|
|
24
|
+
else
|
|
25
|
+
require 'git'
|
|
26
|
+
git = Git.open('.')
|
|
27
|
+
|
|
28
|
+
write_update
|
|
29
|
+
git.add('lib/service_template/version.rb')
|
|
30
|
+
git.commit("Version bump: #{release_tag}")
|
|
31
|
+
git.add_tag(release_tag)
|
|
32
|
+
git.push(git.remote('upstream'), git.branch, release_tag) if git.remote('upstream')
|
|
33
|
+
puts "Version bumped: #{release_tag}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def write_update
|
|
38
|
+
filedata = File.read('lib/service_template/version.rb')
|
|
39
|
+
changed_filedata = filedata.gsub("VERSION = '#{ServiceTemplate::VERSION}'\n", "VERSION = '#{@new_version}'\n")
|
|
40
|
+
File.open('lib/service_template/version.rb',"w"){|file| file.puts changed_filedata}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def clean_staging_area?
|
|
44
|
+
`git ls-files --deleted --modified --others --exclude-standard` == ""
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def release_tag
|
|
48
|
+
"v#{@new_version}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|