Exemplo n.º 1
0
  def test_authenticate_general_password(self):
    """
    Tests the authenticate function's password argument.
    """

    # this is a much better test if we're just using password auth, since
    # authenticate will work reguardless if there's something else to
    # authenticate with

    runner = test.runner.get_runner()
    tor_options = runner.get_options()
    is_password_only = test.runner.Torrc.PASSWORD in tor_options and test.runner.Torrc.COOKIE not in tor_options

    # tests without a password
    with runner.get_tor_socket(False) as control_socket:
      if is_password_only:
        self.assertRaises(stem.connection.MissingPassword, stem.connection.authenticate, control_socket)
      else:
        stem.connection.authenticate(control_socket, chroot_path = runner.get_chroot())
        test.runner.exercise_controller(self, control_socket)

    # tests with the incorrect password
    with runner.get_tor_socket(False) as control_socket:
      if is_password_only:
        self.assertRaises(stem.connection.IncorrectPassword, stem.connection.authenticate, control_socket, 'blarg')
      else:
        stem.connection.authenticate(control_socket, 'blarg', runner.get_chroot())
        test.runner.exercise_controller(self, control_socket)

    # tests with the right password
    with runner.get_tor_socket(False) as control_socket:
      stem.connection.authenticate(control_socket, test.runner.CONTROL_PASSWORD, runner.get_chroot())
      test.runner.exercise_controller(self, control_socket)
Exemplo n.º 2
0
 def test_authenticate_general_password(self):
   """
   Tests the authenticate function's password argument.
   """
   
   if test.runner.require_control(self): return
   
   # this is a much better test if we're just using password auth, since
   # authenticate will work reguardless if there's something else to
   # authenticate with
   
   runner = test.runner.get_runner()
   tor_options = runner.get_options()
   is_password_only = test.runner.Torrc.PASSWORD in tor_options and not test.runner.Torrc.COOKIE in tor_options
   
   # tests without a password
   with runner.get_tor_socket(False) as control_socket:
     if is_password_only:
       self.assertRaises(stem.connection.MissingPassword, stem.connection.authenticate, control_socket)
     else:
       stem.connection.authenticate(control_socket, chroot_path = runner.get_chroot())
       test.runner.exercise_controller(self, control_socket)
   
   # tests with the incorrect password
   with runner.get_tor_socket(False) as control_socket:
     if is_password_only:
       self.assertRaises(stem.connection.IncorrectPassword, stem.connection.authenticate, control_socket, "blarg")
     else:
       stem.connection.authenticate(control_socket, "blarg", runner.get_chroot())
       test.runner.exercise_controller(self, control_socket)
   
   # tests with the right password
   with runner.get_tor_socket(False) as control_socket:
     stem.connection.authenticate(control_socket, test.runner.CONTROL_PASSWORD, runner.get_chroot())
     test.runner.exercise_controller(self, control_socket)
Exemplo n.º 3
0
  def test_connection_time(self):
    """
    Checks that our connection_time method tracks when our state's changed.
    """

    test_start = time.time()
    runner = test.runner.get_runner()

    with runner.get_tor_socket() as control_socket:
      connection_time = control_socket.connection_time()

      # connection time should be between our tests start and now

      self.assertTrue(test_start <= connection_time <= time.time())

      # connection time should be absolute (shouldn't change as time goes on)

      time.sleep(0.1)
      self.assertEqual(connection_time, control_socket.connection_time())

      # should change to the disconnection time if we detactch

      control_socket.close()
      disconnection_time = control_socket.connection_time()
      self.assertTrue(connection_time < disconnection_time <= time.time())

      # then change again if we reconnect

      time.sleep(0.1)
      control_socket.connect()
      reconnection_time = control_socket.connection_time()
      self.assertTrue(disconnection_time < reconnection_time <= time.time())
Exemplo n.º 4
0
  def test_get_connections(self):
    """
    Checks for our control port in the stem.util.proc.get_connections output if
    we have one.
    """

    runner = test.runner.get_runner()

    if not proc.is_available():
      test.runner.skip(self, "(proc unavailable)")
      return
    elif not test.runner.Torrc.PORT in runner.get_options():
      test.runner.skip(self, "(no control port)")
      return
    elif not test.runner.get_runner().is_ptraceable():
      test.runner.skip(self, "(DisableDebuggerAttachment is set)")
      return

    # making a controller connection so that we have something to query for
    with runner.get_tor_socket():
      tor_pid = test.runner.get_runner().get_pid()

      for conn in proc.get_connections(tor_pid):
        if ("127.0.0.1", test.runner.CONTROL_PORT) == conn[:2]:
          return

      self.fail()
