appmap 0.77.4 → 0.80.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.travis.yml +4 -16
  4. data/CHANGELOG.md +30 -0
  5. data/{spec/fixtures/rails5_users_app/Dockerfile.pg → Dockerfile.pg} +0 -0
  6. data/README.md +14 -44
  7. data/README_CI.md +0 -7
  8. data/Rakefile +12 -150
  9. data/appmap.gemspec +3 -2
  10. data/docker-compose.yml +10 -0
  11. data/ext/appmap/appmap.c +21 -2
  12. data/lib/appmap/agent.rb +8 -0
  13. data/lib/appmap/builtin_hooks/ruby.yml +6 -3
  14. data/lib/appmap/event.rb +19 -12
  15. data/lib/appmap/gem_hooks/actionpack.yml +6 -0
  16. data/lib/appmap/handler/eval.rb +41 -0
  17. data/lib/appmap/handler/rails/render_handler.rb +29 -0
  18. data/lib/appmap/handler/rails/request_handler.rb +13 -11
  19. data/lib/appmap/handler/rails/sql_handler.rb +43 -1
  20. data/lib/appmap/handler.rb +3 -0
  21. data/lib/appmap/hook/method.rb +0 -1
  22. data/lib/appmap/version.rb +1 -1
  23. data/spec/config_spec.rb +1 -1
  24. data/spec/depends/api_spec.rb +13 -5
  25. data/spec/depends/spec_helper.rb +0 -9
  26. data/spec/fixtures/database.yml +11 -0
  27. data/spec/fixtures/rails5_users_app/config/database.yml +1 -0
  28. data/spec/fixtures/rails6_users_app/Gemfile +1 -25
  29. data/spec/fixtures/rails6_users_app/config/database.yml +1 -0
  30. data/spec/fixtures/rails7_users_app/Gemfile +1 -25
  31. data/spec/fixtures/rails7_users_app/config/database.yml +1 -0
  32. data/spec/handler/eval_spec.rb +66 -0
  33. data/spec/hook_spec.rb +6 -1
  34. data/spec/rails_recording_spec.rb +7 -21
  35. data/spec/rails_spec_helper.rb +76 -63
  36. data/spec/rails_test_spec.rb +7 -17
  37. data/spec/railtie_spec.rb +4 -18
  38. data/spec/record_sql_rails_pg_spec.rb +44 -75
  39. data/spec/remote_recording_spec.rb +18 -30
  40. data/spec/spec_helper.rb +1 -0
  41. data/spec/swagger/swagger_spec.rb +1 -16
  42. data/spec/util_spec.rb +1 -1
  43. data/test/expectations/openssl_test_key_sign2-3.1.json +2 -1
  44. metadata +24 -21
  45. data/Dockerfile.appmap +0 -5
  46. data/spec/fixtures/rack_users_app/Dockerfile +0 -32
  47. data/spec/fixtures/rack_users_app/docker-compose.yml +0 -9
  48. data/spec/fixtures/rails5_users_app/Dockerfile +0 -29
  49. data/spec/fixtures/rails5_users_app/config/database.yml +0 -18
  50. data/spec/fixtures/rails5_users_app/create_app +0 -33
  51. data/spec/fixtures/rails5_users_app/docker-compose.yml +0 -31
  52. data/spec/fixtures/rails6_users_app/.ruby-version +0 -1
  53. data/spec/fixtures/rails6_users_app/Dockerfile +0 -44
  54. data/spec/fixtures/rails6_users_app/Dockerfile.pg +0 -3
  55. data/spec/fixtures/rails6_users_app/config/database.yml +0 -18
  56. data/spec/fixtures/rails6_users_app/create_app +0 -33
  57. data/spec/fixtures/rails6_users_app/docker-compose.yml +0 -31
  58. data/spec/fixtures/rails7_users_app/.ruby-version +0 -1
  59. data/spec/fixtures/rails7_users_app/Dockerfile +0 -30
  60. data/spec/fixtures/rails7_users_app/Dockerfile.pg +0 -3
  61. data/spec/fixtures/rails7_users_app/config/database.yml +0 -86
  62. data/spec/fixtures/rails7_users_app/create_app +0 -31
  63. data/spec/fixtures/rails7_users_app/docker-compose.yml +0 -31
