text: from mock import patch, MagicMock
  
  from ooni.settings import config
  from ooni.director import Director
  from ooni.nettest import NetTestLoader
  from ooni.tests.bases import ConfigTestCase
  
  from ooni.nettest import NetTestLoader
  
  from twisted.internet import defer
  from twisted.trial import unittest
  
  from txtorcon import TorControlProtocol
  
  test_failing_twice = """
  from twisted.internet import defer, reactor
  from ooni.nettest import NetTestCase
  
  class TestFailingTwice(NetTestCase):
      inputs = ["spam-{}".format(idx) for idx in range(50)]
  
      def setUp(self):
          self.summary[self.input] = self.summary.get(self.input, 0)
  
      def test_a(self):
          run_count = self.summary[self.input]
          delay = float(self.input.split("-")[1])/1000
          d = defer.Deferred()
          def callback():
              self.summary[self.input] += 1
              if run_count < 3:
                  d.errback(Exception("Failing"))
              else:
                  d.callback(self.summary[self.input])
  
          reactor.callLater(delay, callback)
          return d
  """
  
  proto = MagicMock()
  proto.tor_protocol = TorControlProtocol()
  
  mock_TorState = MagicMock()
  # We use the instance of mock_TorState so that the mock caching will
  # return the same instance when TorState is created.
  mts = mock_TorState()
  mts.protocol.get_conf = lambda x: defer.succeed({'SocksPort': '4242'})
  mts.post_bootstrap = defer.succeed(mts)
  
  # Set the tor_protocol to be already fired
  state = MagicMock()
  proto.tor_protocol.post_bootstrap = defer.succeed(state)
  
  mock_launch_tor = MagicMock()
  mock_launch_tor.return_value = defer.succeed(proto)
  
  
  class TestDirector(ConfigTestCase):
      def tearDown(self):
          super(TestDirector, self).tearDown()
          config.tor_state = None
  
      def test_get_net_tests(self):
          director = Director()
          nettests = director.getNetTests()
          assert 'http_requests' in nettests
          assert 'dns_consistency' in nettests
          assert 'http_header_field_manipulation' in nettests
          assert 'traceroute' in nettests
  
      @patch('ooni.director.TorState', mock_TorState)
      @patch('ooni.director.launch_tor', mock_launch_tor)
      def test_start_tor(self):
          @defer.inlineCallbacks
          def director_start_tor():
              director = Director()
              yield director.startTor()
              assert config.tor.socks_port == 4242
              assert config.tor.control_port == 4242
  
          return director_start_tor()
  
      def test_run_test_fails_twice(self):
          finished = defer.Deferred()
  
          def net_test_done(net_test):
              summary_items = net_test.summary.items()
              self.assertEqual(len(summary_items), 50)
              for input_name, run_count in summary_items:
                  self.assertEqual(run_count, 3)
              finished.callback(None)
  
          net_test_loader = NetTestLoader(('spam','ham'))
          net_test_loader.loadNetTestString(test_failing_twice)
          director = Director()
          director.netTestDone = net_test_done
          director.startNetTest(net_test_loader, None, no_yamloo=True)
          return finished
  
  
  class TestStartSniffing(unittest.TestCase):
      def setUp(self):
          self.director = Director()
          self.testDetails = {
              'test_name': 'foo',
              'test_start_time': '2016-01-01 12:34:56'
          }
  
          # Each NetTestCase has a name attribute
          class FooTestCase(object):
              name = 'foo'
          self.FooTestCase = FooTestCase
  
      def test_start_sniffing_once(self):
          with patch('ooni.settings.config.scapyFactory') as mock_scapy_factory:
              with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
                  self.director.startSniffing(self.testDetails)
                  sniffer = mock_scapy_sniffer.return_value
                  mock_scapy_factory.registerProtocol.assert_called_once_with(sniffer)
  
      def test_start_sniffing_twice(self):
          with patch('ooni.settings.config.scapyFactory') as mock_scapy_factory:
              with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
                  sniffer = mock_scapy_sniffer.return_value
                  sniffer.pcapwriter.filename = 'foo1_filename'
                  self.director.startSniffing(self.testDetails)
                  self.assertEqual(len(self.director.sniffers), 1)
  
              self.testDetails = {
                  'test_name': 'bar',
                  'test_start_time': '2016-01-01 12:34:56'
              }
              with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
                  sniffer = mock_scapy_sniffer.return_value
                  sniffer.pcapwriter.filename = 'foo2_filename'
                  self.director.startSniffing(self.testDetails)
                  self.assertEqual(len(self.director.sniffers), 2)
  
      def test_measurement_succeeded(self):
          with patch('ooni.settings.config.scapyFactory') as mock_scapy_factory:
              with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
                  self.director.startSniffing(self.testDetails)
                  self.assertEqual(len(self.director.sniffers), 1)
                  measurement = MagicMock()
                  measurement.testInstance = self.FooTestCase()
                  self.director.measurementSucceeded('awesome', measurement)
                  self.assertEqual(len(self.director.sniffers), 0)
                  sniffer = mock_scapy_sniffer.return_value
                  mock_scapy_factory.unRegisterProtocol.assert_called_once_with(sniffer)
  
  