def setUp(self):
     self.start_time = 0
     self.sample_time = 10
     with mock.patch('downstream_farmer.utils.time.clock') as t:
         t.return_value = self.start_time
         self.tracker = LoadTracker(self.sample_time)
 def setUp(self):
     self.start_time = 0
     self.sample_time = 10
     with mock.patch('downstream_farmer.utils.time.clock') as t:
         t.return_value = self.start_time
         self.tracker = LoadTracker(self.sample_time)
class TestLoadTracker(unittest.TestCase):

    def setUp(self):
        self.start_time = 0
        self.sample_time = 10
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = self.start_time
            self.tracker = LoadTracker(self.sample_time)

    def test_init(self):
        self.assertEqual(self.start_time, self.tracker.start)

    def test_sample_start_full(self):
        now = 20
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = now
            sample_start = self.tracker.sample_start
        self.assertEqual(sample_start, now - self.sample_time)

    def test_sample_start_partial(self):
        now = 5
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = now
            sample_start = self.tracker.sample_start
        self.assertEqual(sample_start, self.start_time)

    def test_normal_chunks(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            # add a couple of work chunks
            t.return_value = 20
            self.tracker.start_work()
            t.return_value = 21
            self.tracker.finish_work()
            t.return_value = 22
            self.tracker.start_work()
            t.return_value = 23
            self.tracker.finish_work()
            self.assertEqual(self.tracker.work_time(), 2)
            self.assertAlmostEqual(self.tracker.load(), 2. / self.sample_time)

    def test_early_chunks(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = 1.
            self.tracker.start_work()
            t.return_value = 2.
            self.tracker.finish_work()
            self.assertEqual(self.tracker.work_time(), 1)
            self.assertAlmostEqual(self.tracker.load(), 1. / t.return_value)

    def test_finish_before_start(self):
        with self.assertRaises(RuntimeError) as ex:
            self.tracker.finish_work()
        self.assertEqual(str(ex.exception), 'Load tracker work chunk must be '
                         'started before it can be finished.')

    def test_chunk_expiry(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = 5
            self.tracker.start_work()
            t.return_value = 10
            self.tracker.finish_work()
            t.return_value = 15
            self.tracker.start_work()
            t.return_value = 20
            self.tracker.finish_work()
            t.return_value = 25
            self.tracker.start_work()
            t.return_value = 29
            self.tracker.finish_work()
            self.assertEqual(self.tracker.work_time(), 5)
            self.assertAlmostEqual(self.tracker.load(), 0.5)

    def test_unfinished_work(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = 5
            self.tracker.start_work()
            t.return_value = 10
            self.assertEqual(self.tracker.work_time(), 5)
            self.assertAlmostEqual(self.tracker.load(), 0.5)
class TestLoadTracker(unittest.TestCase):
    def setUp(self):
        self.start_time = 0
        self.sample_time = 10
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = self.start_time
            self.tracker = LoadTracker(self.sample_time)

    def test_init(self):
        self.assertEqual(self.start_time, self.tracker.start)

    def test_sample_start_full(self):
        now = 20
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = now
            sample_start = self.tracker.sample_start
        self.assertEqual(sample_start, now - self.sample_time)

    def test_sample_start_partial(self):
        now = 5
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = now
            sample_start = self.tracker.sample_start
        self.assertEqual(sample_start, self.start_time)

    def test_normal_chunks(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            # add a couple of work chunks
            t.return_value = 20
            self.tracker.start_work()
            t.return_value = 21
            self.tracker.finish_work()
            t.return_value = 22
            self.tracker.start_work()
            t.return_value = 23
            self.tracker.finish_work()
            self.assertEqual(self.tracker.work_time(), 2)
            self.assertAlmostEqual(self.tracker.load(), 2. / self.sample_time)

    def test_early_chunks(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = 1.
            self.tracker.start_work()
            t.return_value = 2.
            self.tracker.finish_work()
            self.assertEqual(self.tracker.work_time(), 1)
            self.assertAlmostEqual(self.tracker.load(), 1. / t.return_value)

    def test_finish_before_start(self):
        with self.assertRaises(RuntimeError) as ex:
            self.tracker.finish_work()
        self.assertEqual(
            str(ex.exception), 'Load tracker work chunk must be '
            'started before it can be finished.')

    def test_chunk_expiry(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = 5
            self.tracker.start_work()
            t.return_value = 10
            self.tracker.finish_work()
            t.return_value = 15
            self.tracker.start_work()
            t.return_value = 20
            self.tracker.finish_work()
            t.return_value = 25
            self.tracker.start_work()
            t.return_value = 29
            self.tracker.finish_work()
            self.assertEqual(self.tracker.work_time(), 5)
            self.assertAlmostEqual(self.tracker.load(), 0.5)

    def test_unfinished_work(self):
        with mock.patch('downstream_farmer.utils.time.clock') as t:
            t.return_value = 5
            self.tracker.start_work()
            t.return_value = 10
            self.assertEqual(self.tracker.work_time(), 5)
            self.assertAlmostEqual(self.tracker.load(), 0.5)