rbkit 0.0.1 → 0.1.6
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/.gitignore +5 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -2
- data/LICENSE.txt +22 -0
- data/README.md +74 -11
- data/Rakefile +27 -3
- data/docs/EVENT_FORMAT.md +195 -0
- data/experiments/object_dump.rb +1 -1
- data/experiments/rbkit_command_test.rb +3 -1
- data/experiments/using_rbkit.rb +1 -1
- data/ext/extconf.rb +95 -12
- data/ext/rbkit_allocation_info.c +91 -0
- data/ext/rbkit_allocation_info.h +17 -0
- data/ext/rbkit_event.c +71 -0
- data/ext/rbkit_event.h +63 -0
- data/ext/rbkit_event_packer.c +251 -0
- data/ext/rbkit_event_packer.h +23 -0
- data/ext/rbkit_message_aggregator.c +9 -16
- data/ext/rbkit_message_aggregator.h +0 -1
- data/ext/rbkit_object_graph.c +6 -49
- data/ext/rbkit_object_graph.h +12 -3
- data/ext/rbkit_test_helper.c +25 -0
- data/ext/rbkit_test_helper.h +1 -0
- data/ext/rbkit_tracer.c +106 -323
- data/ext/rbkit_tracer.h +2 -10
- data/lib/rbkit.rb +57 -35
- data/lib/rbkit/rbkit_gc.rb +79 -0
- data/lib/rbkit/version.rb +1 -1
- data/logo.png +0 -0
- data/rbkit.gemspec +1 -0
- data/setup.rb +37 -0
- data/spec/gc_stat_spec.rb +31 -0
- data/spec/hash_event_spec.rb +29 -0
- data/spec/obj_created_spec.rb +52 -0
- data/spec/obj_destroyed_spec.rb +44 -0
- data/spec/object_space_dump_spec.rb +77 -0
- data/spec/rbkit_helpful_messages_spec.rb +61 -0
- data/spec/spec_helper.rb +11 -6
- data/spec/start_server_spec.rb +29 -0
- data/spec/status_spec.rb +48 -0
- data/spec/support/foo_bar_sample_class.rb +24 -0
- data/spec/support/have_message_matcher.rb +26 -0
- metadata +40 -4
- data/schema/tracing_info.md +0 -8
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/have_message_matcher'
|
3
|
+
require 'msgpack'
|
4
|
+
|
5
|
+
describe "Objectspace dump" do
|
6
|
+
let(:payload) { Rbkit::MESSAGE_FIELDS[:payload] }
|
7
|
+
let(:event_type) { Rbkit::MESSAGE_FIELDS[:event_type] }
|
8
|
+
let(:object_id) { Rbkit::MESSAGE_FIELDS[:object_id] }
|
9
|
+
let(:class_name) { Rbkit::MESSAGE_FIELDS[:class_name] }
|
10
|
+
let(:file) { Rbkit::MESSAGE_FIELDS[:file] }
|
11
|
+
let(:line) { Rbkit::MESSAGE_FIELDS[:line] }
|
12
|
+
let(:size) { Rbkit::MESSAGE_FIELDS[:size] }
|
13
|
+
let(:references) { Rbkit::MESSAGE_FIELDS[:references] }
|
14
|
+
let(:message) do
|
15
|
+
message = @message_list[payload]
|
16
|
+
.find{|x| x[event_type] == Rbkit::EVENT_TYPES[:object_space_dump]}
|
17
|
+
end
|
18
|
+
let(:foo_info) do
|
19
|
+
message[payload].select{|x| x[class_name] == 'Foo'}
|
20
|
+
end
|
21
|
+
let(:bar_info) do
|
22
|
+
message[payload].select{|x| x[class_name] == 'Bar'}
|
23
|
+
end
|
24
|
+
let(:short_lived_bar_info) do
|
25
|
+
message[payload].select{|x| x[class_name] == 'ShortLivedBar'}
|
26
|
+
end
|
27
|
+
let(:array_info) do
|
28
|
+
message[payload]
|
29
|
+
.select{|obj| obj[object_id] == foo_info.first[references].last }
|
30
|
+
end
|
31
|
+
before(:all) do
|
32
|
+
Rbkit.start_profiling(enable_gc_stats: false, enable_object_trace: true)
|
33
|
+
@foo_obj_line = __LINE__ + 1
|
34
|
+
@foo_obj = Foo.new
|
35
|
+
Rbkit.send_objectspace_dump
|
36
|
+
packed_message = Rbkit.get_queued_messages
|
37
|
+
Rbkit.stop_server
|
38
|
+
@message_list = MessagePack.unpack packed_message
|
39
|
+
end
|
40
|
+
it "should be part of message list" do
|
41
|
+
expect(@message_list)
|
42
|
+
.to have_message(Rbkit::EVENT_TYPES[:object_space_dump])
|
43
|
+
.with_count(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should record objects only once' do
|
47
|
+
expect(foo_info.size).to eql 1
|
48
|
+
expect(bar_info.size).to eql 1
|
49
|
+
expect(short_lived_bar_info.size).to eql 1
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should record correct file info' do
|
53
|
+
expect(foo_info.first[file]).to eql __FILE__
|
54
|
+
expect(bar_info.first[file]).to eql foo_bar_source_file
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should record correct line info' do
|
58
|
+
expect(foo_info.first[line]).to eql @foo_obj_line
|
59
|
+
expect(bar_info.first[line]).to eql bar_obj_line
|
60
|
+
expect(array_info.first[line]).to eql array_line
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should record correct references' do
|
64
|
+
expect(foo_info.first[object_id]).to eql @foo_obj.object_id
|
65
|
+
expect(bar_info.first[object_id]).to eql @foo_obj.bar.object_id
|
66
|
+
expect(array_info.first[object_id]).to eql @foo_obj.array.object_id
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should record correct references' do
|
70
|
+
expect(foo_info.first[references]).to include(bar_info.first[object_id])
|
71
|
+
expect(foo_info.first[references]).to include(array_info.first[object_id])
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should record correct size' do
|
75
|
+
expect(array_info.first[size]).to be > 0
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Messages printed by Rbkit on errors' do
|
4
|
+
let(:error_message) {
|
5
|
+
"Rbkit server couldn't bind to socket, check if it is already" \
|
6
|
+
" running. Profiling data will not be available."
|
7
|
+
}
|
8
|
+
|
9
|
+
context 'when Rbkit.start_server is run twice' do
|
10
|
+
it 'should print helpful message and return false the second time' do
|
11
|
+
expect($stderr).to receive(:puts).with(error_message).once
|
12
|
+
expect(Rbkit.start_server).to be_truthy
|
13
|
+
expect(Rbkit.start_server).to be_falsey
|
14
|
+
Rbkit.stop_server
|
15
|
+
end
|
16
|
+
end
|
17
|
+
context 'when Rbkit.start_profiling is run twice' do
|
18
|
+
it 'should print helpful message and return false the second time' do
|
19
|
+
expect($stderr).to receive(:puts).with(error_message).once
|
20
|
+
expect(Rbkit.start_profiling).to be_truthy
|
21
|
+
expect(Rbkit.start_profiling).to be_falsey
|
22
|
+
Rbkit.stop_server
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context 'when Rbkit.stop_server is run without starting the server' do
|
26
|
+
it 'should print helpful message and return false' do
|
27
|
+
expect($stderr).to receive(:puts).with("Cannot stop Rbkit server. Is it running?").once
|
28
|
+
expect(Rbkit.stop_server).to be_falsey
|
29
|
+
end
|
30
|
+
end
|
31
|
+
context 'when Rbkit.stop_server is run twice' do
|
32
|
+
it 'should print helpful message and return false the second time' do
|
33
|
+
expect($stderr).to receive(:puts).with("Cannot stop Rbkit server. Is it running?").once
|
34
|
+
expect(Rbkit.start_server).to be_truthy
|
35
|
+
expect(Rbkit.stop_server).to be_truthy
|
36
|
+
expect(Rbkit.stop_server).to be_falsey
|
37
|
+
end
|
38
|
+
end
|
39
|
+
context 'during normal operation' do
|
40
|
+
it 'should not print anything' do
|
41
|
+
expect($stderr).not_to receive(:puts)
|
42
|
+
expect(Rbkit.start_server).to be_truthy
|
43
|
+
expect(Rbkit.stop_server).to be_truthy
|
44
|
+
expect(Rbkit.start_server).to be_truthy
|
45
|
+
expect(Rbkit.stop_server).to be_truthy
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context 'after a series of failed attempts' do
|
49
|
+
it 'should be able to resume normal operation' do
|
50
|
+
allow($stderr).to receive(:puts)
|
51
|
+
expect(Rbkit.stop_server).to be_falsey
|
52
|
+
expect(Rbkit.start_server).to be_truthy
|
53
|
+
expect(Rbkit.start_server).to be_falsey
|
54
|
+
expect(Rbkit.stop_server).to be_truthy
|
55
|
+
expect(Rbkit.stop_server).to be_falsey
|
56
|
+
|
57
|
+
expect(Rbkit.start_server).to be_truthy
|
58
|
+
expect(Rbkit.stop_server).to be_truthy
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'rbkit'
|
8
|
+
require 'support/foo_bar_sample_class'
|
9
|
+
Rbkit.enable_test_mode
|
7
10
|
RSpec.configure do |config|
|
8
11
|
config.run_all_when_everything_filtered = true
|
9
12
|
config.filter_run :focus
|
13
|
+
|
14
|
+
config.before(:all) { GC.start }
|
10
15
|
# Run specs in random order to surface order dependencies. If you find an
|
11
16
|
# order dependency and want to debug it, you can fix the order by providing
|
12
17
|
# the seed, which is printed after each run.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Rbkit.start_server' do
|
4
|
+
before(:all) do
|
5
|
+
Rbkit.start_server
|
6
|
+
@foo_obj = Foo.new
|
7
|
+
@messages = Rbkit.get_queued_messages
|
8
|
+
Rbkit.stop_server
|
9
|
+
end
|
10
|
+
it 'should not send any messages' do
|
11
|
+
expect(@messages).to be_nil
|
12
|
+
end
|
13
|
+
context 'when pub port is out of range' do
|
14
|
+
it 'should raise ArgumentError' do
|
15
|
+
expect{ Rbkit.start_server(pub_port: 1023) }
|
16
|
+
.to raise_error(ArgumentError, 'Invalid port value')
|
17
|
+
expect{ Rbkit.start_server(pub_port: 65001) }
|
18
|
+
.to raise_error(ArgumentError, 'Invalid port value')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
context 'when request port is out of range' do
|
22
|
+
it 'should raise ArgumentError' do
|
23
|
+
expect{ Rbkit.start_server(request_port: 1023) }
|
24
|
+
.to raise_error(ArgumentError, 'Invalid port value')
|
25
|
+
expect{ Rbkit.start_server(request_port: 65001) }
|
26
|
+
.to raise_error(ArgumentError, 'Invalid port value')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/status_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'msgpack'
|
3
|
+
|
4
|
+
describe 'status' do
|
5
|
+
describe 'object_space_enabled field' do
|
6
|
+
context "when object trace is disabled" do
|
7
|
+
before do
|
8
|
+
Rbkit.start_profiling(enable_object_trace: false)
|
9
|
+
@status = Rbkit.status
|
10
|
+
Rbkit.stop_server
|
11
|
+
end
|
12
|
+
it 'should set object_trace_enabled to 0' do
|
13
|
+
expect(@status[:object_trace_enabled]).to eql 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context "when object trace is enabled" do
|
17
|
+
before do
|
18
|
+
Rbkit.start_profiling(enable_object_trace: true)
|
19
|
+
@status = Rbkit.status
|
20
|
+
Rbkit.stop_server
|
21
|
+
end
|
22
|
+
it 'should set object_trace_enabled to 0' do
|
23
|
+
expect(@status[:object_trace_enabled]).to eql 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'pwd field' do
|
29
|
+
let(:field) { Rbkit.status[:pwd] }
|
30
|
+
it 'should be equal to PWD' do
|
31
|
+
expect(field).to eql Dir.pwd
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "process_name field" do
|
36
|
+
let(:process_name) { Rbkit.status[:process_name] }
|
37
|
+
it "should have process name" do
|
38
|
+
expect(process_name).to eql Process.argv0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'pid field' do
|
43
|
+
let(:field) { Rbkit.status[:pid] }
|
44
|
+
it 'should be equal to Process PID' do
|
45
|
+
expect(field).to eql Process.pid
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Bar;end
|
2
|
+
class ShortLivedBar;end
|
3
|
+
class Foo
|
4
|
+
attr_reader :array, :bar
|
5
|
+
def initialize
|
6
|
+
@bar = Bar.new
|
7
|
+
ShortLivedBar.new #not reference outside this scope
|
8
|
+
@array = [1, 2, 3, 4, 5, 6, 7]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def foo_bar_source_file
|
13
|
+
__FILE__
|
14
|
+
end
|
15
|
+
|
16
|
+
def bar_obj_line
|
17
|
+
# Warning! Hardcoded line number below ¯\_(ツ)_/¯
|
18
|
+
6
|
19
|
+
end
|
20
|
+
|
21
|
+
def array_line
|
22
|
+
# Warning! Hardcoded line number below ¯\_(ツ)_/¯
|
23
|
+
8
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
RSpec::Matchers.define :have_message do |event_type|
|
2
|
+
match do |unpacked_message_list|
|
3
|
+
messages = unpacked_message_list[Rbkit::MESSAGE_FIELDS[:payload]].select do |event|
|
4
|
+
event[Rbkit::MESSAGE_FIELDS[:event_type]] == event_type
|
5
|
+
end
|
6
|
+
|
7
|
+
if @count
|
8
|
+
@size = messages.size
|
9
|
+
messages.size == @count
|
10
|
+
else
|
11
|
+
!messages.empty?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
failure_message do |unpacked_message_list|
|
16
|
+
if @count
|
17
|
+
"Expected message to contain #{@count} #{event_type} event(s) but contains #{@size}."
|
18
|
+
else
|
19
|
+
"Expected message to contain atleast one #{event_type} event."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
chain :with_count do |count|
|
24
|
+
@count = count
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hemant Kumar
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-01-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -63,9 +63,14 @@ extra_rdoc_files: []
|
|
63
63
|
files:
|
64
64
|
- ".bundle/config"
|
65
65
|
- ".gitignore"
|
66
|
+
- ".rspec"
|
67
|
+
- ".travis.yml"
|
68
|
+
- CHANGELOG.md
|
66
69
|
- Gemfile
|
70
|
+
- LICENSE.txt
|
67
71
|
- README.md
|
68
72
|
- Rakefile
|
73
|
+
- docs/EVENT_FORMAT.md
|
69
74
|
- docs/debugging.md
|
70
75
|
- docs/design.md
|
71
76
|
- experiments/benchmark.rb
|
@@ -80,18 +85,38 @@ files:
|
|
80
85
|
- experiments/zmq_client.rb
|
81
86
|
- experiments/zmq_server.rb
|
82
87
|
- ext/extconf.rb
|
88
|
+
- ext/rbkit_allocation_info.c
|
89
|
+
- ext/rbkit_allocation_info.h
|
90
|
+
- ext/rbkit_event.c
|
91
|
+
- ext/rbkit_event.h
|
92
|
+
- ext/rbkit_event_packer.c
|
93
|
+
- ext/rbkit_event_packer.h
|
83
94
|
- ext/rbkit_message_aggregator.c
|
84
95
|
- ext/rbkit_message_aggregator.h
|
85
96
|
- ext/rbkit_object_graph.c
|
86
97
|
- ext/rbkit_object_graph.h
|
98
|
+
- ext/rbkit_test_helper.c
|
99
|
+
- ext/rbkit_test_helper.h
|
87
100
|
- ext/rbkit_tracer.c
|
88
101
|
- ext/rbkit_tracer.h
|
89
102
|
- lib/rbkit.rb
|
103
|
+
- lib/rbkit/rbkit_gc.rb
|
90
104
|
- lib/rbkit/timer.rb
|
91
105
|
- lib/rbkit/version.rb
|
106
|
+
- logo.png
|
92
107
|
- rbkit.gemspec
|
93
|
-
-
|
108
|
+
- setup.rb
|
109
|
+
- spec/gc_stat_spec.rb
|
110
|
+
- spec/hash_event_spec.rb
|
111
|
+
- spec/obj_created_spec.rb
|
112
|
+
- spec/obj_destroyed_spec.rb
|
113
|
+
- spec/object_space_dump_spec.rb
|
114
|
+
- spec/rbkit_helpful_messages_spec.rb
|
94
115
|
- spec/spec_helper.rb
|
116
|
+
- spec/start_server_spec.rb
|
117
|
+
- spec/status_spec.rb
|
118
|
+
- spec/support/foo_bar_sample_class.rb
|
119
|
+
- spec/support/have_message_matcher.rb
|
95
120
|
homepage: http://rbkit.codemancers.com
|
96
121
|
licenses:
|
97
122
|
- MIT
|
@@ -104,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
129
|
requirements:
|
105
130
|
- - ">="
|
106
131
|
- !ruby/object:Gem::Version
|
107
|
-
version:
|
132
|
+
version: 2.1.0
|
108
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
134
|
requirements:
|
110
135
|
- - ">="
|
@@ -117,4 +142,15 @@ signing_key:
|
|
117
142
|
specification_version: 4
|
118
143
|
summary: Ruby profiler for rest of us
|
119
144
|
test_files:
|
145
|
+
- spec/gc_stat_spec.rb
|
146
|
+
- spec/hash_event_spec.rb
|
147
|
+
- spec/obj_created_spec.rb
|
148
|
+
- spec/obj_destroyed_spec.rb
|
149
|
+
- spec/object_space_dump_spec.rb
|
150
|
+
- spec/rbkit_helpful_messages_spec.rb
|
120
151
|
- spec/spec_helper.rb
|
152
|
+
- spec/start_server_spec.rb
|
153
|
+
- spec/status_spec.rb
|
154
|
+
- spec/support/foo_bar_sample_class.rb
|
155
|
+
- spec/support/have_message_matcher.rb
|
156
|
+
has_rdoc:
|