Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factor server code out of conftest to avoid circular dependency... #450

Merged
merged 1 commit into from
Feb 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 1 addition & 69 deletions asdf/conftest.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-


# this contains imports plugins that configure py.test for asdf tests.
# by importing them here in conftest.py they are discoverable by py.test
# no matter how it is invoked within the source tree.

from astropy.tests.plugins.display import PYTEST_HEADER_MODULES, TESTED_VERSIONS

import os
import queue
import shutil
import tempfile
import threading
import http.server
import socketserver

import pytest

Expand All @@ -23,6 +15,7 @@
# This is to figure out the affiliated package version, rather than
# using Astropy's
from . import version
from .tests.httpserver import HTTPServer, RangeHTTPServer

packagename = os.path.basename(os.path.dirname(__file__))
TESTED_VERSIONS[packagename] = version.version
Expand All @@ -45,67 +38,6 @@
pass




def run_server(tmpdir, handler_class, stop_event, queue): # pragma: no cover
"""
Runs an HTTP server serving files from given tmpdir in a separate
process. When it's ready, it sends a URL to the server over a
queue so the main process (the HTTP client) can start making
requests of it.
"""
class HTTPRequestHandler(handler_class):
def translate_path(self, path):
path = handler_class.translate_path(self, path)
path = os.path.join(
tmpdir,
os.path.relpath(path, os.getcwd()))
return path

server = socketserver.TCPServer(("127.0.0.1", 0), HTTPRequestHandler)
domain, port = server.server_address
url = "http://{0}:{1}/".format(domain, port)

# Set a reasonable timeout so that invalid requests (which may occur during
# testing) do not cause the entire test suite to hang indefinitely
server.timeout = 0.1

queue.put(url)

# Using server.serve_forever does not work here since it ignores the
# timeout value set above. Having an explicit loop also allows us to kill
# the server from the parent thread.
while not stop_event.isSet():
server.handle_request()

server.server_close()


class HTTPServer(object):
handler_class = http.server.SimpleHTTPRequestHandler

def __init__(self):
self.tmpdir = tempfile.mkdtemp()

q = queue.Queue()
self.stop_event = threading.Event()

args = (self.tmpdir, self.handler_class, self.stop_event, q)
self.thread = threading.Thread(target=run_server, args=args)
self.thread.start()

self.url = q.get()

def finalize(self):
self.stop_event.set()
self.thread.join()
shutil.rmtree(self.tmpdir)


class RangeHTTPServer(HTTPServer):
handler_class = RangeHTTPRequestHandler


@pytest.fixture()
def httpserver(request):
"""
Expand Down
2 changes: 1 addition & 1 deletion asdf/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
CartesianDifferential = None

from ..asdf import AsdfFile, get_asdf_library_info
from ..conftest import RangeHTTPServer
from .httpserver import RangeHTTPServer
from ..extension import default_extensions
from .. import util
from .. import versioning
Expand Down
75 changes: 75 additions & 0 deletions asdf/tests/httpserver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-

import os
import queue
import shutil
import tempfile
import threading
import http.server
import socketserver


from ..extern.RangeHTTPServer import RangeHTTPRequestHandler


__all__ = ['HTTPServer', 'RangeHTTPServer']


def run_server(tmpdir, handler_class, stop_event, queue): # pragma: no cover
"""
Runs an HTTP server serving files from given tmpdir in a separate
process. When it's ready, it sends a URL to the server over a
queue so the main process (the HTTP client) can start making
requests of it.
"""
class HTTPRequestHandler(handler_class):
def translate_path(self, path):
path = handler_class.translate_path(self, path)
path = os.path.join(
tmpdir,
os.path.relpath(path, os.getcwd()))
return path

server = socketserver.TCPServer(("127.0.0.1", 0), HTTPRequestHandler)
domain, port = server.server_address
url = "http://{0}:{1}/".format(domain, port)

# Set a reasonable timeout so that invalid requests (which may occur during
# testing) do not cause the entire test suite to hang indefinitely
server.timeout = 0.1

queue.put(url)

# Using server.serve_forever does not work here since it ignores the
# timeout value set above. Having an explicit loop also allows us to kill
# the server from the parent thread.
while not stop_event.isSet():
server.handle_request()

server.server_close()


class HTTPServer(object):
handler_class = http.server.SimpleHTTPRequestHandler

def __init__(self):
self.tmpdir = tempfile.mkdtemp()

q = queue.Queue()
self.stop_event = threading.Event()

args = (self.tmpdir, self.handler_class, self.stop_event, q)
self.thread = threading.Thread(target=run_server, args=args)
self.thread.start()

self.url = q.get()

def finalize(self):
self.stop_event.set()
self.thread.join()
shutil.rmtree(self.tmpdir)


class RangeHTTPServer(HTTPServer):
handler_class = RangeHTTPRequestHandler