From f8203cfd8560478d13cf5ca8883faafd626ca998 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Fri, 4 Apr 2014 16:23:22 +0100 Subject: Better tests --- lib/chutney/TorNet.py | 2 + networks/hs-intro-fail | 358 ----------------------------------------------- networks/hs-intro-fail-2 | 189 +++++++++++++++++++++++++ networks/hs-intro-fail-3 | 2 - 4 files changed, 191 insertions(+), 360 deletions(-) delete mode 100644 networks/hs-intro-fail create mode 100644 networks/hs-intro-fail-2 diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py index 497af5f..334615f 100644 --- a/lib/chutney/TorNet.py +++ b/lib/chutney/TorNet.py @@ -793,6 +793,8 @@ def main(): _BASE_ENVIRON = chutney.Templating.Environ(**DEFAULTS) _THE_NETWORK = Network(_BASE_ENVIRON) + stem.util.log.get_logger().setLevel(logging.WARN) + logger = logging.getLogger() logger.setLevel(logging.DEBUG) diff --git a/networks/hs-intro-fail b/networks/hs-intro-fail deleted file mode 100644 index 8e5470a..0000000 --- a/networks/hs-intro-fail +++ /dev/null @@ -1,358 +0,0 @@ -authority_nodes = Node.create(3, { - "tag": "a", - "authority": 1, - "relay": 1, - "torrc": "authority.tmpl" -}) - -# hidden service (hs) nodes -hs_nodes = [] - -hs_servers = [] - -port = 8081 - -from twisted.web import server, resource -from twisted.internet import reactor - -# Use twisted to create web servers in this script -class Site(resource.Resource): - isLeaf = True - numberRequests = 0 - - def __init__(self, siteNum): - self.siteNum = siteNum - - def render_GET(self, request): - self.numberRequests += 1 - request.setHeader("content-type", "text/plain") - return str(self.siteNum) - -base_port = 9080 -for i in range(2): - - port = base_port + i - - node = Node( - tag="h", - hiddenservice=1, - torrc="hidden-service.tmpl", - hiddenservicetarget="127.0.0.1:%i" % port - ) - hs_nodes.append(node) - - site = server.Site(Site(i)) - - s = reactor.listenTCP(port, site) - hs_servers.append(s) - - port += 1 - -client_nodes = Node.create(6, { - "tag": "c", - "torrc": "client.tmpl" -}) - -relay_nodes = Node.create(10, { - "tag": "r", - "relay": 1, - "torrc": "intro.tmpl" -}) - -thread.start_new_thread(reactor.run, (), {"installSignalHandlers": 0}) - -initial_nodes = authority_nodes + relay_nodes + client_nodes + hs_nodes[:1] - -def start(): - if not all([ n.getController().start() for n in initial_nodes ]): - return False - - logging.info("All initial nodes running") - - for n in authority_nodes + relay_nodes: - fingerprint = n.getStemController().get_info("fingerprint") - nodes_by_fingerprint[fingerprint] = n - - track_introduction_points(hs_nodes[0]) - - def hs_node_0_listener(logevent): - if "Successfully uploaded v2 rend descriptors" in logevent.message: - hs_nodes[0].getStemController().remove_event_listener(hs_node_0_listener) - - hs_nodes[1].getController().start() - - track_introduction_points(hs_nodes[1]) - - def hs_node_1_listener(logevent): - if "Successfully uploaded v2 rend descriptors" in logevent.message: - hs_nodes[1].getStemController().remove_event_listener(hs_node_1_listener) - - thread.start_new_thread(test_intro_failure, ()) - logging.info("out of node 1 listener") - - hs_nodes[1].getStemController().add_event_listener(hs_node_1_listener, EventType.INFO) - - hs_nodes[0].getStemController().add_event_listener(hs_node_0_listener, EventType.INFO) - -def test_intro_failure(): - connection_test() - - time.sleep(5) - - # Select a random node that is being used as an introduction point - nodenum = random.choice(node_intro_circuits.keys()) - fingerprint = random.choice(node_intro_circuits[nodenum].values()) - - node = nodes_by_fingerprint[fingerprint] - - logging.info("stopping " + node._env["nick"] + " (" + fingerprint + ")") - - node.getController().stop() - - logging.info("begining to watch for the establishment of new introduction points") - - changed = [False for n in hs_nodes] - - intro_points_before = [set(node_intro_circuits[n._env["nodenum"]].values()) for n in hs_nodes] - - time.sleep(90) - - intro_points_after = [set(node_intro_circuits[n._env["nodenum"]].values()) for n in hs_nodes] - - for i, node in enumerate(hs_nodes): - before = intro_points_before[i] - after = intro_points_after[i] - - if before != after: - changed[i] = True - - if all(changed): - logging.info("All changed") - else: - logging.info("All did not change") - - check_same_intro_points() - - connection_test() - - for server in hs_servers: - server.stopListening() - - reactor.stop() - logging.info("stopped the reactor") - - stop() - -def connection_test(): - logging.info("connecting to clients") - responses = {"0": 0, "1": 0} - - for c in client_nodes: - result = c.query("http://2oiifbe3wne4iaqb.onion/"); - - if result in responses: - responses[result] += 1 - else: - logging.info("Unknown response:") - - logging.info(str(responses)) - -## Utility Code - -# Introduction Point Tracking - -node_intro_circuits = {} - -node_intro_events = {} - -# node_events - -introduction_point_circuits = {} - -nodes_by_fingerprint = {} - -#{ nodenum: { circuit: "fingerprint", circuit: "fingerprint" } } - -def track_introduction_points(node): - nodenum = node._env["nodenum"] - nodenick = node._env["nick"] - - node_intro_circuits[nodenum] = {} - - node_intro_events[nodenum] = Queue.Queue() - - def listener(logevent): - prefix = "rend_service_intro_has_opened(): Established circuit " - if logevent.message.startswith(prefix): - circuit = logevent.message[len(prefix):].split(" ")[0] - fingerprint = logevent.message[len(prefix):].split(" ")[1][1:] - - node_intro_circuits[nodenum][circuit] = fingerprint - - added_intro_node = nodes_by_fingerprint[fingerprint] - - logging.info("%s: added %s (%s)" % (nodenick, added_intro_node._env["nick"], fingerprint)) - - node_intro_events[nodenum].put(("added", fingerprint)) - - prefix = "rend_services_introduce(): Giving up on " - if logevent.message.startswith(prefix) or "Giving up on" in logevent.message: - fingerprint = logevent.message[len(prefix):].split(" ")[0][1:41] - - for_deletion = [] - - for circuit, fp in node_intro_circuits[nodenum].iteritems(): - #log("circuit " + str(circuit) + " fp " + str(fp)) - if fingerprint == fp: - for_deletion.append(circuit) - - if len(for_deletion) == 0: - logging.info("got log message " + logevent.message + " but not deleting an introduction point") - - for circuit in for_deletion: - fingerprint = node_intro_circuits[nodenum][circuit] - - removed_intro_node = nodes_by_fingerprint[fingerprint] - - logging.info("%s: removed %s (%s)" % (nodenick, removed_intro_node._env["nick"], fingerprint)) - - node_intro_events[nodenum].put(("removed", fingerprint)) - del node_intro_circuits[nodenum][circuit] - logging.debug(nodenick + ": " + logevent.message) - - - node.getStemController().add_event_listener(listener, EventType.INFO) - logging.info("Tracking introduction points for " + node._env["nick"]) - -def track_introduction_point(node): - nodenum = node._env["nodenum"] - nodenick = node._env["nick"] - - introduction_point_circuits[node] = {} - - def listener(logevent): - prefix = " " - if logevent.message.startswith(prefix): - circuit = logevent.message[len(prefix):].split(" ")[0] - fingerprint = logevent.message[len(prefix):].split(" ")[1][1:] - - node_intro_circuits[nodenum][circuit] = fingerprint - - added_intro_node = nodes_by_fingerprint[fingerprint] - - logging.info("%s: added %s (%s)" % (nodenick, added_intro_node._env["nick"], fingerprint)) - - node_intro_events[nodenum].put(("added", fingerprint)) - - prefix = "rend_services_introduce(): Giving up on " - if logevent.message.startswith(prefix) or "Giving up on" in logevent.message: - logging.info(logevent.message) - fingerprint = logevent.message[len(prefix):].split(" ")[0][1:41] - - for_deletion = [] - - for circuit, fp in node_intro_circuits[nodenum].iteritems(): - #log("circuit " + str(circuit) + " fp " + str(fp)) - if fingerprint == fp: - for_deletion.append(circuit) - - if len(for_deletion) == 0: - logging.info("got log message " + logevent.message + " but not deleting an introduction point") - - for circuit in for_deletion: - fingerprint = node_intro_circuits[nodenum][circuit] - - removed_intro_node = nodes_by_fingerprint[fingerprint] - - logging.info("%s: removed %s (%s)" % (nodenick, removed_intro_node._env["nick"], fingerprint)) - - node_intro_events[nodenum].put(("removed", fingerprint)) - del node_intro_circuits[nodenum][circuit] - - - node.getStemController().add_event_listener(listener, EventType.INFO) - logging.info("Tracking introduction points for " + node._env["nick"]) - - -def determine_max_load(service_url, clients): - request_queue = Queue.Queue(1000) - singlelock = threading.Lock() - - responses = [] - - running = True - - class worker(threading.Thread): - def __init__ (self, client): - super(worker, self).__init__() - self.client = client - - def run(self): - while running: - try: - request = request_queue.get(True, 1) - - print("making request") - result = self.client.query("http://2oiifbe3wne4iaqb.onion/"); - - singlelock.acquire() - responses.append((result, time.time())) - print("result " + str(result)) - singlelock.release() - - # Let the queue know the job is finished. - request_queue.task_done() - except: - pass - - # Create worker threads - for client in clients: - worker(client).start() - - # Add elements to eueue at rate current_load - # Check size of queue, if above limit, return current_load - - while True: - # Determine Average Load - time_barrier = time.time() - 10.0 - - last_responses = [] - - singlelock.acquire() - for response, response_time in reversed(responses): - if response_time < time_barrier: - break - last_responses.append(response) - singlelock.release() - - current_average_load = len(last_responses) / 10.0 - print("current average load %f" % current_average_load) - - new_load = int(current_average_load) + 1 - - time_per_item = 1.0 / new_load - - for i in range(new_load): - print("putting in item") - request_queue.put(1) - time.sleep(time_per_item) - -def check_same_intro_points(): - intro_sets = [] - for introduction_points in node_intro_circuits.values(): - intro_sets.append(set(introduction_points.values())) - - if intro_sets[0].issubset(intro_sets[1]) and intro_sets[1].issubset(intro_sets[0]): - logging.info("Same introduction points") - for fingerprint in node_intro_circuits.values()[0].values(): - node = nodes_by_fingerprint[fingerprint] - logging.info(" - " + node._env["nick"] + "(" + fingerprint + ")") - return True - else: - logging.info("Not the same introduction points") - for num, circuits in node_intro_circuits.items(): - logging.info("node %i" % num) - for fingerprint in circuits.values(): - node = nodes_by_fingerprint[fingerprint] - logging.info(" - " + node._env["nick"] + "(" + fingerprint + ")") - return False diff --git a/networks/hs-intro-fail-2 b/networks/hs-intro-fail-2 new file mode 100644 index 0000000..23d4c6e --- /dev/null +++ b/networks/hs-intro-fail-2 @@ -0,0 +1,189 @@ +from chutney.Testing import * + +authority_nodes = Node.create(3, { + "tag": "a", + "authority": 1, + "relay": 1, + "torrc": "authority.tmpl" +}) + +# hidden service (hs) nodes +hs_nodes = [] + +hs_servers = [] + +from twisted.web import server, resource +from twisted.internet import reactor + +# Use twisted to create web servers in this script +class Site(resource.Resource): + isLeaf = True + numberRequests = 0 + + def __init__(self, siteNum): + self.siteNum = siteNum + + def render_GET(self, request): + self.numberRequests += 1 + request.setHeader("content-type", "text/plain") + return str(self.siteNum) + +base_port = 10080 +for i in range(2): + + port = base_port + i + + node = Node( + tag="h", + hiddenservice=1, + torrc="hidden-service.tmpl", + hiddenservicetarget="127.0.0.1:%i" % port + ) + hs_nodes.append(node) + + site = server.Site(Site(i)) + + s = reactor.listenTCP(port, site) + hs_servers.append(s) + + port += 1 + +client_nodes = Node.create(12, { + "tag": "c", + "torrc": "client.tmpl" +}) + +relay_nodes = Node.create(10, { + "tag": "r", + "relay": 1, + "torrc": "intro.tmpl" +}) + +thread.start_new_thread(reactor.run, (), {"installSignalHandlers": 0}) + +initial_nodes = authority_nodes + relay_nodes + client_nodes + hs_nodes[:1] + +def start(): + if not all([ n.getController().start() for n in initial_nodes ]): + return False + + logging.info("All initial nodes running") + + nodes_by_fingerprint = get_node_fingerprints(authority_nodes + relay_nodes) + + track_introduction_points(hs_nodes[0]) + + node_0_published_descriptor = threading.Event() + + def hs_node_0_listener(logevent): + if "Successfully uploaded v2 rend descriptors" in logevent.message: + node_0_published_descriptor.set() + + + hs_nodes[0].getStemController().add_event_listener(hs_node_0_listener, EventType.INFO) + + node_0_published_descriptor.wait() + + hs_nodes[0].getStemController().remove_event_listener(hs_node_0_listener) + + # list to cope with scope problems + node_counter = [len(hs_nodes) - 1] + node_counter_lock = threading.RLock() + + nodes_published_descriptors = threading.Event() + + def hs_node_listener(logevent): + if "Successfully uploaded v2 rend descriptors" in logevent.message: + with node_counter_lock: + node_counter[0] -= 1 + + if node_counter[0] == 0: + nodes_published_descriptors.set() + + for node in hs_nodes[1:]: + node.getController().start() + track_introduction_points(node) + + node.getStemController().add_event_listener(hs_node_listener, EventType.INFO) + + nodes_published_descriptors.wait() + + for node in hs_nodes[1:]: + node.getStemController().remove_event_listener(hs_node_listener) + + test_intro_failure(nodes_by_fingerprint) + +def test_intro_failure(nodes_by_fingerprint): + connection_test() + + time.sleep(5) + + # Select a random node that is being used as an introduction point + nodenum = random.choice(node_intro_circuits.keys()) + fingerprint = random.choice(node_intro_circuits[nodenum].values()) + + node = nodes_by_fingerprint[fingerprint] + + logging.info("stopping " + node._env["nick"] + " (" + fingerprint + ")") + + node.getStemController().close() + node.getController().stop() + + logging.info("begining to watch for the establishment of new introduction points") + + changed = [False for n in hs_nodes] + + intro_points_before = [set(node_intro_circuits[n._env["nodenum"]].values()) for n in hs_nodes] + + time.sleep(20) + + intro_points_after = [set(node_intro_circuits[n._env["nodenum"]].values()) for n in hs_nodes] + + for i, node in enumerate(hs_nodes): + before = intro_points_before[i] + after = intro_points_after[i] + + if before != after: + changed[i] = True + + if all(changed): + logging.info("All changed") + else: + logging.info("All did not change") + + check_same_intro_points() + + connection_test() + + for server in hs_servers: + server.stopListening() + + reactor.stop() + + stop() + +def connection_test(): + logging.info("Connecting to clients") + + responses = {str(i): 0 for i in range(len(hs_servers))} + + for c in client_nodes: + result = c.query("http://2oiifbe3wne4iaqb.onion/"); + + if result in responses: + responses[result] += 1 + else: + logging.info("Unknown response: " + str(result)) + + test_pass = True + + for node, responses in sorted(responses.items()): + logging.info(node + ": " + str(responses)) + + if responses == 0: + test_pass = False + + if test_pass: + logging.info("Test PASS") + else: + logging.info("Test FAIL") diff --git a/networks/hs-intro-fail-3 b/networks/hs-intro-fail-3 index 43b2d07..0e1b95c 100644 --- a/networks/hs-intro-fail-3 +++ b/networks/hs-intro-fail-3 @@ -111,7 +111,6 @@ def start(): for node in hs_nodes[1:]: node.getStemController().remove_event_listener(hs_node_listener) - #thread.start_new_thread(test_intro_failure, ()) test_intro_failure(nodes_by_fingerprint) def test_intro_failure(nodes_by_fingerprint): @@ -160,7 +159,6 @@ def test_intro_failure(nodes_by_fingerprint): server.stopListening() reactor.stop() - logging.info("stopped the reactor") stop() -- cgit v1.2.3