Exemplo n.º 5
0
    def check_resolver(self, resolver):
        runner = test.runner.get_runner()

        if test.runner.Torrc.PORT not in runner.get_options():
            self.skipTest('(no control port)')
            return
        elif resolver not in system_resolvers():
            self.skipTest('(resolver unavailable on this platform)')
            return

        with runner.get_tor_socket():
            connections = get_connections(resolver,
                                          process_pid=runner.get_pid())

            for conn in connections:
                if conn.local_address == '127.0.0.1' and conn.local_port == test.runner.CONTROL_PORT:
                    return

            resolver_command = RESOLVER_COMMAND[resolver].format(
                pid=runner.get_pid())
            resolver_output = stem.util.system.call(resolver_command)

            self.fail(
                'Unable to find our controller connection with %s (%s). Connections found were...\n\n%s\n\nCommand output was...\n\n%s'
                % (resolver, resolver_command, '\n'.join(map(
                    str, connections)), resolver_output))
Exemplo n.º 6
0
  def test_connections(self):
    """
    Checks for our control port in the stem.util.proc.connections output if
    we have one.
    """

    runner = test.runner.get_runner()

    if not proc.is_available():
      test.runner.skip(self, '(proc unavailable)')
      return
    elif test.runner.Torrc.PORT not in runner.get_options():
      test.runner.skip(self, '(no control port)')
      return
    elif not test.runner.get_runner().is_ptraceable():
      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
      return
    elif not os.access('/proc/net/tcp', os.R_OK) or not os.access('/proc/net/udp', os.R_OK):
      test.runner.skip(self, '(proc lacks read permissions)')
      return

    # making a controller connection so that we have something to query for
    with runner.get_tor_socket():
      tor_pid = test.runner.get_runner().get_pid()

      for conn in proc.connections(tor_pid):
        if ('127.0.0.1', test.runner.CONTROL_PORT) == conn[:2]:
          return

      self.fail()
Exemplo n.º 7
0
 def test_authenticate_general_cookie(self):
   """
   Tests the authenticate function with only cookie authentication methods.
   This manipulates our PROTOCOLINFO response to test each method
   individually.
   """
   
   if test.runner.require_control(self): return
   
   runner = test.runner.get_runner()
   tor_options = runner.get_options()
   is_cookie_only = test.runner.Torrc.COOKIE in tor_options and not test.runner.Torrc.PASSWORD in tor_options
   
   # test both cookie authentication mechanisms
   with runner.get_tor_socket(False) as control_socket:
     if is_cookie_only:
       for method in (stem.connection.AuthMethod.COOKIE, stem.connection.AuthMethod.SAFECOOKIE):
         protocolinfo_response = stem.connection.get_protocolinfo(control_socket)
         
         if method in protocolinfo_response.auth_methods:
           # narrow to *only* use cookie auth or safecooke, so we exercise
           # both independently
           
           protocolinfo_response.auth_methods = (method, )
           stem.connection.authenticate(control_socket, chroot_path = runner.get_chroot(), protocolinfo_response = protocolinfo_response)
Exemplo n.º 8
0
    def test_connection_time(self):
        """
    Checks that our connection_time method tracks when our state's changed.
    """

        test_start = time.time()
        runner = test.runner.get_runner()

        with runner.get_tor_socket() as control_socket:
            connection_time = control_socket.connection_time()

            # connection time should be between our tests start and now

            self.assertTrue(test_start <= connection_time <= time.time())

            # connection time should be absolute (shouldn't change as time goes on)

            time.sleep(0.001)
            self.assertEqual(connection_time, control_socket.connection_time())

            # should change to the disconnection time if we detactch

            control_socket.close()
            disconnection_time = control_socket.connection_time()
            self.assertTrue(
                connection_time < disconnection_time <= time.time())

            # then change again if we reconnect

            time.sleep(0.001)
            control_socket.connect()
            reconnection_time = control_socket.connection_time()
            self.assertTrue(
                disconnection_time < reconnection_time <= time.time())
