Ejemplo n.º 1
0
    def test_differential_rate(self):
        difference = 2
        shortest = 10
        longest = 20
        patcher = mock.patch('katcp.sampling.time')
        mtime = patcher.start()
        self.addCleanup(patcher.stop)
        time_ = mtime.time
        time_.return_value = 0
        drate = sampling.SampleDifferentialRate(
            self.inform, self.sensor, difference, shortest, longest)
        self.assertEqual(
            drate.get_sampling(), sampling.SampleStrategy.DIFFERENTIAL_RATE)

        new_period = mock.Mock()
        drate.set_new_period_callback(new_period)

        self.assertEqual(len(self.calls), 0)
        drate.attach()
        self.assertEqual(len(self.calls), 1)
        # Bigger than `difference`, but too soon
        self.sensor.set_value(0)
        # Should not have added a call
        self.assertEqual(len(self.calls), 1)
        # Should have requested a future update at shortest-time
        new_period.assert_called_once_with(drate, 10)
        new_period.reset_mock()

        # call before shortest update period
        drate.periodic(7)
        # Should not have added a call
        self.assertEqual(len(self.calls), 1)
        # Call at next period, should call, and schedule a periodic update
        # `longest` later
        next_p = drate.periodic(10)
        self.assertEqual(len(self.calls), 2)
        self.assertEqual(next_p, 30)
        next_p = drate.periodic(30)
        self.assertEqual(len(self.calls), 3)
        self.assertEqual(next_p, 50)

        # Update with a too-small difference in value, should not send an
        # update, nor should it schedule a shortest-time future-update
        self.sensor.set_value(-1)
        self.assertEqual(len(self.calls), 3)
        self.assertEqual(new_period.called, False)

        next_p = drate.periodic(50)
        self.assertEqual(len(self.calls), 4)
        self.assertEqual(next_p, 70)
Ejemplo n.º 2
0
    def test_differential_rate(self):
        max_period = 10.
        min_period = 1.
        difference = 2
        differential_rate_strat = sampling.SampleDifferentialRate(
            self.inform, self.sensor, difference, min_period, max_period)
        self._add_strategy(differential_rate_strat)

        no_max_periods = 3

        # Do some 'max period' updates where the sensor has not changed
        for i in range(no_max_periods):
            self.timewarp(max_period, event_to_await=self.inform_called)

        call_times = [t for t, vals in self.calls]
        self.assertEqual(len(self.calls), no_max_periods + 1)
        self.assertEqual(call_times,
                         [self.start_time + i*max_period
                          for i in range(no_max_periods + 1)])

        del self.calls[:]

        # Now do a sensor update by more than `difference` without moving time
        # along, should not result in any additional updates
        update_time = self.time()
        expected_send_time = update_time + min_period
        # Intial value = 3, difference = 2, 3-2 = 1, but sensor must differ by
        # _more_ than difference, so choose 0
        self.sensor.set_value(0, self.sensor.NOMINAL, update_time)
        # There should, however, be a wake-wait event
        self.wake_waits.get(timeout=1)

        self.assertEqual(len(self.calls), 0)
        # Timewarp less than min update period, should not result in an inform
        # callback
        self.timewarp(min_period*0.6)
        self.assertEqual(len(self.calls), 0)

        # Move time beyond minimum step
        self.timewarp(min_period*1.01, event_to_await=self.inform_called)

        self.assertEqual(len(self.calls), 1)
        self.assertEqual(self.calls,
                         [(expected_send_time,
                           (self.sensor.name, update_time, 'nominal', '0'))])
        # Should not be any outstanding wake-waits
        self.assertEqual(self.wake_waits.qsize(), 0)

        del self.calls[:]

        # Do a sensor update by less than `difference`
        self.sensor.set_value(1, self.sensor.NOMINAL, update_time)
        # Time we expect the next max-period sample
        expected_send_time += max_period
        update_time = self.time()

        # Move time beyond minimum step, should not send an update, since the
        # sensor changed by less than `difference`
        self.timewarp(min_period*1.1)
        # Timewarp past the next expected max-period sample time
        self.timewarp(max_period - min_period,
                      event_to_await=self.inform_called)

        self.assertEqual(len(self.calls), 1)
        self.assertEqual(self.calls[0][0], expected_send_time)
        self.reactor._debug_now = False
        self.reactor.remove_strategy(differential_rate_strat)
