test_packageindex.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import sys
  2. import distutils.errors
  3. from setuptools.compat import httplib, HTTPError, unicode, pathname2url
  4. import pkg_resources
  5. import setuptools.package_index
  6. from setuptools.tests.server import IndexServer
  7. class TestPackageIndex:
  8. def test_bad_url_bad_port(self):
  9. index = setuptools.package_index.PackageIndex()
  10. url = 'http://127.0.0.1:0/nonesuch/test_package_index'
  11. try:
  12. v = index.open_url(url)
  13. except Exception as v:
  14. assert url in str(v)
  15. else:
  16. assert isinstance(v, HTTPError)
  17. def test_bad_url_typo(self):
  18. # issue 16
  19. # easy_install inquant.contentmirror.plone breaks because of a typo
  20. # in its home URL
  21. index = setuptools.package_index.PackageIndex(
  22. hosts=('www.example.com',)
  23. )
  24. url = 'url:%20https://svn.plone.org/svn/collective/inquant.contentmirror.plone/trunk'
  25. try:
  26. v = index.open_url(url)
  27. except Exception as v:
  28. assert url in str(v)
  29. else:
  30. assert isinstance(v, HTTPError)
  31. def test_bad_url_bad_status_line(self):
  32. index = setuptools.package_index.PackageIndex(
  33. hosts=('www.example.com',)
  34. )
  35. def _urlopen(*args):
  36. raise httplib.BadStatusLine('line')
  37. index.opener = _urlopen
  38. url = 'http://example.com'
  39. try:
  40. v = index.open_url(url)
  41. except Exception as v:
  42. assert 'line' in str(v)
  43. else:
  44. raise AssertionError('Should have raise here!')
  45. def test_bad_url_double_scheme(self):
  46. """
  47. A bad URL with a double scheme should raise a DistutilsError.
  48. """
  49. index = setuptools.package_index.PackageIndex(
  50. hosts=('www.example.com',)
  51. )
  52. # issue 20
  53. url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk'
  54. try:
  55. index.open_url(url)
  56. except distutils.errors.DistutilsError as error:
  57. msg = unicode(error)
  58. assert 'nonnumeric port' in msg or 'getaddrinfo failed' in msg or 'Name or service not known' in msg
  59. return
  60. raise RuntimeError("Did not raise")
  61. def test_bad_url_screwy_href(self):
  62. index = setuptools.package_index.PackageIndex(
  63. hosts=('www.example.com',)
  64. )
  65. # issue #160
  66. if sys.version_info[0] == 2 and sys.version_info[1] == 7:
  67. # this should not fail
  68. url = 'http://example.com'
  69. page = ('<a href="http://www.famfamfam.com]('
  70. 'http://www.famfamfam.com/">')
  71. index.process_index(url, page)
  72. def test_url_ok(self):
  73. index = setuptools.package_index.PackageIndex(
  74. hosts=('www.example.com',)
  75. )
  76. url = 'file:///tmp/test_package_index'
  77. assert index.url_ok(url, True)
  78. def test_links_priority(self):
  79. """
  80. Download links from the pypi simple index should be used before
  81. external download links.
  82. https://bitbucket.org/tarek/distribute/issue/163
  83. Usecase :
  84. - someone uploads a package on pypi, a md5 is generated
  85. - someone manually copies this link (with the md5 in the url) onto an
  86. external page accessible from the package page.
  87. - someone reuploads the package (with a different md5)
  88. - while easy_installing, an MD5 error occurs because the external link
  89. is used
  90. -> Setuptools should use the link from pypi, not the external one.
  91. """
  92. if sys.platform.startswith('java'):
  93. # Skip this test on jython because binding to :0 fails
  94. return
  95. # start an index server
  96. server = IndexServer()
  97. server.start()
  98. index_url = server.base_url() + 'test_links_priority/simple/'
  99. # scan a test index
  100. pi = setuptools.package_index.PackageIndex(index_url)
  101. requirement = pkg_resources.Requirement.parse('foobar')
  102. pi.find_packages(requirement)
  103. server.stop()
  104. # the distribution has been found
  105. assert 'foobar' in pi
  106. # we have only one link, because links are compared without md5
  107. assert len(pi['foobar'])==1
  108. # the link should be from the index
  109. assert 'correct_md5' in pi['foobar'][0].location
  110. def test_parse_bdist_wininst(self):
  111. parse = setuptools.package_index.parse_bdist_wininst
  112. actual = parse('reportlab-2.5.win32-py2.4.exe')
  113. expected = 'reportlab-2.5', '2.4', 'win32'
  114. assert actual == expected
  115. actual = parse('reportlab-2.5.win32.exe')
  116. expected = 'reportlab-2.5', None, 'win32'
  117. assert actual == expected
  118. actual = parse('reportlab-2.5.win-amd64-py2.7.exe')
  119. expected = 'reportlab-2.5', '2.7', 'win-amd64'
  120. assert actual == expected
  121. actual = parse('reportlab-2.5.win-amd64.exe')
  122. expected = 'reportlab-2.5', None, 'win-amd64'
  123. assert actual == expected
  124. def test__vcs_split_rev_from_url(self):
  125. """
  126. Test the basic usage of _vcs_split_rev_from_url
  127. """
  128. vsrfu = setuptools.package_index.PackageIndex._vcs_split_rev_from_url
  129. url, rev = vsrfu('https://example.com/bar@2995')
  130. assert url == 'https://example.com/bar'
  131. assert rev == '2995'
  132. def test_local_index(self, tmpdir):
  133. """
  134. local_open should be able to read an index from the file system.
  135. """
  136. index_file = tmpdir / 'index.html'
  137. with index_file.open('w') as f:
  138. f.write('<div>content</div>')
  139. url = 'file:' + pathname2url(str(tmpdir)) + '/'
  140. res = setuptools.package_index.local_open(url)
  141. assert 'content' in res.read()
  142. class TestContentCheckers:
  143. def test_md5(self):
  144. checker = setuptools.package_index.HashChecker.from_url(
  145. 'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
  146. checker.feed('You should probably not be using MD5'.encode('ascii'))
  147. assert checker.hash.hexdigest() == 'f12895fdffbd45007040d2e44df98478'
  148. assert checker.is_valid()
  149. def test_other_fragment(self):
  150. "Content checks should succeed silently if no hash is present"
  151. checker = setuptools.package_index.HashChecker.from_url(
  152. 'http://foo/bar#something%20completely%20different')
  153. checker.feed('anything'.encode('ascii'))
  154. assert checker.is_valid()
  155. def test_blank_md5(self):
  156. "Content checks should succeed if a hash is empty"
  157. checker = setuptools.package_index.HashChecker.from_url(
  158. 'http://foo/bar#md5=')
  159. checker.feed('anything'.encode('ascii'))
  160. assert checker.is_valid()
  161. def test_get_hash_name_md5(self):
  162. checker = setuptools.package_index.HashChecker.from_url(
  163. 'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
  164. assert checker.hash_name == 'md5'
  165. def test_report(self):
  166. checker = setuptools.package_index.HashChecker.from_url(
  167. 'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
  168. rep = checker.report(lambda x: x, 'My message about %s')
  169. assert rep == 'My message about md5'