Exemplo n.º 9
0
    def test_authenticate_general_cookie(self):
        """
    Tests the authenticate function with only cookie authentication methods.
    This manipulates our PROTOCOLINFO response to test each method
    individually.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()
        tor_options = runner.get_options()
        is_cookie_only = test.runner.Torrc.COOKIE in tor_options and not test.runner.Torrc.PASSWORD in tor_options

        # test both cookie authentication mechanisms
        with runner.get_tor_socket(False) as control_socket:
            if is_cookie_only:
                for method in (stem.connection.AuthMethod.COOKIE,
                               stem.connection.AuthMethod.SAFECOOKIE):
                    protocolinfo_response = stem.connection.get_protocolinfo(
                        control_socket)

                    if method in protocolinfo_response.auth_methods:
                        # narrow to *only* use cookie auth or safecooke, so we exercise
                        # both independently

                        protocolinfo_response.auth_methods = (method, )
                        stem.connection.authenticate(
                            control_socket,
                            chroot_path=runner.get_chroot(),
                            protocolinfo_response=protocolinfo_response)
Exemplo n.º 10
0
    def test_get_connections(self):
        """
    Checks for our control port in the stem.util.proc.get_connections output if
    we have one.
    """

        runner = test.runner.get_runner()

        if not proc.is_available():
            test.runner.skip(self, "(proc unavailable)")
            return
        elif not test.runner.Torrc.PORT in runner.get_options():
            test.runner.skip(self, "(no control port)")
            return
        elif not test.runner.get_runner().is_ptraceable():
            test.runner.skip(self, "(DisableDebuggerAttachment is set)")
            return

        # making a controller connection so that we have something to query for
        with runner.get_tor_socket():
            tor_pid = test.runner.get_runner().get_pid()

            for conn in proc.get_connections(tor_pid):
                if ("127.0.0.1", test.runner.CONTROL_PORT) == conn[:2]:
                    return

            self.fail()
Exemplo n.º 11
0
    def test_connections(self):
        """
    Checks for our control port in the stem.util.proc.connections output if
    we have one.
    """

        runner = test.runner.get_runner()

        if test.runner.Torrc.PORT not in runner.get_options():
            self.skiTestp('(no control port)')
            return
        elif not os.access('/proc/net/tcp', os.R_OK) or not os.access(
                '/proc/net/udp', os.R_OK):
            self.skipTest('(proc lacks read permissions)')
            return

        # making a controller connection so that we have something to query for
        with runner.get_tor_socket():
            tor_pid = test.runner.get_runner().get_pid()

            for conn in proc.connections(tor_pid):
                if ('127.0.0.1', test.runner.CONTROL_PORT) == conn[:2]:
                    return

            self.fail()
Exemplo n.º 12
0
 def test_authenticate_general_socket(self):
   """
   Tests that the authenticate function can authenticate to our socket.
   """
   
   runner = test.runner.get_runner()
   with runner.get_tor_socket(False) as control_socket:
     stem.connection.authenticate(control_socket, test.runner.CONTROL_PASSWORD, runner.get_chroot())
     test.runner.exercise_controller(self, control_socket)
Exemplo n.º 13
0
  def test_authenticate_general_socket(self):
    """
    Tests that the authenticate function can authenticate to our socket.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_socket(False) as control_socket:
      stem.connection.authenticate(control_socket, test.runner.CONTROL_PASSWORD, runner.get_chroot())
      test.runner.exercise_controller(self, control_socket)
