curb 1.2.2 → 1.3.2

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.
@@ -0,0 +1,110 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ require 'tmpdir'
3
+
4
+ class TestServerMethodsWaitForServerReady < Test::Unit::TestCase
5
+ include TestServerMethods
6
+
7
+ def server_startup_timeout
8
+ 0.05
9
+ end
10
+
11
+ def unused_port
12
+ server = TCPServer.new('127.0.0.1', 0)
13
+ port = server.addr[1]
14
+ server.close
15
+ port
16
+ end
17
+
18
+ def test_wait_for_server_ready_returns_false_when_thread_dies
19
+ thread = Thread.new {}
20
+ thread.join
21
+
22
+ started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
23
+ assert_equal false, wait_for_server_ready(unused_port, thread: thread)
24
+ elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
25
+
26
+ assert_operator elapsed, :<, 0.5
27
+ end
28
+
29
+ def test_wait_for_server_ready_times_out_when_server_never_starts
30
+ error = assert_raise(RuntimeError) do
31
+ wait_for_server_ready(unused_port)
32
+ end
33
+
34
+ assert_match(/Failed to startup test server/, error.message)
35
+ end
36
+ end
37
+
38
+ class TestServerMethodsLockHandling < Test::Unit::TestCase
39
+ include TestServerMethods
40
+
41
+ def setup
42
+ @lock_dir = Dir.mktmpdir('curb-server-lock')
43
+ @__port = unused_port
44
+ end
45
+
46
+ def teardown
47
+ super
48
+ FileUtils.remove_entry(@lock_dir) if @lock_dir && File.exist?(@lock_dir)
49
+ end
50
+
51
+ def server_startup_timeout
52
+ 0.05
53
+ end
54
+
55
+ def locked_file
56
+ File.join(@lock_dir, "server_lock-#{@__port}")
57
+ end
58
+
59
+ def unused_port
60
+ server = TCPServer.new('127.0.0.1', 0)
61
+ port = server.addr[1]
62
+ server.close
63
+ port
64
+ end
65
+
66
+ def test_clear_stale_server_lock_removes_legacy_lock_when_server_is_down
67
+ File.write(locked_file, 'locked')
68
+
69
+ clear_stale_server_lock(@__port)
70
+
71
+ assert_equal false, File.exist?(locked_file)
72
+ end
73
+
74
+ def test_clear_stale_server_lock_removes_dead_pid_lock_when_server_is_down
75
+ File.write(locked_file, "999999\n")
76
+
77
+ clear_stale_server_lock(@__port)
78
+
79
+ assert_equal false, File.exist?(locked_file)
80
+ end
81
+
82
+ def test_clear_stale_server_lock_keeps_live_pid_lock_during_startup_window
83
+ write_server_lock(Process.pid)
84
+
85
+ clear_stale_server_lock(@__port)
86
+
87
+ assert_equal true, File.exist?(locked_file)
88
+ end
89
+
90
+ def test_clear_stale_server_lock_removes_non_responding_live_pid_lock_after_timeout
91
+ write_server_lock(Process.pid)
92
+ stale_time = Time.now - 1
93
+ File.utime(stale_time, stale_time, locked_file)
94
+
95
+ clear_stale_server_lock(@__port)
96
+
97
+ assert_equal false, File.exist?(locked_file)
98
+ end
99
+
100
+ def test_stop_test_server_removes_owned_lock_and_shuts_listener_down
101
+ server_setup(@__port)
102
+ assert_equal true, File.exist?(locked_file)
103
+ assert_equal true, server_responding?(@__port)
104
+
105
+ stop_test_server
106
+
107
+ assert_equal false, File.exist?(locked_file)
108
+ assert_equal false, server_responding?(@__port)
109
+ end
110
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
8
8
  - Todd A. Fisher
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-18 00:00:00.000000000 Z
11
+ date: 2026-04-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings
14
14
  for the libcurl(3), a fully-featured client-side URL transfer library. cURL and
@@ -62,6 +62,7 @@ files:
62
62
  - tests/bug_require_last_or_segfault.rb
63
63
  - tests/bugtests.rb
64
64
  - tests/helper.rb
65
+ - tests/leak_trace.rb
65
66
  - tests/mem_check.rb
66
67
  - tests/require_last_or_segfault_script.rb
67
68
  - tests/signals.rb
@@ -74,16 +75,13 @@ files:
74
75
  - tests/tc_curl_easy_setopt.rb
75
76
  - tests/tc_curl_maxfilesize.rb
76
77
  - tests/tc_curl_multi.rb
78
+ - tests/tc_curl_native_coverage.rb
77
79
  - tests/tc_curl_postfield.rb
78
80
  - tests/tc_curl_protocols.rb
79
81
  - tests/tc_fiber_scheduler.rb
80
82
  - tests/tc_ftp_options.rb
81
83
  - tests/tc_gc_compact.rb
82
- - tests/test_basic.rb
83
- - tests/test_fiber_debug.rb
84
- - tests/test_fiber_simple.rb
85
- - tests/test_real_url.rb
86
- - tests/test_simple_fiber.rb
84
+ - tests/tc_test_server_methods.rb
87
85
  - tests/timeout.rb
