Browse Source

Merge remote-tracking branch 'mvdan/master'

Nick Mathewson 9 years ago
parent
commit
b36c79cd73
3 changed files with 74 additions and 79 deletions
  1. 3 2
      lib/chutney/Templating.py
  2. 62 59
      lib/chutney/TorNet.py
  3. 9 18
      lib/chutney/Traffic.py

+ 3 - 2
lib/chutney/Templating.py

@@ -76,6 +76,7 @@
 
 """
 
+from __future__ import print_function
 from __future__ import with_statement
 
 import string
@@ -369,9 +370,9 @@ if __name__ == '__main__':
     if len(sys.argv) == 1:
         import doctest
         doctest.testmod()
-        print "done"
+        print("done")
     else:
         for fn in sys.argv[1:]:
             with open(fn, 'r') as f:
                 t = Template(f.read())
-                print fn, t.freevars()
+                print(fn, t.freevars())

+ 62 - 59
lib/chutney/TorNet.py

@@ -7,6 +7,7 @@
 #  restrict, so long as you retain the above notice(s) and this license
 #  in all redistributed copies and derived works.  There is no warranty.
 
+from __future__ import print_function
 from __future__ import with_statement
 
 # Get verbose tracebacks, so we can diagnose better.
@@ -29,13 +30,17 @@ _TORRC_OPTIONS = None
 _THE_NETWORK = None
 
 
-def mkdir_p(d, mode=0777):
+def mkdir_p(d, mode=511):
     """Create directory 'd' and all of its parents as needed.  Unlike
        os.makedirs, does not give an error if d already exists.
+
+       511 is the decimal representation of the octal number 0777. Since
+       python2 only supports 0777 and python3 only supports 0o777, we can use
+       neither.
     """
     try:
         os.makedirs(d, mode=mode)
-    except OSError, e:
+    except OSError as e:
         if e.errno == errno.EEXIST:
             return
         raise
@@ -66,7 +71,7 @@ class Node(object):
         self._controller = None
 
     def getN(self, N):
-        return [Node(self) for _ in xrange(N)]
+        return [Node(self) for _ in range(N)]
 
     def specialize(self, **kwargs):
         return Node(parent=self, **kwargs)
@@ -352,16 +357,16 @@ class LocalNodeBuilder(NodeBuilder):
             '-c', certfile,
             '-m', str(lifetime),
             '-a', addr]
-        print "Creating identity key %s for %s with %s" % (
-            idfile, self._env['nick'], " ".join(cmdline))
+        print("Creating identity key %s for %s with %s" % (
+            idfile, self._env['nick'], " ".join(cmdline)))
         try:
             p = subprocess.Popen(cmdline, stdin=subprocess.PIPE)
         except OSError as e:
             # only catch file not found error
             if e.errno == errno.ENOENT:
-                print ("Cannot find tor-gencert binary %r. Use "
-                       "CHUTNEY_TOR_GENCERT environment variable to set the "
-                       "path, or put the binary into $PATH.") % tor_gencert
+                print("Cannot find tor-gencert binary %r. Use "
+                      "CHUTNEY_TOR_GENCERT environment variable to set the "
+                      "path, or put the binary into $PATH.") % tor_gencert
                 sys.exit(0)
             else:
                 raise
@@ -387,9 +392,9 @@ class LocalNodeBuilder(NodeBuilder):
         except OSError as e:
             # only catch file not found error
             if e.errno == errno.ENOENT:
-                print ("Cannot find tor binary %r. Use "
-                       "CHUTNEY_TOR environment variable to set the "
-                       "path, or put the binary into $PATH.") % tor
+                print("Cannot find tor binary %r. Use "
+                      "CHUTNEY_TOR environment variable to set the "
+                      "path, or put the binary into $PATH.") % tor
                 sys.exit(0)
             else:
                 raise
@@ -488,7 +493,7 @@ class LocalNodeController(NodeController):
 
         try:
             os.kill(pid, 0)  # "kill 0" == "are you there?"
-        except OSError, e:
+        except OSError as e:
             if e.errno == errno.ESRCH:
                 return False
             raise
@@ -508,18 +513,19 @@ class LocalNodeController(NodeController):
         pid = self.getPid()
         nick = self._env['nick']
         datadir = self._env['dir']
+        corefile = "core.%s" % pid
         if self.isRunning(pid):
             if listRunning:
-                print "%s is running with PID %s" % (nick, pid)
+                print("%s is running with PID %s" % (nick, pid))
             return True
-        elif os.path.exists(os.path.join(datadir, "core.%s" % pid)):
+        elif os.path.exists(os.path.join(datadir, corefile)):
             if listNonRunning:
-                print "%s seems to have crashed, and left core file core.%s" % (
-                    nick, pid)
+                print("%s seems to have crashed, and left core file %s" % (
+                    nick, corefile))
             return False
         else:
             if listNonRunning:
-                print "%s is stopped" % nick
+                print("%s is stopped" % nick)
             return False
 
     def hup(self):
@@ -527,11 +533,11 @@ class LocalNodeController(NodeController):
         pid = self.getPid()
         nick = self._env['nick']
         if self.isRunning(pid):
-            print "Sending sighup to %s" % nick
+            print("Sending sighup to %s" % nick)
             os.kill(pid, signal.SIGHUP)
             return True
         else:
-            print "%s is not running" % nick
+            print("%s is not running" % nick)
             return False
 
     def start(self):
@@ -539,7 +545,7 @@ class LocalNodeController(NodeController):
            already running, False if we failed."""
 
         if self.isRunning():
