libgems 0.0.1

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.
Files changed (177) hide show
  1. data/ChangeLog +5811 -0
  2. data/History.txt +887 -0
  3. data/LICENSE.txt +51 -0
  4. data/README.md +87 -0
  5. data/Rakefile +113 -0
  6. data/lib/gauntlet_libgems.rb +50 -0
  7. data/lib/libgems.rb +1246 -0
  8. data/lib/libgems/builder.rb +102 -0
  9. data/lib/libgems/command.rb +534 -0
  10. data/lib/libgems/command_manager.rb +182 -0
  11. data/lib/libgems/commands/build_command.rb +53 -0
  12. data/lib/libgems/commands/cert_command.rb +86 -0
  13. data/lib/libgems/commands/check_command.rb +80 -0
  14. data/lib/libgems/commands/cleanup_command.rb +106 -0
  15. data/lib/libgems/commands/contents_command.rb +98 -0
  16. data/lib/libgems/commands/dependency_command.rb +195 -0
  17. data/lib/libgems/commands/environment_command.rb +133 -0
  18. data/lib/libgems/commands/fetch_command.rb +67 -0
  19. data/lib/libgems/commands/generate_index_command.rb +133 -0
  20. data/lib/libgems/commands/help_command.rb +172 -0
  21. data/lib/libgems/commands/install_command.rb +178 -0
  22. data/lib/libgems/commands/list_command.rb +35 -0
  23. data/lib/libgems/commands/lock_command.rb +110 -0
  24. data/lib/libgems/commands/mirror_command.rb +111 -0
  25. data/lib/libgems/commands/outdated_command.rb +33 -0
  26. data/lib/libgems/commands/owner_command.rb +75 -0
  27. data/lib/libgems/commands/pristine_command.rb +93 -0
  28. data/lib/libgems/commands/push_command.rb +56 -0
  29. data/lib/libgems/commands/query_command.rb +280 -0
  30. data/lib/libgems/commands/rdoc_command.rb +91 -0
  31. data/lib/libgems/commands/search_command.rb +31 -0
  32. data/lib/libgems/commands/server_command.rb +86 -0
  33. data/lib/libgems/commands/sources_command.rb +157 -0
  34. data/lib/libgems/commands/specification_command.rb +125 -0
  35. data/lib/libgems/commands/stale_command.rb +27 -0
  36. data/lib/libgems/commands/uninstall_command.rb +83 -0
  37. data/lib/libgems/commands/unpack_command.rb +121 -0
  38. data/lib/libgems/commands/update_command.rb +160 -0
  39. data/lib/libgems/commands/which_command.rb +86 -0
  40. data/lib/libgems/config_file.rb +345 -0
  41. data/lib/libgems/custom_require.rb +44 -0
  42. data/lib/libgems/defaults.rb +101 -0
  43. data/lib/libgems/dependency.rb +227 -0
  44. data/lib/libgems/dependency_installer.rb +286 -0
  45. data/lib/libgems/dependency_list.rb +208 -0
  46. data/lib/libgems/doc_manager.rb +242 -0
  47. data/lib/libgems/errors.rb +35 -0
  48. data/lib/libgems/exceptions.rb +91 -0
  49. data/lib/libgems/ext.rb +18 -0
  50. data/lib/libgems/ext/builder.rb +56 -0
  51. data/lib/libgems/ext/configure_builder.rb +25 -0
  52. data/lib/libgems/ext/ext_conf_builder.rb +24 -0
  53. data/lib/libgems/ext/rake_builder.rb +39 -0
  54. data/lib/libgems/format.rb +81 -0
  55. data/lib/libgems/gem_openssl.rb +92 -0
  56. data/lib/libgems/gem_path_searcher.rb +100 -0
  57. data/lib/libgems/gem_runner.rb +79 -0
  58. data/lib/libgems/gemcutter_utilities.rb +49 -0
  59. data/lib/libgems/indexer.rb +720 -0
  60. data/lib/libgems/install_update_options.rb +125 -0
  61. data/lib/libgems/installer.rb +604 -0
  62. data/lib/libgems/local_remote_options.rb +135 -0
  63. data/lib/libgems/old_format.rb +153 -0
  64. data/lib/libgems/package.rb +97 -0
  65. data/lib/libgems/package/f_sync_dir.rb +23 -0
  66. data/lib/libgems/package/tar_header.rb +266 -0
  67. data/lib/libgems/package/tar_input.rb +222 -0
  68. data/lib/libgems/package/tar_output.rb +144 -0
  69. data/lib/libgems/package/tar_reader.rb +106 -0
  70. data/lib/libgems/package/tar_reader/entry.rb +141 -0
  71. data/lib/libgems/package/tar_writer.rb +241 -0
  72. data/lib/libgems/package_task.rb +126 -0
  73. data/lib/libgems/platform.rb +183 -0
  74. data/lib/libgems/remote_fetcher.rb +414 -0
  75. data/lib/libgems/require_paths_builder.rb +18 -0
  76. data/lib/libgems/requirement.rb +153 -0
  77. data/lib/libgems/security.rb +814 -0
  78. data/lib/libgems/server.rb +872 -0
  79. data/lib/libgems/source_index.rb +597 -0
  80. data/lib/libgems/source_info_cache.rb +395 -0
  81. data/lib/libgems/source_info_cache_entry.rb +56 -0
  82. data/lib/libgems/spec_fetcher.rb +337 -0
  83. data/lib/libgems/specification.rb +1487 -0
  84. data/lib/libgems/test_utilities.rb +147 -0
  85. data/lib/libgems/text.rb +65 -0
  86. data/lib/libgems/uninstaller.rb +278 -0
  87. data/lib/libgems/user_interaction.rb +527 -0
  88. data/lib/libgems/validator.rb +240 -0
  89. data/lib/libgems/version.rb +316 -0
  90. data/lib/libgems/version_option.rb +65 -0
  91. data/lib/rbconfig/datadir.rb +20 -0
  92. data/test/bogussources.rb +8 -0
  93. data/test/data/gem-private_key.pem +27 -0
  94. data/test/data/gem-public_cert.pem +20 -0
  95. data/test/fake_certlib/openssl.rb +7 -0
  96. data/test/foo/discover.rb +0 -0
  97. data/test/gem_installer_test_case.rb +97 -0
  98. data/test/gem_package_tar_test_case.rb +132 -0
  99. data/test/gemutilities.rb +605 -0
  100. data/test/insure_session.rb +43 -0
  101. data/test/mockgemui.rb +56 -0
  102. data/test/plugin/exception/libgems_plugin.rb +2 -0
  103. data/test/plugin/load/libgems_plugin.rb +1 -0
  104. data/test/plugin/standarderror/libgems_plugin.rb +2 -0
  105. data/test/private_key.pem +27 -0
  106. data/test/public_cert.pem +20 -0
  107. data/test/rubygems_plugin.rb +21 -0
  108. data/test/simple_gem.rb +66 -0
  109. data/test/test_config.rb +12 -0
  110. data/test/test_gem.rb +780 -0
  111. data/test/test_gem_builder.rb +27 -0
  112. data/test/test_gem_command.rb +178 -0
  113. data/test/test_gem_command_manager.rb +207 -0
  114. data/test/test_gem_commands_build_command.rb +74 -0
  115. data/test/test_gem_commands_cert_command.rb +124 -0
  116. data/test/test_gem_commands_check_command.rb +18 -0
  117. data/test/test_gem_commands_contents_command.rb +156 -0
  118. data/test/test_gem_commands_dependency_command.rb +216 -0
  119. data/test/test_gem_commands_environment_command.rb +144 -0
  120. data/test/test_gem_commands_fetch_command.rb +76 -0
  121. data/test/test_gem_commands_generate_index_command.rb +135 -0
  122. data/test/test_gem_commands_install_command.rb +315 -0
  123. data/test/test_gem_commands_list_command.rb +36 -0
  124. data/test/test_gem_commands_lock_command.rb +68 -0
  125. data/test/test_gem_commands_mirror_command.rb +60 -0
  126. data/test/test_gem_commands_outdated_command.rb +40 -0
  127. data/test/test_gem_commands_owner_command.rb +105 -0
  128. data/test/test_gem_commands_pristine_command.rb +108 -0
  129. data/test/test_gem_commands_push_command.rb +81 -0
  130. data/test/test_gem_commands_query_command.rb +426 -0
  131. data/test/test_gem_commands_server_command.rb +59 -0
  132. data/test/test_gem_commands_sources_command.rb +209 -0
  133. data/test/test_gem_commands_specification_command.rb +139 -0
  134. data/test/test_gem_commands_stale_command.rb +38 -0
  135. data/test/test_gem_commands_uninstall_command.rb +83 -0
  136. data/test/test_gem_commands_unpack_command.rb +199 -0
  137. data/test/test_gem_commands_update_command.rb +207 -0
  138. data/test/test_gem_commands_which_command.rb +66 -0
  139. data/test/test_gem_config_file.rb +287 -0
  140. data/test/test_gem_dependency.rb +149 -0
  141. data/test/test_gem_dependency_installer.rb +661 -0
  142. data/test/test_gem_dependency_list.rb +230 -0
  143. data/test/test_gem_doc_manager.rb +31 -0
  144. data/test/test_gem_ext_configure_builder.rb +84 -0
  145. data/test/test_gem_ext_ext_conf_builder.rb +173 -0
  146. data/test/test_gem_ext_rake_builder.rb +81 -0
  147. data/test/test_gem_format.rb +70 -0
  148. data/test/test_gem_gem_path_searcher.rb +78 -0
  149. data/test/test_gem_gem_runner.rb +45 -0
  150. data/test/test_gem_gemcutter_utilities.rb +103 -0
  151. data/test/test_gem_indexer.rb +673 -0
  152. data/test/test_gem_install_update_options.rb +68 -0
  153. data/test/test_gem_installer.rb +857 -0
  154. data/test/test_gem_local_remote_options.rb +97 -0
  155. data/test/test_gem_package_tar_header.rb +130 -0
  156. data/test/test_gem_package_tar_input.rb +112 -0
  157. data/test/test_gem_package_tar_output.rb +97 -0
  158. data/test/test_gem_package_tar_reader.rb +46 -0
  159. data/test/test_gem_package_tar_reader_entry.rb +109 -0
  160. data/test/test_gem_package_tar_writer.rb +144 -0
  161. data/test/test_gem_package_task.rb +59 -0
  162. data/test/test_gem_platform.rb +264 -0
  163. data/test/test_gem_remote_fetcher.rb +740 -0
  164. data/test/test_gem_requirement.rb +292 -0
  165. data/test/test_gem_server.rb +356 -0
  166. data/test/test_gem_silent_ui.rb +113 -0
  167. data/test/test_gem_source_index.rb +461 -0
  168. data/test/test_gem_spec_fetcher.rb +410 -0
  169. data/test/test_gem_specification.rb +1334 -0
  170. data/test/test_gem_stream_ui.rb +218 -0
  171. data/test/test_gem_text.rb +43 -0
  172. data/test/test_gem_uninstaller.rb +146 -0
  173. data/test/test_gem_validator.rb +63 -0
  174. data/test/test_gem_version.rb +181 -0
  175. data/test/test_gem_version_option.rb +89 -0
  176. data/test/test_kernel.rb +59 -0
  177. metadata +402 -0