88
86
  - tests/timeout_server.rb
89
87
  - tests/unittests.rb
@@ -102,14 +100,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
100
  requirements:
103
101
  - - ">="
104
102
  - !ruby/object:Gem::Version
105
- version: '0'
103
+ version: '2.2'
106
104
  required_rubygems_version: !ruby/object:Gem::Requirement
107
105
  requirements:
108
106
  - - ">="
109
107
  - !ruby/object:Gem::Version
110
108
  version: '0'
111
109
  requirements: []
112
- rubygems_version: 3.6.9
110
+ rubygems_version: 4.0.6
113
111
  specification_version: 4
114
112
  summary: Ruby libcurl bindings
115
113
  test_files:
@@ -131,6 +129,7 @@ test_files:
131
129
  - tests/bug_require_last_or_segfault.rb
132
130
  - tests/bugtests.rb
133
131
  - tests/helper.rb
132
+ - tests/leak_trace.rb
134
133
  - tests/mem_check.rb
135
134
  - tests/require_last_or_segfault_script.rb
136
135
  - tests/signals.rb
@@ -143,16 +142,13 @@ test_files:
143
142
  - tests/tc_curl_easy_setopt.rb
144
143
  - tests/tc_curl_maxfilesize.rb
145
144
  - tests/tc_curl_multi.rb
145
+ - tests/tc_curl_native_coverage.rb
146
146
  - tests/tc_curl_postfield.rb
147
147
  - tests/tc_curl_protocols.rb
148
148
  - tests/tc_fiber_scheduler.rb
149
149
  - tests/tc_ftp_options.rb
150
150
  - tests/tc_gc_compact.rb
151
- - tests/test_basic.rb
152
- - tests/test_fiber_debug.rb
153
- - tests/test_fiber_simple.rb
154
- - tests/test_real_url.rb
155
- - tests/test_simple_fiber.rb
151
+ - tests/tc_test_server_methods.rb
156
152
  - tests/timeout.rb
157
153
  - tests/timeout_server.rb
158
154
  - tests/unittests.rb
