def create():
  api = API()
  metric_id = 'API_TEST_METRIC'
  value = ranint(0, 99)
  source = 'foo'
  timestamp = datetime.now().strftime('%s')
  api.measurement_create(metric_id, value, source, timestamp)
Example #2
0
    def setUp(self):
        self.api = API()
        logging.basicConfig(level=logging.DEBUG)
        self.name = 'TEST_' + TestUtils.random_string(6)
        self.display_name = 'green'
        self.display_name_short = 'blue'
        self.description = 'magenta'
        self.default_aggregate = aggregates.SUM
        self.default_resolution = 60000
        self.unit = units.DURATION
        self.type = 'FOOBAR'
        self.is_disabled = False
        self.metric = Metric(name=self.name,
                             display_name=self.display_name,
                             display_name_short=self.display_name_short,
                             description=self.description,
                             default_aggregate=self.default_aggregate,
                             default_resolution=self.default_resolution,
                             unit=self.unit,
                             _type=self.type,
                             is_disabled=self.is_disabled)

        self.api.metric_create_batch([self.metric])

        logging.basicConfig(level=logging.INFO)
Example #3
0
class Common(object):
    def __init__(self, ):
        self.api = API()
        self.usage_args = ""
        # Set our application id from the environment variable
        self.app_id = os.environ['TSI_APP_ID']

    @staticmethod
    def usage(args):
        sys.stderr.write("usage: {0} {1}\n".format(os.path.basename(sys.argv[0]), args))

    def send_measurements(self, measurements):
        """
        Sends measurements using the Measurement API

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def run(self):
        """
        Main loop
        """
        while True:
            print("Doing absolutely nothing")
            time.sleep(self.interval)
Example #4
0
class Common(object):
    def __init__(self, ):
        self.api = API()
        self.usage_args = ""
        # Set our application id from the environment variable
        self.app_id = os.environ['TSI_APP_ID']

    @staticmethod
    def usage(args):
        sys.stderr.write("usage: {0} {1}\n".format(
            os.path.basename(sys.argv[0]), args))

    def send_measurements(self, measurements):
        """
        Sends measurements using the Measurement API

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def run(self):
        """
        Main loop
        """
        while True:
            print("Doing absolutely nothing")
            time.sleep(self.interval)
class HostgroupTest(TestCase):
    def setUp(self):
        self.api = API()

    def test_create(self):
        self.api.hostgroup_create("test" + TestUtils.random_string(6), ["red", "green", "blue"])

    def test_empty_name(self):
        try:
            self.api.hostgroup_create(None, ["red", "green", "blue"])
        except HTTPResponseError as e:
            pass
def create_batch():
  delay = 30
  api = API()
  measurements = []
  timestamp = int(datetime.now().strftime('%s'))
  # skew timestamp by 5 seconds
  timestamp = timestamp - delay
  measurements.append(Measurement(metric='API_TEST_METRIC', value=randint(0, 99), source='red', timestamp=timestamp))
  measurements.append(Measurement(metric='API_TEST_METRIC', value=randint(0, 99), source='green', timestamp=timestamp))
  measurements.append(Measurement(metric='API_TEST_METRIC', value=randint(0, 99), source='blue', timestamp=timestamp))
#  sleep(float(delay))
  api.measurement_create_batch(measurements)
Example #7
0
class HostgroupTest(TestCase):
    def setUp(self):
        self.api = API()

    def test_create(self):
        self.api.hostgroup_create('test' + TestUtils.random_string(6),
                                  ['red', 'green', 'blue'])

    def test_empty_name(self):
        try:
            self.api.hostgroup_create(None, ['red', 'green', 'blue'])
        except HTTPResponseError as e:
            pass
Example #8
0
 def __init__(self, email=None, api_token=None):
     self._wm = None
     self._api = API(email=email, api_token=api_token)
     self._buttons = None
     self._accelerometers = None
     self._measurements = None
     self._timestamp = None
    def setUp(self):
        self.api = API()
        logging.basicConfig(level=logging.DEBUG)
        self.name = "TEST_" + TestUtils.random_string(6)
        self.display_name = "green"
        self.display_name_short = "blue"
        self.description = "magenta"
        self.default_aggregate = aggregates.SUM
        self.default_resolution = 60000
        self.unit = units.DURATION
        self.type = "FOOBAR"
        self.is_disabled = False
        self.metric = Metric(
            name=self.name,
            display_name=self.display_name,
            display_name_short=self.display_name_short,
            description=self.description,
            default_aggregate=self.default_aggregate,
            default_resolution=self.default_resolution,
            unit=self.unit,
            _type=self.type,
            is_disabled=self.is_disabled,
        )

        self.api.metric_create_batch([self.metric])

        logging.basicConfig(level=logging.INFO)
