예제 #1
0
    def test_query_data(self):
        """Test querying for data."""
        n_records = 20

        channels = ["ch1", "ch2", "TRG"]
        trg_index = -1
        channel_count = len(channels)

        buf = Buffer(channels=channels)

        for i, data in enumerate(mock_data(n_records, channel_count)):
            data[trg_index] = 1.0 if i >= 10 else 0.0
            timestamp = float(i)
            buf.append(Record(data, timestamp, None))

        rows = buf.query_data(filters=[("TRG", ">", 0)],
                              ordering=("timestamp", "asc"),
                              max_results=1)

        self.assertEqual(len(rows), 1, "Should have limited to max_results.")
        self.assertEqual(rows[0].data[trg_index], 1.0,
                         "Should get filtered data.")
        self.assertEqual(rows[0].timestamp, 10.0,
                         "Should get first instance")
        buf.cleanup()
예제 #2
0
def _loop(mailbox, channels, archive_name):
    """Main server loop. Intended to be a Process target (and private to this
    module). Accepts messages through its mailbox queue, and takes the
    appropriate action based on the command and parameters contained within the
    message.

    Parameters
    ----------
        mailbox : Queue
            Used for inter-process communication.
        channels : list of str
            list of channel names in the underlying data table. Any records
            written to the buffer are expected to have an entry for each
            channel.
        archive_name : str
            sqlite database name
    """
    buf = Buffer(channels=channels, archive_name=archive_name)

    while True:
        # Messages should be tuples with the structure:
        # (sender, (command, params))
        # where sender is either None or a Queue.
        msg = mailbox.get()
        sender, body = msg
        command, params = body
        if command == MSG_EXIT:
            buf.cleanup(delete_archive=params)
            sender.put(('exit', 'ok'))
            break
        elif command == MSG_PUT:
            # params is the record to put
            buf.append(params)
        elif command == MSG_GET_ALL:
            sender.put(buf.all())
        elif command == MSG_COUNT:
            sender.put(len(buf))
        elif command == MSG_QUERY_SLICE:
            row_start, row_end, field = params
            log.debug("Sending query: %s", (row_start, row_end, field))
            sender.put(buf.query(row_start, row_end, field))
        elif command == MSG_QUERY:
            # Generic query
            filters, ordering, max_results = params
            sender.put(buf.query_data(filters, ordering, max_results))
        elif command == MSG_STARTED:
            sender.put(('started', 'ok'))
        else:
            log.debug("Error; message not understood: %s", msg)
예제 #3
0
    def test_query_with_invalid_filter_field(self):
        n = 20

        channels = ["ch1", "ch2", "TRG"]
        channel_count = len(channels)

        b = Buffer(channels=channels)

        for i, d in enumerate(_mockdata(n, channel_count)):
            timestamp = float(i)
            b.append(Record(d, timestamp, None))

        with pytest.raises(Exception):
            b.query_data(filters=[("ch3", ">", 0)])
        b.cleanup()
예제 #4
0
    def test_query_with_invalid_filter_field(self):
        """Test query with invalid filter field."""
        n_records = 20

        channels = ["ch1", "ch2", "TRG"]
        channel_count = len(channels)

        buf = Buffer(channels=channels)

        for i, data in enumerate(mock_data(n_records, channel_count)):
            timestamp = float(i)
            buf.append(Record(data, timestamp, None))

        with pytest.raises(Exception):
            buf.query_data(filters=[("ch3", ">", 0)])
        buf.cleanup()
예제 #5
0
    def test_query_with_invalid_order_direction(self):
        n = 20

        channels = ["ch1", "ch2", "TRG"]
        trg_index = -1
        channel_count = len(channels)

        b = Buffer(channels=channels)

        for i, d in enumerate(_mockdata(n, channel_count)):
            d[trg_index] = 1.0 if i >= 10 else 0.0
            timestamp = float(i)
            b.append(Record(d, timestamp, None))

        with pytest.raises(Exception):
            b.query_data(ordering=("ch1", "ascending"))
        b.cleanup()
