Skip to content

Commit 6e04bc7

Browse files
committed
test: Request recording
1 parent 2e89eaf commit 6e04bc7

File tree

3 files changed

+85
-28
lines changed

3 files changed

+85
-28
lines changed

spec/rails_spec_helper.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# frozen_string_literal: true
22

33
require 'open3'
4+
require 'random-port'
5+
require 'socket'
46

57
require 'spec_helper'
68
require 'active_support'
@@ -115,6 +117,40 @@ def run_process(method, cmd, env, options = {})
115117
shared_context 'Rails app pg database' do |dir|
116118
before(:all) { @app = TestRailsApp.for_fixture dir }
117119
let(:app) { @app }
120+
let(:users_path) { '/users' }
121+
end
122+
123+
shared_context 'Rails app service running' do
124+
def start_server(rails_app_environment: { 'ORM_MODULE' => 'sequel', 'APPMAP' => 'true' })
125+
service_port = RandomPort::Pool::SINGLETON.acquire
126+
@app.prepare_db
127+
server = @app.spawn_cmd \
128+
"./bin/rails server -p #{service_port}", rails_app_environment
129+
130+
uri = URI("http://localhost:#{service_port}/health")
131+
132+
100.times do
133+
begin
134+
Net::HTTP.get(uri)
135+
break
136+
rescue Errno::ECONNREFUSED
137+
sleep 0.1
138+
end
139+
end
140+
141+
[ service_port, server ]
142+
end
143+
144+
def json_body(res)
145+
JSON.parse(res.body).deep_symbolize_keys
146+
end
147+
148+
def stop_server(server)
149+
if server
150+
Process.kill 'INT', server
151+
Process.wait server
152+
end
153+
end
118154
end
119155

120156
shared_context 'rails integration test setup' do

spec/remote_recording_spec.rb

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
require 'rails_spec_helper'
22

3-
require 'random-port'
4-
53
require 'net/http'
6-
require 'socket'
74

85
describe 'remote recording', :order => :defined do
96
def json_body(res)
@@ -13,34 +10,16 @@ def json_body(res)
1310
rails_versions.each do |rails_version|
1411
context "with rails #{rails_version}" do
1512
include_context 'rails app', rails_version
13+
include_context 'Rails app service running'
1614

17-
before(:context) do
18-
@service_port = RandomPort::Pool::SINGLETON.acquire
19-
@app.prepare_db
20-
@server = @app.spawn_cmd \
21-
"./bin/rails server -p #{@service_port}",
22-
'ORM_MODULE' => 'sequel',
23-
'APPMAP' => 'true'
24-
25-
uri = URI("http://localhost:#{@service_port}/health")
26-
27-
100.times do
28-
Net::HTTP.get(uri)
29-
break
30-
rescue Errno::ECONNREFUSED
31-
sleep 0.1
32-
end
15+
before(:all) do
16+
@service_port, @server = start_server
3317
end
34-
35-
after(:context) do
36-
if @server
37-
Process.kill 'INT', @server
38-
Process.wait @server
39-
end
18+
after(:all) do
19+
stop_server(@server)
4020
end
4121

4222
let(:service_address) { URI("http://localhost:#{@service_port}") }
43-
let(:users_path) { '/users' }
4423
let(:record_path) { '/_appmap/record' }
4524

4625
it 'returns the recording status' do
@@ -80,10 +59,11 @@ def json_body(res)
8059
end
8160

8261
it 'stops recording' do
83-
# Generate some events
84-
Net::HTTP.start(service_address.hostname, service_address.port) { |http|
62+
users_res = Net::HTTP.start(service_address.hostname, service_address.port) { |http|
8563
http.request(Net::HTTP::Get.new(users_path) )
8664
}
65+
# Request recording is not enabled by environment variable
66+
expect(users_res).to_not include('appmap-file-name')
8767

8868
res = Net::HTTP.start(service_address.hostname, service_address.port) { |http|
8969
http.request(Net::HTTP::Delete.new(record_path))

spec/request_recording_spec.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'rails_spec_helper'
2+
3+
require 'net/http'
4+
5+
describe 'request recording', :order => :defined do
6+
include_context 'Rails app pg database', 'spec/fixtures/rails6_users_app'
7+
include_context 'Rails app service running'
8+
9+
before(:all) do
10+
@service_port, @server = start_server(rails_app_environment: { 'ORM_MODULE' => 'sequel', 'APPMAP' => 'true', 'APPMAP_RECORD_REQUESTS' => 'true' })
11+
end
12+
after(:all) do
13+
stop_server(@server)
14+
end
15+
16+
let(:service_address) { URI("http://localhost:#{@service_port}") }
17+
18+
it 'creates an AppMap for a request' do
19+
# Generate some events
20+
Net::HTTP.start(service_address.hostname, service_address.port) { |http|
21+
http.request(Net::HTTP::Get.new(users_path) )
22+
}
23+
Net::HTTP.start(service_address.hostname, service_address.port) { |http|
24+
http.request(Net::HTTP::Get.new(users_path) )
25+
}
26+
res = Net::HTTP.start(service_address.hostname, service_address.port) { |http|
27+
http.request(Net::HTTP::Get.new(users_path) )
28+
}
29+
30+
expect(res).to be_a(Net::HTTPOK)
31+
expect(res).to include('appmap-file-name')
32+
appmap_file_name = res['AppMap-File-Name']
33+
expect(File.exists?(appmap_file_name)).to be(true)
34+
appmap = JSON.parse(File.read(appmap_file_name))
35+
# Every event should come from the same thread
36+
expect(appmap['events'].map {|evt| evt['thread_id']}.uniq.length).to eq(1)
37+
# AppMap should contain only one request and response
38+
expect(appmap['events'].select {|evt| evt['http_server_request']}.length).to eq(1)
39+
expect(appmap['events'].select {|evt| evt['http_server_response']}.length).to eq(1)
40+
end
41+
end

0 commit comments

Comments
 (0)