mirror of
https://github.com/torproject/stem.git
synced 2024-12-04 16:36:28 +00:00
Moving integration test init/shutdown into class
Making a Runner class which will be available to integration tests. This both better modularizes the code and will allow for us to give runtime context to the tests.
This commit is contained in:
parent
bdbf352ad7
commit
0c03d4eb2a
120
run_tests.py
120
run_tests.py
@ -4,18 +4,14 @@
|
||||
Runs unit and integration tests.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
import signal
|
||||
import tempfile
|
||||
import unittest
|
||||
import subprocess
|
||||
import test.unit.message
|
||||
import test.unit.version
|
||||
import test.integ.runner
|
||||
|
||||
from stem.util import enum, system, term
|
||||
from stem.util import enum, term
|
||||
|
||||
OPT = "uit:h"
|
||||
OPT_EXPANDED = ["unit", "integ", "targets=", "help"]
|
||||
@ -51,57 +47,6 @@ Runs tests for the stem library.
|
||||
%s
|
||||
"""
|
||||
|
||||
# Number of seconds before we time out our attempt to start a tor instance
|
||||
TOR_INIT_TIMEOUT = 20
|
||||
|
||||
def init_tor_process(torrc_dst):
|
||||
"""
|
||||
Initializes and returns a tor process. This blocks until initialization
|
||||
completes or we error out.
|
||||
|
||||
Arguments:
|
||||
torrc_dst (str) - path for a torrc configuration to use
|
||||
|
||||
Returns:
|
||||
subprocess.Popen instance for the instantiated tor process
|
||||
|
||||
Raises:
|
||||
OSError if we either fail to create the tor process or reached a timeout without success
|
||||
"""
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
# starts a tor subprocess, raising an OSError if it fails
|
||||
tor_process = subprocess.Popen(["tor", "-f", torrc_dst], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
|
||||
# time ourselves out if we reach TOR_INIT_TIMEOUT
|
||||
def timeout_handler(signum, frame):
|
||||
# terminates the uninitialized tor process and raise on timeout
|
||||
tor_process.kill()
|
||||
raise OSError("unable to start tor: reached a %i second timeout without success" % TOR_INIT_TIMEOUT)
|
||||
|
||||
signal.signal(signal.SIGALRM, timeout_handler)
|
||||
signal.alarm(TOR_INIT_TIMEOUT)
|
||||
|
||||
print term.format("Starting tor...", term.Color.BLUE, term.Attr.BOLD)
|
||||
|
||||
while True:
|
||||
init_line = tor_process.stdout.readline().strip()
|
||||
|
||||
# this will provide empty results if the process is terminated
|
||||
if not init_line:
|
||||
tor_process.kill() # ... but best make sure
|
||||
raise OSError("tor process terminated")
|
||||
|
||||
print term.format(" %s" % init_line, term.Color.BLUE)
|
||||
|
||||
# return the process if we're done with bootstrapping
|
||||
if init_line.endswith("Bootstrapped 100%: Done."):
|
||||
print term.format(" done (%i seconds)" % (time.time() - start_time), term.Color.BLUE, term.Attr.BOLD)
|
||||
print
|
||||
|
||||
return tor_process
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_unit_tests = False
|
||||
run_integ_tests = False
|
||||
@ -160,62 +105,21 @@ if __name__ == '__main__':
|
||||
print
|
||||
|
||||
if run_integ_tests:
|
||||
# TODO: check if there's already a tor instance running
|
||||
|
||||
print "%s\n%s\n%s\n" % (DIVIDER, "INTEGRATION TESTS".center(70), DIVIDER)
|
||||
|
||||
print term.format("Setting up a test instance...", term.Color.BLUE, term.Attr.BOLD)
|
||||
|
||||
# makes a temporary directory for the runtime resources of our integ test
|
||||
test_dir = tempfile.mktemp("-stem-integ")
|
||||
integ_runner = test.integ.runner.Runner()
|
||||
|
||||
try:
|
||||
os.makedirs(test_dir)
|
||||
print term.format(" created test directory: %s" % test_dir, term.Color.BLUE, term.Attr.BOLD)
|
||||
except OSError, exc:
|
||||
print term.format("Unable to make testing directory: %s" % exc, term.Color.RED, term.Attr.BOLD)
|
||||
sys.exit(1)
|
||||
|
||||
# makes a basic torrc for the integration tests to run against
|
||||
torrc_contents = """# basic integration testing configuration
|
||||
DataDirectory %s
|
||||
ControlPort 9051
|
||||
""" % test_dir
|
||||
|
||||
# writes our testing torrc
|
||||
torrc_dst = os.path.join(test_dir, "torrc")
|
||||
try:
|
||||
torrc_file = open(torrc_dst, "w")
|
||||
torrc_file.write(torrc_contents)
|
||||
torrc_file.close()
|
||||
integ_runner.run_setup()
|
||||
integ_runner.start()
|
||||
|
||||
print term.format(" wrote torrc: %s" % torrc_dst, term.Color.BLUE, term.Attr.BOLD)
|
||||
|
||||
for line in torrc_contents.split("\n"):
|
||||
print term.format(" %s" % line.strip(), term.Color.BLUE)
|
||||
except Exception, exc:
|
||||
print term.format("Unable to write testing torrc: %s" % exc, term.Color.RED, term.Attr.BOLD)
|
||||
sys.exit(1)
|
||||
|
||||
# starts a tor instance
|
||||
try:
|
||||
tor_process = init_tor_process(torrc_dst)
|
||||
except OSError, exc:
|
||||
print term.format("Unable to start a tor instance: %s" % exc, term.Color.RED, term.Attr.BOLD)
|
||||
sys.exit(1)
|
||||
|
||||
print term.format("Running tests...", term.Color.BLUE, term.Attr.BOLD)
|
||||
print
|
||||
|
||||
# TODO: run tests
|
||||
|
||||
print term.format("Shutting down tor...", term.Color.BLUE, term.Attr.BOLD)
|
||||
tor_process.kill()
|
||||
print term.format(" done", term.Color.BLUE, term.Attr.BOLD)
|
||||
|
||||
|
||||
|
||||
|
||||
# TODO: run tests
|
||||
print term.format("Running tests...", term.Color.BLUE, term.Attr.BOLD)
|
||||
print
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
integ_runner.stop()
|
||||
|
||||
# TODO: we might do target selection later but for now we should simply
|
||||
# work with a single simple tor instance and see how it works out
|
||||
|
@ -2,5 +2,5 @@
|
||||
Integration tests for the stem library.
|
||||
"""
|
||||
|
||||
__all__ = []
|
||||
__all__ = ["runner"]
|
||||
|
||||
|
130
test/integ/runner.py
Normal file
130
test/integ/runner.py
Normal file
@ -0,0 +1,130 @@
|
||||
"""
|
||||
Starts and stops test instances for integration tests.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
from stem.util import term
|
||||
|
||||
# number of seconds before we time out our attempt to start a tor instance
|
||||
TOR_INIT_TIMEOUT = 30
|
||||
|
||||
BASIC_TORRC = """# configuration for stem integration tests
|
||||
DataDirectory %s
|
||||
ControlPort 1111
|
||||
"""
|
||||
|
||||
class Runner:
|
||||
def __init__(self):
|
||||
self._test_dir = tempfile.mktemp("-stem-integ")
|
||||
self._torrc_contents = BASIC_TORRC % self._test_dir
|
||||
self._tor_process = None
|
||||
|
||||
def run_setup(self):
|
||||
"""
|
||||
Makes a temporary directory for the runtime resources of our integ tests.
|
||||
|
||||
Raises:
|
||||
OSError if unsuccessful
|
||||
"""
|
||||
|
||||
print term.format("Setting up a test instance...", term.Color.BLUE, term.Attr.BOLD)
|
||||
|
||||
# makes a temporary directory for the runtime resources of our integ test
|
||||
try:
|
||||
sys.stdout.write(term.format(" making test directory (%s)... " % self._test_dir, term.Color.BLUE, term.Attr.BOLD))
|
||||
os.makedirs(self._test_dir)
|
||||
sys.stdout.write(term.format("done\n", term.Color.BLUE, term.Attr.BOLD))
|
||||
except OSError, exc:
|
||||
sys.stdout.write(term.format("failed (%s)\n" % exc, term.Color.RED, term.Attr.BOLD))
|
||||
raise exc
|
||||
|
||||
# writes our testing torrc
|
||||
torrc_dst = os.path.join(self._test_dir, "torrc")
|
||||
try:
|
||||
sys.stdout.write(term.format(" writing torrc (%s)... " % torrc_dst, term.Color.BLUE, term.Attr.BOLD))
|
||||
|
||||
torrc_file = open(torrc_dst, "w")
|
||||
torrc_file.write(self._torrc_contents)
|
||||
torrc_file.close()
|
||||
|
||||
sys.stdout.write(term.format("done\n", term.Color.BLUE, term.Attr.BOLD))
|
||||
|
||||
for line in self._torrc_contents.strip().split("\n"):
|
||||
print term.format(" %s" % line.strip(), term.Color.BLUE)
|
||||
except Exception, exc:
|
||||
sys.stdout.write(term.format("failed (%s)\n" % exc, term.Color.RED, term.Attr.BOLD))
|
||||
raise exc
|
||||
finally:
|
||||
print # extra newline
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Initializes a tor process. This blocks until initialization completes or we
|
||||
error out.
|
||||
|
||||
Raises:
|
||||
OSError if we either fail to create the tor process or reached a timeout
|
||||
without success
|
||||
"""
|
||||
|
||||
print term.format("Starting tor...", term.Color.BLUE, term.Attr.BOLD)
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
# terminate our previous instance before continuing if we had one
|
||||
if self._tor_process: self._tor_process.kill()
|
||||
|
||||
# double check that we have a torrc to work with
|
||||
torrc_dst = os.path.join(self._test_dir, "torrc")
|
||||
if not os.path.exists(torrc_dst):
|
||||
raise OSError("torrc doesn't exist (%s)" % torrc_dst)
|
||||
|
||||
# starts a tor subprocess, raising an OSError if it fails
|
||||
self._tor_process = subprocess.Popen(["tor", "-f", torrc_dst], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
|
||||
# time ourselves out if we reach TOR_INIT_TIMEOUT
|
||||
def timeout_handler(signum, frame):
|
||||
# terminates the uninitialized tor process and raise on timeout
|
||||
self._tor_process.kill()
|
||||
raise OSError("reached a %i second timeout without success" % TOR_INIT_TIMEOUT)
|
||||
|
||||
signal.signal(signal.SIGALRM, timeout_handler)
|
||||
signal.alarm(TOR_INIT_TIMEOUT)
|
||||
|
||||
while True:
|
||||
init_line = self._tor_process.stdout.readline().strip()
|
||||
|
||||
# this will provide empty results if the process is terminated
|
||||
if not init_line:
|
||||
self._tor_process.kill() # ... but best make sure
|
||||
raise OSError("process terminated")
|
||||
|
||||
print term.format(" %s" % init_line, term.Color.BLUE)
|
||||
|
||||
# return the process if we're done with bootstrapping
|
||||
if init_line.endswith("Bootstrapped 100%: Done."):
|
||||
print term.format(" done (%i seconds)" % (time.time() - start_time), term.Color.BLUE, term.Attr.BOLD)
|
||||
return
|
||||
except OSError, exc:
|
||||
print term.format(" failed to start tor: %s" % exc, term.Color.RED, term.Attr.BOLD)
|
||||
raise exc
|
||||
finally:
|
||||
print # extra newline
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Terminates our tor instance.
|
||||
"""
|
||||
|
||||
if self._tor_process:
|
||||
sys.stdout.write(term.format("Shutting down tor... ", term.Color.BLUE, term.Attr.BOLD))
|
||||
self._tor_process.kill()
|
||||
sys.stdout.write(term.format("done\n", term.Color.BLUE, term.Attr.BOLD))
|
||||
print # extra newline
|
||||
|
Loading…
Reference in New Issue
Block a user