Exemplo n.º 14
0
    def test_getinfo_config_text(self):
        """
    Parses the 'GETINFO config-text' response.
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_version(
                self, stem.version.Requirement.GETINFO_CONFIG_TEXT):
            return

        runner = test.runner.get_runner()

        # We can't be certain of the order, and there may be extra config-text
        # entries as per...
        # https://trac.torproject.org/projects/tor/ticket/2362
        #
        # so we'll just check that the response is a superset of our config

        torrc_contents = []

        for line in runner.get_torrc_contents().splitlines():
            line = line.strip()

            if line and not line.startswith("#"):
                torrc_contents.append(line)

        with runner.get_tor_socket() as control_socket:
            control_socket.send("GETINFO config-text")
            config_text_response = control_socket.recv()

            # the response should contain two entries, the first being a data response
            self.assertEqual(2, len(list(config_text_response)))
            self.assertEqual("OK", list(config_text_response)[1])
            self.assertEqual(("250", " ", "OK"),
                             config_text_response.content()[1])
            self.assertTrue(config_text_response.raw_content().startswith(
                "250+config-text=\r\n"))
            self.assertTrue(config_text_response.raw_content().endswith(
                "\r\n.\r\n250 OK\r\n"))
            self.assertTrue(
                str(config_text_response).startswith("config-text=\n"))
            self.assertTrue(str(config_text_response).endswith("\nOK"))

            for torrc_entry in torrc_contents:
                self.assertTrue("\n%s\n" %
                                torrc_entry in str(config_text_response))
                self.assertTrue(torrc_entry in list(config_text_response)[0])
                self.assertTrue(
                    "%s\r\n" %
                    torrc_entry in config_text_response.raw_content())
                self.assertTrue(
                    "%s" % torrc_entry in config_text_response.content()[0][2])
Exemplo n.º 15
0
  def test_getinfo_config_file(self):
    """
    Parses the 'GETINFO config-file' response.
    """

    runner = test.runner.get_runner()
    torrc_dst = runner.get_torrc_path()

    with runner.get_tor_socket() as control_socket:
      control_socket.send('GETINFO config-file')
      config_file_response = control_socket.recv()
      self.assertEqual('config-file=%s\nOK' % torrc_dst, str(config_file_response))
      self.assertEqual(['config-file=%s' % torrc_dst, 'OK'], list(config_file_response))
      self.assertEqual('250-config-file=%s\r\n250 OK\r\n' % torrc_dst, config_file_response.raw_content())
      self.assertEqual([('250', '-', 'config-file=%s' % torrc_dst), ('250', ' ', 'OK')], config_file_response.content())
Exemplo n.º 16
0
 def test_getinfo_config_file(self):
   """
   Parses the 'GETINFO config-file' response.
   """
   
   runner = test.runner.get_runner()
   torrc_dst = runner.get_torrc_path()
   
   with runner.get_tor_socket() as control_socket:
     control_socket.send("GETINFO config-file")
     config_file_response = control_socket.recv()
     self.assertEquals("config-file=%s\nOK" % torrc_dst, str(config_file_response))
     self.assertEquals(["config-file=%s" % torrc_dst, "OK"], list(config_file_response))
     self.assertEquals("250-config-file=%s\r\n250 OK\r\n" % torrc_dst, config_file_response.raw_content())
     self.assertEquals([("250", "-", "config-file=%s" % torrc_dst), ("250", " ", "OK")], config_file_response.content())
Exemplo n.º 17
0
  def test_send_buffered(self):
    """
    Sends multiple requests before receiving back any of the replies.
    """

    runner = test.runner.get_runner()
    tor_version = runner.get_tor_version()

    with runner.get_tor_socket() as control_socket:
      for _ in range(100):
        control_socket.send('GETINFO version')

      for _ in range(100):
        response = control_socket.recv()
        self.assertTrue(str(response).startswith('version=%s' % tor_version))
        self.assertTrue(str(response).endswith('\nOK'))
Exemplo n.º 18
0
    def test_getinfo_config_text(self):
        """
    Parses the 'GETINFO config-text' response.
    """

        runner = test.runner.get_runner()

        # We can't be certain of the order, and there may be extra config-text
        # entries as per...
        # https://trac.torproject.org/projects/tor/ticket/2362
        #
        # so we'll just check that the response is a superset of our config

        torrc_contents = []

        for line in runner.get_torrc_contents().splitlines():
            line = line.strip()

            if line and not line.startswith('#'):
                torrc_contents.append(line)

        with runner.get_tor_socket() as control_socket:
            control_socket.send('GETINFO config-text')
            config_text_response = control_socket.recv()

            # the response should contain two entries, the first being a data response
            self.assertEqual(2, len(list(config_text_response)))
            self.assertEqual('OK', list(config_text_response)[1])
            self.assertEqual(('250', ' ', 'OK'),
                             config_text_response.content()[1])
            self.assertTrue(config_text_response.raw_content().startswith(
                '250+config-text=\r\n'))
            self.assertTrue(config_text_response.raw_content().endswith(
                '\r\n.\r\n250 OK\r\n'))
            self.assertTrue(
                str(config_text_response).startswith('config-text=\n'))
            self.assertTrue(str(config_text_response).endswith('\nOK'))

            for torrc_entry in torrc_contents:
                self.assertTrue('\n%s\n' %
                                torrc_entry in str(config_text_response))
                self.assertTrue(torrc_entry in list(config_text_response)[0])
                self.assertTrue(
                    '%s\r\n' %
                    torrc_entry in config_text_response.raw_content())
                self.assertTrue(
                    '%s' % torrc_entry in config_text_response.content()[0][2])
Exemplo n.º 19
0
    def test_send_buffered(self):
        """
    Sends multiple requests before receiving back any of the replies.
    """

        runner = test.runner.get_runner()
        tor_version = runner.get_tor_version()

        with runner.get_tor_socket() as control_socket:
            for _ in range(100):
                control_socket.send('GETINFO version')

            for _ in range(100):
                response = control_socket.recv()
                self.assertTrue(
                    str(response).startswith('version=%s' % tor_version))
                self.assertTrue(str(response).endswith('\nOK'))
Exemplo n.º 20
0
  def test_getinfo_config_file(self):
    """
    Parses the 'GETINFO config-file' response.
    """

    if test.runner.require_control(self):
      return

    runner = test.runner.get_runner()
    torrc_dst = runner.get_torrc_path()

    with runner.get_tor_socket() as control_socket:
      control_socket.send('GETINFO config-file')
      config_file_response = control_socket.recv()
      self.assertEqual('config-file=%s\nOK' % torrc_dst, str(config_file_response))
      self.assertEqual(['config-file=%s' % torrc_dst, 'OK'], list(config_file_response))
      self.assertEqual('250-config-file=%s\r\n250 OK\r\n' % torrc_dst, config_file_response.raw_content())
      self.assertEqual([('250', '-', 'config-file=%s' % torrc_dst), ('250', ' ', 'OK')], config_file_response.content())
Exemplo n.º 21
0
  def check_resolver(self, resolver):
    runner = test.runner.get_runner()

    if test.runner.Torrc.PORT not in runner.get_options():
      self.skipTest('(no control port)')
      return
    elif resolver not in system_resolvers():
      self.skipTest('(resolver unavailable on this platform)')
      return

    with runner.get_tor_socket():
      connections = get_connections(resolver, process_pid = runner.get_pid())

      for conn in connections:
        if conn.local_address == '127.0.0.1' and conn.local_port == test.runner.CONTROL_PORT:
          return

      self.fail('Unable to find localhost connection with %s:\n%s' % (resolver, '\n'.join(connections)))
Exemplo n.º 22
0
  def test_getinfo_config_text(self):
    """
    Parses the 'GETINFO config-text' response.
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_version(self, stem.version.Requirement.GETINFO_CONFIG_TEXT):
      return

    runner = test.runner.get_runner()

    # We can't be certain of the order, and there may be extra config-text
    # entries as per...
    # https://trac.torproject.org/projects/tor/ticket/2362
    #
    # so we'll just check that the response is a superset of our config

    torrc_contents = []

    for line in runner.get_torrc_contents().splitlines():
      line = line.strip()

      if line and not line.startswith("#"):
        torrc_contents.append(line)

    with runner.get_tor_socket() as control_socket:
      control_socket.send("GETINFO config-text")
      config_text_response = control_socket.recv()

      # the response should contain two entries, the first being a data response
      self.assertEqual(2, len(list(config_text_response)))
      self.assertEqual("OK", list(config_text_response)[1])
      self.assertEqual(("250", " ", "OK"), config_text_response.content()[1])
      self.assertTrue(config_text_response.raw_content().startswith("250+config-text=\r\n"))
      self.assertTrue(config_text_response.raw_content().endswith("\r\n.\r\n250 OK\r\n"))
      self.assertTrue(str(config_text_response).startswith("config-text=\n"))
      self.assertTrue(str(config_text_response).endswith("\nOK"))

      for torrc_entry in torrc_contents:
        self.assertTrue("\n%s\n" % torrc_entry in str(config_text_response))
        self.assertTrue(torrc_entry in list(config_text_response)[0])
        self.assertTrue("%s\r\n" % torrc_entry in config_text_response.raw_content())
        self.assertTrue("%s" % torrc_entry in config_text_response.content()[0][2])
