appmap 0.77.4 → 0.80.0

Sign up to get free protection for your applications and to get access to all the features.
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