@@ -7,6 +7,7 @@ require 'appmap/util'
7
7
  module AppMap
8
8
  module Handler
9
9
  module Rails
10
+
10
11
  module RequestHandler
11
12
  class HTTPServerRequest < AppMap::Event::MethodEvent
12
13
  attr_accessor :normalized_path_info, :request_method, :path_info, :params, :headers
@@ -46,8 +47,7 @@ module AppMap
46
47
  value: self.class.display_string(val),
47
48
  object_id: val.__id__,
48
49
  }.tap do |message|
49
- properties = object_properties(val)
50
- message[:properties] = properties if properties
50
+ AppMap::Event::MethodEvent.add_schema message, val
51
51
  end
52
52
  end
53
53
  end
@@ -67,16 +67,16 @@ module AppMap
67
67
  end
68
68
  end
69
69
 
70
- class HTTPServerResponse < AppMap::Event::MethodReturnIgnoreValue
70
+ class HTTPServerResponse < AppMap::Event::MethodReturn
71
71
  attr_accessor :status, :headers
72
72
 
73
- def initialize(response, parent_id, elapsed)
74
- super AppMap::Event.next_id_counter, :return, Thread.current.object_id
75
-
76
- self.status = response.status
77
- self.parent_id = parent_id
78
- self.elapsed = elapsed
79
- self.headers = response.headers.dup
73
+ class << self
74
+ def build_from_invocation(parent_id, return_value, elapsed, response, event: HTTPServerResponse.new)
75
+ event ||= HTTPServerResponse.new
76
+ event.status = response.status
77
+ event.headers = response.headers.dup
78
+ AppMap::Event::MethodReturn.build_from_invocation parent_id, return_value, nil, elapsed: elapsed, event: event, parameter_schema: true
79
+ end
80
80
  end
81
81
 
82
82
  def to_h
@@ -108,7 +108,9 @@ module AppMap
108
108
  end
109
109
 
110
110
  def after_hook(receiver, call_event, elapsed, *)
111
- return_event = HTTPServerResponse.new receiver.response, call_event.id, elapsed
111
+ return_value = Thread.current[TEMPLATE_RENDER_VALUE]
112
+ Thread.current[TEMPLATE_RENDER_VALUE] = nil
113
+ return_event = HTTPServerResponse.build_from_invocation call_event.id, return_value, elapsed, receiver.response
112
114
  AppMap.tracing.record_event return_event
113
115
  end
114
116
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'appmap/event'
4
+ require 'appmap/hook/method'
4
5
 
5
6
  module AppMap
6
7
  module Handler
@@ -21,6 +22,7 @@ module AppMap
21
22
  sql: payload[:sql],
22
23
  database_type: payload[:database_type]
23
24
  }.tap do |sql_query|
25
+ sql_query[:query_plan] = payload[:query_plan] if payload[:query_plan]
24
26
  %i[server_version].each do |attribute|
25
27
  sql_query[attribute] = payload[attribute] if payload[attribute]
26
28
  end
@@ -43,6 +45,36 @@ module AppMap
43
45
  def examine(payload, sql:)
44
46
  return unless (examiner = build_examiner)
45
47
 