Exemplo n.º 23
0
    def check_resolver(self, resolver):
        runner = test.runner.get_runner()

        if test.runner.Torrc.PORT not in runner.get_options():
            self.skipTest('(no control port)')
            return
        elif resolver not in system_resolvers():
            self.skipTest('(resolver unavailable on this platform)')
            return

        with runner.get_tor_socket():
            connections = get_connections(resolver,
                                          process_pid=runner.get_pid())

            for conn in connections:
                if conn.local_address == '127.0.0.1' and conn.local_port == test.runner.CONTROL_PORT:
                    return

            self.fail('Unable to find localhost connection with %s:\n%s' %
                      (resolver, '\n'.join(connections)))
Exemplo n.º 24
0
  def test_get_connections(self):
    runner = test.runner.get_runner()

    if not test.runner.Torrc.PORT in runner.get_options():
      test.runner.skip(self, '(no control port)')
      return
    elif not test.runner.get_runner().is_ptraceable():
      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
      return

    for resolver in get_system_resolvers():
      with runner.get_tor_socket():
        tor_pid = test.runner.get_runner().get_pid()
        connections = get_connections(resolver, process_pid = tor_pid)

        for conn in connections:
          if conn.local_address == '127.0.0.1' and conn.local_port == test.runner.CONTROL_PORT:
            return

        self.fail('Unable to find localhost connection with %s:\n%s' % (resolver, '\n'.join(connections)))
