ruby-dtrace-consumer 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE +20 -0
- data/README.md +51 -0
- data/ext/Makefile +187 -0
- data/ext/dtrace_aggdata.c +132 -0
- data/ext/dtrace_aggdata.c~ +141 -0
- data/ext/dtrace_aggdata.o +0 -0
- data/ext/dtrace_api.bundle +0 -0
- data/ext/dtrace_api.c +102 -0
- data/ext/dtrace_api.c~ +113 -0
- data/ext/dtrace_api.h +138 -0
- data/ext/dtrace_api.h~ +155 -0
- data/ext/dtrace_api.o +0 -0
- data/ext/dtrace_bufdata.c +130 -0
- data/ext/dtrace_bufdata.c~ +139 -0
- data/ext/dtrace_bufdata.o +0 -0
- data/ext/dtrace_dropdata.c +121 -0
- data/ext/dtrace_dropdata.c~ +131 -0
- data/ext/dtrace_dropdata.o +0 -0
- data/ext/dtrace_errdata.c +100 -0
- data/ext/dtrace_errdata.c~ +110 -0
- data/ext/dtrace_errdata.o +0 -0
- data/ext/dtrace_hdl.c +677 -0
- data/ext/dtrace_hdl.c~ +689 -0
- data/ext/dtrace_hdl.o +0 -0
- data/ext/dtrace_probedata.c +273 -0
- data/ext/dtrace_probedata.c~ +283 -0
- data/ext/dtrace_probedata.o +0 -0
- data/ext/dtrace_probedesc.c +93 -0
- data/ext/dtrace_probedesc.c~ +78 -0
- data/ext/dtrace_probedesc.o +0 -0
- data/ext/dtrace_process.c +44 -0
- data/ext/dtrace_process.c~ +56 -0
- data/ext/dtrace_process.o +0 -0
- data/ext/dtrace_program.c +52 -0
- data/ext/dtrace_program.c~ +62 -0
- data/ext/dtrace_program.o +0 -0
- data/ext/dtrace_programinfo.c +70 -0
- data/ext/dtrace_programinfo.c~ +60 -0
- data/ext/dtrace_programinfo.o +0 -0
- data/ext/dtrace_recdesc.c +37 -0
- data/ext/dtrace_recdesc.c~ +46 -0
- data/ext/dtrace_recdesc.o +0 -0
- data/ext/dtrace_util.c +92 -0
- data/ext/dtrace_util.o +0 -0
- data/ext/extconf.rb +7 -0
- data/lib/dtrace.rb +95 -0
- data/lib/dtrace/aggregate.rb +40 -0
- data/lib/dtrace/aggregateset.rb +19 -0
- data/lib/dtrace/consumer.rb +174 -0
- data/lib/dtrace/data.rb +85 -0
- data/lib/dtrace/dof.rb +8 -0
- data/lib/dtrace/printfrecord.rb +10 -0
- data/lib/dtrace/probedata.rb +23 -0
- data/lib/dtrace/probedesc.rb +15 -0
- data/lib/dtrace/record.rb +11 -0
- data/lib/dtrace/stackrecord.rb +31 -0
- data/lib/dtrace/tracer.rb +35 -0
- data/lib/dtrace/version.rb +8 -0
- data/lib/dtrace/version.rb~ +8 -0
- data/lib/dtraceconsumer.rb +9 -0
- data/test/test_aggregates.rb +45 -0
- data/test/test_drops_errors.rb +166 -0
- data/test/test_dtrace.rb +155 -0
- data/test/test_gc.rb +11 -0
- data/test/test_helper.rb +20 -0
- data/test/test_helper.rb~ +16 -0
- data/test/test_legacy_consumer.rb +47 -0
- data/test/test_probedata.rb +30 -0
- data/test/test_processes.rb +66 -0
- data/test/test_profile.rb +198 -0
- data/test/test_repeat.rb +50 -0
- data/test/test_rubyprobe.rb +52 -0
- data/test/test_rubyprobe.rb~ +52 -0
- data/test/test_typefilter.rb +94 -0
- metadata +121 -0
data/test/test_dtrace.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Tests for the DTrace handle class
|
4
|
+
|
5
|
+
class TestDTrace < DTraceTest
|
6
|
+
|
7
|
+
def test_dtrace
|
8
|
+
assert_equal Object, DTrace.superclass
|
9
|
+
assert_equal DTrace, @dtp.class
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_list_probes
|
13
|
+
probe_count = 0
|
14
|
+
@dtp.each_probe do |probe|
|
15
|
+
assert probe.provider
|
16
|
+
assert probe.mod
|
17
|
+
assert probe.func
|
18
|
+
assert probe.name
|
19
|
+
probe_count += 1
|
20
|
+
end
|
21
|
+
assert probe_count
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_list_probes_match
|
25
|
+
probe_count = 0
|
26
|
+
@dtp.each_probe('syscall:::') do |probe|
|
27
|
+
assert probe.provider
|
28
|
+
assert probe.mod
|
29
|
+
assert probe.func
|
30
|
+
assert probe.name
|
31
|
+
probe_count += 1
|
32
|
+
end
|
33
|
+
assert probe_count
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_list_probes_match_usdt
|
37
|
+
probe_count = 0
|
38
|
+
@dtp.each_probe("pid#{$$}:::return") do |probe|
|
39
|
+
puts probe
|
40
|
+
assert probe.provider
|
41
|
+
assert probe.mod
|
42
|
+
assert probe.func
|
43
|
+
assert probe.name
|
44
|
+
probe_count += 1
|
45
|
+
end
|
46
|
+
assert probe_count
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_list_probes_match_prog
|
50
|
+
progtext = "syscall:::return
|
51
|
+
{
|
52
|
+
@calls[execname] = count();
|
53
|
+
@fcalls[probefunc] = count();
|
54
|
+
}
|
55
|
+
|
56
|
+
syscall:::entry
|
57
|
+
/pid == $1/
|
58
|
+
{
|
59
|
+
@calls[execname] = count();
|
60
|
+
@fcalls[probefunc] = count();
|
61
|
+
}"
|
62
|
+
prog = @dtp.compile(progtext, $$.to_s)
|
63
|
+
prog.execute
|
64
|
+
|
65
|
+
probe_count = 0
|
66
|
+
@dtp.each_probe_prog(prog) do |probe|
|
67
|
+
assert probe.provider
|
68
|
+
assert probe.mod
|
69
|
+
assert probe.func
|
70
|
+
assert probe.name
|
71
|
+
probe_count += 1
|
72
|
+
end
|
73
|
+
assert probe_count
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_list_probes_match_badpattern
|
77
|
+
probe_count = 0
|
78
|
+
assert_raises DTrace::Exception do
|
79
|
+
@dtp.each_probe('syscall') do |probe|
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_compile
|
86
|
+
progtext = "syscall:::entry
|
87
|
+
{
|
88
|
+
@calls[execname] = count();
|
89
|
+
@fcalls[probefunc] = count();
|
90
|
+
}"
|
91
|
+
|
92
|
+
prog = @dtp.compile progtext
|
93
|
+
assert prog
|
94
|
+
prog.execute
|
95
|
+
|
96
|
+
info = prog.info
|
97
|
+
assert info
|
98
|
+
assert info.aggregates_count
|
99
|
+
assert_equal 0, info.speculations_count
|
100
|
+
assert info.recgens_count
|
101
|
+
assert info.matches_count
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_compile_with_args
|
105
|
+
progtext = "syscall:::entry
|
106
|
+
/pid == $1/
|
107
|
+
{
|
108
|
+
@calls[execname] = count();
|
109
|
+
@fcalls[probefunc] = count();
|
110
|
+
}"
|
111
|
+
|
112
|
+
prog = @dtp.compile(progtext, $$.to_s)
|
113
|
+
assert prog
|
114
|
+
prog.execute
|
115
|
+
|
116
|
+
info = prog.info
|
117
|
+
assert info
|
118
|
+
assert_equal 2, info.aggregates_count
|
119
|
+
assert_equal 0, info.speculations_count
|
120
|
+
assert_equal 4, info.recgens_count
|
121
|
+
|
122
|
+
# matches_count is platform dependent
|
123
|
+
assert info.matches_count
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_run
|
127
|
+
progtext = "syscall:::entry
|
128
|
+
{
|
129
|
+
@calls[execname] = count();
|
130
|
+
@fcalls[probefunc] = count();
|
131
|
+
}"
|
132
|
+
|
133
|
+
prog = @dtp.compile progtext
|
134
|
+
assert prog
|
135
|
+
prog.execute
|
136
|
+
assert_equal 0, @dtp.status # none
|
137
|
+
|
138
|
+
@dtp.go
|
139
|
+
|
140
|
+
assert_equal 1, @dtp.status # ok
|
141
|
+
sleep 1
|
142
|
+
assert_equal 1, @dtp.status # ok
|
143
|
+
@dtp.stop
|
144
|
+
assert_equal 4, @dtp.status # stopped
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_bad_program
|
148
|
+
progtext = "blah blahb albhacasfas"
|
149
|
+
e = assert_raise DTrace::Exception do
|
150
|
+
prog = @dtp.compile progtext
|
151
|
+
end
|
152
|
+
assert_equal "probe description :::blah does not match any probes", e.message
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
data/test/test_gc.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'dtrace'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class DTraceTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@dtp = DTrace.new
|
8
|
+
@dtp.setopt("bufsize", "4m")
|
9
|
+
@dtp.setopt("aggsize", "4m")
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
@dtp.close unless @dtp.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_nothing
|
17
|
+
assert(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'dtrace'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class DTraceTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@dtp = DTrace.new
|
8
|
+
@dtp.setopt("bufsize", "4m")
|
9
|
+
@dtp.setopt("aggsize", "4m")
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
@dtp.close unless @dtp.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Tests using the DTrace profile provider.
|
4
|
+
|
5
|
+
class TestLegacyConsumer < DTraceTest
|
6
|
+
|
7
|
+
def test_aggregate_group
|
8
|
+
progtext =<<EOD
|
9
|
+
profile-1000
|
10
|
+
{
|
11
|
+
@a[execname] = count();
|
12
|
+
@b[execname] = count();
|
13
|
+
}
|
14
|
+
|
15
|
+
profile-1
|
16
|
+
{
|
17
|
+
printa(@a);
|
18
|
+
printa(@b);
|
19
|
+
}
|
20
|
+
EOD
|
21
|
+
|
22
|
+
prog = @dtp.compile progtext
|
23
|
+
prog.execute
|
24
|
+
@dtp.go
|
25
|
+
|
26
|
+
sleep 3
|
27
|
+
|
28
|
+
c = DTraceConsumer.new(@dtp)
|
29
|
+
assert c
|
30
|
+
|
31
|
+
data = []
|
32
|
+
c.consume_once do |d|
|
33
|
+
data << d
|
34
|
+
end
|
35
|
+
|
36
|
+
assert data.length > 0
|
37
|
+
data.each do |d|
|
38
|
+
assert d
|
39
|
+
assert_equal DTrace::Data, d.class
|
40
|
+
d.data.each do |agg|
|
41
|
+
assert_equal DTrace::AggregateSet, agg.class
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Tests for trace()d data.
|
4
|
+
|
5
|
+
class TestProbedata < DTraceTest
|
6
|
+
|
7
|
+
def test_longlongs
|
8
|
+
code = <<D
|
9
|
+
profile-100
|
10
|
+
{
|
11
|
+
trace(walltimestamp);
|
12
|
+
}
|
13
|
+
D
|
14
|
+
@dtp.compile(code).execute
|
15
|
+
@dtp.go
|
16
|
+
|
17
|
+
c = DTrace::Consumer.new(@dtp)
|
18
|
+
assert c
|
19
|
+
|
20
|
+
i = 0
|
21
|
+
c.consume do |d|
|
22
|
+
wallts = d.data[0].value
|
23
|
+
assert wallts > 2**32
|
24
|
+
i = i + 1
|
25
|
+
if i > 10
|
26
|
+
c.finish
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Tests for creating and grabbing processes.
|
4
|
+
|
5
|
+
class TestDTraceProcesses < DTraceTest
|
6
|
+
|
7
|
+
def test_createprocess
|
8
|
+
progtext = <<EOD
|
9
|
+
pid$target:*::entry,
|
10
|
+
pid$target:*::return
|
11
|
+
{
|
12
|
+
trace(pid);
|
13
|
+
}
|
14
|
+
EOD
|
15
|
+
|
16
|
+
p = @dtp.createprocess([ '/usr/bin/true' ])
|
17
|
+
prog = @dtp.compile(progtext)
|
18
|
+
prog.execute
|
19
|
+
@dtp.go
|
20
|
+
p.continue
|
21
|
+
|
22
|
+
i = 0
|
23
|
+
c = DTrace::Consumer.new(@dtp)
|
24
|
+
c.consume do |d|
|
25
|
+
assert d
|
26
|
+
assert_equal "pid#{d.data[0].value}", d.probe.provider
|
27
|
+
i = i + 1
|
28
|
+
|
29
|
+
if i > 10
|
30
|
+
c.finish
|
31
|
+
end
|
32
|
+
end
|
33
|
+
assert i > 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_grabprocess
|
37
|
+
pid = Kernel.fork { exec '/bin/sleep', '2' }
|
38
|
+
|
39
|
+
progtext = <<EOD
|
40
|
+
pid$target:::entry,
|
41
|
+
pid$target:::return
|
42
|
+
{
|
43
|
+
trace(execname);
|
44
|
+
}
|
45
|
+
EOD
|
46
|
+
|
47
|
+
p = @dtp.grabprocess(pid)
|
48
|
+
prog = @dtp.compile(progtext)
|
49
|
+
prog.execute
|
50
|
+
|
51
|
+
@dtp.go
|
52
|
+
p.continue
|
53
|
+
|
54
|
+
records = 0
|
55
|
+
c = DTrace::Consumer.new(@dtp)
|
56
|
+
c.consume do |d|
|
57
|
+
assert d
|
58
|
+
assert_equal "pid#{pid}", d.probe.provider
|
59
|
+
records = records + 1
|
60
|
+
c.finish
|
61
|
+
end
|
62
|
+
assert records > 0
|
63
|
+
|
64
|
+
Process.waitpid(pid, 0)
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Tests using the DTrace profile provider.
|
4
|
+
|
5
|
+
class TestProfile < DTraceTest
|
6
|
+
|
7
|
+
def test_dprogram_run
|
8
|
+
progtext = 'profile:::profile-1 { trace("foo"); }'
|
9
|
+
|
10
|
+
prog = @dtp.compile progtext
|
11
|
+
prog.execute
|
12
|
+
@dtp.go
|
13
|
+
sleep 2
|
14
|
+
|
15
|
+
c = DTrace::Consumer.new(@dtp)
|
16
|
+
assert c
|
17
|
+
|
18
|
+
i = 0
|
19
|
+
c.consume do |d|
|
20
|
+
assert d
|
21
|
+
assert_equal "profile:::profile-1", d.probe.to_s
|
22
|
+
assert_not_nil d.cpu
|
23
|
+
|
24
|
+
d.data.each do |r|
|
25
|
+
assert_equal r.value, "foo"
|
26
|
+
end
|
27
|
+
|
28
|
+
i = i + 1
|
29
|
+
if i > 10
|
30
|
+
c.finish
|
31
|
+
end
|
32
|
+
end
|
33
|
+
assert i > 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_dprogram_aggregate
|
37
|
+
progtext = <<EOD
|
38
|
+
profile-1000
|
39
|
+
{
|
40
|
+
@a[execname] = count();
|
41
|
+
}
|
42
|
+
|
43
|
+
profile-10
|
44
|
+
{
|
45
|
+
printa(@a)
|
46
|
+
}
|
47
|
+
EOD
|
48
|
+
|
49
|
+
prog = @dtp.compile progtext
|
50
|
+
prog.execute
|
51
|
+
@dtp.go
|
52
|
+
sleep 2
|
53
|
+
|
54
|
+
c = DTrace::Consumer.new(@dtp)
|
55
|
+
|
56
|
+
i = 0
|
57
|
+
c.consume do |d|
|
58
|
+
assert d
|
59
|
+
assert_not_nil d.cpu
|
60
|
+
assert_equal "profile:::profile-10", d.probe.to_s
|
61
|
+
|
62
|
+
d.data.each do |r|
|
63
|
+
assert_equal DTrace::AggregateSet, r.class
|
64
|
+
r.data.each do |a|
|
65
|
+
assert_not_nil a.value
|
66
|
+
assert_not_nil a.tuple
|
67
|
+
assert_equal 1, a.tuple.length
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
i = i + 1
|
72
|
+
if i >= 10
|
73
|
+
c.finish
|
74
|
+
end
|
75
|
+
end
|
76
|
+
assert i > 0
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_dprogram_printf
|
80
|
+
progtext = <<EOD
|
81
|
+
profile-1
|
82
|
+
{
|
83
|
+
printf("execname: %s %s", execname, "foo")
|
84
|
+
}
|
85
|
+
EOD
|
86
|
+
|
87
|
+
prog = @dtp.compile progtext
|
88
|
+
prog.execute
|
89
|
+
@dtp.go
|
90
|
+
sleep 2
|
91
|
+
|
92
|
+
c = DTrace::Consumer.new(@dtp)
|
93
|
+
|
94
|
+
i = 0
|
95
|
+
c.consume do |d|
|
96
|
+
assert d
|
97
|
+
assert_not_nil d.cpu
|
98
|
+
assert_equal "profile:::profile-1", d.probe.to_s
|
99
|
+
|
100
|
+
i = i + 1
|
101
|
+
if i >= 10
|
102
|
+
c.finish
|
103
|
+
end
|
104
|
+
end
|
105
|
+
assert i > 0
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_dprogram_aggregate_once
|
109
|
+
progtext = <<EOD
|
110
|
+
profile-1000hz
|
111
|
+
{
|
112
|
+
@a[execname] = count();
|
113
|
+
}
|
114
|
+
|
115
|
+
END
|
116
|
+
{
|
117
|
+
printa(@a)
|
118
|
+
}
|
119
|
+
EOD
|
120
|
+
|
121
|
+
prog = @dtp.compile progtext
|
122
|
+
prog.execute
|
123
|
+
@dtp.go
|
124
|
+
sleep 2
|
125
|
+
|
126
|
+
i = 0
|
127
|
+
c = DTrace::Consumer.new(@dtp)
|
128
|
+
c.consume_once do |d|
|
129
|
+
i = i + 1
|
130
|
+
assert d
|
131
|
+
assert_not_nil d.cpu
|
132
|
+
assert_equal "dtrace:::END", d.probe.to_s
|
133
|
+
|
134
|
+
d.data.each do |r|
|
135
|
+
assert_equal DTrace::AggregateSet, r.class
|
136
|
+
r.data.each do |a|
|
137
|
+
assert_not_nil a.value
|
138
|
+
assert_not_nil a.tuple
|
139
|
+
assert_equal 1, a.tuple.length
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
assert i > 0
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_stack
|
147
|
+
progtext = "profile-1 { trace(execname); stack(); }"
|
148
|
+
prog = @dtp.compile progtext
|
149
|
+
prog.execute
|
150
|
+
@dtp.go
|
151
|
+
sleep 2
|
152
|
+
|
153
|
+
c = DTrace::Consumer.new(@dtp)
|
154
|
+
i = 0
|
155
|
+
c.consume do |d|
|
156
|
+
assert d
|
157
|
+
assert_not_nil d.cpu
|
158
|
+
assert_equal "profile:::profile-1", d.probe.to_s
|
159
|
+
|
160
|
+
assert_equal 2, d.data.length
|
161
|
+
assert_equal DTrace::Record, d.data[0].class
|
162
|
+
assert_equal DTrace::StackRecord, d.data[1].class
|
163
|
+
|
164
|
+
i = i + 1
|
165
|
+
if i > 10
|
166
|
+
c.finish
|
167
|
+
end
|
168
|
+
end
|
169
|
+
assert i > 0
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_ustack
|
173
|
+
progtext = "profile-1 { trace(execname); ustack(); }"
|
174
|
+
prog = @dtp.compile progtext
|
175
|
+
prog.execute
|
176
|
+
@dtp.go
|
177
|
+
sleep 2
|
178
|
+
|
179
|
+
c = DTrace::Consumer.new(@dtp)
|
180
|
+
i = 0
|
181
|
+
c.consume do |d|
|
182
|
+
assert d
|
183
|
+
assert_not_nil d.cpu
|
184
|
+
assert_equal "profile:::profile-1", d.probe.to_s
|
185
|
+
|
186
|
+
assert_equal 2, d.data.length
|
187
|
+
assert_equal DTrace::Record, d.data[0].class
|
188
|
+
assert_equal DTrace::StackRecord, d.data[1].class
|
189
|
+
|
190
|
+
i = i + 1
|
191
|
+
if i > 10
|
192
|
+
c.finish
|
193
|
+
end
|
194
|
+
end
|
195
|
+
assert i > 0
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|