48
+ in_transaction = examiner.in_transaction?
49
+
50
+ if AppMap.explain_queries? && examiner.database_type == :postgres
51
+ if sql =~ /\A(SELECT|INSERT|UPDATE|DELETE|WITH)/i
52
+ savepoint_established = \
53
+ begin
54
+ tx_query = in_transaction ? 'SAVEPOINT appmap_sql_examiner' : 'BEGIN TRANSACTION'
55
+ examiner.execute_query tx_query
56
+ true
57
+ rescue
58
+ # Probably: Sequel::DatabaseError: PG::InFailedSqlTransaction
59
+ warn $!
60
+ false
61
+ end
62
+
63
+ if savepoint_established
64
+ plan = nil
65
+ begin
66
+ plan = examiner.execute_query(%(EXPLAIN #{sql}))
67
+ payload[:query_plan] = plan.map { |line| line[:'QUERY PLAN'] }.join("\n")
68
+ rescue
69
+ warn "(appmap) Error explaining query: #{$!}"
70
+ ensure
71
+ tx_query = in_transaction ? 'ROLLBACK TO SAVEPOINT appmap_sql_examiner' : 'ROLLBACK'
72
+ examiner.execute_query tx_query
73
+ end
74
+ end
75
+ end
76
+ end
77
+
46
78
  payload[:server_version] = examiner.server_version
47
79
  payload[:database_type] = examiner.database_type.to_s
48
80
  end
@@ -67,6 +99,10 @@ module AppMap
67
99
  Sequel::Model.db.database_type.to_sym
68
100
  end
69
101
 
102
+ def in_transaction?
103
+ Sequel::Model.db.in_transaction?
104
+ end
105
+
70
106
  def execute_query(sql)
71
107
  Sequel::Model.db[sql].all
72
108
  end
@@ -93,8 +129,12 @@ module AppMap
93
129
  type
94
130
  end
95
131
 
132
+ def in_transaction?
133
+ ActiveRecord::Base.connection.open_transactions > 0
134
+ end
135
+
96
136
  def execute_query(sql)
97
- ActiveRecord::Base.connection.execute(sql).inject([]) { |memo, r| memo << r; memo }
137
+ ActiveRecord::Base.connection.execute(sql).to_a
98
138
  end
99
139
  end
100
140
  end
@@ -102,6 +142,8 @@ module AppMap
102
142
  def call(_, started, finished, _, payload) # (name, started, finished, unique_id, payload)
103
143
  return if AppMap.tracing.empty?
104
144
 
145
+ return if Thread.current[AppMap::Hook::Method::HOOK_DISABLE_KEY] == true
146
+
105
147
  reentry_key = "#{self.class.name}#call"
106
148
  return if Thread.current[reentry_key] == true
107
149
 
@@ -5,6 +5,9 @@ require 'active_support/inflector/methods'
5
5
  module AppMap
6
6
  # Specific hook handler classes and general related utilities.
7
7
  module Handler
8
+ TEMPLATE_RENDER_FORMAT = 'appmap.handler.template.return_value_format'
9
+ TEMPLATE_RENDER_VALUE = 'appmap.handler.template.return_value'
10
+
8
11
  # Try to find handler module with a given name.
9
12
  #
10
13
  # If the module is not loaded, tries to require the appropriate file
@@ -24,7 +24,6 @@ module AppMap
24
24
  attr_reader :hook_package, :hook_class, :hook_method, :parameters, :arity
25
25
 
26
26
  HOOK_DISABLE_KEY = 'AppMap::Hook.disable'
27
- private_constant :HOOK_DISABLE_KEY
28
27
 
29
28
  def initialize(hook_package, hook_class, hook_method)
30
29
  @hook_package = hook_package
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.77.4'
6
+ VERSION = '0.80.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
data/spec/config_spec.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'rails_spec_helper'
4
4
  require 'appmap/config'
5
5
 
6
- describe AppMap::Config, docker: false do
6
+ describe AppMap::Config do
7
7
  it 'loads as expected' do
8
8
  config_data = {
9
9
  name: 'test',
@@ -33,7 +33,7 @@ module AppMap
33
33
  end
34
34
  end
35
35
  end
36
- end
36
+ end
37
37
 
38
38
  describe 'Depends API' do
39
39
  let(:api) { AppMap::Depends::API.new(ENV['DEBUG'] == 'true') }
@@ -112,12 +112,12 @@ describe 'Depends API' do
112
112
  around do |test|
113
113
  @minitest_test_command_method = AppMap.configuration.depends_config.minitest_test_command_method
114
114
  AppMap.configuration.depends_config.minitest_test_command_method = 'AppMap::Depends::APISpec.minitest_test_command'
115
-
115
+
116
116
  test.call
117
117
  ensure
118
118
  AppMap.configuration.depends_config.minitest_test_command_method = @minitest_test_command
119
119
  end
120
-
120
+
121
121
  it 'passes a smoke test' do
122
122
  run_tests
123
123
  end
@@ -175,10 +175,18 @@ describe 'Depends API' do
175
175
  # At this point, we would run tests to bring the AppMaps up to date
176
176
  # Then once the tests have finished, remove any AppMaps that weren't refreshed
177
177
  removed = api.remove_out_of_date_appmaps(since, appmap_dir: DEPENDS_TEST_DIR, base_dir: DEPENDS_BASE_DIR)
178
- expect(removed).to eq([ appmap_path.split('.')[0] ])
178
+ expect(removed).to eq([ appmap_path.split('.')[0] ])
179
179
  ensure
180
- File.write(appmap_path, appmap)
180
+ File.write(appmap_path, appmap)
181
181
  end
182
182
  end
183
183
  end
184
+
185
+ before do
186
+ Dir.glob("#{DEPENDS_TEST_DIR}/*.appmap.json").each { |fname| FileUtils.touch fname }
187
+ update_appmap_index
188
+
189
+ FileUtils.rm_rf 'spec/tmp'
190
+ FileUtils.mkdir_p 'spec/tmp'
191
+ end
184
192
  end
@@ -16,12 +16,3 @@ def update_appmap_index
16
16
  system cmd.join(' ') or raise "Failed to update AppMap index in #{DEPENDS_TEST_DIR}"
17
17
  end
18
18
 
19
- RSpec.configure do |rspec|
20
- rspec.before do
21
- Dir.glob("#{DEPENDS_TEST_DIR}/*.appmap.json").each { |fname| FileUtils.touch fname }
22
- update_appmap_index
23
-
24
- FileUtils.rm_rf 'spec/tmp'
25
- FileUtils.mkdir_p 'spec/tmp'
26
- end
27
- end
@@ -0,0 +1,11 @@
1
+ default: &default
2
+ url: <%= ENV['DATABASE_URL'] %>
3
+ adapter: postgresql
4
+ database: <%= ENV['TEST_DATABASE'] || 'appland-rails6-test' %>
5
+
6
+ development:
7
+ <<: *default
8
+ test:
9
+ <<: *default
10
+ production:
11
+ <<: *default
@@ -0,0 +1 @@
1
+ ../../database.yml
@@ -11,32 +11,8 @@ gem 'sequel', '>= 5.43.0', require: false
11
11
  gem 'sequel-rails', require: false
12
12
  gem 'sequel_secure_password', require: false
13
13
 
14
- appmap_path = \
15
- # Support debugging inside the container with volume-mounted source
16
- if File.directory?('/src/appmap-ruby')
17
- '/src/appmap-ruby'
18
- elsif File.exist?('../../../appmap.gemspec')
19
- '../../..'
20
- end
21
-
22
- if appmap_path
23
- # Set the branch parameter, so that 'bundle config local.appmap' will work
24
- appmap_branch = Dir.chdir appmap_path do
25
- `git rev-parse --abbrev-ref HEAD`.strip
26
- end
27
- end
28
-
29
- appmap_options = \
30
- if appmap_path && appmap_branch
31
- { git: appmap_path, branch: appmap_branch }
32
- elsif appmap_path
33
- { path: appmap_path }
34
- else
35
- {}
36
- end.merge(require: %w[appmap])
37
-
38
14
  group :development, :test do
39
- gem 'appmap', appmap_options
15
+ gem 'appmap', path: '../../..'
40
16
  gem 'cucumber-rails', require: false
41
17
  gem 'rspec-rails'
42
18
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
@@ -0,0 +1 @@
1
+ ../../database.yml
@@ -69,31 +69,7 @@ group :test do
69
69
  gem "webdrivers"
70
70
  end
71
71
 
72
- appmap_path = \
73
- # Support debugging inside the container with volume-mounted source
74
- if File.directory?('/src/appmap-ruby')
75
- '/src/appmap-ruby'
76
- elsif File.exist?('../../../appmap.gemspec')
77
- '../../..'
78
- end
79
-
80
- if appmap_path
81
- # Set the branch parameter, so that 'bundle config local.appmap' will work
82
- appmap_branch = Dir.chdir appmap_path do
83
- `git rev-parse --abbrev-ref HEAD`.strip
84
- end
85
- end
86
-
87
- appmap_options = \
88
- if appmap_path && appmap_branch
89
- { git: appmap_path, branch: appmap_branch }
90
- elsif appmap_path
91
- { path: appmap_path }
92
- else
93
- {}
94
- end.merge(require: %w[appmap])
95
-
96
72
  group :development, :test do
97
- gem 'appmap', appmap_options
73
+ gem 'appmap', path: '../../..'
98
74
  gem 'pry-byebug', '>=0', '< 99'
99
75
  end
@@ -0,0 +1 @@
1
+ ../../database.yml
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Security/Eval, Style/EvalWithLocation
4
+
5
+ require 'spec_helper'
6
+ require 'appmap/config'
7
+
8
+ describe 'AppMap::Handler::Eval' do
9
+ include_context 'collect events'
10
+ let!(:config) { AppMap::Config.new('hook_spec') }
11
+ before { AppMap.configuration = config }
12
+ after { AppMap.configuration = nil }
13
+
14
+ def record_block
15
+ AppMap::Hook.new(config).enable do
16
+ tracer = AppMap.tracing.trace
17
+ AppMap::Event.reset_id_counter
18
+ begin
19
+ yield
20
+ ensure
21
+ AppMap.tracing.delete(tracer)
22
+ end
23
+ tracer
24
+ end
25
+ end
26
+
27
+ it 'produces a simple result' do
28
+ tracer = record_block do
29
+ expect(eval('12')).to eq(12)
30
+ end
31
+ events = collect_events(tracer)
32
+ expect(events[0]).to match hash_including \
33
+ defined_class: 'Kernel',
34
+ method_id: 'eval',
35
+ parameters: [{ class: 'Array', kind: :rest, name: 'arg', size: 1, value: '[12]' }]
36
+ end
37
+
38
+ # a la Ruby 2.6.3 ruby-token.rb
39
+ # token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
40
+ it 'can define a new class' do
41
+ num = (Random.random_number * 10_000).to_i
42
+ class_name = "Cls_#{num}"
43
+ m = ClassMaker
44
+ cls = nil
45
+ record_block do
46
+ cls = m.make_class class_name
47
+ end
48
+ expect(cls).to be_instance_of(Class)
49
+ # If execution context wasn't substituted, the class would be defined as
50
+ # eg. AppMap::Handler::Eval::Cls_7566
51
+ expect { AppMap::Handler::Eval.const_get(class_name) }.to raise_error(NameError)
52
+ # This would be the right behavior
53
+ expect(m.const_get(class_name)).to be_instance_of(Class)
54
+ expect(m.const_get(class_name)).to eq(cls)
55
+ new_cls = Class.new do
56
+ include m
57
+ end
58
+ expect(new_cls.const_get(class_name)).to eq(cls)
59
+ end
60
+ end
61
+
62
+ module ClassMaker
63
+ def self.make_class(class_name)
64
+ eval "class #{class_name}; end; #{class_name}"
65
+ end
66
+ end
data/spec/hook_spec.rb CHANGED
@@ -16,7 +16,7 @@ module ShowYamlNulls
16
16
  end
17
17
  Psych::Visitors::YAMLTree.prepend(ShowYamlNulls)
18
18
 
19
- describe 'AppMap class Hooking', docker: false do
19
+ describe 'AppMap class Hooking' do
20
20
  include_context 'collect events'
21
21
 
22
22
  def invoke_test_file(file, setup: nil, packages: nil)
@@ -491,6 +491,7 @@ describe 'AppMap class Hooking', docker: false do
491
491
  :class: Array
492
492
  :value: "[4, 5]"
493
493
  :kind: :rest
494
+ :size: 2
494
495
  - :name: :kw1
495
496
  :class: String
496
497
  :value: one
@@ -503,6 +504,7 @@ describe 'AppMap class Hooking', docker: false do
503
504
  :class: Hash
504
505
  :value: "{:kw3=>:three}"
505
506
  :kind: :keyrest
507
+ :size: 1
506
508
  :receiver:
507
509
  :class: InstanceMethod
508
510
  :value: Instance Method fixture
@@ -1139,6 +1141,7 @@ describe 'AppMap class Hooking', docker: false do
1139
1141
  :class: Array
1140
1142
  :value: "[foo]"
1141
1143
  :kind: :rest
1144
+ :size: 1
1142
1145
  - :name: :kw1
1143
1146
  :class: String
1144
1147
  :value: kw1
@@ -1151,6 +1154,7 @@ describe 'AppMap class Hooking', docker: false do
1151
1154
  :class: Hash
1152
1155
  :value: "{}"
1153
1156
  :kind: :keyrest
1157
+ :size: 0
1154
1158
  :receiver:
1155
1159
  :class: ReportParameters
1156
1160
  :value: ReportParameters
@@ -1160,6 +1164,7 @@ describe 'AppMap class Hooking', docker: false do
1160
1164
  :return_value:
1161
1165
  :class: Array
1162
1166
  :value: "[[:rest, :args], [:keyreq, :kw1], [:key, :kw2], [:keyrest, :kws]]"
1167
+ :size: 4
1163
1168
  YAML
1164
1169
  parameters = [[:rest, :args], [:keyreq, :kw1], [:key, :kw2], [:keyrest, :kws]]
1165
1170
  test_hook_behavior 'spec/fixtures/hook/report_parameters.rb', events do
@@ -15,14 +15,6 @@ describe 'Rails' do
15
15
  include_context 'Rails app pg database', "spec/fixtures/rails#{rails_major_version}_users_app" unless use_existing_data?
16
16
  include_context 'rails integration test setup'
17
17
 
18
- def run_spec(spec_name)
19
- cmd = <<~CMD.gsub "\n", ' '
20
- docker-compose run --rm -e RAILS_ENV=test -e APPMAP=true
21
- -v #{File.absolute_path tmpdir}:/app/tmp app ./bin/rspec #{spec_name}
22
- CMD
23
- run_cmd cmd, chdir: fixture_dir
24
- end
25
-
26
18
  describe 'an API route' do
27
19
  describe 'creating an object' do
28
20
  let(:appmap_json_file) do
@@ -62,7 +54,8 @@ describe 'Rails' do
62
54
  'http_server_response' => hash_including(
63
55
  'status_code' => 201,
64
56
  'headers' => hash_including('Content-Type' => 'application/json; charset=utf-8'),
65
- )
57
+ ),
58
+ 'return_value' => hash_including('class' => 'Hash', 'object_id' => Integer, 'properties' => include({'name' => 'login', 'class' => 'String'})),
66
59
  )
67
60
  )