Exemplo n.º 25
0
  def test_getinfo_config_text(self):
    """
    Parses the 'GETINFO config-text' response.
    """

    runner = test.runner.get_runner()

    # We can't be certain of the order, and there may be extra config-text
    # entries as per...
    # https://trac.torproject.org/projects/tor/ticket/2362
    #
    # so we'll just check that the response is a superset of our config

    torrc_contents = []

    for line in runner.get_torrc_contents().splitlines():
      line = line.strip()

      if line and not line.startswith('#'):
        torrc_contents.append(line)

    with runner.get_tor_socket() as control_socket:
      control_socket.send('GETINFO config-text')
      config_text_response = control_socket.recv()

      # the response should contain two entries, the first being a data response
      self.assertEqual(2, len(list(config_text_response)))
      self.assertEqual('OK', list(config_text_response)[1])
      self.assertEqual(('250', ' ', 'OK'), config_text_response.content()[1])
      self.assertTrue(config_text_response.raw_content().startswith('250+config-text=\r\n'))
      self.assertTrue(config_text_response.raw_content().endswith('\r\n.\r\n250 OK\r\n'))
      self.assertTrue(str(config_text_response).startswith('config-text=\n'))
      self.assertTrue(str(config_text_response).endswith('\nOK'))

      for torrc_entry in torrc_contents:
        self.assertTrue('\n%s\n' % torrc_entry in str(config_text_response))
        self.assertTrue(torrc_entry in list(config_text_response)[0])
        self.assertTrue('%s\r\n' % torrc_entry in config_text_response.raw_content())
        self.assertTrue('%s' % torrc_entry in config_text_response.content()[0][2])
Exemplo n.º 26
0
    def test_getinfo_config_file(self):
        """
    Parses the 'GETINFO config-file' response.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()
        torrc_dst = runner.get_torrc_path()

        with runner.get_tor_socket() as control_socket:
            control_socket.send("GETINFO config-file")
            config_file_response = control_socket.recv()
            self.assertEquals("config-file=%s\nOK" % torrc_dst,
                              str(config_file_response))
            self.assertEquals(["config-file=%s" % torrc_dst, "OK"],
                              list(config_file_response))
            self.assertEquals("250-config-file=%s\r\n250 OK\r\n" % torrc_dst,
                              config_file_response.raw_content())
            self.assertEquals([("250", "-", "config-file=%s" % torrc_dst),
                               ("250", " ", "OK")],
                              config_file_response.content())