예제 #6
0
    def test_query_with_invalid_order_direction(self):
        """Test query with invalid order direction"""
        n_records = 20

        channels = ["ch1", "ch2", "TRG"]
        trg_index = -1
        channel_count = len(channels)

        buf = Buffer(channels=channels)

        for i, data in enumerate(mock_data(n_records, channel_count)):
            data[trg_index] = 1.0 if i >= 10 else 0.0
            timestamp = float(i)
            buf.append(Record(data, timestamp, None))

        with pytest.raises(Exception):
            buf.query_data(ordering=("ch1", "ascending"))
        buf.cleanup()
예제 #7
0
    def test_buffer(self):
        """Test Buffer functionality."""

        n_records = 15000
        channel_count = 25
        channels = ["ch" + str(c) for c in range(channel_count)]

        buf = Buffer(channels=channels, chunksize=10000)

        append_timer = _Timer()
        timevalues = {}
        for i, data in enumerate(mock_data(n_records, channel_count)):
            timestamp = float(i)
            if i % 1000 == 0:
                timevalues[timestamp] = data
            with append_timer:
                buf.append(Record(data, timestamp, None))

        self.assertEqual(buf.start_time, 0.0)
        starttime = 0.0
        rows = buf.query(start=starttime, end=starttime +
                         1.0, field='timestamp')

        self.assertEqual(len(rows), 1, "Results should not include end value.")

        self.assertEqual(rows[0].timestamp, starttime)
        self.assertEqual(rows[0].data, timevalues[starttime])

        start_time = 1000.0
        end_time = 2000.0
        rows = buf.query(start=start_time, end=end_time, field='timestamp')
        self.assertEqual(len(rows), start_time)
        self.assertEqual(rows[0].data, timevalues[start_time])

        rows = buf.query(start=buf.start_time, field='timestamp')
        self.assertEqual(
            len(rows), n_records, ("Providing only the start should return "
                                   "the rest."))
        buf.cleanup()
예제 #8
0
    def test_query_before_flush(self):
        """If a query is made before chunksize records have been written,
        the data should still be available."""

        n = 1000
        channel_count = 25
        channels = ["ch" + str(c) for c in range(channel_count)]

        b = Buffer(channels=channels, chunksize=10000)

        for i, d in enumerate(_mockdata(n, channel_count)):
            timestamp = float(i)
            b.append(Record(d, timestamp, None))

        rows = b.query(start=b.start_time, field='timestamp')
        self.assertEqual(len(rows), n)
        self.assertEqual(len(b.all()), n)

        b.cleanup()
예제 #9
0
    def test_len(self):
        """Test buffer len."""
        n = 1000
        channel_count = 25
        channels = ["ch" + str(c) for c in range(channel_count)]

        b = Buffer(channels=channels)

        for i, d in enumerate(_mockdata(n, channel_count)):
            b.append(Record(d, float(i), None))

        self.assertEqual(len(b), n)
        b.cleanup()
예제 #10
0
    def test_len(self):
        """Test buffer len."""
        n_records = 1000
        channel_count = 25
        channels = ["ch" + str(c) for c in range(channel_count)]

        buf = Buffer(channels=channels)

        for i, data in enumerate(mock_data(n_records, channel_count)):
            buf.append(Record(data, float(i), None))

        self.assertEqual(len(buf), n_records)
        buf.cleanup()
예제 #11
0
    def test_latest(self):
        """Test query for most recent items."""
        n = 1000
        latest_n = 100
        channel_count = 25
        channels = ["ch" + str(c) for c in range(channel_count)]

        b = Buffer(channels=channels)

        latest = []
        for i, d in enumerate(_mockdata(n, channel_count)):
            timestamp = float(i)
            if i >= n - latest_n:
                latest.append((d, timestamp, i + 1))
            b.append(Record(d, timestamp, None))

        rows = b.latest(latest_n)
        for j, item in enumerate(reversed(latest)):
            self.assertEqual(item, rows[j])
        b.cleanup()