-            print "%s is already running" % self._env['nick']
+            print("%s is already running" % self._env['nick'])
             return True
         tor_path = self._env['tor']
         torrc = self._getTorrcFname()
@@ -553,9 +559,9 @@ class LocalNodeController(NodeController):
         except OSError as e:
             # only catch file not found error
             if e.errno == errno.ENOENT:
-                print ("Cannot find tor binary %r. Use CHUTNEY_TOR "
-                       "environment variable to set the path, or put the binary "
-                       "into $PATH.") % tor_path
+                print("Cannot find tor binary %r. Use CHUTNEY_TOR "
+                      "environment variable to set the path, or put the "
+                      "binary into $PATH.") % tor_path
                 sys.exit(0)
             else:
                 raise
@@ -578,16 +584,16 @@ class LocalNodeController(NodeController):
             p.poll()
         if p.returncode != None and p.returncode != 0:
             if self._env['poll_launch_time'] is None:
-                print "Couldn't launch %s (%s): %s" % (self._env['nick'],
+                print("Couldn't launch %s (%s): %s" % (self._env['nick'],
                                                        " ".join(cmdline),
-                                                       p.returncode)
+                                                       p.returncode))
             else:
-                print ("Couldn't poll %s (%s) "
+                print("Couldn't poll %s (%s) "
                        "after waiting %s seconds for launch"
-                       ": %s") % (self._env['nick'],
+                       ": %s" % (self._env['nick'],
                                   " ".join(cmdline),
                                   self._env['poll_launch_time'],
-                                  p.returncode)
+                                  p.returncode))
             return False
         return True
 
@@ -595,17 +601,16 @@ class LocalNodeController(NodeController):
         """Try to stop this node by sending it the signal 'sig'."""
         pid = self.getPid()
         if not self.isRunning(pid):
-            print "%s is not running" % self._env['nick']
+            print("%s is not running" % self._env['nick'])
             return
         os.kill(pid, sig)
 
     def cleanup_lockfile(self):
         lf = self._env['lockfile']
-        if self.isRunning() or (not os.path.exists(lf)):
-            return
-        print 'Removing stale lock file for {0} ...'.format(
-            self._env['nick'])
-        os.remove(lf)
+        if not self.isRunning() and os.path.exists(lf):
+            print('Removing stale lock file for {0} ...'.format(
+                self._env['nick']))
+            os.remove(lf)
 
     def waitOnLaunch(self):
         """Check whether we can wait() for the tor process to launch"""
@@ -709,16 +714,14 @@ class TorEnviron(chutney.Templating.Environ):
     def _get_dir(self, my):
         return os.path.abspath(os.path.join(my['net_base_dir'],
                                             "nodes",
-                                            "%03d%s" % (my['nodenum'], my['tag'])))
+                                            "%03d%s" % (
+                                                my['nodenum'], my['tag'])))
 
     def _get_nick(self, my):
         return "test%03d%s" % (my['nodenum'], my['tag'])
 
     def _get_tor_gencert(self, my):
-        if my['tor-gencert']:
-            return my['tor-gencert']
-        else:
-            return '{0}-gencert'.format(my['tor'])
+        return my['tor-gencert'] or '{0}-gencert'.format(my['tor'])
 
     def _get_auth_passphrase(self, my):
         return self['nick']  # OMG TEH SECURE!
@@ -778,10 +781,8 @@ class Network(object):
     def status(self):
         statuses = [n.getController().check() for n in self._nodes]
         n_ok = len([x for x in statuses if x])
-        print "%d/%d nodes are running" % (n_ok, len(self._nodes))
-        if n_ok != len(self._nodes):
-            return False
-        return True
+        print("%d/%d nodes are running" % (n_ok, len(self._nodes)))
+        return n_ok == len(self._nodes)
 
     def restart(self):
         self.stop()
@@ -793,17 +794,17 @@ class Network(object):
             sys.stdout.write("Starting nodes")
             sys.stdout.flush()
         else:
-            print "Starting nodes"
+            print("Starting nodes")
         rv = all([n.getController().start() for n in self._nodes])
         # now print a newline unconditionally - this stops poll()ing
         # output from being squashed together, at the cost of a blank
         # line in wait()ing output
-        print ""
+        print("")
         return rv
     
 
     def hup(self):
-        print "Sending SIGHUP to nodes"
+        print("Sending SIGHUP to nodes")
         return all([n.getController().hup() for n in self._nodes])
 
     def stop(self):
@@ -811,12 +812,12 @@ class Network(object):
         for sig, desc in [(signal.SIGINT, "SIGINT"),
                           (signal.SIGINT, "another SIGINT"),
                           (signal.SIGKILL, "SIGKILL")]:
