curb 0.1.4 → 0.7.15

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.
data/tests/helper.rb CHANGED
@@ -11,5 +11,173 @@ $:.unshift($EXTDIR)
11
11
 
12
12
  require 'curb'
13
13
  require 'test/unit'
14
+ require 'fileutils'
14
15
 
15
16
  $TEST_URL = "file://#{URI.escape(File.expand_path(__FILE__).tr('\\','/').tr(':','|'))}"
17
+
18
+ require 'thread'
19
+ require 'webrick'
20
+
21
+ # set this to true to avoid testing with multiple threads
22
+ # or to test with multiple threads set it to false
23
+ # this is important since, some code paths will change depending
24
+ # on the presence of multiple threads
25
+ TEST_SINGLE_THREADED=false
26
+
27
+ # keep webrick quiet
28
+ class ::WEBrick::HTTPServer
29
+ def access_log(config, req, res)
30
+ # nop
31
+ end
32
+ end
33
+ class ::WEBrick::BasicLog
34
+ def log(level, data)
35
+ # nop
36
+ end
37
+ end
38
+
39
+ #
40
+ # Simple test server to record number of times a request is sent/recieved of a specific
41
+ # request type, e.g. GET,POST,PUT,DELETE
42
+ #
43
+ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
44
+
45
+ def self.port=(p)
46
+ @port = p
47
+ end
48
+
49
+ def self.port
50
+ (@port or 9129)
51
+ end
52
+
53
+ def self.path
54
+ '/methods'
55
+ end
56
+
57
+ def self.url
58
+ "http://127.0.0.1:#{port}#{path}"
59
+ end
60
+
61
+ def respond_with(method,req,res)
62
+ res.body = method.to_s
63
+ $auth_header = req['Authorization']
64
+ res['Content-Type'] = "text/plain"
65
+ end
66
+
67
+ def do_GET(req,res)
68
+ respond_with(:GET,req,res)
69
+ end
70
+
71
+ def do_HEAD(req,res)
72
+ res['Location'] = "/nonexistent"
73
+ respond_with(:HEAD, req, res)
74
+ end
75
+
76
+ def do_POST(req,res)
77
+ if req.query['filename'].nil?
78
+ if req.body
79
+ params = {}
80
+ req.body.split('&').map{|s| k,v=s.split('='); params[k] = v }
81
+ end
82
+ if params and params['s'] == '500'
83
+ res.status = 500
84
+ else
85
+ respond_with("POST\n#{req.body}",req,res)
86
+ end
87
+ else
88
+ respond_with(req.query['filename'],req,res)
89
+ end
90
+ end
91
+
92
+ def do_PUT(req,res)
93
+ res['X-Requested-Content-Type'] = req.content_type
94
+ respond_with("PUT\n#{req.body}",req,res)
95
+ end
96
+
97
+ def do_DELETE(req,res)
98
+ respond_with(:DELETE,req,res)
99
+ end
100
+
101
+ def do_PURGE(req,res)
102
+ respond_with(:PURGE,req,res)
103
+ end
104
+
105
+ def do_COPY(req,res)
106
+ respond_with(:COPY,req,res)
107
+ end
108
+
109
+ end
110
+
111
+ module TestServerMethods
112
+ def locked_file
113
+ File.join(File.dirname(__FILE__),"server_lock-#{@__port}")
114
+ end
115
+
116
+ def server_setup(port=9129,servlet=TestServlet)
117
+ @__port = port
118
+ if @server.nil? and !File.exist?(locked_file)
119
+
120
+ File.open(locked_file,'w') {|f| f << 'locked' }
121
+ if TEST_SINGLE_THREADED
122
+ rd, wr = IO.pipe
123
+ @__pid = fork do
124
+ rd.close
125
+ rd = nil
126
+
127
+ # start up a webrick server for testing delete
128
+ server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
129
+
130
+ server.mount(servlet.path, servlet)
131
+ server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
132
+
133
+ trap("INT") { server.shutdown }
134
+ GC.start
135
+ wr.flush
136
+ wr.close
137
+ server.start
138
+ end
139
+ wr.close
140
+ rd.read
141
+ rd.close
142
+ else
143
+ # start up a webrick server for testing delete
144
+ @server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
145
+
146
+ @server.mount(servlet.path, servlet)
147
+ @server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
148
+ queue = Queue.new # synchronize the thread startup to the main thread
149
+
150
+ @test_thread = Thread.new { queue << 1; @server.start }
151
+
152
+ # wait for the queue
153
+ value = queue.pop
154
+ if !value
155
+ STDERR.puts "Failed to startup test server!"
156
+ exit(1)
157
+ end
158
+
159
+ end
160
+
161
+ exit_code = lambda do
162
+ begin
163
+ if File.exist?(locked_file)
164
+ File.unlink locked_file
165
+ if TEST_SINGLE_THREADED
166
+ Process.kill 'INT', @__pid
167
+ else
168
+ @server.shutdown unless @server.nil?
169
+ end
170
+ end
171
+ #@server.shutdown unless @server.nil?
172
+ rescue Object => e
173
+ puts "Error #{__FILE__}:#{__LINE__}\n#{e.message}"
174
+ end
175
+ end
176
+
177
+ trap("INT"){exit_code.call}
178
+ at_exit{exit_code.call}
179
+
180
+ end
181
+ rescue Errno::EADDRINUSE
182
+ end
183
+ end
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ #require 'rubygems'
3
+ #require 'rmem'
4
+
5
+ #
6
+ # Run some tests to measure the memory usage of curb, these tests require fork and ps
7
+ #
8
+ class TestCurbMemory < Test::Unit::TestCase
9
+
10
+ def test_easy_memory
11
+ easy_avg, easy_std = measure_object_memory(Curl::Easy)
12
+ printf "Easy average: %.2f kilobytes +/- %.2f kilobytes\n", easy_avg.to_f, easy_std.to_f
13
+
14
+ multi_avg, multi_std = measure_object_memory(Curl::Multi)
15
+ printf "Multi average: %.2f kilobytes +/- %.2f kilobytes\n", multi_avg.to_f, multi_std.to_f
16
+
17
+ # now that we have the average size of an easy handle lets see how much a multi request consumes with 10 requests
18
+ end
19
+
20
+ def c_avg(report)
21
+ sum = 0
22
+ report.each {|r| sum += r.last }
23
+ (sum.to_f / report.size)
24
+ end
25
+
26
+ def c_std(report,avg)
27
+ var = 0
28
+ report.each {|r| var += (r.last-avg)*(r.last-avg) }
29
+ Math.sqrt(var / (report.size-1))
30
+ end
31
+
32
+ def measure_object_memory(klass)
33
+ report = []
34
+ 200.times do
35
+ res = mem_check do
36
+ obj = klass.new
37
+ end
38
+ report << res
39
+ end
40
+ avg = c_avg(report)
41
+ std = c_std(report,avg)
42
+ [avg,std]
43
+ end
44
+
45
+ def mem_check
46
+ # see: http://gist.github.com/264060 for inspiration of ps command line
47
+ rd, wr = IO.pipe
48
+ memory_usage = `ps -o rss= -p #{Process.pid}`.to_i # in kilobytes
49
+ fork do
50
+ before = `ps -o rss= -p #{Process.pid}`.to_i # in kilobytes
51
+ rd.close
52
+ yield
53
+ after = `ps -o rss= -p #{Process.pid}`.to_i # in kilobytes
54
+ wr.write((after - before))
55
+ wr.flush
56
+ wr.close
57
+ end
58
+ wr.close
59
+ total = rd.read.to_i
60
+ rd.close
61
+ Process.wait
62
+ # return the delta and the total
63
+ [memory_usage, total]
64
+ end
65
+ end
@@ -21,8 +21,8 @@
21
21
  # Aborted
