server.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. """Basic http server for tests to simulate PyPI or custom indexes
  2. """
  3. import sys
  4. import time
  5. import threading
  6. from setuptools.compat import BaseHTTPRequestHandler
  7. from setuptools.compat import (urllib2, URLError, HTTPServer,
  8. SimpleHTTPRequestHandler)
  9. class IndexServer(HTTPServer):
  10. """Basic single-threaded http server simulating a package index
  11. You can use this server in unittest like this::
  12. s = IndexServer()
  13. s.start()
  14. index_url = s.base_url() + 'mytestindex'
  15. # do some test requests to the index
  16. # The index files should be located in setuptools/tests/indexes
  17. s.stop()
  18. """
  19. def __init__(self, server_address=('', 0),
  20. RequestHandlerClass=SimpleHTTPRequestHandler):
  21. HTTPServer.__init__(self, server_address, RequestHandlerClass)
  22. self._run = True
  23. def serve(self):
  24. while self._run:
  25. self.handle_request()
  26. def start(self):
  27. self.thread = threading.Thread(target=self.serve)
  28. self.thread.start()
  29. def stop(self):
  30. "Stop the server"
  31. # Let the server finish the last request and wait for a new one.
  32. time.sleep(0.1)
  33. # self.shutdown is not supported on python < 2.6, so just
  34. # set _run to false, and make a request, causing it to
  35. # terminate.
  36. self._run = False
  37. url = 'http://127.0.0.1:%(server_port)s/' % vars(self)
  38. try:
  39. if sys.version_info >= (2, 6):
  40. urllib2.urlopen(url, timeout=5)
  41. else:
  42. urllib2.urlopen(url)
  43. except URLError:
  44. # ignore any errors; all that's important is the request
  45. pass
  46. self.thread.join()
  47. self.socket.close()
  48. def base_url(self):
  49. port = self.server_port
  50. return 'http://127.0.0.1:%s/setuptools/tests/indexes/' % port
  51. class RequestRecorder(BaseHTTPRequestHandler):
  52. def do_GET(self):
  53. requests = vars(self.server).setdefault('requests', [])
  54. requests.append(self)
  55. self.send_response(200, 'OK')
  56. class MockServer(HTTPServer, threading.Thread):
  57. """
  58. A simple HTTP Server that records the requests made to it.
  59. """
  60. def __init__(self, server_address=('', 0),
  61. RequestHandlerClass=RequestRecorder):
  62. HTTPServer.__init__(self, server_address, RequestHandlerClass)
  63. threading.Thread.__init__(self)
  64. self.setDaemon(True)
  65. self.requests = []
  66. def run(self):
  67. self.serve_forever()
  68. def url(self):
  69. return 'http://localhost:%(server_port)s/' % vars(self)
  70. url = property(url)