-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathabrt_handler_spec.rb
More file actions
149 lines (123 loc) · 4.9 KB
/
abrt_handler_spec.rb
File metadata and controls
149 lines (123 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
require_relative 'spec_helper'
require 'abrt/handler'
describe "ABRT" do
describe "#handle_exception" do
let(:exception) do
RuntimeError.new("baz").tap do |e|
e.set_backtrace([
"/foo/bar.rb:3:in `block in func'",
"/foo/bar.rb:2:in `each'",
"/foo/bar.rb:2:in `func'",
"/foo.rb:2:in `<main>'"
])
end
end
let(:exception_report) do
"PUT / HTTP/1.1\r\n\r\n" +
"PID=#{Process.pid}\u0000" +
"EXECUTABLE=/foo.rb\u0000" +
"ANALYZER=Ruby\u0000" +
"TYPE=Ruby\u0000" +
"BASENAME=rbhook\u0000" +
"REASON=/foo/bar.rb:3:in `block in func': baz (RuntimeError)\u0000" +
"BACKTRACE=/foo/bar.rb:3:in `block in func': baz (RuntimeError)\n" +
"\tfrom /foo/bar.rb:2:in `each'\n" +
"\tfrom /foo/bar.rb:2:in `func'\n" +
"\tfrom /foo.rb:2:in `<main>'\u0000"
end
let(:null_byte_injection_exception) do
RuntimeError.new("baz\u0000bar").tap do |e|
e.set_backtrace([
"/foo\u0000.rb:2:in `<main>'\u0000INJECTION=injected"
])
end
end
let(:abrt) do
allow(ABRT).to receive(:syslog).and_return(syslog)
allow(ABRT).to receive(:abrt_socket).and_return(nil)
ABRT
end
let(:syslog) do
double("syslog").as_null_object.tap do |syslog|
allow(syslog).to receive(:err).with("%s", anything)
end
end
let(:io) { StringIO.new }
it "handles exceptions" do
expect(abrt).to receive(:abrt_socket).and_return(io)
expect(io).to receive(:read).and_return("HTTP/1.1 201 \r\n\r\n")
expect(syslog).to_not receive(:err)
abrt.handle_exception exception
expect(io.string).to eq(exception_report)
end
it "does not suffer null byte injection" do
expect(abrt).to receive(:abrt_socket).and_return(io)
expect(io).to receive(:read).and_return("HTTP/1.1 201 \r\n\r\n")
expect(io).to receive(:write).at_least(1).times do |arg|
expect(arg =~ /\u0000/).to be_nil.or be >= arg.size - 1
end
expect(syslog).to_not receive(:err)
abrt.handle_exception null_byte_injection_exception
end
it "logs unhandled exception message into syslog" do
expect(syslog).to receive(:notice).with("detected unhandled Ruby exception in '/foo.rb'")
abrt.handle_exception exception
end
it "ignores executables with relative path" do
expect(abrt).to_not receive(:write_dump)
exception.set_backtrace("./foo.rb:2:in `<main>'")
abrt.handle_exception exception
end
it "ignores oneline scripts" do
expect(abrt).to_not receive(:write_dump)
exception.set_backtrace([
"-e:1:in `/'",
"-e:1:in `<main>'"
])
abrt.handle_exception exception
end
context "logs error into syslog when" do
it "receive empty response" do
expect(abrt).to receive(:abrt_socket).and_return(io)
expect(syslog).to receive(:err).with("error sending data to ABRT daemon. Empty response received")
abrt.handle_exception exception
end
it "receive malformed response" do
expect(abrt).to receive(:abrt_socket).and_return(io)
expect(io).to receive(:read).and_return("foo")
expect(syslog).to receive(:err).with("%s", "error sending data to ABRT daemon: foo")
abrt.handle_exception exception
end
it "receive error code" do
expect(abrt).to receive(:abrt_socket).and_return(io)
expect(io).to receive(:read).and_return("HTTP/1.1 400 \r\n\r\n")
expect(syslog).to receive(:err).with("%s", "error sending data to ABRT daemon: HTTP/1.1 400 \r\n\r\n")
abrt.handle_exception exception
end
context "can't communicate with ABRT daemon" do
it "due to non-existing socket" do
socket_path = 'some/non/existing/path/to/socket'
expect(abrt).to receive(:abrt_socket).and_wrap_original do |original_method, *args, &block|
args << socket_path
original_method.call(*args)
end
expect(syslog).to receive(:err).with("%s", /can't communicate with ABRT daemon, is it running\? No such file or directory -( connect\(2\) for)? "?#{socket_path}"?/)
abrt.handle_exception exception
end
it "because no-one is listeing on the other side" do
# This file is not correct UNIX socket, so it should be usable for the test.
require 'tempfile'
Tempfile.create do |tf|
socket_path = tf.path
expect(abrt).to receive(:abrt_socket).and_wrap_original do |original_method, *args, &block|
args << tf.path
original_method.call(*args)
end
expect(syslog).to receive(:err).with("%s", /can't communicate with ABRT daemon, is it running\? Connection refused -( connect\(2\) for)? "?#{socket_path}"?/)
abrt.handle_exception exception
end
end
end
end
end
end