Example #10
0
class ApacheLogfileParser(LogfileParser):
    def __init__(self, path=None):
        super(ApacheLogfileParser, self).__init__(path)
        log_format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}\i"'
        self.parser = apachelog.parser(log_format)
        self.api = API()
        logging.basicConfig(level=logging.INFO)

    def send_measurements(self, measurements):
        """
        Sends measurements to standard out to be read by plugin manager

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def parse_line(self):
        """
        Parse each of the lines of the Apache HTTP server access log.
        :return:
        """
        parsed = parse_apache_line(self.parser, self.line)
        measurements = []
        user_agent = parsed['%{User-Agent}\i"'].replace('/', '')
        bytes = int(parsed['%b'])
        status_code = parsed['%>s']
        properties = {"app_id": self.app_id}
        # Split the line by spaces and get the request in the first value
        request = parsed['%r'].split(' ')[0]
        logging.info("user_agent: {0}, bytes: {1}, request: {2}, status_code: {3}".format(
                user_agent, bytes, request, status_code))

        measurements.append(Measurement(
                metric='HTTP_REQUESTS',
                value=1,
                source=request,
                properties=properties))

        measurements.append(Measurement(
                metric='HTTP_BYTES',
                value=bytes,
                source=user_agent,
                properties=properties))

        self.send_measurements(measurements)
Example #11
0
class APIDataSink(DataSink):

    def __init__(self, email=None, api_token=None, api_host=None):
        super(APIDataSink, self).__init__()
        self._api = API(email=email, api_token=api_token, api_host=api_host)

    def send_event(self, event):
        pass

    def send_events(self, events):
        pass

    def send_measurement(self, measurement):
        self._api.measurement_create(metric=measurement.metric,
                                     value=measurement.value,
                                     source=measurement.source,
                                     timestamp=measurement.timestamp,
                                     properties=measurement.properties)

    def send_measurements(self, measurements):
        self._api.measurement_create_batch(measurements)
Example #12
0
 def __init__(self, path=None):
     super(ApacheLogfileParser, self).__init__(path)
     log_format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}\i"'
     self.parser = apachelog.parser(log_format)
     self.api = API()
     logging.basicConfig(level=logging.INFO)
 def setUp(self):
     self.api = API()
class MeasurementTest(TestCase):
    def setUp(self):
        self.api = API()

    def test_measurement_constructor(self):
        metric = 'CPU'
        value = 0.5
        source = 'foobar'
        timestamp = int(datetime.now().strftime('%s'))
        properties = {"app_id": "red", "source_type": "blue", "origin": "green"}
        measurement = Measurement(metric=metric, value=value, source=source,
                                  timestamp=timestamp, properties=properties)

        self.assertEqual(metric, measurement.metric)
        self.assertEqual(value, measurement.value)
        self.assertEqual(source, measurement.source)
        self.assertEqual(timestamp, measurement.timestamp)
        self.assertEqual(properties, measurement.properties)

    def test_measurement_defaults(self):
        measurement = Measurement()

        self.assertIsNone(measurement.metric)
        self.assertIsNone(measurement.value)
        self.assertIsNone(measurement.source)
        self.assertIsNone(measurement.timestamp)
        self.assertIsNone(measurement.properties)

    def test_measurement_create(self):
        metric_id = 'CPU'
        value = 0.75
        source = 'API_TEST_SOURCE'
        timestamp = int(datetime.now().strftime('%s'))
        self.api.measurement_create(metric_id, value, source, timestamp)

    def test_measurement_create_datetime(self):
        metric_id = 'CPU'
        value = 0.75
        source = 'API_TEST_SOURCE'
        timestamp = datetime.now()
        self.api.measurement_create(metric_id, value, source, timestamp)

    def test_measurement_create_with_properties(self):
        metric_id = 'CPU'
        value = 0.75
        source = 'API_TEST_SOURCE'
        timestamp = int(datetime.now().strftime('%s'))
        properties = {"app_id": "red", "source_type": "blue", "origin": "green"}
        self.api.measurement_create(metric=metric_id, value=value, source=source,
                                    timestamp=timestamp, properties=properties)

    def test_measurement_create_batch(self):
        measurements = []
        timestamp = int(datetime.now().strftime('%s'))
        measurements.append(Measurement(metric='CPU', value=0.5, source='red', timestamp=timestamp))
        measurements.append(Measurement(metric='CPU', value=0.6, source='green', timestamp=timestamp))
        measurements.append(Measurement(metric='CPU', value=0.7, source='blue', timestamp=timestamp))
        self.api.measurement_create_batch(measurements)

    def test_measurement_create_batch_datetime(self):
        measurements = []
        timestamp = datetime.now()
        measurements.append(Measurement(metric='CPU', value=0.5, source='red', timestamp=timestamp))
        measurements.append(Measurement(metric='CPU', value=0.6, source='green', timestamp=timestamp))
        measurements.append(Measurement(metric='CPU', value=0.7, source='blue', timestamp=timestamp))
        self.api.measurement_create_batch(measurements)

    def test_measurement_create_batch_with_properties(self):
        measurements = []
        properties = {"app_id": "red", "source_type": "blue", "origin": "green"}
        timestamp = int(datetime.now().strftime('%s'))
        measurements.append(Measurement(metric='CPU', value=0.5, source='red',
                                        timestamp=timestamp, properties=properties))
        measurements.append(Measurement(metric='CPU', value=0.6, source='green',
                                        timestamp=timestamp, properties=properties))
        measurements.append(Measurement(metric='CPU', value=0.7, source='blue',
                                        timestamp=timestamp, properties=properties))
        self.api.measurement_create_batch(measurements)

    def test_measurement_get(self):
        metric = 'CPU'
        value = 0.0
        source = 'API_TEST_SOURCE' + TestUtils.random_string(6)
        properties = {"app_id": "red", "source_type": "blue", "origin": "green"}
        start = int(datetime.now().strftime('%s'))
        timestamp = start
        for i in range(0, 10):
            self.api.measurement_create(metric=metric, value=value, source=source,
                                        timestamp=timestamp, properties=properties)
            timestamp += 1
            value += 0.1

        measurements = self.api.measurement_get(source=source, start=start, aggregate='avg')
        value = 0.0
        timestamp = start
        for measure in measurements:
            self.assertEqual(metric, measure.metric)
            self.assertEqual(value, measure.value)
            self.assertEqual(source, measure.source)
            self.assertEqual(timestamp, measure.timestamp/1000)
            timestamp += 1
            value += 0.1

    def test_parse_timestamp_date_string_yymmddhhmm(self):
        d = datetime.utcnow()
        s = d.strftime('%Y-%m-%d %H:%M:%S')
        ts = Measurement.parse_timestamp(s)
        self.assertEqual(type(ts), int)
        self.assertEqual(ts, int(d.strftime('%s')))

    def test_parse_timestamp_date_string_yymmddhhmmss(self):
        d = datetime.utcnow()
        s = d.strftime('%Y-%m-%d %I:%M:%S%p')
        ts = Measurement.parse_timestamp(s)
        self.assertEqual(type(ts), int)
        self.assertEqual(ts, int(d.strftime('%s')))

    def test_parse_timestamp_date_string_yymmddHHMM(self):
        d = datetime.utcnow()
        s = d.strftime('%Y-%m-%d %I:%M:%S%p')
        ts = Measurement.parse_timestamp(s)
        self.assertEqual(type(ts), int)
        self.assertEqual(ts, int(d.strftime('%s')))

    def test_parse_timestamp_date_string_epoch_time(self):
        s = '1466704787'
        d = Measurement.parse_timestamp(s)
        self.assertEqual(type(d), int)
        self.assertEqual(d, 1466704787)
Example #15
0
class Driver(object):
    def __init__(self, email=None, api_token=None):
        self._wm = None
        self._api = API(email=email, api_token=api_token)
        self._buttons = None
        self._accelerometers = None
        self._measurements = None
        self._timestamp = None

    def queue_measurement(self, metric, value, source):
        self._measurements.append(Measurement(metric=metric, value=value, source=source, timestamp=self._timestamp))

    def send_measurements(self):
        logging.debug('send measurements')
        self._api.measurement_create_batch(self._measurements)

    def connect(self, retries=10):
        """
        Attempt to connect to the Wiimote
        :param retries: Number of times to attempting connection before raising an exception.
        :return:
        """
        print('Press 1+2 on your Wiimote now...')
        i = 1
        while self._wm is None:
            try:
                self._wm = cwiid.Wiimote()
            except RuntimeError:
                logging.error("Error opening wiimote connection, attempt: {0}".format(str(i)))
                i += 1
                if i > retries:
                    raise RuntimeError
        self._wm.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_STATUS
        print("connected!")

    def button_status(self, button):
        return 1 if self._buttons & button else 0

    def collect_init(self):

        # Initialze the array to hold the collected measurements
        self._measurements = []

        # Get the current time and use for all measurements
        self._timestamp = int(datetime.now().strftime('%s'))

        # Snapshot the current state of buttons and accelerometers
        self._buttons = self._wm.state['buttons']
        self._accelerometers = self._wm.state['acc']
        self._battery = self._wm.state['battery']

    def collect_battery_status(self):
        self.queue_measurement('WIIMOTE_BATTERY', float(self._battery)/100.0, 'battery')

    def collect_button_status(self):

        button_left = self.button_status(cwiid.BTN_LEFT)
        self.queue_measurement('WIIMOTE_BUTTON_LEFT', button_left, 'button-left')
        self.queue_measurement('WIIMOTE_BUTTON', button_left, 'button-left')

        button_right = self.button_status(cwiid.BTN_RIGHT)
        self.queue_measurement('WIIMOTE_BUTTON_RIGHT', button_right, 'button-right')
        self.queue_measurement('WIIMOTE_BUTTON', button_right, 'button-right')

        button_up = self.button_status(cwiid.BTN_UP)
        self.queue_measurement('WIIMOTE_BUTTON_UP', button_up, 'button-up')
        self.queue_measurement('WIIMOTE_BUTTON', button_up, 'button-up')

        button_down = self.button_status(cwiid.BTN_DOWN)
        self.queue_measurement('WIIMOTE_BUTTON_DOWN', button_down, 'button-down')
        self.queue_measurement('WIIMOTE_BUTTON', button_down, 'button-down')

        button_1 = self.button_status(cwiid.BTN_1)
        self.queue_measurement('WIIMOTE_BUTTON_1', button_1, 'button-1')
        self.queue_measurement('WIIMOTE_BUTTON', button_1, 'button-1')

        button_2 = self.button_status(cwiid.BTN_2)
        self.queue_measurement('WIIMOTE_BUTTON_2', button_2, 'button-2')
        self.queue_measurement('WIIMOTE_BUTTON', button_2, 'button-2')

        button_a = self.button_status(cwiid.BTN_A)
        self.queue_measurement('WIIMOTE_BUTTON_A', button_a, 'button-a')
        self.queue_measurement('WIIMOTE_BUTTON', button_a, 'button-a')

        button_b = self.button_status(cwiid.BTN_B)
        self.queue_measurement('WIIMOTE_BUTTON_B', button_b, 'button-b')
        self.queue_measurement('WIIMOTE_BUTTON', button_b, 'button-b')

        button_home = self.button_status(cwiid.BTN_HOME)
        self.queue_measurement('WIIMOTE_BUTTON_HOME', button_home, 'button-home')
        self.queue_measurement('WIIMOTE_BUTTON', button_home, 'button-home')

        button_minus = self.button_status(cwiid.BTN_MINUS)
        self.queue_measurement('WIIMOTE_BUTTON_MINUS', button_minus, 'button-minus')
        self.queue_measurement('WIIMOTE_BUTTON', button_minus, 'button-minus')

        button_plus = self.button_status(cwiid.BTN_PLUS)
        self.queue_measurement('WIIMOTE_BUTTON_PLUS', button_plus, 'button-plus')
        self.queue_measurement('WIIMOTE_BUTTON', button_plus, 'button-plus')

    def collect_accelerator_status(self):
        self.queue_measurement('WIIMOTE_ACCELEROMETER_X', self._accelerometers[0], 'accelerometer-x')
        self.queue_measurement('WIIMOTE_ACCELEROMETER_Y', self._accelerometers[1], 'accelerometer-y')
        self.queue_measurement('WIIMOTE_ACCELEROMETER_Z', self._accelerometers[2], 'accelerometer-z')
        self.queue_measurement('WIIMOTE_ACCELEROMETER', self._accelerometers[0], 'accelerometer-x');
        self.queue_measurement('WIIMOTE_ACCELEROMETER', self._accelerometers[1], 'accelerometer-y');
        self.queue_measurement('WIIMOTE_ACCELEROMETER', self._accelerometers[2], 'accelerometer-z');

    def collection_loop(self):
        logging.debug("start collection loop")
        while True:
            self.collect_init()
            self.collect_battery_status()
            self.collect_button_status()
            self.collect_accelerator_status()
            self.send_measurements()

    def run(self):
        self.connect()
        self.collection_loop()
Example #16
0
 def setUp(self):
     self.api = API()
Example #17
0
class RawEventTest(TestCase):

    def setUp(self):
        self.api = API()

    def test_default_constructor(self):
        raw_event = RawEvent()
        self.assertIsNone(raw_event.created_at)
        self.assertIsNone(raw_event.event_id)
        self.assertIsNone(raw_event.fingerprint_fields)
        self.assertIsNone(raw_event.id)
        self.assertIsNone(raw_event.message)
        self.assertIsNone(raw_event.properties)
        self.assertIsNone(raw_event.received_at)
        self.assertIsNone(raw_event.sender)
        self.assertIsNone(raw_event.severity)
        self.assertIsNone(raw_event.source)
        self.assertIsNone(raw_event.status)
        self.assertIsNone(raw_event.tags)
        self.assertIsNone(raw_event.tenant_id)
        self.assertIsNone(raw_event.title)

    def test_constructor_args(self):
        created_at = int(datetime.now().strftime('%s'))
        event_id = random.randrange(1, 1000000000)
        fingerprint_fields = '@title'
        id = random.randrange(1, 1000000000)
        raw_event = RawEvent(
            created_at=created_at,
            event_id=event_id,
            fingerprint_fields=fingerprint_fields,
        )

        self.assertEqual(created_at, raw_event.created_at)

    def test_repr_(self):
        created_at = int(datetime.now().strftime('%s'))
        event_id = random.randrange(1, 1000000000)
        fingerprint_fields = '@title'
        id = random.randrange(1, 1000000000)
        event_class = 'CHANGE'
        message = TestUtils.random_string(32)
        properties = {"foo": "bar", "color": "red"}
        received_at = int(datetime.now().strftime('%s'))
        sender = TestUtils.random_string(10)
        severity = 'INFO'
        source = Source(ref=TestUtils.random_string(10), _type='host', name='foobar')
        status = 'OPEN'
        tags = {"foo": "bar", "color": "red"}
        tenant_id = random.randrange(1, 10000000)
        title = TestUtils.random_string(16)
        raw_event = RawEvent(
            created_at=created_at,
            event_id=event_id,
            event_class=event_class,
            fingerprint_fields=fingerprint_fields,
            id=id,
            message=message,
            properties=properties,
            received_at=received_at,
            sender=sender,
            severity=severity,
            source=source,
            status=status,
            tags=tags,
            tenant_id=tenant_id,
            title=title
        )
        expected = []
        expected.append("RawEvent(created_at={0}".format(created_at, event_id))
        expected.append(", event_id='{0}'".format(event_id))
        expected.append(", event_class='{0}'".format(event_class))
        expected.append(", fingerprint_fields='{0}'".format(fingerprint_fields))
        expected.append(", id='{0}'".format(id))
        expected.append(", message='{0}'".format(message))
        expected.append(", properties={0}".format(properties))
        expected.append(", source='{0}'".format(source))
        expected.append(", sender='{0}'".format(sender))
        expected.append(", severity='{0}'".format(severity))
        expected.append(", status='{0}'".format(status))
        expected.append(", tags='{0}'".format(tags))
        expected.append(", tenant_id={0}".format(tenant_id))
        expected.append(", title='{0}')".format(title))

        expected = "".join(expected)

        self.assertEqual(expected, raw_event.__repr__())

    def test_create_event(self):
        source = Source(ref='localhost', _type='host', name='bubba')
        self.api.event_create(title='Hello World', fingerprint_fields=['@title'], source=source)

    def test_create_event_with_date(self):
        source = Source(ref='localhost', _type='host', name='bubba')
        dt = datetime.now()
        self.api.event_create(created_at=dt, title='Hello World', fingerprint_fields=['@title'], source=source)

    def test_create_event_with_finger_print_fields(self):
        fingerprint_fields = ['@message']
        source = Source(ref='localhost', _type='host', name='bubba')
        message = 'hello' + TestUtils.random_string(6)
        dt = datetime.now()
        self.api.event_create(message=message, created_at=dt, title='Hello World', fingerprint_fields=fingerprint_fields, source=source)

    def test_create_event_with_properties(self):
        source = Source(ref='localhost', _type='host', name='bubba')
        title = 'sending tags'
        properties = {"foo": "bar"}
        self.api.event_create(title=title, fingerprint_fields=['@title'], source=source, properties=properties)

    def test_create_event_with_class(self):
        source = Source(ref='localhost', _type='host', name='bubba')
        title = 'Event class'
        event_class = 'MyClass'
        self.api.event_create(title=title, fingerprint_fields=['@title'], source=source, event_class=event_class)

    def test_create_event_with_sender(self):
        source = Source(ref='localhost', _type='host', name='bubba')
        sender = Sender(ref='localhost', _type='host', name='bubba')
        self.api.event_create(title='Hello World', fingerprint_fields=['@title'], source=source, sender=sender)

    def test_create_bad_source(self):
        try:
            ref = 'Hello World'
            self.api.event_create(title='Hello World', fingerprint_fields=['@title'], source=ref)
            self.assertTrue(False)
        except ValueError:
            pass

    def test_create_bad_sender(self):
        try:
            source = Source(ref='localhost', _type='host', name='bubba')
            ref = 'Hello World'
            self.api.event_create(title='Hello World', fingerprint_fields=['@title'], source=source, sender=ref)
            self.assertTrue(False)
        except ValueError:
            pass

    def test_event_get(self):
        events = self.api.event_list()
        for event in events:
            print(event)

    def test_to_json(self):
        ref = 'device'
        _type = 'blah'
        name = 'hello'
        properties = {'red': 1, 'blue': 'foo', 'green': 1.0}
        source = Source(ref=ref, _type=_type, name=name, properties=properties)
        event = RawEvent(title='Hello World', fingerprint_fields=['@title'], source=source)
        output = json.dumps(event, sort_keys=True, default=tspapi.event.serialize_instance)
        expected = '{"source": {"name": "hello", "properties": {"blue": "foo", "green": 1.0, "red": 1}, ' + \
                   '"ref": "device", "type": "blah"}, "title": "Hello World"}'
        self.assertEqual(expected, output)

    def test_parse_date_datetime(self):
        d = datetime.now()
        expected = int(d.strftime('%s'))
        timestamp = Measurement.parse_timestamp(d)
        self.assertEqual(expected, timestamp)

    def test_parse_date_epoch(self):
        expected = int(datetime.now().strftime('%s'))
        timestamp = Measurement.parse_timestamp(expected)
        self.assertEqual(expected, timestamp)

    def test_parse_date_ymd(self):
        s = '2015-06-30'
        timestamp = Measurement.parse_timestamp(s)
        expected = int(datetime(2015, 6, 30).strftime('%s'))
        self.assertEqual(expected, timestamp)

    def test_parse_date_ymd_hms24(self):
        s = '2014-06-30 14:27:16'
        timestamp = Measurement.parse_timestamp(s)
        expected = int(datetime(2014, 6, 30, 14, 27, 16).strftime('%s'))
        self.assertEqual(expected, timestamp)

    def test_parse_date_ymd_hms(self):
        s = '2014-06-30 02:27:16PM'
        timestamp = Measurement.parse_timestamp(s)
        expected = int(datetime(2014, 6, 30, 14, 27, 16).strftime('%s'))
        self.assertEqual(expected, timestamp)

    def test_parse_date_bad_date_format(self):
        try:
            s = 'foobar'
            timestamp = Measurement.parse_timestamp(s)
            self.assertTrue(False)
        except ValueError:
            pass
Example #18
0
 def __init__(self, ):
     self.api = API()
     self.usage_args = ""
     # Set our application id from the environment variable
     self.app_id = os.environ['TSI_APP_ID']
Example #19
0
class MeasurementTest(TestCase):
    def setUp(self):
        self.api = API()

    def test_measurement_constructor(self):
        metric = 'CPU'
        value = 0.5
        source = 'foobar'
        timestamp = int(datetime.now().strftime('%s'))
        properties = {
            "app_id": "red",
            "source_type": "blue",
            "origin": "green"
        }
        measurement = Measurement(metric=metric,
                                  value=value,
                                  source=source,
                                  timestamp=timestamp,
                                  properties=properties)

        self.assertEqual(metric, measurement.metric)
        self.assertEqual(value, measurement.value)
        self.assertEqual(source, measurement.source)
        self.assertEqual(timestamp, measurement.timestamp)
        self.assertEqual(properties, measurement.properties)

    def test_measurement_defaults(self):
        measurement = Measurement()

        self.assertIsNone(measurement.metric)
        self.assertIsNone(measurement.value)
        self.assertIsNone(measurement.source)
        self.assertIsNone(measurement.timestamp)
        self.assertIsNone(measurement.properties)

    def test_measurement_create(self):
        metric_id = 'CPU'
        value = 0.75
        source = 'API_TEST_SOURCE'
        timestamp = int(datetime.now().strftime('%s'))
        self.api.measurement_create(metric_id, value, source, timestamp)

    def test_measurement_create_datetime(self):
        metric_id = 'CPU'
        value = 0.75
        source = 'API_TEST_SOURCE'
        timestamp = datetime.now()
        self.api.measurement_create(metric_id, value, source, timestamp)

    def test_measurement_create_with_properties(self):
        metric_id = 'CPU'
        value = 0.75
        source = 'API_TEST_SOURCE'
        timestamp = int(datetime.now().strftime('%s'))
        properties = {
            "app_id": "red",
            "source_type": "blue",
            "origin": "green"
        }
        self.api.measurement_create(metric=metric_id,
                                    value=value,
                                    source=source,
                                    timestamp=timestamp,
                                    properties=properties)

    def test_measurement_create_batch(self):
        measurements = []
        timestamp = int(datetime.now().strftime('%s'))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.5,
                        source='red',
                        timestamp=timestamp))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.6,
                        source='green',
                        timestamp=timestamp))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.7,
                        source='blue',
                        timestamp=timestamp))
        self.api.measurement_create_batch(measurements)

    def test_measurement_create_batch_datetime(self):
        measurements = []
        timestamp = datetime.now()
        measurements.append(
            Measurement(metric='CPU',
                        value=0.5,
                        source='red',
                        timestamp=timestamp))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.6,
                        source='green',
                        timestamp=timestamp))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.7,
                        source='blue',
                        timestamp=timestamp))
        self.api.measurement_create_batch(measurements)

    def test_measurement_create_batch_with_properties(self):
        measurements = []
        properties = {
            "app_id": "red",
            "source_type": "blue",
            "origin": "green"
        }
        timestamp = int(datetime.now().strftime('%s'))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.5,
                        source='red',
                        timestamp=timestamp,
                        properties=properties))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.6,
                        source='green',
                        timestamp=timestamp,
                        properties=properties))
        measurements.append(
            Measurement(metric='CPU',
                        value=0.7,
                        source='blue',
                        timestamp=timestamp,
                        properties=properties))
        self.api.measurement_create_batch(measurements)

    def test_measurement_get(self):
        metric = 'CPU'
        value = 0.0
        source = 'API_TEST_SOURCE' + TestUtils.random_string(6)
        properties = {
            "app_id": "red",
            "source_type": "blue",
            "origin": "green"
        }
        start = int(datetime.now().strftime('%s'))
        timestamp = start
        for i in range(0, 10):
            self.api.measurement_create(metric=metric,
                                        value=value,
                                        source=source,
                                        timestamp=timestamp,
                                        properties=properties)
            timestamp += 1
            value += 0.1

        measurements = self.api.measurement_get(source=source,
                                                start=start,
                                                aggregate='avg')
        value = 0.0
        timestamp = start
        for measure in measurements:
            self.assertEqual(metric, measure.metric)
            self.assertEqual(value, measure.value)
            self.assertEqual(source, measure.source)
            self.assertEqual(timestamp, measure.timestamp / 1000)
            timestamp += 1
            value += 0.1

    def test_parse_timestamp_date_string_yymmddhhmm(self):
        d = datetime.utcnow()
        s = d.strftime('%Y-%m-%d %H:%M:%S')
        ts = Measurement.parse_timestamp(s)
        self.assertEqual(type(ts), int)
        self.assertEqual(ts, int(d.strftime('%s')))

    def test_parse_timestamp_date_string_yymmddhhmmss(self):
        d = datetime.utcnow()
        s = d.strftime('%Y-%m-%d %I:%M:%S%p')
        ts = Measurement.parse_timestamp(s)
        self.assertEqual(type(ts), int)
        self.assertEqual(ts, int(d.strftime('%s')))

    def test_parse_timestamp_date_string_yymmddHHMM(self):
        d = datetime.utcnow()
        s = d.strftime('%Y-%m-%d %I:%M:%S%p')
        ts = Measurement.parse_timestamp(s)
        self.assertEqual(type(ts), int)
        self.assertEqual(ts, int(d.strftime('%s')))

    def test_parse_timestamp_date_string_epoch_time(self):
        s = '1466704787'
        d = Measurement.parse_timestamp(s)
        self.assertEqual(type(d), int)
        self.assertEqual(d, 1466704787)
class MetricTest(TestCase):
    def setUp(self):
        self.api = API()
        logging.basicConfig(level=logging.DEBUG)
        self.name = "TEST_" + TestUtils.random_string(6)
        self.display_name = "green"
        self.display_name_short = "blue"
        self.description = "magenta"
        self.default_aggregate = aggregates.SUM
        self.default_resolution = 60000
        self.unit = units.DURATION
        self.type = "FOOBAR"
        self.is_disabled = False
        self.metric = Metric(
            name=self.name,
            display_name=self.display_name,
            display_name_short=self.display_name_short,
            description=self.description,
            default_aggregate=self.default_aggregate,
            default_resolution=self.default_resolution,
            unit=self.unit,
            _type=self.type,
            is_disabled=self.is_disabled,
        )

        self.api.metric_create_batch([self.metric])

        logging.basicConfig(level=logging.INFO)

    def tearDown(self):
        self.api.metric_delete(self.metric.name)

    def test_minimal_constructor(self):
        name = "FOO"
        m = Metric(name=name)

        self.assertEqual(name, m.name)
        self.assertEqual(name, m.display_name)
        self.assertEqual(name, m.display_name_short)
        self.assertEqual("", m.description)
        self.assertEqual(m.default_aggregate, aggregates.AVG)
        self.assertEqual(m.default_resolution, 1000)
        self.assertEqual(m.unit, units.NUMBER)
        self.assertIsNone(m.type)

    def test_constructor_arguments(self):
        self.assertEqual(self.name, self.metric.name)
        self.assertEqual(self.display_name, self.metric.display_name)
        self.assertEqual(self.display_name_short, self.metric.display_name_short)
        self.assertEqual(self.description, self.metric.description)
        self.assertEqual(self.default_aggregate, self.metric.default_aggregate)
        self.assertEqual(self.default_resolution, self.metric.default_resolution)
        self.assertEqual(self.unit, self.metric.unit)
        self.assertEqual(self.type, self.metric.type)
        self.assertEqual(self.is_disabled, self.metric.is_disabled)

    def test_representation_string(self):
        """
        Test the output of the __repr__ method
        :param self:
        :return:
        """
        expected = [
            "Metric(name='{0}', display_name='green', display_name_short='blue',".format(self.metric.name),
            " description='magenta', default_aggregate='sum', default_resolution=60000,",
            " unit='duration', _type='FOOBAR', is_disabled='False')",
        ]
        self.assertEqual("".join(expected), self.metric.__repr__())

    def test_metric_to_json(self):
        m = Metric(name="TEST")
        data = json.dumps(m, sort_keys=True, default=tspapi.metric.serialize_instance)
        s = [
            '{"defaultAggregate": "avg", "defaultResolutionMS": 1000, "description": "",',
            ' "displayName": "TEST", "displayNameShort": "TEST", "isDisabled": false, "name": "TEST",',
            ' "unit": "number"}',
        ]
        expected = "".join(s)
        self.assertEqual(expected, data)

    def test_metric_list_to_json(self):
        l = [Metric(name="ONE"), Metric(name="TWO")]
        self.maxDiff = None
        s = [
            '[{"defaultAggregate": "avg", "defaultResolutionMS": 1000, "description": "", "displayName": "ONE",',
            ' "displayNameShort": "ONE", "isDisabled": false, "name": "ONE",',
            ' "unit": "number"},',
            ' {"defaultAggregate": "avg", "defaultResolutionMS": 1000, "description": "", "displayName": "TWO",',
            ' "displayNameShort": "TWO", "isDisabled": false, "name": "TWO",',
            ' "unit": "number"}]',
        ]
        expected = "".join(s)

        data = json.dumps(l, sort_keys=True, default=tspapi.metric.serialize_instance)
        self.assertEqual(expected, data)

    def test_metric_instance_empty_name(self):
        """
        Ensure that creating a metric with an empty name throws a
        ValueError exception
        :return:
        """
        try:
            m = Metric()
            print(m)
            self.assertTrue(False)
        except ValueError:
            pass

    def test_metric_empty_name(self):
        """
        Ensure that trying to call the create metric API with an empty name
        throws a ValueError exception
        :return:
        """
        try:
            self.api.metric_create()
            self.assertTrue(False)
        except ValueError:
            pass

    def test_metric_create(self):
        name = "TEST_CREATE_FOOBAR" + TestUtils.random_string(6)
        display_name = "TEST_METRIC_CREATE" + TestUtils.random_string(6)
        display_name_short = "TEST_METRIC" + TestUtils.random_string(6)
        description = TestUtils.random_string(32)
        default_aggregate = aggregates.AVG
        default_resolution = 60000
        unit = units.DURATION
        _type = "FOO"
        is_disabled = True
        metric = self.api.metric_create(
            name=name,
            display_name=display_name,
            display_name_short=display_name_short,
            description=description,
            default_aggregate=default_aggregate,
            default_resolution=default_resolution,
            unit=unit,
            _type=_type,
            is_disabled=is_disabled,
        )
        self.assertEqual(name, metric.name)
        self.assertEqual(display_name, metric.display_name)
        self.assertEqual(display_name_short, metric.display_name_short)
        self.assertEqual(description, metric.description)
        self.assertEqual(default_aggregate.upper(), metric.default_aggregate)
        self.assertEqual(default_resolution, metric.default_resolution)
        self.assertEqual(unit, metric.unit)
        self.assertEqual(_type, metric.type)
        self.assertEqual(is_disabled, metric.is_disabled)

    def test_metric_create_one_batch(self):
        name = "TEST_CREATE_BATCH_ONE_FOOBAR" + TestUtils.random_string(6)
        display_name = "BATCH" + TestUtils.random_string(6)
        display_name_short = "BATCH" + TestUtils.random_string(3)
        description = TestUtils.random_string(32)
        default_aggregate = aggregates.SUM
        default_resolution = random.randrange(1000, 60000)
        unit = units.PERCENT
        _type = "FOO"
        is_disabled = True

        metric1 = Metric(
            name=name,
            display_name=display_name,
            display_name_short=display_name_short,
            description=description,
            default_aggregate=default_aggregate,
            default_resolution=default_resolution,
            unit=unit,
            _type=_type,
            is_disabled=is_disabled,
        )

        metrics = self.api.metric_create_batch([metric1])
        self.assertEqual(len(metrics), 1)

        m = metrics[0]
        self.assertEqual(name, m.name)
        self.assertEqual(display_name, m.display_name)
        self.assertEqual(display_name_short, m.display_name_short)
        self.assertEqual(description, m.description)
        self.assertEqual(default_aggregate.upper(), m.default_aggregate)
        self.assertEqual(default_resolution, m.default_resolution)
        self.assertEqual(unit, m.unit)
        self.assertEqual(_type, m.type)
        self.assertEqual(is_disabled, m.is_disabled)

        self.api.metric_delete(name)

    def test_metric_large_display_name(self):
        """
        Test to see that we can handle a display name up to 1K characters
        :return:
        """
        try:
            name = "TEST_CREATE" + TestUtils.random_string(6)
            display_name = TestUtils.random_string(1024 * 1024)
            metric = self.api.metric_create(name=name, display_name=display_name)
            self.assertTrue(True)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.request_entity_too_large, e.status_code)

    def test_metric_large_short_display_name(self):
        """
        Test on the limit of the short display name
        :return:
        """
        try:
            name = "TEST_CREATE" + TestUtils.random_string(6)
            display_name_short = TestUtils.random_string(1024 * 1024)
            metric = self.api.metric_create(name=name, display_name_short=display_name_short)
            self.assertTrue(True)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.request_entity_too_large, e.status_code)

    def test_metric_bad_aggregate(self):
        try:
            name = "TEST_CREATE" + TestUtils.random_string(6)
            display_name = TestUtils.random_string(32)
            metric = self.api.metric_create(name=name, display_name=display_name, default_aggregate="foo")
            self.assertTrue(False)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.unprocessable_entity, e.status_code)

    def test_metric_bad_unit(self):
        try:
            name = "TEST_CREATE" + TestUtils.random_string(6)
            display_name = TestUtils.random_string(32)
            metric = self.api.metric_create(name=name, display_name=display_name, unit="foo")
            self.assertTrue(False)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.unprocessable_entity, e.status_code)

    def test_metric_create_multiple_batch(self):
        name1 = "TEST_CREATE_BATCH_ONE_FOOBAR" + TestUtils.random_string(6)
        name2 = "TEST_CREATE_BATCH_TWO_FOOBAR" + TestUtils.random_string(6)
        name3 = "TEST_CREATE_BATCH_THREE_FOOBAR" + TestUtils.random_string(6)
        name4 = "TEST_CREATE_BATCH_FOUR_FOOBAR" + TestUtils.random_string(6)

        display_name1 = "TEST_DISPLAY_NAME" + TestUtils.random_string(6)
        display_name2 = "TEST_DISPLAY_NAME" + TestUtils.random_string(6)
        display_name3 = "TEST_DISPLAY_NAME" + TestUtils.random_string(6)
        display_name4 = "TEST_DISPLAY_NAME" + TestUtils.random_string(6)

        display_name_short1 = "TEST_SHORT" + TestUtils.random_string(10)
        display_name_short2 = "TEST_SHORT" + TestUtils.random_string(10)
        display_name_short3 = "TEST_SHORT" + TestUtils.random_string(10)
        display_name_short4 = "TEST_SHORT" + TestUtils.random_string(10)

        description1 = TestUtils.random_string(32)
        description2 = TestUtils.random_string(32)
        description3 = TestUtils.random_string(32)
        description4 = TestUtils.random_string(32)

        default_aggregate1 = aggregates.AVG
        default_aggregate2 = aggregates.MIN
        default_aggregate3 = aggregates.MAX
        default_aggregate4 = aggregates.SUM

        default_resolution1 = random.randrange(1000, 60000)
        default_resolution2 = random.randrange(1000, 60000)
        default_resolution3 = random.randrange(1000, 60000)
        default_resolution4 = random.randrange(1000, 60000)

        unit1 = units.BYTECOUNT
        unit2 = units.DURATION
        unit3 = units.NUMBER
        unit4 = units.PERCENT

        is_disabled1 = True
        is_disabled2 = False
        is_disabled3 = True
        is_disabled4 = False

        _type1 = TestUtils.random_string(6)
        _type2 = TestUtils.random_string(6)
        _type3 = TestUtils.random_string(6)
        _type4 = TestUtils.random_string(6)

        new_metrics = [
            Metric(
                name=name1,
                display_name=display_name1,
                display_name_short=display_name_short1,
                description=description1,
                default_aggregate=default_aggregate1,
                default_resolution=default_resolution1,
                unit=unit1,
                _type=_type1,
                is_disabled=is_disabled1,
            ),
            Metric(
                name=name2,
                display_name=display_name2,
                display_name_short=display_name_short2,
                description=description2,
                default_aggregate=default_aggregate2,
                default_resolution=default_resolution2,
                unit=unit2,
                _type=_type2,
                is_disabled=is_disabled2,
            ),
            Metric(
                name=name3,
                display_name=display_name3,
                display_name_short=display_name_short3,
                description=description3,
                default_aggregate=default_aggregate3,
                default_resolution=default_resolution3,
                unit=unit3,
                _type=_type3,
                is_disabled=is_disabled3,
            ),
            Metric(
                name=name4,
                display_name=display_name4,
                display_name_short=display_name_short4,
                description=description4,
                default_aggregate=default_aggregate4,
                default_resolution=default_resolution4,
                unit=unit4,
                _type=_type4,
                is_disabled=is_disabled4,
            ),
        ]

        metrics = self.api.metric_create_batch(new_metrics)

        self.assertEqual(4, len(metrics))

    def test_metric_create_batch_from_file(self):
        self.api.metric_create_batch(path="tests/unit/tspapi/metric_batch.json")
        self.api.metric_delete("TEST_MY_COOL_METRIC_31")
        self.api.metric_delete("TEST_MY_COOL_METRIC_32")

    def test_metric_get(self):
        metrics = self.api.metric_get()
        self.assertIsNotNone(metrics)

    def test_metric_delete(self):
        name = "TEST_DELETE_FOOBAR" + TestUtils.random_string(6)
        self.api.metric_create(name=name)
        self.api.metric_delete(name)

    def test_metric_delete_no_name(self):
        try:
            self.api.metric_delete()
            self.assertTrue(False)
        except ValueError:
            pass

    def test_metric_delete_name_does_not_exist(self):
        try:
            self.api.metric_delete(TestUtils.random_string(10))
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.unprocessable_entity, e.status_code)

    def test_metric_update(self):
        name = "TEST_UPDATE_" + TestUtils.random_string(6)
        display_name = TestUtils.random_string(8)
        display_name_short = TestUtils.random_string(16)
        description = TestUtils.random_string(16)
        default_aggregate = aggregates.SUM
        default_resolution = 60000
        unit = units.PERCENT
        is_disabled = False
        _type = "DEVICE"
        self.api.metric_create(
            name=name,
            display_name=display_name,
            display_name_short=display_name_short,
            description=description,
            default_aggregate=default_aggregate,
            default_resolution=default_resolution,
            unit=unit,
            is_disabled=is_disabled,
            _type=_type,
        )

        display_name = TestUtils.random_string(8)
        display_name_short = TestUtils.random_string(16)
        description = TestUtils.random_string(16)
        default_aggregate = aggregates.MAX
        default_resolution = 30000
        unit = units.DURATION
        is_disabled = True
        _type = "HOST"
        metric = self.api.metric_update(
            name=name,
            display_name=display_name,
            display_name_short=display_name_short,
            description=description,
            default_aggregate=default_aggregate,
            default_resolution=default_resolution,
            unit=unit,
            is_disabled=is_disabled,
            _type=_type,
        )

        self.assertEqual(name, metric.name)
        self.assertEqual(display_name, metric.display_name)
        self.assertEqual(display_name_short, metric.display_name_short)
        self.assertEqual(description, metric.description)
        self.assertEqual(default_aggregate.upper(), metric.default_aggregate)
        self.assertEqual(default_resolution, metric.default_resolution)
        self.assertEqual(unit, metric.unit)
        self.assertEqual(_type, metric.type)
        self.assertEqual(is_disabled, metric.is_disabled)

        self.api.metric_delete(name)

    def test_metric_batch_update(self):
        pass
Example #21
0
 def __init__(self, ):
     self.api = API()
     self.usage_args = ""
     # Set our application id from the environment variable
     self.app_id = os.environ['TSI_APP_ID']
Example #22
0
 def __init__(self, email=None, api_token=None, api_host=None):
     super(APIDataSink, self).__init__()
     self._api = API(email=email, api_token=api_token, api_host=api_host)
Example #23
0
class MetricTest(TestCase):
    def setUp(self):
        self.api = API()
        logging.basicConfig(level=logging.DEBUG)
        self.name = 'TEST_' + TestUtils.random_string(6)
        self.display_name = 'green'
        self.display_name_short = 'blue'
        self.description = 'magenta'
        self.default_aggregate = aggregates.SUM
        self.default_resolution = 60000
        self.unit = units.DURATION
        self.type = 'FOOBAR'
        self.is_disabled = False
        self.metric = Metric(name=self.name,
                             display_name=self.display_name,
                             display_name_short=self.display_name_short,
                             description=self.description,
                             default_aggregate=self.default_aggregate,
                             default_resolution=self.default_resolution,
                             unit=self.unit,
                             _type=self.type,
                             is_disabled=self.is_disabled)

        self.api.metric_create_batch([self.metric])

        logging.basicConfig(level=logging.INFO)

    def tearDown(self):
        self.api.metric_delete(self.metric.name)

    def test_minimal_constructor(self):
        name = 'FOO'
        m = Metric(name=name)

        self.assertEqual(name, m.name)
        self.assertEqual(name, m.display_name)
        self.assertEqual(name, m.display_name_short)
        self.assertEqual('', m.description)
        self.assertEqual(m.default_aggregate, aggregates.AVG)
        self.assertEqual(m.default_resolution, 1000)
        self.assertEqual(m.unit, units.NUMBER)
        self.assertIsNone(m.type)

    def test_constructor_arguments(self):
        self.assertEqual(self.name, self.metric.name)
        self.assertEqual(self.display_name, self.metric.display_name)
        self.assertEqual(self.display_name_short,
                         self.metric.display_name_short)
        self.assertEqual(self.description, self.metric.description)
        self.assertEqual(self.default_aggregate, self.metric.default_aggregate)
        self.assertEqual(self.default_resolution,
                         self.metric.default_resolution)
        self.assertEqual(self.unit, self.metric.unit)
        self.assertEqual(self.type, self.metric.type)
        self.assertEqual(self.is_disabled, self.metric.is_disabled)

    def test_representation_string(self):
        """
        Test the output of the __repr__ method
        :param self:
        :return:
        """
        expected = [
            "Metric(name='{0}', display_name='green', display_name_short='blue',"
            .format(self.metric.name),
            " description='magenta', default_aggregate='sum', default_resolution=60000,",
            " unit='duration', _type='FOOBAR', is_disabled='False')"
        ]
        self.assertEqual("".join(expected), self.metric.__repr__())

    def test_metric_to_json(self):
        m = Metric(name="TEST")
        data = json.dumps(m,
                          sort_keys=True,
                          default=tspapi.metric.serialize_instance)
        s = [
            '{"defaultAggregate": "avg", "defaultResolutionMS": 1000, "description": "",',
            ' "displayName": "TEST", "displayNameShort": "TEST", "isDisabled": false, "name": "TEST",',
            ' "unit": "number"}'
        ]
        expected = "".join(s)
        self.assertEqual(expected, data)

    def test_metric_list_to_json(self):
        l = [Metric(name="ONE"), Metric(name="TWO")]
        self.maxDiff = None
        s = [
            '[{"defaultAggregate": "avg", "defaultResolutionMS": 1000, "description": "", "displayName": "ONE",',
            ' "displayNameShort": "ONE", "isDisabled": false, "name": "ONE",',
            ' "unit": "number"},',
            ' {"defaultAggregate": "avg", "defaultResolutionMS": 1000, "description": "", "displayName": "TWO",',
            ' "displayNameShort": "TWO", "isDisabled": false, "name": "TWO",',
            ' "unit": "number"}]'
        ]
        expected = "".join(s)

        data = json.dumps(l,
                          sort_keys=True,
                          default=tspapi.metric.serialize_instance)
        self.assertEqual(expected, data)

    def test_metric_instance_empty_name(self):
        """
        Ensure that creating a metric with an empty name throws a
        ValueError exception
        :return:
        """
        try:
            m = Metric()
            print(m)
            self.assertTrue(False)
        except ValueError:
            pass

    def test_metric_empty_name(self):
        """
        Ensure that trying to call the create metric API with an empty name
        throws a ValueError exception
        :return:
        """
        try:
            self.api.metric_create()
            self.assertTrue(False)
        except ValueError:
            pass

    def test_metric_create(self):
        name = "TEST_CREATE_FOOBAR" + TestUtils.random_string(6)
        display_name = "TEST_METRIC_CREATE" + TestUtils.random_string(6)
        display_name_short = "TEST_METRIC" + TestUtils.random_string(6)
        description = TestUtils.random_string(32)
        default_aggregate = aggregates.AVG
        default_resolution = 60000
        unit = units.DURATION
        _type = 'FOO'
        is_disabled = True
        metric = self.api.metric_create(name=name,
                                        display_name=display_name,
                                        display_name_short=display_name_short,
                                        description=description,
                                        default_aggregate=default_aggregate,
                                        default_resolution=default_resolution,
                                        unit=unit,
                                        _type=_type,
                                        is_disabled=is_disabled)
        self.assertEqual(name, metric.name)
        self.assertEqual(display_name, metric.display_name)
        self.assertEqual(display_name_short, metric.display_name_short)
        self.assertEqual(description, metric.description)
        self.assertEqual(default_aggregate.upper(), metric.default_aggregate)
        self.assertEqual(default_resolution, metric.default_resolution)
        self.assertEqual(unit, metric.unit)
        self.assertEqual(_type, metric.type)
        self.assertEqual(is_disabled, metric.is_disabled)

    def test_metric_create_one_batch(self):
        name = 'TEST_CREATE_BATCH_ONE_FOOBAR' + TestUtils.random_string(6)
        display_name = "BATCH" + TestUtils.random_string(6)
        display_name_short = "BATCH" + TestUtils.random_string(3)
        description = TestUtils.random_string(32)
        default_aggregate = aggregates.SUM
        default_resolution = random.randrange(1000, 60000)
        unit = units.PERCENT
        _type = 'FOO'
        is_disabled = True

        metric1 = Metric(name=name,
                         display_name=display_name,
                         display_name_short=display_name_short,
                         description=description,
                         default_aggregate=default_aggregate,
                         default_resolution=default_resolution,
                         unit=unit,
                         _type=_type,
                         is_disabled=is_disabled)

        metrics = self.api.metric_create_batch([metric1])
        self.assertEqual(len(metrics), 1)

        m = metrics[0]
        self.assertEqual(name, m.name)
        self.assertEqual(display_name, m.display_name)
        self.assertEqual(display_name_short, m.display_name_short)
        self.assertEqual(description, m.description)
        self.assertEqual(default_aggregate.upper(), m.default_aggregate)
        self.assertEqual(default_resolution, m.default_resolution)
        self.assertEqual(unit, m.unit)
        self.assertEqual(_type, m.type)
        self.assertEqual(is_disabled, m.is_disabled)

        self.api.metric_delete(name)

    def test_metric_large_display_name(self):
        """
        Test to see that we can handle a display name up to 1K characters
        :return:
        """
        try:
            name = 'TEST_CREATE' + TestUtils.random_string(6)
            display_name = TestUtils.random_string(1024 * 1024)
            metric = self.api.metric_create(name=name,
                                            display_name=display_name)
            self.assertTrue(True)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.request_entity_too_large,
                             e.status_code)

    def test_metric_large_short_display_name(self):
        """
        Test on the limit of the short display name
        :return:
        """
        try:
            name = 'TEST_CREATE' + TestUtils.random_string(6)
            display_name_short = TestUtils.random_string(1024 * 1024)
            metric = self.api.metric_create(
                name=name, display_name_short=display_name_short)
            self.assertTrue(True)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.request_entity_too_large,
                             e.status_code)

    def test_metric_bad_aggregate(self):
        try:
            name = 'TEST_CREATE' + TestUtils.random_string(6)
            display_name = TestUtils.random_string(32)
            metric = self.api.metric_create(name=name,
                                            display_name=display_name,
                                            default_aggregate='foo')
            self.assertTrue(False)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.unprocessable_entity,
                             e.status_code)

    def test_metric_bad_unit(self):
        try:
            name = 'TEST_CREATE' + TestUtils.random_string(6)
            display_name = TestUtils.random_string(32)
            metric = self.api.metric_create(name=name,
                                            display_name=display_name,
                                            unit='foo')
            self.assertTrue(False)
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.unprocessable_entity,
                             e.status_code)

    def test_metric_create_multiple_batch(self):
        name1 = 'TEST_CREATE_BATCH_ONE_FOOBAR' + TestUtils.random_string(6)
        name2 = 'TEST_CREATE_BATCH_TWO_FOOBAR' + TestUtils.random_string(6)
        name3 = 'TEST_CREATE_BATCH_THREE_FOOBAR' + TestUtils.random_string(6)
        name4 = 'TEST_CREATE_BATCH_FOUR_FOOBAR' + TestUtils.random_string(6)

        display_name1 = 'TEST_DISPLAY_NAME' + TestUtils.random_string(6)
        display_name2 = 'TEST_DISPLAY_NAME' + TestUtils.random_string(6)
        display_name3 = 'TEST_DISPLAY_NAME' + TestUtils.random_string(6)
        display_name4 = 'TEST_DISPLAY_NAME' + TestUtils.random_string(6)

        display_name_short1 = 'TEST_SHORT' + TestUtils.random_string(10)
        display_name_short2 = 'TEST_SHORT' + TestUtils.random_string(10)
        display_name_short3 = 'TEST_SHORT' + TestUtils.random_string(10)
        display_name_short4 = 'TEST_SHORT' + TestUtils.random_string(10)

        description1 = TestUtils.random_string(32)
        description2 = TestUtils.random_string(32)
        description3 = TestUtils.random_string(32)
        description4 = TestUtils.random_string(32)

        default_aggregate1 = aggregates.AVG
        default_aggregate2 = aggregates.MIN
        default_aggregate3 = aggregates.MAX
        default_aggregate4 = aggregates.SUM

        default_resolution1 = random.randrange(1000, 60000)
        default_resolution2 = random.randrange(1000, 60000)
        default_resolution3 = random.randrange(1000, 60000)
        default_resolution4 = random.randrange(1000, 60000)

        unit1 = units.BYTECOUNT
        unit2 = units.DURATION
        unit3 = units.NUMBER
        unit4 = units.PERCENT

        is_disabled1 = True
        is_disabled2 = False
        is_disabled3 = True
        is_disabled4 = False

        _type1 = TestUtils.random_string(6)
        _type2 = TestUtils.random_string(6)
        _type3 = TestUtils.random_string(6)
        _type4 = TestUtils.random_string(6)

        new_metrics = [
            Metric(name=name1,
                   display_name=display_name1,
                   display_name_short=display_name_short1,
                   description=description1,
                   default_aggregate=default_aggregate1,
                   default_resolution=default_resolution1,
                   unit=unit1,
                   _type=_type1,
                   is_disabled=is_disabled1),
            Metric(name=name2,
                   display_name=display_name2,
                   display_name_short=display_name_short2,
                   description=description2,
                   default_aggregate=default_aggregate2,
                   default_resolution=default_resolution2,
                   unit=unit2,
                   _type=_type2,
                   is_disabled=is_disabled2),
            Metric(name=name3,
                   display_name=display_name3,
                   display_name_short=display_name_short3,
                   description=description3,
                   default_aggregate=default_aggregate3,
                   default_resolution=default_resolution3,
                   unit=unit3,
                   _type=_type3,
                   is_disabled=is_disabled3),
            Metric(name=name4,
                   display_name=display_name4,
                   display_name_short=display_name_short4,
                   description=description4,
                   default_aggregate=default_aggregate4,
                   default_resolution=default_resolution4,
                   unit=unit4,
                   _type=_type4,
                   is_disabled=is_disabled4)
        ]

        metrics = self.api.metric_create_batch(new_metrics)

        self.assertEqual(4, len(metrics))

    def test_metric_create_batch_from_file(self):
        self.api.metric_create_batch(
            path="tests/unit/tspapi/metric_batch.json")
        self.api.metric_delete('TEST_MY_COOL_METRIC_31')
        self.api.metric_delete('TEST_MY_COOL_METRIC_32')

    def test_metric_get(self):
        metrics = self.api.metric_get()
        self.assertIsNotNone(metrics)

    def test_metric_delete(self):
        name = 'TEST_DELETE_FOOBAR' + TestUtils.random_string(6)
        self.api.metric_create(name=name)
        self.api.metric_delete(name)

    def test_metric_delete_no_name(self):
        try:
            self.api.metric_delete()
            self.assertTrue(False)
        except ValueError:
            pass

    def test_metric_delete_name_does_not_exist(self):
        try:
            self.api.metric_delete(TestUtils.random_string(10))
        except HTTPResponseError as e:
            self.assertEqual(requests.codes.unprocessable_entity,
                             e.status_code)

    def test_metric_update(self):
        name = 'TEST_UPDATE_' + TestUtils.random_string(6)
        display_name = TestUtils.random_string(8)
        display_name_short = TestUtils.random_string(16)
        description = TestUtils.random_string(16)
        default_aggregate = aggregates.SUM
        default_resolution = 60000
        unit = units.PERCENT
        is_disabled = False
        _type = 'DEVICE'
        self.api.metric_create(name=name,
                               display_name=display_name,
                               display_name_short=display_name_short,
                               description=description,
                               default_aggregate=default_aggregate,
                               default_resolution=default_resolution,
                               unit=unit,
                               is_disabled=is_disabled,
                               _type=_type)

        display_name = TestUtils.random_string(8)
        display_name_short = TestUtils.random_string(16)
        description = TestUtils.random_string(16)
        default_aggregate = aggregates.MAX
        default_resolution = 30000
        unit = units.DURATION
        is_disabled = True
        _type = 'HOST'
        metric = self.api.metric_update(name=name,
                                        display_name=display_name,
                                        display_name_short=display_name_short,
                                        description=description,
                                        default_aggregate=default_aggregate,
                                        default_resolution=default_resolution,
                                        unit=unit,
                                        is_disabled=is_disabled,
                                        _type=_type)

        self.assertEqual(name, metric.name)
        self.assertEqual(display_name, metric.display_name)
        self.assertEqual(display_name_short, metric.display_name_short)
        self.assertEqual(description, metric.description)
        self.assertEqual(default_aggregate.upper(), metric.default_aggregate)
        self.assertEqual(default_resolution, metric.default_resolution)
        self.assertEqual(unit, metric.unit)
        self.assertEqual(_type, metric.type)
        self.assertEqual(is_disabled, metric.is_disabled)

        self.api.metric_delete(name)

    def test_metric_batch_update(self):
        pass