curb 0.8.4 → 1.3.5
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 +7 -0
- data/README.md +522 -0
- data/Rakefile +79 -26
- data/ext/banned.h +32 -0
- data/ext/curb.c +549 -230
- data/ext/curb.h +19 -10
- data/ext/curb_easy.c +1935 -366
- data/ext/curb_easy.h +16 -0
- data/ext/curb_errors.c +115 -18
- data/ext/curb_errors.h +8 -5
- data/ext/curb_macros.h +33 -21
- data/ext/curb_multi.c +1858 -272
- data/ext/curb_multi.h +10 -3
- data/ext/curb_postfield.c +149 -77
- data/ext/curb_postfield.h +1 -0
- data/ext/curb_upload.c +38 -11
- data/ext/curb_upload.h +2 -0
- data/ext/extconf.rb +353 -35
- data/lib/curb.rb +1 -0
- data/lib/curl/easy.rb +314 -78
- data/lib/curl/multi.rb +134 -28
- data/lib/curl.rb +217 -11
- data/tests/bug_crash_on_debug.rb +14 -28
- data/tests/bug_crash_on_progress.rb +32 -16
- data/tests/bug_curb_easy_blocks_ruby_threads.rb +10 -15
- data/tests/bug_curb_easy_post_with_string_no_content_length_header.rb +6 -30
- data/tests/bug_follow_redirect_288.rb +83 -0
- data/tests/bug_instance_post_differs_from_class_post.rb +3 -5
- data/tests/bug_issue102.rb +1 -1
- data/tests/bug_issue_noproxy.rb +56 -0
- data/tests/bug_issue_post_redirect.rb +93 -0
- data/tests/bug_issue_spnego.rb +41 -0
- data/tests/bug_multi_segfault.rb +1 -0
- data/tests/bug_raise_on_callback.rb +30 -0
- data/tests/helper.rb +400 -44
- data/tests/leak_trace.rb +237 -0
- data/tests/mem_check.rb +3 -0
- data/tests/tc_curl.rb +31 -1
- data/tests/tc_curl_download.rb +12 -7
- data/tests/tc_curl_easy.rb +911 -63
- data/tests/tc_curl_easy_cookielist.rb +277 -0
- data/tests/tc_curl_easy_request_target.rb +41 -0
- data/tests/tc_curl_easy_resolve.rb +48 -0
- data/tests/tc_curl_maxfilesize.rb +12 -0
- data/tests/tc_curl_multi.rb +855 -53
- data/tests/tc_curl_native_coverage.rb +145 -0
- data/tests/tc_curl_postfield.rb +207 -30
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/tc_fiber_scheduler.rb +543 -0
- data/tests/tc_ftp_options.rb +39 -0
- data/tests/tc_gc_compact.rb +223 -0
- data/tests/tc_test_server_methods.rb +110 -0
- data/tests/timeout.rb +30 -6
- metadata +59 -36
- data/README +0 -194
|
@@ -22,26 +22,15 @@ end
|
|
|
22
22
|
Any insight you care to share would be helpful. Thanks.
|
|
23
23
|
=end
|
|
24
24
|
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
25
|
-
require 'webrick'
|
|
26
|
-
class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
|
|
27
|
-
class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
|
|
28
25
|
|
|
29
26
|
class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
|
|
30
|
-
|
|
31
|
-
server = WEBrick::HTTPServer.new( :Port => 9999 )
|
|
32
|
-
server.mount_proc("/test") do|req,res|
|
|
33
|
-
assert_equal '15', req['Content-Length']
|
|
34
|
-
res.body = "hi"
|
|
35
|
-
res['Content-Type'] = "text/html"
|
|
36
|
-
end
|
|
27
|
+
include BugTestServerSetupTeardown
|
|
37
28
|
|
|
38
|
-
|
|
39
|
-
srv.start
|
|
40
|
-
end
|
|
29
|
+
def test_bug_workaround
|
|
41
30
|
params = {:cat => "hat", :foo => "bar"}
|
|
42
31
|
|
|
43
32
|
post_body = params.map{|f,k| "#{Curl::Easy.new.escape(f)}=#{Curl::Easy.new.escape(k)}"}.join('&')
|
|
44
|
-
c = Curl::Easy.http_post("http://127.0.0.1
|
|
33
|
+
c = Curl::Easy.http_post("http://127.0.0.1:#{@port}/test",post_body) do |curl|
|
|
45
34
|
curl.headers["User-Agent"] = "Curl/Ruby"
|
|
46
35
|
curl.headers["X-Tender-Auth"] = "A Token"
|
|
47
36
|
curl.headers["Accept"] = "application/vnd.tender-v1+json"
|
|
@@ -50,23 +39,12 @@ class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
|
|
|
50
39
|
curl.enable_cookies = true
|
|
51
40
|
end
|
|
52
41
|
|
|
53
|
-
server.shutdown
|
|
54
|
-
thread.join
|
|
55
42
|
end
|
|
56
|
-
def test_bug
|
|
57
|
-
server = WEBrick::HTTPServer.new( :Port => 9999 )
|
|
58
|
-
server.mount_proc("/test") do|req,res|
|
|
59
|
-
assert_equal '15', req['Content-Length']
|
|
60
|
-
res.body = "hi"
|
|
61
|
-
res['Content-Type'] = "text/html"
|
|
62
|
-
end
|
|
63
43
|
|
|
64
|
-
|
|
65
|
-
srv.start
|
|
66
|
-
end
|
|
44
|
+
def test_bug
|
|
67
45
|
params = {:cat => "hat", :foo => "bar"}
|
|
68
46
|
|
|
69
|
-
c = Curl::Easy.http_post("http://127.0.0.1
|
|
47
|
+
c = Curl::Easy.http_post("http://127.0.0.1:#{@port}/test") do |curl|
|
|
70
48
|
curl.headers["User-Agent"] = "Curl/Ruby"
|
|
71
49
|
curl.headers["X-Tender-Auth"] = "A Token"
|
|
72
50
|
curl.headers["Accept"] = "application/vnd.tender-v1+json"
|
|
@@ -76,8 +54,6 @@ class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
|
|
|
76
54
|
curl.follow_location = true
|
|
77
55
|
curl.enable_cookies = true
|
|
78
56
|
end
|
|
79
|
-
|
|
80
|
-
server.shutdown
|
|
81
|
-
thread.join
|
|
82
57
|
end
|
|
58
|
+
|
|
83
59
|
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
class BugFollowRedirect288 < Test::Unit::TestCase
|
|
4
|
+
include BugTestServerSetupTeardown
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@port = unused_local_port
|
|
8
|
+
super
|
|
9
|
+
@server.mount_proc("/redirect_to_test") do|req,res|
|
|
10
|
+
res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, "/test")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_follow_redirect_with_no_redirect
|
|
15
|
+
|
|
16
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
|
|
17
|
+
did_call_redirect = false
|
|
18
|
+
c.on_redirect do|x|
|
|
19
|
+
did_call_redirect = true
|
|
20
|
+
end
|
|
21
|
+
c.perform
|
|
22
|
+
|
|
23
|
+
assert !did_call_redirect, "should reach this point redirect should not have been called"
|
|
24
|
+
|
|
25
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/test")
|
|
26
|
+
did_call_redirect = false
|
|
27
|
+
c.on_redirect do|x|
|
|
28
|
+
did_call_redirect = true
|
|
29
|
+
end
|
|
30
|
+
c.follow_location = true
|
|
31
|
+
c.perform
|
|
32
|
+
|
|
33
|
+
assert_equal 0, c.redirect_count
|
|
34
|
+
assert !did_call_redirect, "should reach this point redirect should not have been called"
|
|
35
|
+
|
|
36
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/redirect_to_test")
|
|
37
|
+
did_call_redirect = false
|
|
38
|
+
c.on_redirect do|x|
|
|
39
|
+
did_call_redirect = true
|
|
40
|
+
end
|
|
41
|
+
c.perform
|
|
42
|
+
assert_equal 307, c.response_code
|
|
43
|
+
|
|
44
|
+
assert did_call_redirect, "we should have called on_redirect"
|
|
45
|
+
|
|
46
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/redirect_to_test")
|
|
47
|
+
did_call_redirect = false
|
|
48
|
+
c.follow_location = true
|
|
49
|
+
# NOTE: while this API is not supported by libcurl e.g. there is no redirect function callback in libcurl we could
|
|
50
|
+
# add support in ruby for this by executing this callback if redirect_count is greater than 0 at the end of a request in curb_multi.c
|
|
51
|
+
c.on_redirect do|x|
|
|
52
|
+
did_call_redirect = true
|
|
53
|
+
end
|
|
54
|
+
c.perform
|
|
55
|
+
assert_equal 1, c.redirect_count
|
|
56
|
+
assert_equal 200, c.response_code
|
|
57
|
+
|
|
58
|
+
assert did_call_redirect, "we should have called on_redirect"
|
|
59
|
+
|
|
60
|
+
c.url = "http://127.0.0.1:#{@port}/test"
|
|
61
|
+
c.perform
|
|
62
|
+
assert_equal 0, c.redirect_count
|
|
63
|
+
assert_equal 200, c.response_code
|
|
64
|
+
|
|
65
|
+
puts "checking for raise support"
|
|
66
|
+
did_raise = false
|
|
67
|
+
begin
|
|
68
|
+
c = Curl::Easy.new("http://127.0.0.1:#{@port}/redirect_to_test")
|
|
69
|
+
did_call_redirect = false
|
|
70
|
+
c.on_redirect do|x|
|
|
71
|
+
raise "raise"
|
|
72
|
+
did_call_redirect = true
|
|
73
|
+
end
|
|
74
|
+
c.perform
|
|
75
|
+
rescue => e
|
|
76
|
+
did_raise = true
|
|
77
|
+
end
|
|
78
|
+
assert_equal 307, c.response_code
|
|
79
|
+
assert did_raise
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
@@ -35,15 +35,13 @@ class BugTestInstancePostDiffersFromClassPost < Test::Unit::TestCase
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def do_test
|
|
38
|
-
c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth',
|
|
39
|
-
Curl::PostField.content('ltmpl','m_blanco'))
|
|
38
|
+
c = Curl::Easy.http_post('https://www.google.com/accounts/ServiceLoginAuth', Curl::PostField.content('ltmpl','m_blanco'))
|
|
40
39
|
body_c, header_c = c.body_str, c.header_str
|
|
41
40
|
|
|
42
41
|
sleep 2
|
|
43
42
|
|
|
44
|
-
c.http_post('https://www.google.com/accounts/ServiceLoginAuth',
|
|
45
|
-
|
|
46
|
-
body_i, header_i = c.body_str, c.header_str
|
|
43
|
+
c.http_post('https://www.google.com/accounts/ServiceLoginAuth', Curl::PostField.content('ltmpl','m_blanco'))
|
|
44
|
+
body_i, header_i = c.body, c.head
|
|
47
45
|
|
|
48
46
|
# timestamps will differ, just check first bit. We wont get here if
|
|
49
47
|
# the bug bites anyway...
|
data/tests/bug_issue102.rb
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
class BugIssueNoproxy < Test::Unit::TestCase
|
|
4
|
+
def test_noproxy_option_support
|
|
5
|
+
# Test that CURLOPT_NOPROXY constant is defined
|
|
6
|
+
assert Curl.const_defined?(:CURLOPT_NOPROXY), "CURLOPT_NOPROXY constant should be defined"
|
|
7
|
+
|
|
8
|
+
# Test basic noproxy setting using setopt
|
|
9
|
+
c = Curl::Easy.new('https://google.com')
|
|
10
|
+
|
|
11
|
+
# This should not raise an error
|
|
12
|
+
assert_nothing_raised do
|
|
13
|
+
c.setopt(Curl::CURLOPT_NOPROXY, "localhost,127.0.0.1")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Test using the convenience method if it exists
|
|
17
|
+
if c.respond_to?(:noproxy=)
|
|
18
|
+
assert_nothing_raised do
|
|
19
|
+
c.noproxy = "localhost,127.0.0.1"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Test getter if it exists
|
|
23
|
+
if c.respond_to?(:noproxy)
|
|
24
|
+
assert_equal "localhost,127.0.0.1", c.noproxy
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_noproxy_with_set_method
|
|
30
|
+
c = Curl::Easy.new('https://google.com')
|
|
31
|
+
|
|
32
|
+
# The issue specifically mentions using the set method
|
|
33
|
+
# This currently raises TypeError as reported in the issue
|
|
34
|
+
assert_nothing_raised(TypeError) do
|
|
35
|
+
c.set(:noproxy, "localhost,127.0.0.1")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_noproxy_empty_string
|
|
40
|
+
c = Curl::Easy.new('https://google.com')
|
|
41
|
+
|
|
42
|
+
# Test setting empty string to override environment variables
|
|
43
|
+
assert_nothing_raised do
|
|
44
|
+
c.setopt(Curl::CURLOPT_NOPROXY, "")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_noproxy_nil_value
|
|
49
|
+
c = Curl::Easy.new('https://google.com')
|
|
50
|
+
|
|
51
|
+
# Test setting nil to reset
|
|
52
|
+
assert_nothing_raised do
|
|
53
|
+
c.setopt(Curl::CURLOPT_NOPROXY, nil)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
class BugIssuePostRedirect < Test::Unit::TestCase
|
|
5
|
+
include BugTestServerSetupTeardown
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@port = 9998
|
|
9
|
+
super
|
|
10
|
+
# Mount a POST endpoint that returns a redirect
|
|
11
|
+
@server.mount_proc("/post_redirect") do |req, res|
|
|
12
|
+
if req.request_method == "POST"
|
|
13
|
+
res.status = 302
|
|
14
|
+
res['Location'] = "http://127.0.0.1:#{@port}/redirected"
|
|
15
|
+
res.body = "Redirecting..."
|
|
16
|
+
else
|
|
17
|
+
res.status = 405
|
|
18
|
+
res.body = "Method not allowed"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Mount the redirect target
|
|
23
|
+
@server.mount_proc("/redirected") do |req, res|
|
|
24
|
+
res.status = 200
|
|
25
|
+
res['Content-Type'] = "text/plain"
|
|
26
|
+
res.body = "You have been redirected"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_post_with_max_redirects_zero_should_not_follow_redirect
|
|
31
|
+
# Test case replicating the issue: POST with max_redirects=0 and follow_location=false
|
|
32
|
+
# should NOT trigger on_redirect callback or follow the redirect
|
|
33
|
+
|
|
34
|
+
redirect_called = false
|
|
35
|
+
|
|
36
|
+
handle = Curl::Easy.new("http://127.0.0.1:#{@port}/post_redirect") do |curl|
|
|
37
|
+
curl.max_redirects = 0
|
|
38
|
+
curl.follow_location = false
|
|
39
|
+
curl.on_redirect do |easy|
|
|
40
|
+
redirect_called = true
|
|
41
|
+
end
|
|
42
|
+
curl.headers['Content-Type'] = 'application/json'
|
|
43
|
+
curl.post_body = {test: "data"}.to_json
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
handle.http(:POST)
|
|
47
|
+
|
|
48
|
+
# The response should be the redirect response (302)
|
|
49
|
+
assert_equal 302, handle.response_code
|
|
50
|
+
assert_match(/Redirecting/, handle.body_str)
|
|
51
|
+
|
|
52
|
+
# on_redirect should NOT be called when follow_location is false
|
|
53
|
+
assert !redirect_called, "on_redirect callback should not be called when follow_location is false"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_post_with_follow_location_true_triggers_redirect
|
|
57
|
+
# Test that on_redirect IS called when follow_location is true
|
|
58
|
+
redirect_called = false
|
|
59
|
+
|
|
60
|
+
handle = Curl::Easy.new("http://127.0.0.1:#{@port}/post_redirect") do |curl|
|
|
61
|
+
curl.follow_location = true
|
|
62
|
+
curl.on_redirect do |easy|
|
|
63
|
+
redirect_called = true
|
|
64
|
+
end
|
|
65
|
+
curl.headers['Content-Type'] = 'application/json'
|
|
66
|
+
curl.post_body = {test: "data"}.to_json
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
handle.http(:POST)
|
|
70
|
+
|
|
71
|
+
# Should follow the redirect and get the final response
|
|
72
|
+
assert_equal 200, handle.response_code
|
|
73
|
+
assert_match(/You have been redirected/, handle.body_str)
|
|
74
|
+
|
|
75
|
+
# on_redirect SHOULD be called when follow_location is true
|
|
76
|
+
assert redirect_called, "on_redirect callback should be called when follow_location is true"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_curl_post_class_method_respects_redirect_settings
|
|
80
|
+
# Test that Curl.post (class method) respects redirect settings
|
|
81
|
+
# According to the issue, this works correctly
|
|
82
|
+
|
|
83
|
+
response = Curl.post("http://127.0.0.1:#{@port}/post_redirect", {test: "data"}.to_json) do |curl|
|
|
84
|
+
curl.max_redirects = 0
|
|
85
|
+
curl.follow_location = false
|
|
86
|
+
curl.headers['Content-Type'] = 'application/json'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Should get the redirect response, not follow it
|
|
90
|
+
assert_equal 302, response.response_code
|
|
91
|
+
assert_match(/Redirecting/, response.body_str)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
class BugIssueSpnego < Test::Unit::TestCase
|
|
4
|
+
def test_spnego_detection_works
|
|
5
|
+
# The fix for issue #227 ensures that Curl.spnego? checks for both
|
|
6
|
+
# CURL_VERSION_SPNEGO (newer libcurl) and CURL_VERSION_GSSNEGOTIATE (older libcurl)
|
|
7
|
+
#
|
|
8
|
+
# We can't test that it returns true because that depends on how libcurl
|
|
9
|
+
# was compiled on the system. We can only test that:
|
|
10
|
+
# 1. The method exists and works
|
|
11
|
+
# 2. If CURLAUTH_GSSNEGOTIATE is available, we can use it
|
|
12
|
+
|
|
13
|
+
# Check if CURLAUTH_GSSNEGOTIATE is available
|
|
14
|
+
if Curl.const_defined?(:CURLAUTH_GSSNEGOTIATE) && Curl.const_get(:CURLAUTH_GSSNEGOTIATE) != 0
|
|
15
|
+
# Test that we can use GSSNEGOTIATE auth type
|
|
16
|
+
c = Curl::Easy.new('http://example.com')
|
|
17
|
+
assert_nothing_raised do
|
|
18
|
+
c.http_auth_types = Curl::CURLAUTH_GSSNEGOTIATE
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The fix ensures spnego? won't incorrectly return false when
|
|
22
|
+
# older libcurl versions have GSSNEGOTIATE support
|
|
23
|
+
# (The actual return value depends on system libcurl compilation)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# The important fix is that the method now checks both constants
|
|
27
|
+
# This test passes if no exceptions are raised
|
|
28
|
+
assert true, "SPNEGO detection is working correctly"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_spnego_method_exists
|
|
32
|
+
# The method should always exist
|
|
33
|
+
assert Curl.respond_to?(:spnego?), "Curl should respond to spnego?"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_spnego_returns_boolean
|
|
37
|
+
# The method should return a boolean
|
|
38
|
+
result = Curl.spnego?
|
|
39
|
+
assert [true, false].include?(result), "Curl.spnego? should return true or false, got #{result.inspect}"
|
|
40
|
+
end
|
|
41
|
+
end
|
data/tests/bug_multi_segfault.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# irb: multi = Curl::Multi.new
|
|
4
4
|
# irb: exit
|
|
5
5
|
# <main>:47140: [BUG] Bus Error
|
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
6
7
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','ext'))
|
|
7
8
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
|
|
8
9
|
require 'curb'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
|
|
3
|
+
class BugRaiseOnCallback < Test::Unit::TestCase
|
|
4
|
+
include BugTestServerSetupTeardown
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@port = unused_local_port
|
|
8
|
+
super
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_on_complte
|
|
12
|
+
url = "http://127.0.0.1:#{@port}/test"
|
|
13
|
+
c = Curl::Easy.new(url)
|
|
14
|
+
did_raise = false
|
|
15
|
+
begin
|
|
16
|
+
c.on_complete do|x|
|
|
17
|
+
assert_equal url, x.url
|
|
18
|
+
raise "error complete" # this will get swallowed
|
|
19
|
+
end
|
|
20
|
+
c.perform
|
|
21
|
+
rescue => e
|
|
22
|
+
did_raise = true
|
|
23
|
+
end
|
|
24
|
+
assert did_raise, "we want to raise an exception if the ruby callbacks raise"
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#test_on_debug
|