data/tests/test_basic.rb DELETED
@@ -1,29 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
-
3
- class TestBasic < Test::Unit::TestCase
4
- include TestServerMethods
5
-
6
- def setup
7
- server_setup
8
- end
9
-
10
- def test_basic_request
11
- puts "\n=== Testing basic request ==="
12
- easy = Curl::Easy.new(TestServlet.url)
13
- easy.perform
14
- puts "Response code: #{easy.response_code}"
15
- puts "Body (first 100 chars): #{easy.body_str[0..100]}"
16
- assert_equal 200, easy.response_code
17
- end
18
-
19
- def test_slow_request
20
- puts "\n=== Testing slow request ==="
21
- url = TestServlet.url_to("/slow?seconds=0.1")
22
- puts "URL: #{url}"
23
- easy = Curl::Easy.new(url)
24
- easy.perform
25
- puts "Response code: #{easy.response_code}"
26
- puts "Body: #{easy.body_str}"
27
- assert_equal 200, easy.response_code
28
- end
29
- end
@@ -1,69 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
- require 'async'
3
-
4
- class TestFiberDebug < Test::Unit::TestCase
5
- include TestServerMethods
6
-
7
- def setup
8
- server_setup
9
- end
10
-
11
- def test_simple_fiber_request
12
- puts "\n=== Starting simple fiber request test ==="
13
-
14
- run_async do |task|
15
- puts "Inside Async block"
16
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
17
-
18
- multi = Curl::Multi.new
19
- easy = Curl::Easy.new(TestServlet.url)
20
- easy.on_complete { |curl| puts "Request completed: #{curl.response_code}" }
21
-
22
- multi.add(easy)
23
- puts "Added easy handle to multi"
24
-
25
- # Perform without block first
26
- puts "Calling perform..."
27
- multi.perform
28
- puts "Perform completed"
29
- end
30
-
31
- puts "Test completed"
32
- end
33
-
34
- def test_fiber_with_block
35
- puts "\n=== Starting fiber with block test ==="
36
-
37
- run_async do |task|
38
- puts "Inside Async block"
39
-
40
- multi = Curl::Multi.new
41
- easy = Curl::Easy.new(TestServlet.url_to("/slow?seconds=0.1"))
42
- easy.on_complete { |curl| puts "Request completed: #{curl.response_code}" }
43
-
44
- multi.add(easy)
45
-
46
- block_calls = 0
47
- multi.perform do
48
- block_calls += 1
49
- puts "Block called: #{block_calls}"
50
- if block_calls < 5 # Limit iterations to prevent infinite loop
51
- Async::Task.yield
52
- end
53
- end
54
-
55
- puts "Perform completed, block called #{block_calls} times"
56
- end
57
-
58
- puts "Test completed"
59
- end
60
-
61
- private
62
- def run_async(&block)
63
- if defined?(Async) && Async.respond_to?(:run)
64
- Async.run(&block)
65
- else
66
- Async(&block)
67
- end
68
- end
69
- end
@@ -1,65 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
- require 'async'
3
-
4
- class TestFiberSimple < Test::Unit::TestCase
5
- include TestServerMethods
6
-
7
- def setup
8
- server_setup
9
- end
10
-
11
- def test_simple_concurrent
12
- puts "\n=== Testing simple concurrent requests ==="
13
-
14
- results = []
15
-
16
- if Async.respond_to?(:run)
17
- Async.run do |task|
18
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
19
-
20
- multi = Curl::Multi.new
21
-
22
- # Add 3 requests
23
- 3.times do |i|
24
- easy = Curl::Easy.new(TestServlet.url_to("/slow?seconds=0.2&id=#{i}"))
25
- easy.on_complete { |curl|
26
- results << { id: i, code: curl.response_code }
27
- puts "Request #{i} completed"
28
- }
29
- multi.add(easy)
30
- end
31
-
32
- puts "Starting perform..."
33
- start_time = Time.now
34
- multi.perform # No block
35
- elapsed = Time.now - start_time
36
- puts "Perform completed in #{elapsed.round(2)}s"
37
- end
38
- else
39
- Async do |task|
40
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
41
-
42
- multi = Curl::Multi.new
43
-
44
- # Add 3 requests
45
- 3.times do |i|
46
- easy = Curl::Easy.new(TestServlet.url_to("/slow?seconds=0.2&id=#{i}"))
47
- easy.on_complete { |curl|
48
- results << { id: i, code: curl.response_code }
49
- puts "Request #{i} completed"
50
- }
51
- multi.add(easy)
52
- end
53
-
54
- puts "Starting perform..."
55
- start_time = Time.now
56
- multi.perform # No block
57
- elapsed = Time.now - start_time
58
- puts "Perform completed in #{elapsed.round(2)}s"
59
- end
60
- end
61
-
62
- assert_equal 3, results.size
63
- results.each { |r| assert_equal 200, r[:code] }
64
- end
65
- end
@@ -1,65 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../lib/curb'))
2
- require 'async'
3
-
4
- puts "Testing fiber scheduler with real URLs..."
5
-
6
- # Test without fiber scheduler
7
- puts "\n1. Without fiber scheduler:"
8
- start = Time.now
9
- multi = Curl::Multi.new
10
-
11
- easies = []
12
- 3.times do |i|
13
- easy = Curl::Easy.new("https://httpbin.org/delay/1")
14
- easy.on_complete { |curl| puts "Request #{i} completed: #{curl.response_code}" }
15
- multi.add(easy)
16
- easies << easy
17
- end
18
-
19
- multi.perform
20
- elapsed = Time.now - start
21
- puts "Total time: #{elapsed.round(2)}s"
22
-
23
- # Test with fiber scheduler
24
- puts "\n2. With fiber scheduler:"
25
- if Async.respond_to?(:run)
26
- Async.run do
27
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
28
-
29
- start = Time.now
30
- multi = Curl::Multi.new
31
-
32
- easies = []
33
- 3.times do |i|
34
- easy = Curl::Easy.new("https://httpbin.org/delay/1")
35
- easy.on_complete { |curl| puts "Request #{i} completed: #{curl.response_code}" }
36
- multi.add(easy)
37
- easies << easy
38
- end
39
-
40
- multi.perform
41
- elapsed = Time.now - start
42
- puts "Total time: #{elapsed.round(2)}s"
43
- end
44
- else
45
- Async do
46
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
47
-
48
- start = Time.now
49
- multi = Curl::Multi.new
50
-
51
- easies = []
52
- 3.times do |i|
53
- easy = Curl::Easy.new("https://httpbin.org/delay/1")
54
- easy.on_complete { |curl| puts "Request #{i} completed: #{curl.response_code}" }
55
- multi.add(easy)
56
- easies << easy
57
- end
58
-
59
- multi.perform
60
- elapsed = Time.now - start
61
- puts "Total time: #{elapsed.round(2)}s"
62
- end
63
- end
64
-
65
- puts "\nDone!"
@@ -1,34 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../lib/curb'))
2
- require 'async'
3
-
4
- puts "Testing simple fiber scheduler..."
5
-
6
- if Async.respond_to?(:run)
7
- Async.run do
8
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
9
-
10
- multi = Curl::Multi.new
11
- easy = Curl::Easy.new("https://httpbin.org/delay/1")
12
- easy.on_complete { |curl| puts "Request completed: #{curl.response_code}" }
13
-
14
- multi.add(easy)
15
- puts "Starting perform..."
16
- multi.perform
17
- puts "Perform completed"
18
- end
19
- else
20
- Async do
21
- puts "Fiber scheduler available: #{Curl::Multi.fiber_scheduler_available?}"
22
-
23
- multi = Curl::Multi.new
24
- easy = Curl::Easy.new("https://httpbin.org/delay/1")
25
- easy.on_complete { |curl| puts "Request completed: #{curl.response_code}" }
26
-
27
- multi.add(easy)
28
- puts "Starting perform..."
29
- multi.perform
30
- puts "Perform completed"
31
- end
32
- end
33
-
34
- puts "Done!"