def test_downloader_download(): "Downloader#download() Should call the right handler given the protocol of the link being processed" # Given that I have a Downloader instance service = downloader.Downloader() # And I mock all the actual protocol handlers (`_download_*()`) service._download_http = Mock() service._download_git = Mock() service._download_hg = Mock() service._download_svn = Mock() # When I try to download certain URLs service.download('http://source.com/blah') service.download('git+ssh://github.com/clarete/curdling.git') service.download('hg+http://hg.python.org.com/cpython') service.download('svn+http://svn.oldschool.com/repo') # Then I see that the right handlers were called. Notice that the vcs # prefixes will be stripped out service._download_http.assert_called_once_with('http://source.com/blah') service._download_git.assert_called_once_with( 'ssh://github.com/clarete/curdling.git') service._download_hg.assert_called_once_with( 'http://hg.python.org.com/cpython') service._download_svn.assert_called_once_with( 'http://svn.oldschool.com/repo')
def test_downloader_download_with_locator(): "Downloader#download() should reuse the authentication information present in the locator's URL" # Given that I have a Downloader instance service = downloader.Downloader() # And I mock all the actual HTTP handler service._download_http = Mock() # When I download an HTTP link with a locator service.download('http://source.com/blah', 'http://*****:*****@source.com') # Then I see URL forwarded to the handler still have the authentication info service._download_http.assert_called_once_with( 'http://*****:*****@source.com/blah')
def test_downloader_download_http_handler_use_content_disposition(): "Downloader#_download_http() should know how to use the header Content-Disposition to name the new file" # Given that I have a Downloader instance service = downloader.Downloader(index=Mock()) # And I patch the opener so we'll just pretend the HTTP IO is happening response = Mock(status=200) response.headers.get.return_value = 'attachment; filename=sure-0.1.1.tar.gz' service.opener.retrieve = Mock(return_value=(response, None)) # When I download an HTTP link service._download_http('http://blah/package.tar.gz') # Then I see the file name forward to the index was the one found in the header service.index.from_data.assert_called_once_with('sure-0.1.1.tar.gz', response.read.return_value)
def test_downloader_download_bad_url(): "Downloader#download() Should raise an exception if we can't handle the link" # Given that I have a Downloader instance service = downloader.Downloader() # When I try to download a weird link service.download.when.called_with('weird link').should.throw( UnknownURL, '''\ "weird link" Your URL looks wrong. Make sure it's a valid HTTP link or a valid VCS link prefixed with the name of the VCS of your choice. Eg.: $ curd install https://pypi.python.org/simple/curdling/curdling-0.1.2.tar.gz $ curd install git+ssh://github.com/clarete/curdling.git''')
def test_downloader_download_http_handler_blow_up_on_error(): "Downloader#_download_http() should handle HTTP status != 200" # Given that I have a Downloader instance service = downloader.Downloader() # And I patch the opener so we'll just pretend the HTTP IO is happening response = Mock(status=500) response.headers.get.return_value = '' service.opener.retrieve = Mock(return_value=(response, None)) # When I download an HTTP link service._download_http.when.called_with( 'http://blah/package.tar.gz' ).should.throw( ReportableError, 'Failed to download url `http://blah/package.tar.gz\': 500 (Internal Server Error)' )
def test_downloader_download_vcs_handlers(util, tempfile): "Downloader#_download_{git,hg,svn}() should call their respective shell commands to retrieve a VCS URL" tempfile.mkdtemp.return_value = 'tmp' # Given that I have a Downloader instance service = downloader.Downloader() # When I call the VCS handlers service._download_git('git-url') service._download_hg('hg-url') service._download_svn('svn-url') # Then I see that all the calls for the shell commands were done properly list(util.execute_command.call_args_list).should.equal([ call('git', 'clone', 'git-url', 'tmp'), call('hg', 'clone', 'hg-url', 'tmp'), call('svn', 'co', 'svn-url', 'tmp'), ])
def test_downloader_handle(): "Downloader#handle() should return the `tarball' path" # Given that I have a Downloader instance service = downloader.Downloader(index=Mock()) service._download_http = Mock(return_value=('tarball', 'package-0.1.zip')) # When I call the service handler with a URL requirement tarball = service.handle( 'tests', { 'requirement': 'package (0.1)', 'url': 'http://host/path/package-0.1.zip', }) # Then I see that the right tarball name was returned tarball.should.equal({ 'requirement': 'package (0.1)', 'tarball': 'package-0.1.zip', })
def test_downloader_download_vcs_handlers_with_rev(util, tempfile): "Downloader#_download_{git,hg,svn}() Should find the revision informed in the URL and point the retrieved code to it" tempfile.mkdtemp.return_value = 'tmp' # Given that I have a Downloader instance service = downloader.Downloader() # When I call the VCS handlers with a revision service._download_git('git-url@rev') service._download_hg('hg-url@rev') service._download_svn('svn-url@rev') # Then I see that all the calls for the shell commands were done properly list(util.execute_command.call_args_list).should.equal([ call('git', 'clone', 'git-url', 'tmp'), call('git', 'reset', '--hard', 'rev', cwd='tmp'), call('hg', 'clone', 'hg-url', 'tmp'), call('hg', 'update', '-q', 'rev', cwd='tmp'), call('svn', 'co', '-q', '-r', 'rev', 'svn-url', 'tmp'), ])
def test_downloader_download_http_handler_use_right_url_on_redirect( http_retrieve): "Downloader#_download_http() should handle HTTP status = 302" # Given that I have a Downloader instance service = downloader.Downloader(index=Mock()) # And I patch the opener so we'll just pretend the HTTP IO is happening response = Mock(status=200) response.headers.get.side_effect = {}.get http_retrieve.return_value = response, 'pkg-0.1.tar.gz' # When I download an HTTP link that redirects to another location service._download_http('http://pkg.io/download') # Then I see the package name being read from the redirected URL, # not from the original one. service.index.from_data.assert_called_once_with( 'pkg-0.1.tar.gz', response.read.return_value, )
def test_downloader_download_http_handler(): "Downloader#_download_http() should download HTTP links" # Given that I have a Downloader instance service = downloader.Downloader(index=Mock()) # And I patch the opener so we'll just pretend the HTTP IO is happening response = Mock(status=200) response.headers.get.return_value = '' service.opener.retrieve = Mock(return_value=(response, None)) # When I download an HTTP link service._download_http('http://blah/package.tar.gz') # Then I see that the URL was properly forward to the indexer service.index.from_data.assert_called_once_with( 'http://blah/package.tar.gz', response.read.return_value) # And Then I see that the response was read raw to avoid problems with # gzipped packages; The curdler component will do that! response.read.assert_called_once_with(cache_content=True, decode_content=False)
def test_downloader_handle_return_wheel(): "Downloader#handle() should return the `wheel' path when it downloads a whl file" # Given that I have a Downloader instance service = downloader.Downloader(index=Mock()) service._download_http = Mock( return_value=('wheel', 'package-0.1-cp27-none-macosx_10_8_x86_64.whl')) # When I call the service handler with a URL requirement tarball = service.handle( 'tests', { 'requirement': 'package (0.1)', 'url': 'http://host/path/package-0.1-cp27-none-macosx_10_8_x86_64.whl', }) # Then I see that the right tarball name was returned tarball.should.equal({ 'requirement': 'package (0.1)', 'wheel': 'package-0.1-cp27-none-macosx_10_8_x86_64.whl', })