@@ -0,0 +1,740 @@
1
+ require File.expand_path('../gemutilities', __FILE__)
2
+ require 'ostruct'
3
+ require 'webrick'
4
+ require 'libgems/remote_fetcher'
5
+ require 'libgems/format'
6
+
7
+ # = Testing Proxy Settings
8
+ #
9
+ # These tests check the proper proxy server settings by running two
10
+ # web servers. The web server at http://localhost:#{SERVER_PORT}
11
+ # represents the normal gem server and returns a gemspec with a rake
12
+ # version of 0.4.11. The web server at http://localhost:#{PROXY_PORT}
13
+ # represents the proxy server and returns a different dataset where
14
+ # rake has version 0.4.2. This allows us to detect which server is
15
+ # returning the data.
16
+ #
17
+ # Note that the proxy server is not a *real* proxy server. But our
18
+ # software doesn't really care, as long as we hit the proxy URL when a
19
+ # proxy is configured.
20
+
21
+ class TestGemRemoteFetcher < RubyGemTestCase
22
+
23
+ include LibGems::DefaultUserInteraction
24
+
25
+ SERVER_DATA = <<-EOY
26
+ --- !ruby/object:LibGems::Cache
27
+ gems:
28
+ rake-0.4.11: !ruby/object:LibGems::Specification
29
+ rubygems_version: "0.7"
30
+ specification_version: 1
31
+ name: rake
32
+ version: !ruby/object:LibGems::Version
33
+ version: 0.4.11
34
+ date: 2004-11-12
35
+ summary: Ruby based make-like utility.
36
+ require_paths:
37
+ - lib
38
+ author: Jim Weirich
39
+ email: jim@weirichhouse.org
40
+ homepage: http://rake.rubyforge.org
41
+ rubyforge_project: rake
42
+ description: Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax.
43
+ autorequire:
44
+ default_executable: rake
45
+ bindir: bin
46
+ has_rdoc: true
47
+ required_ruby_version: !ruby/object:LibGems::Version::Requirement
48
+ requirements:
49
+ -
50
+ - ">"
51
+ - !ruby/object:LibGems::Version
52
+ version: 0.0.0
53
+ version:
54
+ platform: ruby
55
+ files:
56
+ - README
57
+ test_files: []
58
+ library_stubs:
59
+ rdoc_options:
60
+ extra_rdoc_files:
61
+ executables:
62
+ - rake
63
+ extensions: []
64
+ requirements: []
65
+ dependencies: []
66
+ EOY
67
+
68
+ PROXY_DATA = SERVER_DATA.gsub(/0.4.11/, '0.4.2')
69
+
70
+ # don't let 1.8 and 1.9 autotest collide
71
+ RUBY_VERSION =~ /(\d+)\.(\d+)\.(\d+)/
72
+ # don't let parallel runners collide
73
+ PROXY_PORT = process_based_port + 100 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
74
+ SERVER_PORT = process_based_port + 200 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
75
+
76
+ def setup
77
+ super
78
+ self.class.start_servers
79
+ self.class.enable_yaml = true
80
+ self.class.enable_zip = false
81
+ ENV.delete 'http_proxy'
82
+ ENV.delete 'HTTP_PROXY'
83
+ ENV.delete 'http_proxy_user'
84
+ ENV.delete 'HTTP_PROXY_USER'
85
+ ENV.delete 'http_proxy_pass'
86
+ ENV.delete 'HTTP_PROXY_PASS'
87
+
88
+ base_server_uri = "http://localhost:#{SERVER_PORT}"
89
+ @proxy_uri = "http://localhost:#{PROXY_PORT}"
90
+
91
+ @server_uri = base_server_uri + "/yaml"
92
+ @server_z_uri = base_server_uri + "/yaml.Z"
93
+
94
+ # REFACTOR: copied from test_gem_dependency_installer.rb
95
+ @gems_dir = File.join @tempdir, 'gems'
96
+ @cache_dir = File.join @gemhome, 'cache'
97
+ FileUtils.mkdir @gems_dir
98
+
99
+ @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
100
+
101
+ LibGems::RemoteFetcher.fetcher = nil
102
+
103
+ @fetcher = LibGems::RemoteFetcher.fetcher
104
+ end
105
+
106
+ def teardown
107
+ super
108
+ LibGems.configuration[:http_proxy] = nil
109
+ end
110
+
111
+ def test_self_fetcher
112
+ fetcher = LibGems::RemoteFetcher.fetcher
113
+ refute_nil fetcher
114
+ assert_kind_of LibGems::RemoteFetcher, fetcher
115
+ end
116
+
117
+ def test_self_fetcher_with_proxy
118
+ proxy_uri = 'http://proxy.example.com'
119
+ LibGems.configuration[:http_proxy] = proxy_uri
120
+ LibGems::RemoteFetcher.fetcher = nil
121
+
122
+ fetcher = LibGems::RemoteFetcher.fetcher
123
+
124
+ refute_nil fetcher
125
+ assert_kind_of LibGems::RemoteFetcher, fetcher
126
+ assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy_uri).to_s
127
+ end
128
+
129
+ def test_self_fetcher_with_proxy_URI
130
+ proxy_uri = URI.parse 'http://proxy.example.com'
131
+ LibGems.configuration[:http_proxy] = proxy_uri
132
+ LibGems::RemoteFetcher.fetcher = nil
133
+
134
+ fetcher = LibGems::RemoteFetcher.fetcher
135
+ refute_nil fetcher
136
+
137
+ assert_kind_of LibGems::RemoteFetcher, fetcher
138
+ assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy_uri)
139
+ end
140
+
141
+ def test_fetch_size_bad_uri
142
+ fetcher = LibGems::RemoteFetcher.new nil
143
+
144
+ e = assert_raises ArgumentError do
145
+ fetcher.fetch_size 'gems.example.com/yaml'
146
+ end
147
+
148
+ assert_equal 'uri scheme is invalid', e.message
149
+ end
150
+
151
+ def test_fetch_size_socket_error
152
+ fetcher = LibGems::RemoteFetcher.new nil
153
+ def fetcher.connection_for(uri)
154
+ raise SocketError, "tarded"
155
+ end
156
+
157
+ uri = 'http://gems.example.com/yaml'
158
+ e = assert_raises LibGems::RemoteFetcher::FetchError do
159
+ fetcher.fetch_size uri
160
+ end
161
+
162
+ assert_equal "SocketError: tarded (#{uri})", e.message
163
+ end
164
+
165
+ def test_no_proxy
166
+ use_ui @ui do
167
+ assert_data_from_server @fetcher.fetch_path(@server_uri)
168
+ assert_equal SERVER_DATA.size, @fetcher.fetch_size(@server_uri)
169
+ end
170
+ end
171
+
172
+ def util_fuck_with_fetcher data, blow = false
173
+ fetcher = LibGems::RemoteFetcher.fetcher
174
+ fetcher.instance_variable_set :@test_data, data
175
+
176
+ unless blow then
177
+ def fetcher.fetch_path arg
178
+ @test_arg = arg
179
+ @test_data
180
+ end
181
+ else
182
+ def fetcher.fetch_path arg
183
+ # OMG I'm such an ass
184
+ class << self; remove_method :fetch_path; end
185
+ def self.fetch_path arg
186
+ @test_arg = arg
187
+ @test_data
188
+ end
189
+
190
+ raise LibGems::RemoteFetcher::FetchError.new("haha!", nil)
191
+ end
192
+ end
193
+
194
+ fetcher
195
+ end
196
+
197
+ def test_download
198
+ a1_data = nil
199
+ File.open @a1_gem, 'rb' do |fp|
200
+ a1_data = fp.read
201
+ end
202
+
203
+ fetcher = util_fuck_with_fetcher a1_data
204
+
205
+ a1_cache_gem = File.join(@gemhome, 'cache', @a1.file_name)
206
+ assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com')
207
+ assert_equal("http://gems.example.com/gems/a-1.gem",
208
+ fetcher.instance_variable_get(:@test_arg).to_s)
209
+ assert File.exist?(a1_cache_gem)
210
+ end
211
+
212
+ def test_download_cached
213
+ FileUtils.mv @a1_gem, @cache_dir
214
+
215
+ inst = LibGems::RemoteFetcher.fetcher
216
+
217
+ assert_equal File.join(@gemhome, 'cache', @a1.file_name),
218
+ inst.download(@a1, 'http://gems.example.com')
219
+ end
220
+
221
+ def test_download_local
222
+ FileUtils.mv @a1_gem, @tempdir
223
+ local_path = File.join @tempdir, @a1.file_name
224
+ inst = nil
225
+
226
+ Dir.chdir @tempdir do
227
+ inst = LibGems::RemoteFetcher.fetcher
228
+ end
229
+
230
+ assert_equal File.join(@gemhome, 'cache', @a1.file_name),
231
+ inst.download(@a1, local_path)
232
+ end
233
+
234
+ def test_download_local_space
235
+ space_path = File.join @tempdir, 'space path'
236
+ FileUtils.mkdir space_path
237
+ FileUtils.mv @a1_gem, space_path
238
+ local_path = File.join space_path, @a1.file_name
239
+ inst = nil
240
+
241
+ Dir.chdir @tempdir do
242
+ inst = LibGems::RemoteFetcher.fetcher
243
+ end
244
+
245
+ assert_equal File.join(@gemhome, 'cache', @a1.file_name),
246
+ inst.download(@a1, local_path)
247
+ end
248
+
249
+ def test_download_install_dir
250
+ a1_data = nil
251
+ File.open @a1_gem, 'rb' do |fp|
252
+ a1_data = fp.read
253
+ end
254
+
255
+ fetcher = util_fuck_with_fetcher a1_data
256
+
257
+ install_dir = File.join @tempdir, 'more_gems'
258
+
259
+ a1_cache_gem = File.join install_dir, 'cache', @a1.file_name
260
+ FileUtils.mkdir_p(File.dirname(a1_cache_gem))
261
+ actual = fetcher.download(@a1, 'http://gems.example.com', install_dir)
262
+
263
+ assert_equal a1_cache_gem, actual
264
+ assert_equal("http://gems.example.com/gems/a-1.gem",
265
+ fetcher.instance_variable_get(:@test_arg).to_s)
266
+
267
+ assert File.exist?(a1_cache_gem)
268
+ end
269
+
270
+ unless win_platform? # File.chmod doesn't work
271
+ def test_download_local_read_only
272
+ FileUtils.mv @a1_gem, @tempdir
273
+ local_path = File.join @tempdir, @a1.file_name
274
+ inst = nil
275
+ File.chmod 0555, File.join(@gemhome, 'cache')
276
+
277
+ Dir.chdir @tempdir do
278
+ inst = LibGems::RemoteFetcher.fetcher
279
+ end
280
+
281
+ assert_equal File.join(@tempdir, @a1.file_name),
282
+ inst.download(@a1, local_path)
283
+ ensure
284
+ File.chmod 0755, File.join(@gemhome, 'cache')
285
+ end
286
+
287
+ def test_download_read_only
288
+ File.chmod 0555, File.join(@gemhome, 'cache')
289
+ File.chmod 0555, File.join(@gemhome)
290
+
291
+ fetcher = util_fuck_with_fetcher File.read(@a1_gem)
292
+ fetcher.download(@a1, 'http://gems.example.com')
293
+ assert File.exist?(File.join(LibGems.user_dir, 'cache', @a1.file_name))
294
+ ensure
295
+ File.chmod 0755, File.join(@gemhome)
296
+ File.chmod 0755, File.join(@gemhome, 'cache')
297
+ end
298
+ end
299
+
300
+ def test_download_platform_legacy
301
+ original_platform = 'old-platform'
302
+
303
+ e1, e1_gem = util_gem 'e', '1' do |s|
304
+ s.platform = LibGems::Platform::CURRENT
305
+ s.instance_variable_set :@original_platform, original_platform
306
+ end
307
+
308
+ e1_data = nil
309
+ File.open e1_gem, 'rb' do |fp|
310
+ e1_data = fp.read
311
+ end
312
+
313
+ fetcher = util_fuck_with_fetcher e1_data, :blow_chunks
314
+
315
+ e1_cache_gem = File.join(@gemhome, 'cache', e1.file_name)
316
+
317
+ assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com')
318
+
319
+ assert_equal("http://gems.example.com/gems/#{e1.original_name}.gem",
320
+ fetcher.instance_variable_get(:@test_arg).to_s)
321
+ assert File.exist?(e1_cache_gem)
322
+ end
323
+
324
+ def test_download_same_file
325
+ FileUtils.mv @a1_gem, @tempdir
326
+ local_path = File.join @tempdir, @a1.file_name
327
+ inst = nil
328
+
329
+ Dir.chdir @tempdir do
330
+ inst = LibGems::RemoteFetcher.fetcher
331
+ end
332
+
333
+ cache_path = File.join @gemhome, 'cache', @a1.file_name
334
+ FileUtils.mv local_path, cache_path
335
+
336
+ gem = LibGems::Format.from_file_by_path cache_path
337
+
338
+ assert_equal cache_path, inst.download(gem.spec, cache_path)
339
+ end
340
+
341
+ def test_download_unsupported
342
+ inst = LibGems::RemoteFetcher.fetcher
343
+
344
+ e = assert_raises LibGems::InstallError do
345
+ inst.download @a1, 'ftp://gems.rubyforge.org'
346
+ end
347
+
348
+ assert_equal 'unsupported URI scheme ftp', e.message
349
+ end
350
+
351
+ def test_explicit_proxy
352
+ use_ui @ui do
353
+ fetcher = LibGems::RemoteFetcher.new @proxy_uri
354
+ assert_equal PROXY_DATA.size, fetcher.fetch_size(@server_uri)
355
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
356
+ end
357
+ end
358
+
359
+ def test_explicit_proxy_with_user_auth
360
+ use_ui @ui do
361
+ uri = URI.parse @proxy_uri
362
+ uri.user, uri.password = 'foo', 'bar'
363
+ fetcher = LibGems::RemoteFetcher.new uri.to_s
364
+ proxy = fetcher.instance_variable_get("@proxy_uri")
365
+ assert_equal 'foo', proxy.user
366
+ assert_equal 'bar', proxy.password
367
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
368
+ end
369
+
370
+ use_ui @ui do
371
+ uri = URI.parse @proxy_uri
372
+ uri.user, uri.password = 'domain%5Cuser', 'bar'
373
+ fetcher = LibGems::RemoteFetcher.new uri.to_s
374
+ proxy = fetcher.instance_variable_get("@proxy_uri")
375
+ assert_equal 'domain\user', URI.unescape(proxy.user)
376
+ assert_equal 'bar', proxy.password
377
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
378
+ end
379
+
380
+ use_ui @ui do
381
+ uri = URI.parse @proxy_uri
382
+ uri.user, uri.password = 'user', 'my%20pass'
383
+ fetcher = LibGems::RemoteFetcher.new uri.to_s
384
+ proxy = fetcher.instance_variable_get("@proxy_uri")
385
+ assert_equal 'user', proxy.user
386
+ assert_equal 'my pass', URI.unescape(proxy.password)
387
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
388
+ end
389
+ end
390
+
391
+ def test_explicit_proxy_with_user_auth_in_env
392
+ use_ui @ui do
393
+ ENV['http_proxy'] = @proxy_uri
394
+ ENV['http_proxy_user'] = 'foo'
395
+ ENV['http_proxy_pass'] = 'bar'
396
+ fetcher = LibGems::RemoteFetcher.new nil
397
+ proxy = fetcher.instance_variable_get("@proxy_uri")
398
+ assert_equal 'foo', proxy.user
399
+ assert_equal 'bar', proxy.password
400
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
401
+ end
402
+
403
+ use_ui @ui do
404
+ ENV['http_proxy'] = @proxy_uri
405
+ ENV['http_proxy_user'] = 'foo\user'
406
+ ENV['http_proxy_pass'] = 'my bar'
407
+ fetcher = LibGems::RemoteFetcher.new nil
408
+ proxy = fetcher.instance_variable_get("@proxy_uri")
409
+ assert_equal 'foo\user', URI.unescape(proxy.user)
410
+ assert_equal 'my bar', URI.unescape(proxy.password)
411
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
412
+ end
413
+ end
414
+
415
+ def test_fetch_path_gzip
416
+ fetcher = LibGems::RemoteFetcher.new nil
417
+
418
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
419
+ LibGems.gzip 'foo'
420
+ end
421
+
422
+ assert_equal 'foo', fetcher.fetch_path(@uri + 'foo.gz')
423
+ end
424
+
425
+ def test_fetch_path_gzip_unmodified
426
+ fetcher = LibGems::RemoteFetcher.new nil
427
+
428
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
429
+ nil
430
+ end
431
+
432
+ assert_equal nil, fetcher.fetch_path(@uri + 'foo.gz', Time.at(0))
433
+ end
434
+
435
+ def test_fetch_path_io_error
436
+ fetcher = LibGems::RemoteFetcher.new nil
437
+
438
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
439
+ raise EOFError
440
+ end
441
+
442
+ e = assert_raises LibGems::RemoteFetcher::FetchError do
443
+ fetcher.fetch_path 'uri'
444
+ end
445
+
446
+ assert_equal 'EOFError: EOFError (uri)', e.message
447
+ assert_equal 'uri', e.uri
448
+ end
449
+
450
+ def test_fetch_path_socket_error
451
+ fetcher = LibGems::RemoteFetcher.new nil
452
+
453
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
454
+ raise SocketError
455
+ end
456
+
457
+ e = assert_raises LibGems::RemoteFetcher::FetchError do
458
+ fetcher.fetch_path 'uri'
459
+ end
460
+
461
+ assert_equal 'SocketError: SocketError (uri)', e.message
462
+ assert_equal 'uri', e.uri
463
+ end
464
+
465
+ def test_fetch_path_system_call_error
466
+ fetcher = LibGems::RemoteFetcher.new nil
467
+
468
+ def fetcher.open_uri_or_path(uri, mtime = nil, head = nil)
469
+ raise Errno::ECONNREFUSED, 'connect(2)'
470
+ end
471
+
472
+ e = assert_raises LibGems::RemoteFetcher::FetchError do
473
+ fetcher.fetch_path 'uri'
474
+ end
475
+
476
+ assert_match %r|ECONNREFUSED:.*connect\(2\) \(uri\)\z|,
477
+ e.message
478
+ assert_equal 'uri', e.uri
479
+ end
480
+
481
+ def test_fetch_path_unmodified
482
+ fetcher = LibGems::RemoteFetcher.new nil
483
+
484
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
485
+ nil
486
+ end
487
+
488
+ assert_equal nil, fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
489
+ end
490
+
491
+ def test_get_proxy_from_env_auto_normalizes
492
+ fetcher = LibGems::RemoteFetcher.new(nil)
493
+ ENV['HTTP_PROXY'] = 'fakeurl:12345'
494
+
495
+ assert_equal('http://fakeurl:12345', fetcher.get_proxy_from_env.to_s)
496
+ end
497
+
498
+ def test_get_proxy_from_env_empty
499
+ orig_env_HTTP_PROXY = ENV['HTTP_PROXY']
500
+ orig_env_http_proxy = ENV['http_proxy']
501
+
502
+ ENV['HTTP_PROXY'] = ''
503
+ ENV.delete 'http_proxy'
504
+
505
+ fetcher = LibGems::RemoteFetcher.new nil
506
+
507
+ assert_equal nil, fetcher.send(:get_proxy_from_env)
508
+
509
+ ensure
510
+ orig_env_HTTP_PROXY.nil? ? ENV.delete('HTTP_PROXY') :
511
+ ENV['HTTP_PROXY'] = orig_env_HTTP_PROXY
512
+ orig_env_http_proxy.nil? ? ENV.delete('http_proxy') :
513
+ ENV['http_proxy'] = orig_env_http_proxy
514
+ end
515
+
516
+ def test_implicit_no_proxy
517
+ use_ui @ui do
518
+ ENV['http_proxy'] = 'http://fakeurl:12345'
519
+ fetcher = LibGems::RemoteFetcher.new :no_proxy
520
+ assert_data_from_server fetcher.fetch_path(@server_uri)
521
+ end
522
+ end
523
+
524
+ def test_implicit_proxy
525
+ use_ui @ui do
526
+ ENV['http_proxy'] = @proxy_uri
527
+ fetcher = LibGems::RemoteFetcher.new nil
528
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
529
+ end
530
+ end
531
+
532
+ def test_implicit_upper_case_proxy
533
+ use_ui @ui do
534
+ ENV['HTTP_PROXY'] = @proxy_uri
535
+ fetcher = LibGems::RemoteFetcher.new nil
536
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
537
+ end
538
+ end
539
+
540
+ def test_implicit_proxy_no_env
541
+ use_ui @ui do
542
+ fetcher = LibGems::RemoteFetcher.new nil
543
+ assert_data_from_server fetcher.fetch_path(@server_uri)
544
+ end
545
+ end
546
+
547
+ def test_open_uri_or_path
548
+ fetcher = LibGems::RemoteFetcher.new nil
549
+
550
+ conn = Object.new
551
+ def conn.started?() true end
552
+ def conn.request(req)
553
+ unless defined? @requested then
554
+ @requested = true
555
+ res = Net::HTTPMovedPermanently.new nil, 301, nil
556
+ res.add_field 'Location', 'http://gems.example.com/real_path'
557
+ res
558
+ else
559
+ res = Net::HTTPOK.new nil, 200, nil
560
+ def res.body() 'real_path' end
561
+ res
562
+ end
563
+ end
564
+
565
+ conn = { "#{Thread.current.object_id}:gems.example.com:80" => conn }
566
+ fetcher.instance_variable_set :@connections, conn
567
+
568
+ data = fetcher.open_uri_or_path 'http://gems.example.com/redirect'
569
+
570
+ assert_equal 'real_path', data
571
+ end
572
+
573
+ def test_open_uri_or_path_limited_redirects
574
+ fetcher = LibGems::RemoteFetcher.new nil
575
+
576
+ conn = Object.new
577
+ def conn.started?() true end
578
+ def conn.request(req)
579
+ res = Net::HTTPMovedPermanently.new nil, 301, nil
580
+ res.add_field 'Location', 'http://gems.example.com/redirect'
581
+ res
582
+ end
583
+
584
+ conn = { "#{Thread.current.object_id}:gems.example.com:80" => conn }
585
+ fetcher.instance_variable_set :@connections, conn
586
+
587
+ e = assert_raises LibGems::RemoteFetcher::FetchError do
588
+ fetcher.open_uri_or_path 'http://gems.example.com/redirect'
589
+ end
590
+
591
+ assert_equal 'too many redirects (http://gems.example.com/redirect)',
592
+ e.message
593
+ end
594
+
595
+ def test_request
596
+ uri = URI.parse "#{@gem_repo}/specs.#{LibGems.marshal_version}"
597
+ util_stub_connection_for :body => :junk, :code => 200
598
+
599
+ response = @fetcher.request uri, Net::HTTP::Get
600
+
601
+ assert_equal 200, response.code
602
+ assert_equal :junk, response.body
603
+ end
604
+
605
+ def test_request_head
606
+ uri = URI.parse "#{@gem_repo}/specs.#{LibGems.marshal_version}"
607
+ util_stub_connection_for :body => '', :code => 200
608
+ response = @fetcher.request uri, Net::HTTP::Head
609
+
610
+ assert_equal 200, response.code
611
+ assert_equal '', response.body
612
+ end
613
+
614
+ def test_request_unmodifed
615
+ uri = URI.parse "#{@gem_repo}/specs.#{LibGems.marshal_version}"
616
+ conn = util_stub_connection_for :body => '', :code => 304
617
+
618
+ t = Time.now
619
+ response = @fetcher.request uri, Net::HTTP::Head, t
620
+
621
+ assert_equal 304, response.code
622
+ assert_equal '', response.body
623
+
624
+ assert_equal t.rfc2822, conn.payload['if-modified-since']
625
+ end
626
+
627
+ def test_yaml_error_on_size
628
+ use_ui @ui do
629
+ self.class.enable_yaml = false
630
+ fetcher = LibGems::RemoteFetcher.new nil
631
+ assert_error { fetcher.size }
632
+ end
633
+ end
634
+
635
+ def util_stub_connection_for hash
636
+ def @fetcher.connection= conn
637
+ @conn = conn
638
+ end
639
+
640
+ def @fetcher.connection_for uri
641
+ @conn
642
+ end
643
+
644
+ @fetcher.connection = Conn.new OpenStruct.new(hash)
645
+ end
646
+
647
+ def assert_error(exception_class=Exception)
648
+ got_exception = false
649
+ begin
650
+ yield
651
+ rescue exception_class => ex
652
+ got_exception = true
653
+ end
654
+ assert got_exception, "Expected exception conforming to #{exception_class}"
655
+ end
656
+
657
+ def assert_data_from_server(data)
658
+ assert_block("Data is not from server") { data =~ /0\.4\.11/ }
659
+ end
660
+
661
+ def assert_data_from_proxy(data)
662
+ assert_block("Data is not from proxy") { data =~ /0\.4\.2/ }
663
+ end
664
+
665
+ class Conn
666
+ attr_accessor :payload
667
+
668
+ def initialize(response)
669
+ @response = response
670
+ self.payload = nil
671
+ end
672
+
673
+ def request(req)
674
+ self.payload = req
675
+ @response
676
+ end
677
+ end
678
+
679
+ class NilLog < WEBrick::Log
680
+ def log(level, data) #Do nothing
681
+ end
682
+ end
683
+
684
+ class << self
685
+ attr_reader :normal_server, :proxy_server
686
+ attr_accessor :enable_zip, :enable_yaml
687
+
688
+ def start_servers
689
+ @normal_server ||= start_server(SERVER_PORT, SERVER_DATA)
690
+ @proxy_server ||= start_server(PROXY_PORT, PROXY_DATA)
691
+ @enable_yaml = true
692
+ @enable_zip = false
693
+ end
694
+
695
+ private
696
+
697
+ def start_server(port, data)
698
+ Thread.new do
699
+ begin
700
+ null_logger = NilLog.new
701
+ s = WEBrick::HTTPServer.new(
702
+ :Port => port,
703
+ :DocumentRoot => nil,
704
+ :Logger => null_logger,
705
+ :AccessLog => null_logger
706
+ )
707
+ s.mount_proc("/kill") { |req, res| s.shutdown }
708
+ s.mount_proc("/yaml") { |req, res|
709
+ if @enable_yaml
710
+ res.body = data
711
+ res['Content-Type'] = 'text/plain'
712
+ res['content-length'] = data.size
713
+ else
714
+ res.status = "404"
715
+ res.body = "<h1>NOT FOUND</h1>"
716
+ res['Content-Type'] = 'text/html'
717
+ end
718
+ }
719
+ s.mount_proc("/yaml.Z") { |req, res|
720
+ if @enable_zip
721
+ res.body = Zlib::Deflate.deflate(data)
722
+ res['Content-Type'] = 'text/plain'
723
+ else
724
+ res.status = "404"
725
+ res.body = "<h1>NOT FOUND</h1>"
726
+ res['Content-Type'] = 'text/html'
727
+ end
728
+ }
729
+ s.start
730
+ rescue Exception => ex
731
+ abort ex.message
732
+ puts "ERROR during server thread: #{ex.message}"
733
+ end
734
+ end
735
+ sleep 0.2 # Give the servers time to startup
736
+ end
737
+ end
738
+
739
+ end
740
+