68
61
  end
@@ -80,6 +73,7 @@ describe 'Rails' do
80
73
  'name' => 'params',
81
74
  'class' => 'ActiveSupport::HashWithIndifferentAccess',
82
75
  'object_id' => Integer,
76
+ 'size' => 1,
83
77
  'value' => '{login=>alice}',
84
78
  'kind' => 'req'
85
79
  ),
@@ -123,7 +117,7 @@ describe 'Rails' do
123
117
  )
124
118
  )
125
119
  )
126
- )
120
+ )
127
121
  end
128
122
  end
129
123
  end
@@ -201,7 +195,7 @@ describe 'Rails' do
201
195
  'path_info' => '/users/alice',
202
196
  'normalized_path_info' => '/users/{id}',
203
197
  'headers' => {
204
- 'Host' => 'test.host',
198
+ 'Host' => 'test.host',
205
199
  'User-Agent' => 'Rails Testing'
206
200
  }
207
201
  }
@@ -236,7 +230,7 @@ describe 'Rails' do
236
230
  'defined_class' => 'inline_template',
237
231
  'method_id' => 'render'
238
232
  )
239
-
233
+
240
234
  expect(appmap['classMap']).to include hash_including(
241
235
  'name' => 'actionview',
242
236
  'children' => include(hash_including(
@@ -251,7 +245,7 @@ describe 'Rails' do
251
245
  ))
252
246
  ))
253
247
  )
254
- end
248
+ end
255
249
  end
256
250
  end
257
251
  end
@@ -261,14 +255,6 @@ describe 'Rails' do
261
255
  include_context 'Rails app pg database', "spec/fixtures/rails6_users_app" unless use_existing_data?
262
256
  include_context 'rails integration test setup'
263
257
 
264
- def run_spec(spec_name)
265
- cmd = <<~CMD.gsub "\n", ' '
266
- docker-compose run --rm -e RAILS_ENV=test -e APPMAP=true -e APPMAP_CONFIG_FILE=no/such/file
267
- -v #{File.absolute_path tmpdir}:/app/tmp app ./bin/rspec #{spec_name}
268
- CMD
269
- run_cmd cmd, chdir: fixture_dir
270
- end
271
-
272
258
  let(:appmap_json_file) do
273
259
  'Api_UsersController_POST_api_users_with_required_parameters_creates_a_user.appmap.json'
274
260
  end