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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +17 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +6 -2
  7. data/LICENSE.txt +22 -0
  8. data/README.md +74 -11
  9. data/Rakefile +27 -3
  10. data/docs/EVENT_FORMAT.md +195 -0
  11. data/experiments/object_dump.rb +1 -1
  12. data/experiments/rbkit_command_test.rb +3 -1
  13. data/experiments/using_rbkit.rb +1 -1
  14. data/ext/extconf.rb +95 -12
  15. data/ext/rbkit_allocation_info.c +91 -0
  16. data/ext/rbkit_allocation_info.h +17 -0
  17. data/ext/rbkit_event.c +71 -0
  18. data/ext/rbkit_event.h +63 -0
  19. data/ext/rbkit_event_packer.c +251 -0
  20. data/ext/rbkit_event_packer.h +23 -0
  21. data/ext/rbkit_message_aggregator.c +9 -16
  22. data/ext/rbkit_message_aggregator.h +0 -1
  23. data/ext/rbkit_object_graph.c +6 -49
  24. data/ext/rbkit_object_graph.h +12 -3
  25. data/ext/rbkit_test_helper.c +25 -0
  26. data/ext/rbkit_test_helper.h +1 -0
  27. data/ext/rbkit_tracer.c +106 -323
  28. data/ext/rbkit_tracer.h +2 -10
  29. data/lib/rbkit.rb +57 -35
  30. data/lib/rbkit/rbkit_gc.rb +79 -0
  31. data/lib/rbkit/version.rb +1 -1
  32. data/logo.png +0 -0
  33. data/rbkit.gemspec +1 -0
  34. data/setup.rb +37 -0
  35. data/spec/gc_stat_spec.rb +31 -0
  36. data/spec/hash_event_spec.rb +29 -0
  37. data/spec/obj_created_spec.rb +52 -0
  38. data/spec/obj_destroyed_spec.rb +44 -0
  39. data/spec/object_space_dump_spec.rb +77 -0
  40. data/spec/rbkit_helpful_messages_spec.rb +61 -0
  41. data/spec/spec_helper.rb +11 -6
  42. data/spec/start_server_spec.rb +29 -0
  43. data/spec/status_spec.rb +48 -0
  44. data/spec/support/foo_bar_sample_class.rb +24 -0
  45. data/spec/support/have_message_matcher.rb +26 -0
  46. metadata +40 -4
  47. 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
@@ -1,12 +1,17 @@
1
- require "pry"
2
- require "simplecov"
3
- SimpleCov.start do
4
- add_filter "/spec/"
5
- end
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
@@ -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.0.1
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: 2014-09-21 00:00:00.000000000 Z
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
- - schema/tracing_info.md
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: '0'
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:
@@ -1,8 +0,0 @@
1
- ## How we send tracing information ##
2
-
3
- 1. For now Tracing information is sent via simple strings like:
4
-
5
- obj_created <klass_name> <object_id_in_hex>
6
- obj_destroyed <klass_name> <object_id_in_hex>
7
- gc_start
8
- gc_end_s