[tor-commits] [stem/master] Moving test target attributes to config
atagar at torproject.org
atagar at torproject.org
Sat Jan 21 23:37:25 UTC 2012
commit 6c3fb340a83865f75399c60b4e9201810f60c8ee
Author: Damian Johnson <atagar at torproject.org>
Date: Sat Jan 21 15:34:43 2012 -0800
Moving test target attributes to config
Moving the attributes for integration testing targets from a big dictionary in
the source to a separate configuration file. Progress!
---
run_tests.py | 141 +++++++++++++++--------------------------------------
stem/util/conf.py | 15 ++++--
stem/util/enum.py | 26 +++++++++-
test/settings.cfg | 58 ++++++++++++++++++++++
4 files changed, 131 insertions(+), 109 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 770953d..fdd6901 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -32,7 +32,7 @@ import stem.util.enum
import stem.util.log as log
import stem.util.term as term
-OPT = "uic:t:l:h"
+OPT = "uic:l:t:h"
OPT_EXPANDED = ["unit", "integ", "config=", "targets=", "log=", "tor=", "help"]
DIVIDER = "=" * 70
@@ -64,99 +64,21 @@ INTEG_TESTS = (
# Integration tests above the basic suite.
TARGETS = stem.util.enum.Enum(*[(v, v) for v in ("ONLINE", "RELATIVE", "CONN_NONE", "CONN_OPEN", "CONN_PASSWORD", "CONN_COOKIE", "CONN_MULTIPLE", "CONN_SOCKET", "CONN_SCOOKIE", "CONN_PTRACE", "CONN_ALL")])
-# Attributes that integ targets can have are...
-#
-# config
-# Configuration option with which this is synced. If an option is set via
-# both the config and '--target' argument then the argument takes precedence.
-#
-# description
-# The '--help' description of the target.
-#
-# prereq
-# Version that we need to run the target.
-#
-# torrc
-# Configuration options for the test instance. For each of these targets that
-# we have we make an integration test run.
-#
-# TODO: This is a very, very long block and it's only gonna get worse. Should
-# this be moved to a 'settings.cfg'? It might be problematic due to constants.
+CONFIG = {
+ "target.config": {},
+ "target.description": {},
+ "target.prereq": {},
+ "target.torrc": {},
+}
-TARGET_ATTR = {
- TARGETS.ONLINE: {
- "config": "test.integ.target.online",
- "description": "Includes tests that require network activity.",
- },
- TARGETS.RELATIVE: {
- "config": "test.integ.target.relative_data_dir",
- "description": "Uses a relative path for tor's data directory.",
- },
- TARGETS.CONN_NONE: {
- "config": "test.integ.target.connection.none",
- "description": "Configuration without a way for controllers to connect.",
- "torrc": (),
- },
- TARGETS.CONN_OPEN: {
- "config": "test.integ.target.connection.open",
- "description": "Configuration with an open control port (default).",
- "torrc": (
- test.runner.OPT_PORT,
- ),
- },
- TARGETS.CONN_PASSWORD: {
- "config": "test.integ.target.connection.password",
- "description": "Configuration with password authentication.",
- "torrc": (
- test.runner.OPT_PORT,
- test.runner.OPT_PASSWORD,
- ),
- },
- TARGETS.CONN_COOKIE: {
- "config": "test.integ.target.connection.cookie",
- "description": "Configuration with an authentication cookie.",
- "torrc": (
- test.runner.OPT_PORT,
- test.runner.OPT_COOKIE,
- ),
- },
- TARGETS.CONN_MULTIPLE: {
- "config": "test.integ.target.connection.multiple",
- "description": "Configuration with both password and cookie authentication.",
- "torrc": (
- test.runner.OPT_PORT,
- test.runner.OPT_PASSWORD,
- test.runner.OPT_COOKIE,
- ),
- },
- TARGETS.CONN_SOCKET: {
- "config": "test.integ.target.connection.socket",
- "description": "Configuration with a control socket.",
- "torrc": (
- test.runner.OPT_SOCKET,
- ),
- },
- TARGETS.CONN_SCOOKIE: {
- "config": "test.integ.target.connection.scookie",
- "description": "Configuration with a control socket and authentication cookie.",
- "torrc": (
- test.runner.OPT_SOCKET,
- test.runner.OPT_COOKIE,
- ),
- },
- TARGETS.CONN_PTRACE: {
- "config": "test.integ.target.connection.ptrace",
- "description": "Configuration with an open control port and 'DisableDebuggerAttachment 0'",
- "prereq": stem.version.Requirement.DISABLE_DEBUGGER_ATTACHMENT,
- "torrc": (
- test.runner.OPT_PORT,
- test.runner.OPT_PTRACE,
- ),
- },
- TARGETS.CONN_ALL: {
- "config": "test.integ.target.connection.all",
- "description": "Runs integration tests for all connection configurations.",
- },
+# mapping between 'target.torrc' options and runner attributes
+# TODO: switch OPT_* to enums so this is unnecessary
+RUNNER_OPT_MAPPING = {
+ "PORT": test.runner.OPT_PORT,
+ "PASSWORD": test.runner.OPT_PASSWORD,
+ "COOKIE": test.runner.OPT_COOKIE,
+ "SOCKET": test.runner.OPT_SOCKET,
+ "PTRACE": test.runner.OPT_PTRACE,
}
DEFAULT_RUN_TARGET = TARGETS.CONN_OPEN
@@ -202,11 +124,26 @@ def print_logging(logging_buffer):
print
if __name__ == '__main__':
+ # loads the builtin testing configuration
+ stem_path = os.path.join(*os.path.split(__file__)[:-1])
+ stem_path = stem.util.system.expand_path(stem_path)
+ settings_path = os.path.join(stem_path, "test", "settings.cfg")
+
+ test_config = stem.util.conf.get_config("test")
+ test_config.load(settings_path)
+ test_config.update(CONFIG)
+
+ # parses target.torrc as csv values and convert to runner OPT_* values
+ for target in CONFIG["target.torrc"]:
+ CONFIG["target.torrc"][target] = []
+
+ for opt in test_config.get_str_csv("target.torrc", [], sub_key = target):
+ CONFIG["target.torrc"][target].append(RUNNER_OPT_MAPPING[opt])
+
start_time = time.time()
run_unit_tests = False
run_integ_tests = False
config_path = None
- test_config = stem.util.conf.get_config("test")
override_targets = []
logging_runlevel = None
tor_cmd = "tor"
@@ -259,7 +196,7 @@ if __name__ == '__main__':
target_lines = []
for target in TARGETS:
- target_lines.append(description_format % (target, TARGET_ATTR[target]["description"]))
+ target_lines.append(description_format % (target, CONFIG["target.description"].get(target, "")))
print HELP_MSG % "\n ".join(target_lines)
sys.exit()
@@ -294,7 +231,7 @@ if __name__ == '__main__':
# override our configuration flags if both set a target.
for target in override_targets:
- target_config = TARGET_ATTR[target].get("config")
+ target_config = CONFIG["target.config"].get(target)
if target_config: test_config.set(target_config, "true")
error_tracker = test.output.ErrorTracker()
@@ -332,14 +269,14 @@ if __name__ == '__main__':
# Queue up all the targets with torrc options we want to run against.
integ_run_targets = []
- all_run_targets = [t for t in TARGETS if "torrc" in TARGET_ATTR[t]]
+ all_run_targets = [t for t in TARGETS if CONFIG["target.torrc"].get(t)]
if test_config.get("test.integ.target.connection.all", False):
# test against everything with torrc options
integ_run_targets = all_run_targets
else:
for target in all_run_targets:
- target_config = TARGET_ATTR[target].get("config")
+ target_config = CONFIG["target.config"].get(target)
if target_config and test_config.get(target_config, False):
integ_run_targets.append(target)
@@ -354,21 +291,21 @@ if __name__ == '__main__':
our_version, skip_targets = None, []
for target in integ_run_targets:
- target_prereq = TARGET_ATTR[target].get("prereq")
+ target_prereq = CONFIG["target.prereq"].get(target)
if target_prereq:
# lazy loaded to skip system call if we don't have any prereqs
if not our_version:
our_version = stem.version.get_system_tor_version(tor_cmd)
- if our_version < target_prereq:
+ if our_version < stem.version.Requirement[target_prereq]:
skip_targets.append(target)
for target in integ_run_targets:
if target in skip_targets: continue
try:
- integ_runner.start(tor_cmd, extra_torrc_opts = TARGET_ATTR[target].get("torrc", []))
+ integ_runner.start(tor_cmd, extra_torrc_opts = CONFIG["target.torrc"].get(target, []))
print term.format("Running tests...", term.Color.BLUE, term.Attr.BOLD)
print
@@ -392,7 +329,7 @@ if __name__ == '__main__':
print
for target in skip_targets:
- print term.format("Unable to run target %s, this requires tor version %s" % (target, TARGET_ATTR[target]["prereq"]), term.Color.RED, term.Attr.BOLD)
+ print term.format("Unable to run target %s, this requires tor version %s" % (target, CONFIG["target.prereq"][target]), term.Color.RED, term.Attr.BOLD)
print
diff --git a/stem/util/conf.py b/stem/util/conf.py
index 199a20c..132dbce 100644
--- a/stem/util/conf.py
+++ b/stem/util/conf.py
@@ -375,7 +375,7 @@ class Config():
return val
- def get_str_csv(self, key, default = None, count = None):
+ def get_str_csv(self, key, default = None, count = None, sub_key = None):
"""
Fetches the given key as a comma separated value.
@@ -385,13 +385,18 @@ class Config():
the count
count (int) - if set then the default is returned when the number of
elements doesn't match this value
+ sub_key (str) - handle the configuration entry as a dictionary and use
+ this key within it
Returns:
list with the stripped values
"""
- conf_value = self.get_value(key)
+ if sub_key: conf_value = self.get(key, {}).get(sub_key)
+ else: conf_value = self.get_value(key)
+
if conf_value == None: return default
+ elif not conf_value.strip(): return [] # empty string
else:
conf_comp = [entry.strip() for entry in conf_value.split(",")]
@@ -407,7 +412,7 @@ class Config():
return conf_comp
- def get_int_csv(self, key, default = None, count = None, min_value = None, max_value = None):
+ def get_int_csv(self, key, default = None, count = None, min_value = None, max_value = None, sub_key = None):
"""
Fetches the given comma separated value, returning the default if the
values aren't integers or don't follow the given constraints.
@@ -419,12 +424,14 @@ class Config():
count (int) - checks that the number of values matches this if set
min_value (int) - checks that all values are over this if set
max_value (int) - checks that all values are under this if set
+ sub_key (str) - handle the configuration entry as a dictionary and use
+ this key within it
Returns:
list with the stripped values
"""
- conf_comp = self.get_str_csv(key, default, count)
+ conf_comp = self.get_str_csv(key, default, count, sub_key)
if conf_comp == default: return default
# validates the input, setting the error_msg if there's a problem
diff --git a/stem/util/enum.py b/stem/util/enum.py
index 6891663..c750352 100644
--- a/stem/util/enum.py
+++ b/stem/util/enum.py
@@ -80,7 +80,7 @@ class Enum:
Provides the index of the given value in the collection.
Arguments:
- value - entry to be looked up
+ value (str) - entry to be looked up
Returns:
integer index of the given entry
@@ -96,7 +96,7 @@ class Enum:
Provides the next enumeration after the given value.
Arguments:
- value - enumeration for which to get the next entry
+ value (str) - enumeration for which to get the next entry
Returns:
enum value following the given entry
@@ -116,7 +116,7 @@ class Enum:
Provides the previous enumeration before the given value.
Arguments:
- value - enumeration for which to get the previous entry
+ value (str) - enumeration for which to get the previous entry
Returns:
enum value proceeding the given entry
@@ -131,6 +131,26 @@ class Enum:
prev_index = (self._values.index(value) - 1) % len(self._values)
return self._values[prev_index]
+ def __getitem__(self, item):
+ """
+ Provides the values for the given key.
+
+ Arguments:
+ item (str) - key to be looked up
+
+ Returns:
+ str with the value for the given key
+
+ Raises:
+ ValueError if the key doesn't exist
+ """
+
+ if item in self.__dict__:
+ return self.__dict__[item]
+ else:
+ keys = ", ".join(self.keys())
+ raise ValueError("'%s' isn't among our enumeration keys, which includes: %s" % (item, keys))
+
def __iter__(self):
"""
Provides an ordered listing of the enums in this set.
diff --git a/test/settings.cfg b/test/settings.cfg
new file mode 100644
index 0000000..75977d6
--- /dev/null
+++ b/test/settings.cfg
@@ -0,0 +1,58 @@
+# Testing Configuration
+#
+# The following are globally accessable configuration attributes used by stem's
+# unit and integration tests. Top level configuraion categories are...
+#
+# target.* - Attributes of the integration testing targets. This helps
+# determine what is ran when the user runs with '--target'.
+
+ ##################
+# CATEGORY: TARGET #
+ ##################
+
+# Configuration option with which the target is synced. If an option is set via
+# both the config and '--target' argument then the argument takes precedence.
+
+target.config ONLINE => test.integ.target.online
+target.config RELATIVE => test.integ.target.relative_data_dir
+target.config CONN_NONE => test.integ.target.connection.none
+target.config CONN_OPEN => test.integ.target.connection.open
+target.config CONN_PASSWORD => test.integ.target.connection.password
+target.config CONN_COOKIE => test.integ.target.connection.cookie
+target.config CONN_MULTIPLE => test.integ.target.connection.multiple
+target.config CONN_SOCKET => test.integ.target.connection.socket
+target.config CONN_SCOOKIE => test.integ.target.connection.scookie
+target.config CONN_PTRACE => test.integ.target.connection.ptrace
+target.config CONN_ALL => test.integ.target.connection.all
+
+# The '--help' description of the target.
+
+target.description ONLINE => Includes tests that require network activity.
+target.description RELATIVE => Uses a relative path for tor's data directory.
+target.description CONN_NONE => Configuration without a way for controllers to connect.
+target.description CONN_OPEN => Configuration with an open control port (default).
+target.description CONN_PASSWORD => Configuration with password authentication.
+target.description CONN_COOKIE => Configuration with an authentication cookie.
+target.description CONN_MULTIPLE => Configuration with both password and cookie authentication.
+target.description CONN_SOCKET => Configuration with a control socket.
+target.description CONN_SCOOKIE => Configuration with a control socket and authentication cookie.
+target.description CONN_PTRACE => Configuration with an open control port and 'DisableDebuggerAttachment 0'
+target.description CONN_ALL => Runs integration tests for all connection configurations.
+
+# Version that we need to run the target. These need to match an enumeration of
+# stem.version.Requirement.
+
+target.prereq CONN_PTRACE => DISABLE_DEBUGGER_ATTACHMENT
+
+# Torrc configuration options included with the target. Having this option set
+# means that each of these targets will have a dedicated integration test run.
+
+target.torrc CONN_NONE =>
+target.torrc CONN_OPEN => PORT
+target.torrc CONN_PASSWORD => PORT, PASSWORD
+target.torrc CONN_COOKIE => PORT, COOKIE
+target.torrc CONN_MULTIPLE => PORT, PASSWORD, COOKIE
+target.torrc CONN_SOCKET => SOCKET
+target.torrc CONN_SCOOKIE => SOCKET, COOKIE
+target.torrc CONN_PTRACE => PORT, PTRACE
+
More information about the tor-commits
mailing list