22
22
  # ------------------------------------------------------------------
23
23
  #
24
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'ext'))
25
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
24
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'ext')))
25
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
26
26
  require 'curb'
27
27
  require 'uri'
28
28
 
@@ -0,0 +1,75 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class TestCurbCurlDownload < Test::Unit::TestCase
4
+ include TestServerMethods
5
+
6
+ def setup
7
+ server_setup
8
+ end
9
+
10
+ def test_download_url_to_file_via_string
11
+ dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
12
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
13
+
14
+ curb = Curl::Easy.download(dl_url, dl_path)
15
+ assert File.exist?(dl_path)
16
+ assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
17
+ ensure
18
+ File.unlink(dl_path) if File.exist?(dl_path)
19
+ end
20
+
21
+ def test_download_url_to_file_via_file_io
22
+ dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
23
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
24
+ io = File.open(dl_path, 'wb')
25
+
26
+ curb = Curl::Easy.download(dl_url, io)
27
+ assert io.closed?
28
+ assert File.exist?(dl_path)
29
+ assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
30
+ ensure
31
+ File.unlink(dl_path) if File.exist?(dl_path)
32
+ end
33
+
34
+ def test_download_url_to_file_via_io
35
+ dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
36
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
37
+ reader, writer = IO.pipe
38
+
39
+ # Write to local file
40
+ fork do
41
+ begin
42
+ writer.close
43
+ File.open(dl_path, 'wb') { |file| file << reader.read }
44
+ ensure
45
+ reader.close rescue IOError # if the stream has already been closed
46
+ end
47
+ end
48
+
49
+ # Download remote source
50
+ begin
51
+ reader.close
52
+ curb = Curl::Easy.download(dl_url, writer)
53
+ Process.wait
54
+ ensure
55
+ writer.close rescue IOError # if the stream has already been closed, which occurs in Easy::download
56
+ end
57
+
58
+ assert File.exist?(dl_path)
59
+ assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
60
+ ensure
61
+ File.unlink(dl_path) if File.exist?(dl_path)
62
+ end
63
+
64
+ def test_download_bad_url_gives_404
65
+ dl_url = "http://127.0.0.1:9129/this_file_does_not_exist.html"
66
+ dl_path = File.join(Dir::tmpdir, "dl_url_test.file")
67
+
68
+ curb = Curl::Easy.download(dl_url, dl_path)
69
+ assert_equal Curl::Easy, curb.class
70
+ assert_equal 404, curb.response_code
71
+ ensure
72
+ File.unlink(dl_path) if File.exist?(dl_path)
73
+ end
74
+
75
+ end