-            print "Sending %s to nodes" % desc
+            print("Sending %s to nodes" % desc)
             for c in controllers:
                 if c.isRunning():
                     c.stop(sig=sig)
-            print "Waiting for nodes to finish."
-            for n in xrange(15):
+            print("Waiting for nodes to finish.")
+            for n in range(15):
                 time.sleep(1)
                 if all(not c.isRunning() for c in controllers):
                     # check for stale lock file when Tor crashes
@@ -832,10 +833,7 @@ class Network(object):
         sys.stdout.write("Verifying data transmission: ")
         sys.stdout.flush()
         status = self._verify_traffic()
-        if status:
-            print("Success")
-        else:
-            print("Failure")
+        print("Success" if status else "Failure")
         return status
 
     def _verify_traffic(self):
@@ -850,7 +848,8 @@ class Network(object):
         tt = chutney.Traffic.TrafficTester(bind_to, tmpdata, TIMEOUT)
         for op in filter(lambda n: n._env['tag'] == 'c', self._nodes):
             tt.add(chutney.Traffic.Source(tt, bind_to, tmpdata,
-                                          ('localhost', int(op._env['socksport']))))
+                                          ('localhost',
+                                           int(op._env['socksport']))))
         return tt.run()
 
 
@@ -866,7 +865,8 @@ def ConfigureNodes(nodelist):
 def usage(network):
     return "\n".join(["Usage: chutney {command} {networkfile}",
                       "Known commands are: %s" % (
-                          " ".join(x for x in dir(network) if not x.startswith("_")))])
+                          " ".join(x for x in dir(network)
+                                   if not x.startswith("_")))])
 
 
 def exit_on_error(err_msg):
@@ -874,18 +874,21 @@ def exit_on_error(err_msg):
     print usage(_THE_NETWORK)
     sys.exit(1)
 
-def runConfigFile(verb, f):
+def runConfigFile(verb, path):
     _GLOBALS = dict(_BASE_ENVIRON=_BASE_ENVIRON,
                     Node=Node,
                     ConfigureNodes=ConfigureNodes,
                     _THE_NETWORK=_THE_NETWORK)
 
-    exec f in _GLOBALS
+    with open(path) as f:
+        data = f.read()
+
+    exec(data, _GLOBALS)
     network = _GLOBALS['_THE_NETWORK']
 
     if not hasattr(network, verb):
-        print usage(network)
-        print "Error: I don't know how to %s." % verb
+        print(usage(network))
+        print("Error: I don't know how to %s." % verb)
         return
 
     return getattr(network, verb)()

+ 9 - 18
lib/chutney/Traffic.py

@@ -20,6 +20,9 @@
 #
 # For example code, see main() below.
 
+from __future__ import print_function
+
+import sys
 import socket
 import select
 import struct
@@ -152,8 +155,7 @@ class Sink(Peer):
         if len(self.inbuf) == len(data):
             if self.inbuf != data:
                 return -1       # Failed verification.
-            else:
-                debug("successful verification")
+            debug("successful verification")
         return len(data) - len(self.inbuf)
 
 
@@ -178,13 +180,10 @@ class Source(Peer):
     def connect(self, endpoint):
         self.dest = endpoint
         self.state = self.CONNECTING
-        if self.proxy is None:
-            dest = self.dest
-        else:
-            dest = self.proxy
+        dest = self.proxy or self.dest
         try:
             self.s.connect(dest)
-        except socket.error, e:
+        except socket.error as e:
             if e[0] != errno.EINPROGRESS:
                 raise
 
@@ -213,11 +212,7 @@ class Source(Peer):
         return 1                # Keep us around for writing.
 
     def want_to_write(self):
-        if self.state == self.CONNECTING:
-            return True
-        if len(self.outbuf) > 0:
-            return True
-        return False
+        return self.state == self.CONNECTING or len(self.outbuf) > 0
 
     def on_writable(self):
         """Invoked when the socket becomes writable.
@@ -235,7 +230,7 @@ class Source(Peer):
                 self.outbuf = socks_cmd(self.dest)
         try:
             n = self.s.send(self.outbuf)
-        except socket.error, e:
+        except socket.error as e:
             if e[0] == errno.ECONNREFUSED:
                 debug("connection refused (fd=%d)" % self.fd())
                 return -1
@@ -284,9 +279,7 @@ class TrafficTester():
         self.pending_close.append(peer.s)
 
     def run(self):
-        while True:
-            if self.tests.all_done() or self.timeout == 0:
-                break
+        while not self.tests.all_done() and self.timeout > 0:
             rset = [self.listener.fd()] + list(self.peers)
             wset = [p.fd() for p in
                     filter(lambda x: x.want_to_write(), self.sources())]
@@ -329,8 +322,6 @@ class TrafficTester():
             s.close()
         return self.tests.all_done() and self.tests.failure_count() == 0
 
-import sys
-
 
 def main():
     """Test the TrafficTester by sending and receiving some data."""