stackify-ruby-apm 0.9.0 → 1.0.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 +4 -4
- data/Gemfile +18 -0
- data/Gemfile.lock +181 -8
- data/LICENSE.md +66 -0
- data/README.md +5 -3
- data/Rakefile +4 -0
- data/docker-compose.yml +46 -0
- data/lib/stackify/agent.rb +22 -9
- data/lib/stackify/config.rb +65 -29
- data/lib/stackify/context/response.rb +13 -0
- data/lib/stackify/context_builder.rb +0 -2
- data/lib/stackify/error.rb +2 -2
- data/lib/stackify/error_builder.rb +1 -1
- data/lib/stackify/instrumenter.rb +4 -4
- data/lib/stackify/logger/logger_high_version.rb +65 -0
- data/lib/stackify/logger/logger_lower_version.rb +63 -0
- data/lib/stackify/middleware.rb +0 -4
- data/lib/stackify/normalizers.rb +0 -1
- data/lib/stackify/normalizers/active_record.rb +3 -1
- data/lib/stackify/railtie.rb +0 -1
- data/lib/stackify/serializers/errors.rb +8 -7
- data/lib/stackify/serializers/transactions.rb +3 -2
- data/lib/stackify/span.rb +1 -2
- data/lib/stackify/span/context.rb +5 -1
- data/lib/stackify/spies/action_dispatch.rb +8 -1
- data/lib/stackify/spies/httpclient.rb +14 -5
- data/lib/stackify/spies/httprb.rb +45 -0
- data/lib/stackify/spies/mongo.rb +13 -1
- data/lib/stackify/spies/net_http.rb +14 -3
- data/lib/stackify/spies/redis.rb +66 -0
- data/lib/stackify/spies/sinatra.rb +3 -1
- data/lib/stackify/spies/sinatra_activerecord/mysql_adapter.rb +177 -0
- data/lib/stackify/spies/sinatra_activerecord/postgresql_adapter.rb +96 -0
- data/lib/stackify/spies/sinatra_activerecord/sqlite_adapter.rb +48 -0
- data/lib/stackify/spies/tilt.rb +8 -1
- data/lib/stackify/stacktrace_builder.rb +4 -3
- data/lib/stackify/subscriber.rb +4 -4
- data/lib/stackify/trace_logger.rb +6 -23
- data/lib/stackify/transaction.rb +10 -1
- data/lib/stackify/util.rb +0 -13
- data/lib/stackify/version.rb +1 -1
- data/lib/stackify/worker.rb +5 -5
- data/lib/stackify_ruby_apm.rb +2 -6
- data/run-test.sh +75 -0
- data/stackify-ruby-apm.gemspec +0 -1
- metadata +12 -17
- data/lib/stackify/logger.rb +0 -10
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
3
|
+
#
|
4
|
+
module StackifyRubyAPM
|
5
|
+
# @api private
|
6
|
+
module Spies
|
7
|
+
# @api private
|
8
|
+
class PostgresqlAdapterSpy
|
9
|
+
TYPE = 'db.sinatra_active_record.sql'.freeze
|
10
|
+
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
12
|
+
def install
|
13
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements.class_eval do
|
14
|
+
alias exec_query_without_apm exec_query
|
15
|
+
alias exec_delete_without_apm exec_delete
|
16
|
+
alias exec_update_without_apm exec_update
|
17
|
+
|
18
|
+
def exec_update(sql, name = nil, binds = [])
|
19
|
+
result = nil
|
20
|
+
|
21
|
+
unless StackifyRubyAPM.current_transaction
|
22
|
+
exec_update_without_apm(sql, name, binds)
|
23
|
+
end
|
24
|
+
|
25
|
+
ctx = Span::Context.new(
|
26
|
+
CATEGORY: 'Database',
|
27
|
+
SUBCATEGORY: 'Execute',
|
28
|
+
COMPONENT_CATEGORY: 'DB Query',
|
29
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
30
|
+
SQL: sql,
|
31
|
+
PROVIDER: "mysql"
|
32
|
+
)
|
33
|
+
|
34
|
+
result = exec_update_without_apm(sql, name, binds)
|
35
|
+
|
36
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
37
|
+
return result
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def exec_delete(sql, name = nil, binds = [])
|
42
|
+
result = nil
|
43
|
+
|
44
|
+
unless StackifyRubyAPM.current_transaction
|
45
|
+
exec_delete_without_apm(sql, name, binds)
|
46
|
+
end
|
47
|
+
|
48
|
+
ctx = Span::Context.new(
|
49
|
+
CATEGORY: 'Database',
|
50
|
+
SUBCATEGORY: 'Execute',
|
51
|
+
COMPONENT_CATEGORY: 'DB Query',
|
52
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
53
|
+
SQL: sql,
|
54
|
+
PROVIDER: "postgresql"
|
55
|
+
)
|
56
|
+
|
57
|
+
result = exec_delete_without_apm(sql, name, binds)
|
58
|
+
|
59
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
60
|
+
return result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
66
|
+
result = nil
|
67
|
+
|
68
|
+
unless StackifyRubyAPM.current_transaction
|
69
|
+
exec_query_without_apm(sql, name, binds)
|
70
|
+
end
|
71
|
+
|
72
|
+
ctx = Span::Context.new(
|
73
|
+
CATEGORY: 'Database',
|
74
|
+
SUBCATEGORY: 'Execute',
|
75
|
+
COMPONENT_CATEGORY: 'DB Query',
|
76
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
77
|
+
SQL: sql,
|
78
|
+
PROVIDER: "postgresql"
|
79
|
+
)
|
80
|
+
|
81
|
+
result = exec_query_without_apm(sql, name, binds)
|
82
|
+
|
83
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
84
|
+
return result
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# rubocop:enable Metrics/MethodLength
|
91
|
+
end
|
92
|
+
|
93
|
+
register 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements', 'active_record/connection_adapters/postgresql/database_statements', PostgresqlAdapterSpy.new
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
3
|
+
#
|
4
|
+
module StackifyRubyAPM
|
5
|
+
# @api private
|
6
|
+
module Spies
|
7
|
+
# @api private
|
8
|
+
class SqliteAdapterSpy
|
9
|
+
TYPE = 'db.sinatra_active_record.sql'.freeze
|
10
|
+
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
12
|
+
def install
|
13
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.class_eval do
|
14
|
+
alias exec_query_without_apm exec_query
|
15
|
+
|
16
|
+
|
17
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
18
|
+
result = nil
|
19
|
+
|
20
|
+
unless StackifyRubyAPM.current_transaction
|
21
|
+
exec_query_without_apm(sql, name, binds)
|
22
|
+
end
|
23
|
+
|
24
|
+
ctx = Span::Context.new(
|
25
|
+
CATEGORY: 'Database',
|
26
|
+
SUBCATEGORY: 'Execute',
|
27
|
+
COMPONENT_CATEGORY: 'DB Query',
|
28
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
29
|
+
SQL: sql,
|
30
|
+
PROVIDER: "sqlite"
|
31
|
+
)
|
32
|
+
|
33
|
+
result = exec_query_without_apm(sql, name, binds)
|
34
|
+
|
35
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
36
|
+
return result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# rubocop:enable Metrics/MethodLength
|
43
|
+
end
|
44
|
+
|
45
|
+
register 'ActiveRecord::ConnectionAdapters::SQLite3Adapter', 'active_record/connection_adapters/sqlite3_adapter', SqliteAdapterSpy.new
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/lib/stackify/spies/tilt.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Monkey patch for the Tilt::Template class on template rendering and span creation.
|
4
|
+
#
|
2
5
|
|
3
6
|
module StackifyRubyAPM
|
4
7
|
# @api private
|
5
8
|
module Spies
|
6
9
|
# @api private
|
7
10
|
class TiltSpy
|
8
|
-
|
11
|
+
|
9
12
|
TYPE = 'template.tilt'.freeze
|
10
13
|
|
11
14
|
def install
|
@@ -15,6 +18,8 @@ module StackifyRubyAPM
|
|
15
18
|
def render(*args, &block)
|
16
19
|
name = options[:__stackify_apm_template_name] || 'Unknown template'
|
17
20
|
|
21
|
+
# Creates new span for Tilt templating
|
22
|
+
#
|
18
23
|
StackifyRubyAPM.span name, TYPE do
|
19
24
|
render_without_apm(*args, &block)
|
20
25
|
end
|
@@ -23,6 +28,8 @@ module StackifyRubyAPM
|
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
31
|
+
# Registers Tilt spy, go to: /stackify/spies.rb
|
32
|
+
#
|
26
33
|
register 'Tilt::Template', 'tilt/template', TiltSpy.new
|
27
34
|
end
|
28
35
|
end
|
@@ -21,7 +21,7 @@ module StackifyRubyAPM
|
|
21
21
|
|
22
22
|
attr_reader :config
|
23
23
|
|
24
|
-
def build(backtrace, type
|
24
|
+
def build(backtrace, type)
|
25
25
|
Stacktrace.new.tap do |s|
|
26
26
|
s.frames = backtrace.map do |line|
|
27
27
|
@cache[[line, type]]
|
@@ -36,6 +36,7 @@ module StackifyRubyAPM
|
|
36
36
|
line, type = keys
|
37
37
|
abs_path, lineno, function, _module_name = parse_line(line)
|
38
38
|
current_filename = strip_load_path(abs_path)
|
39
|
+
library_frame = library_frame?(config, abs_path)
|
39
40
|
|
40
41
|
frame = Stacktrace::Frame.new
|
41
42
|
#frame.abs_path = abs_path
|
@@ -45,7 +46,7 @@ module StackifyRubyAPM
|
|
45
46
|
#frame.library_frame = library_frame?(config, abs_path)
|
46
47
|
|
47
48
|
line_count =
|
48
|
-
context_lines_for(config, type, library_frame
|
49
|
+
context_lines_for(config, type, library_frame)
|
49
50
|
frame.build_context line_count
|
50
51
|
|
51
52
|
cache[[line, type]] = frame
|
@@ -93,7 +94,7 @@ module StackifyRubyAPM
|
|
93
94
|
prefix ? path[prefix.chomp(File::SEPARATOR).length + 1..-1] : path
|
94
95
|
end
|
95
96
|
|
96
|
-
def context_lines_for(config, type, library_frame
|
97
|
+
def context_lines_for(config, type, library_frame)
|
97
98
|
key = "source_lines_#{type}_#{library_frame ? 'library' : 'app'}_frames"
|
98
99
|
config.send(key.to_sym)
|
99
100
|
end
|
data/lib/stackify/subscriber.rb
CHANGED
@@ -13,7 +13,7 @@ module StackifyRubyAPM
|
|
13
13
|
include Log
|
14
14
|
|
15
15
|
def initialize(agent)
|
16
|
-
debug '
|
16
|
+
debug '[Subscriber] initialize()'
|
17
17
|
debug agent.inspect
|
18
18
|
@agent = agent
|
19
19
|
@normalizers = Normalizers.build(agent.config)
|
@@ -38,7 +38,7 @@ module StackifyRubyAPM
|
|
38
38
|
# [call] Called when the rails version is 3.x
|
39
39
|
def call(name, started, finished, id, payload)
|
40
40
|
return unless (transaction = @agent.current_transaction)
|
41
|
-
debug '
|
41
|
+
debug '[Subscriber] call():'
|
42
42
|
debug id
|
43
43
|
debug name
|
44
44
|
debug transaction
|
@@ -71,7 +71,7 @@ module StackifyRubyAPM
|
|
71
71
|
# [start] Called when the rails version is NOT 3.x
|
72
72
|
def start(name, id, payload)
|
73
73
|
return unless (transaction = @agent.current_transaction)
|
74
|
-
debug '
|
74
|
+
debug '[Subscriber] start():'
|
75
75
|
debug id
|
76
76
|
debug name
|
77
77
|
debug transaction
|
@@ -91,7 +91,7 @@ module StackifyRubyAPM
|
|
91
91
|
# [finish] Called when the rails version is NOT 3.x
|
92
92
|
def finish(_name, id, _payload)
|
93
93
|
# debug "AS::Notification#finish:#{name}:#{id}"
|
94
|
-
debug '
|
94
|
+
debug '[Subscriber] finish():'
|
95
95
|
return unless (transaction = @agent.current_transaction)
|
96
96
|
|
97
97
|
while (notification = transaction.notifications.pop)
|
@@ -22,7 +22,7 @@ module StackifyRubyAPM
|
|
22
22
|
attr_accessor :trace_file_counter, :process_id
|
23
23
|
|
24
24
|
def post(transactions = [])
|
25
|
-
|
25
|
+
|
26
26
|
# convert transactions to json
|
27
27
|
json_traces = []
|
28
28
|
transactions.each do |transaction|
|
@@ -36,31 +36,14 @@ module StackifyRubyAPM
|
|
36
36
|
pid = $PID || Process.pid
|
37
37
|
host_name = @config.hostname || `hostname`
|
38
38
|
date_now = Time.now
|
39
|
-
|
40
|
-
trace_path = @config.log_trace_path
|
41
|
-
trace_file_result = @config.check_lastlog_needs_new(trace_path)
|
42
|
-
current_trace_file = trace_file_result['latest_file']
|
43
|
-
|
44
|
-
if trace_file_result['new_flagger'] == true
|
45
|
-
@trace_file_counter = @trace_file_counter + 1
|
46
|
-
file_ctr = @trace_file_counter
|
47
|
-
current_trace_file = trace_path + host_name + "#" + pid.to_s + "-" + file_ctr.to_s + ".log"
|
48
|
-
else
|
49
|
-
if @process_id != pid
|
50
|
-
@trace_file_counter = 1
|
51
|
-
@process_id = pid
|
52
|
-
file_ctr = @trace_file_counter
|
53
|
-
current_trace_file = trace_path + host_name + "#" + pid.to_s + "-" + file_ctr.to_s + ".log"
|
54
|
-
end
|
55
|
-
end
|
39
|
+
current_datetime = date_now.strftime("%Y-%m-%d, %H:%M:%S.%6N")
|
56
40
|
|
57
|
-
|
58
|
-
open(current_trace_file, 'a') {|f|
|
41
|
+
if(ENV['STACKIFY_RUBY_ENV'] != 'rspec')
|
59
42
|
json_traces.each do |json_trace|
|
60
|
-
|
43
|
+
update_json = current_datetime + " > " + json_trace + "\n"
|
44
|
+
@config.tracer_logger.<<(update_json)
|
61
45
|
end
|
62
|
-
|
63
|
-
|
46
|
+
end
|
64
47
|
end
|
65
48
|
end
|
66
49
|
end
|
data/lib/stackify/transaction.rb
CHANGED
@@ -24,6 +24,7 @@ module StackifyRubyAPM
|
|
24
24
|
|
25
25
|
@notifications = [] # for AS::Notifications
|
26
26
|
@context = context || Context.new
|
27
|
+
@exceptions = []
|
27
28
|
|
28
29
|
yield self if block_given?
|
29
30
|
end
|
@@ -31,7 +32,11 @@ module StackifyRubyAPM
|
|
31
32
|
|
32
33
|
attr_accessor :name, :type, :http_status
|
33
34
|
attr_reader :id, :context, :duration, :dropped_spans,
|
34
|
-
:timestamp, :spans, :result, :notifications, :instrumenter
|
35
|
+
:timestamp, :spans, :result, :notifications, :instrumenter, :exceptions
|
36
|
+
|
37
|
+
def add_exception exception
|
38
|
+
@exceptions << exception
|
39
|
+
end
|
35
40
|
|
36
41
|
def release
|
37
42
|
@instrumenter.current_transaction = nil
|
@@ -60,6 +65,10 @@ module StackifyRubyAPM
|
|
60
65
|
|
61
66
|
self
|
62
67
|
end
|
68
|
+
# This method is being used in unit testing
|
69
|
+
def running_spans
|
70
|
+
spans.select(&:running?)
|
71
|
+
end
|
63
72
|
# rubocop:disable Metrics/MethodLength
|
64
73
|
def span name, type = nil, backtrace: nil, context: nil
|
65
74
|
span = build_and_start_span(name, type, context, backtrace)
|
data/lib/stackify/util.rb
CHANGED
@@ -2,22 +2,9 @@
|
|
2
2
|
module StackifyRubyAPM
|
3
3
|
# @api private
|
4
4
|
module Util
|
5
|
-
def self.nearest_minute(target = Time.now.utc)
|
6
|
-
target - target.to_i % 60
|
7
|
-
end
|
8
|
-
|
9
5
|
def self.micros(target = Time.now.utc)
|
10
6
|
target.to_i * 1_000_000 + target.usec
|
11
7
|
end
|
12
|
-
|
13
|
-
def self.inspect_transaction(transaction)
|
14
|
-
Inspector.new.transaction transaction
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.git_sha
|
18
|
-
sha = `git rev-parse --verify HEAD 2>&1`.chomp
|
19
|
-
$? && $?.success? ? sha : nil # rubocop:disable Style/SpecialGlobalVars
|
20
|
-
end
|
21
8
|
end
|
22
9
|
end
|
23
10
|
require 'stackify/util/inspector'
|
data/lib/stackify/version.rb
CHANGED
data/lib/stackify/worker.rb
CHANGED
@@ -83,13 +83,13 @@ module StackifyRubyAPM
|
|
83
83
|
def collect_and_send_transactions
|
84
84
|
return if pending_transactions.empty?
|
85
85
|
transactions = collect_batched_transactions
|
86
|
-
debug '
|
86
|
+
debug '[Worker] Successfully collect and send transaction to the to trace logger.'
|
87
87
|
begin
|
88
88
|
@trace_logger.post(transactions)
|
89
89
|
rescue ::Exception => e
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
error '[Worker] Collect_and_send_transactions error:'
|
91
|
+
error e.inspect
|
92
|
+
error e.backtrace.join("\n")
|
93
93
|
nil
|
94
94
|
end
|
95
95
|
end
|
@@ -98,7 +98,7 @@ module StackifyRubyAPM
|
|
98
98
|
return if pending_transactions.empty?
|
99
99
|
transactions = collect_batched_transactions
|
100
100
|
payload = @serializers.errors.build_all([msg.error])
|
101
|
-
debug '
|
101
|
+
debug '[Worker] post_error()'
|
102
102
|
# @trace_logger.post(payload, transactions[0])
|
103
103
|
end
|
104
104
|
|
data/lib/stackify_ruby_apm.rb
CHANGED
@@ -15,10 +15,10 @@
|
|
15
15
|
require 'stackify/log'
|
16
16
|
require 'stackify/version'
|
17
17
|
require 'stackify/util/dig'
|
18
|
-
|
19
18
|
require 'stackify/agent'
|
19
|
+
# Checks ruby version
|
20
|
+
require (RUBY_VERSION.to_f >= 2.4) ? 'stackify/logger/logger_high_version' : 'stackify/logger/logger_lower_version'
|
20
21
|
require 'stackify/config'
|
21
|
-
require 'stackify/logger'
|
22
22
|
require 'stackify/context'
|
23
23
|
require 'stackify/instrumenter'
|
24
24
|
require 'stackify/internal_error'
|
@@ -35,8 +35,6 @@ module StackifyRubyAPM
|
|
35
35
|
# @param config [Config] An instance of Config
|
36
36
|
# @return [Agent] The resulting [Agent]
|
37
37
|
def self.start(config = {})
|
38
|
-
# debug "Starts the StackifyRubyAPM Agent self.start()"
|
39
|
-
|
40
38
|
Agent.start config
|
41
39
|
end
|
42
40
|
|
@@ -73,7 +71,6 @@ module StackifyRubyAPM
|
|
73
71
|
# @yield [Transaction] Optional block encapsulating transaction
|
74
72
|
# @return [Transaction] Unless block given
|
75
73
|
def self.transaction(name = nil, type = nil, context: nil, &block)
|
76
|
-
# debug "@stackify_ruby [lib/stackify_ruby_apm.rb] loads self.transaction(name = nil, type = nil, context: nil, &block)"
|
77
74
|
return (block_given? ? yield : nil) unless agent
|
78
75
|
|
79
76
|
agent.transaction(name, type, context: context, &block)
|
@@ -105,7 +102,6 @@ module StackifyRubyAPM
|
|
105
102
|
# @param rack_env [Rack::Env] A Rack env
|
106
103
|
# @return [Context] The built context
|
107
104
|
def self.build_context(rack_env)
|
108
|
-
# debug "@stackify_ruby [lib/stackify_ruby_apm.rb] self.build_context(rack_env)"
|
109
105
|
agent && agent.build_context(rack_env)
|
110
106
|
end
|
111
107
|
|
data/run-test.sh
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
function startContainers() {
|
4
|
+
echo "Starting up containers..."
|
5
|
+
docker-compose up -d -V --remove-orphans --force-recreate
|
6
|
+
}
|
7
|
+
|
8
|
+
function waitForContainers() {
|
9
|
+
echo 'Waiting for container startup 10s...'
|
10
|
+
sleep 5
|
11
|
+
echo 'Waiting for container startup 5s...'
|
12
|
+
sleep 5
|
13
|
+
}
|
14
|
+
|
15
|
+
function stopContainers() {
|
16
|
+
echo "Stopping Containers..."
|
17
|
+
docker-compose down --remove-orphans
|
18
|
+
|
19
|
+
# delete volumes
|
20
|
+
echo "Delete Volumes..."
|
21
|
+
docker volume rm stackify-ruby-apm_postgresdata &> /dev/null
|
22
|
+
docker volume rm stackify-ruby-apm_mysqldata &> /dev/null
|
23
|
+
docker volume rm stackify-ruby-apm_mongodata &> /dev/null
|
24
|
+
docker volume rm stackify-ruby-apm_mongodata_config &> /dev/null
|
25
|
+
echo "Deleted Volumes"
|
26
|
+
}
|
27
|
+
|
28
|
+
function rspec_on_multiple_versions(){
|
29
|
+
# test against multiple ruby versions
|
30
|
+
set -e
|
31
|
+
|
32
|
+
RUBY_VERSIONS=('2.0.0-p648' '2.1.10' '2.2.10' '2.3.7' '2.4.0' '2.5.1' '2.6.0-preview3')
|
33
|
+
# BUNDLER ERROR
|
34
|
+
# '2.0.0-p648' 2.1.10
|
35
|
+
|
36
|
+
for ver in "${RUBY_VERSIONS[@]}"
|
37
|
+
do
|
38
|
+
if ! rbenv versions | grep -w $ver; then
|
39
|
+
# remove stale rbenv shim before rehashing
|
40
|
+
SHIM=/home/$USER/.rbenv/shims/.rbenv-shim
|
41
|
+
if [ -f $SHIM ]; then
|
42
|
+
rm $SHIM
|
43
|
+
fi
|
44
|
+
|
45
|
+
rbenv install --verbose $ver
|
46
|
+
rbenv rehash
|
47
|
+
rbenv local $ver
|
48
|
+
gem install bundler -v '~> 1.16'
|
49
|
+
fi
|
50
|
+
|
51
|
+
rbenv local $ver
|
52
|
+
rbenv exec bundle update
|
53
|
+
|
54
|
+
echo "====================================================="
|
55
|
+
echo "$ver: Start Test"
|
56
|
+
echo "====================================================="
|
57
|
+
|
58
|
+
if ! bundle exec rspec spec/ --format documentation --fail-fast; then
|
59
|
+
echo ">>>Unit Test Error on Version: $ver<<<"
|
60
|
+
stopContainers
|
61
|
+
exit 1
|
62
|
+
else
|
63
|
+
echo "====================================================="
|
64
|
+
echo "$ver: End Test"
|
65
|
+
echo "====================================================="
|
66
|
+
fi
|
67
|
+
done
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
startContainers
|
72
|
+
waitForContainers
|
73
|
+
|
74
|
+
rspec_on_multiple_versions
|
75
|
+
stopContainers
|