Ejemplo n.º 3
0
    def test_differential_rate(self):
        delta = 2
        shortest = 1.5
        longest = 4.5
        t, status, value = self.sensor.read()

        DUT = sampling.SampleDifferentialRate(self.inform, self.sensor, delta,
                                              shortest, longest)
        self.assertEqual(DUT.get_sampling_formatted(),
                         (b'differential-rate', [b'2', b'1.5', b'4.5']))
        self.assertEqual(len(self.calls), 0)
        DUT.start()
        yield self.wake_ioloop()
        # Check initial update
        t_last_sent = self.ioloop_time
        self.assertEqual(self.calls, [(self.sensor, (t, status, value))])
        self.calls = []

        # Too soon, should not send update
        yield self.set_ioloop_time(t_last_sent + shortest * 0.99)
        value = value + delta + 1
        t = self.ioloop_time
        self.sensor.set(t, status, value)
        self.assertEqual(len(self.calls), 0)

        # Too soon again, should not send update
        yield self.set_ioloop_time(t_last_sent + shortest * 0.999)
        value = value + delta + 1
        t = self.ioloop_time
        self.sensor.set(t, status, value)
        self.assertEqual(len(self.calls), 0)

        # Should now get minimum time update
        yield self.set_ioloop_time(t_last_sent + shortest)
        t_last_sent = self.ioloop_time
        self.assertEqual(self.calls, [(self.sensor, (t, status, value))])
        self.calls = []

        # Warp to just before longest period, should not update
        yield self.set_ioloop_time(t_last_sent + longest * 0.999)
        self.assertEqual(len(self.calls), 0)

        # Warp to longest period, should update
        yield self.set_ioloop_time(t_last_sent + longest)
        t_last_sent = self.ioloop_time
        self.assertEqual(self.calls, [(self.sensor, (t, status, value))])
        self.calls = []

        # Warp to just before next longest period, should not update
        yield self.set_ioloop_time(t_last_sent + longest * 0.999)
        self.assertEqual(len(self.calls), 0)

        # Warp to longest period, should update
        yield self.set_ioloop_time(t_last_sent + longest)
        t_last_sent = self.ioloop_time
        self.assertEqual(self.calls, [(self.sensor, (t, status, value))])
        self.calls = []

        # Set value with to small a change, jump past min update time, no update should
        # happen
        value = value - delta
        self.sensor.set(self.ioloop_time, status, value)
        yield self.set_ioloop_time(t_last_sent + shortest)
        self.assertEqual(len(self.calls), 0)

        # Set new value with large enough difference, update should happen
        value = value - 1
        self.sensor.set(self.ioloop_time, status, value)
        t_last_sent = self.ioloop_time
        self.assertEqual(self.calls,
                         [(self.sensor, (t_last_sent, status, value))])
        self.calls = []

        # Now warp to after min period, change only status, update should happen
        yield self.set_ioloop_time(t_last_sent + shortest)
        status = Sensor.ERROR
        self.sensor.set(self.ioloop_time, status, value)
        self.assertEqual(self.calls,
                         [(self.sensor, (self.ioloop_time, status, value))])
        t_last_sent = self.ioloop_time
        self.calls = []

        yield self.set_ioloop_time(t_last_sent + shortest)
        status = Sensor.NOMINAL
        value = value + 1
        yield self._thread_update_check(self.ioloop_time, status, value)
        yield self._check_cancel(DUT)
        self.calls = []

        # Since strategy is cancelled, no futher updates should be sent
        yield self.set_ioloop_time(self.ioloop_time + 5 * longest)
        self.sensor.set(self.ioloop_time, Sensor.WARN, value + 3)
        self.assertEqual(len(self.calls), 0)