def test_write_to_db(self): """Test that topics and data can be written to the DB.""" # Create one topic and one datum to be created. ts = datetime.datetime.now() self.write_to_db([], [db_model.Topic(1, 'Topic')], [db_model.TopicDatum(ts, 1, '1.0')]) # Verify the items were written. session = sqlalchemy.orm.Session(bind=self.engine, expire_on_commit=False) actual_topics = session.query(db_model.Topic).all() actual_data = session.query(db_model.TopicDatum).all() self.assertEqual(1, len(actual_topics)) self.assertEqual(1, len(actual_data)) topic = actual_topics[0] self.assertEqual(1, topic.topic_id) self.assertEqual('Topic', topic.topic_name) datum = actual_data[0] self.assertEqual(ts, datum.ts) self.assertEqual(1, datum.topic_id) self.assertEqual('1.0', datum.value_string) session.close()
def new_data(start, end, topic_id, value_string, delta): """Creates a series of data within a given range. Args: start: The start of the date range (inclusive). end: The end of the date range (inclusive). topic_id: The topic ID. value_string: The value string. Returns: A list of datum objects, evenly spaced apart in the given date range. """ cur = start data = [] while cur <= end: data.append(db_model.TopicDatum(cur, topic_id, value_string)) cur += delta return data
def collect(self): """Queries all known metrics and writes their values to the database. Query string format: - iterations: The number of times to query the metrics. - wait_time: The time in seconds to wait between iterations. It is expected that this method will be invoked periodically by a task scheduling service (e.g. cron). Cron specifically may invoke a task as frequently as once per minute. To collect data approximately once per second, the number of iterations may be set to 60 and the wait time may be set to 1. """ iterations = bottle.request.query.get('iterations', '1') try: iterations = int(iterations) except ValueError: raise bottle.HTTPError(400) wait_time = bottle.request.query.get('wait_time', '1') try: wait_time = int(wait_time) except ValueError: raise bottle.HTTPError(400) # Map topic names to their IDs. topics = self._db_con.get_all_topics() topic_ids_by_name = {t.topic_name: t.topic_id for t in topics} # Query metrics. metrics = self._panel_con.metrics for _ in range(0, iterations): data = [ db_model.TopicDatum(datetime.datetime.now(), topic_ids_by_name[m.topic_name], self._panel_con.get_metric(m.name)) for m in metrics.values() ] self._db_con.write_data(data) time.sleep(wait_time)
def create_datum(options, ts): """Creates a datum object for the given timestamp and topic. Args: options: The configuration options for the current data generation run. ts: The datum timestamp. Returns: A populated datum object, ready for insertion. """ # value = offset # + A_cos * cos(omega * t) # + A_sin * sin(omega * t) # + fuzz factor omega = 2 * math.pi / options.period seconds = (ts - options.start).total_seconds() fuzz = random.uniform(-options.spread, options.spread) x = omega * seconds value = (options.amplitude_offset + options.amplitude_cos * math.cos(x) + options.amplitude_sin * math.sin(x) + fuzz) datum = db_model.TopicDatum(ts, options.topic_id, str(value)) return datum