Ejemplo n.º 1
0
    def test_unique_kvp_key(self):
        reporter = HyperVKvpReportingHandler(kvp_file_path=self.tmp_file_path)
        evt1 = events.ReportingEvent("event_type", 'event_message',
                                     "event_description")
        reporter.publish_event(evt1)

        evt2 = events.ReportingEvent("event_type",
                                     'event_message',
                                     "event_description",
                                     timestamp=evt1.timestamp + 1)
        reporter.publish_event(evt2)

        reporter.q.join()
        kvps = list(reporter._iterate_kvps(0))
        self.assertEqual(2, len(kvps))
        self.assertNotEqual(kvps[0]["key"], kvps[1]["key"],
                            "duplicate keys for KVP entries")
Ejemplo n.º 2
0
def report_diagnostic_event(str):
    """Report a diagnostic event"""
    evt = events.ReportingEvent(DIAGNOSTIC_EVENT_TYPE, 'diagnostic message',
                                str, events.DEFAULT_EVENT_ORIGIN)
    events.report_event(evt)

    # return the event for unit testing purpose
    return evt
Ejemplo n.º 3
0
    def test_events_with_higher_incarnation_not_over_written(self):
        reporter = HyperVKvpReportingHandler(kvp_file_path=self.tmp_file_path)
        self.assertEqual(0, len(list(reporter._iterate_kvps(0))))

        reporter.publish_event(
            events.ReportingEvent('foo', 'name1', 'description'))
        reporter.publish_event(
            events.ReportingEvent('foo', 'name2', 'description'))
        reporter.q.join()
        self.assertEqual(2, len(list(reporter._iterate_kvps(0))))

        reporter3 = HyperVKvpReportingHandler(kvp_file_path=self.tmp_file_path)
        reporter3.incarnation_no = reporter.incarnation_no - 1
        reporter3.publish_event(
            events.ReportingEvent('foo', 'name3', 'description'))
        reporter3.q.join()
        self.assertEqual(3, len(list(reporter3._iterate_kvps(0))))
Ejemplo n.º 4
0
 def test_appropriate_logger_used(self, getLogger):
     event_type, event_name = 'test_type', 'test_name'
     event = events.ReportingEvent(event_type, event_name, 'description')
     reporting.handlers.LogHandler().publish_event(event)
     self.assertEqual(
         [mock.call(
             'cloudinit.reporting.{0}.{1}'.format(event_type, event_name))],
         getLogger.call_args_list)
 def test_appropriate_logger_used(self, getLogger):
     event_type, event_name = "test_type", "test_name"
     event = events.ReportingEvent(event_type, event_name, "description")
     reporting.handlers.LogHandler().publish_event(event)
     self.assertEqual(
         [
             mock.call("cloudinit.reporting.{0}.{1}".format(
                 event_type, event_name))
         ],
         getLogger.call_args_list,
     )
Ejemplo n.º 6
0
def report_diagnostic_event(
        msg: str, *, logger_func=None) -> events.ReportingEvent:
    """Report a diagnostic event"""
    if callable(logger_func):
        logger_func(msg)
    evt = events.ReportingEvent(
        DIAGNOSTIC_EVENT_TYPE, 'diagnostic message',
        msg, events.DEFAULT_EVENT_ORIGIN)
    events.report_event(evt, excluded_handler_types={"log"})

    # return the event for unit testing purpose
    return evt
Ejemplo n.º 7
0
    def test_as_dict(self):
        event_type, name, desc = 'test_type', 'test_name', 'test_desc'
        event = events.ReportingEvent(event_type, name, desc)
        expected = {'event_type': event_type, 'name': name,
                    'description': desc, 'origin': 'cloudinit'}

        # allow for timestamp to differ, but must be present
        as_dict = event.as_dict()
        self.assertIn('timestamp', as_dict)
        del as_dict['timestamp']

        self.assertEqual(expected, as_dict)
Ejemplo n.º 8
0
    def test_events_are_over_written(self):
        reporter = handlers.HyperVKvpReportingHandler(
            kvp_file_path=self.tmp_file_path)

        self.assertEqual(0, len(list(reporter._iterate_kvps(0))))

        reporter.publish_event(
            events.ReportingEvent('foo', 'name1', 'description'))
        reporter.publish_event(
            events.ReportingEvent('foo', 'name2', 'description'))
        reporter.q.join()
        self.assertEqual(2, len(list(reporter._iterate_kvps(0))))

        reporter2 = handlers.HyperVKvpReportingHandler(
            kvp_file_path=self.tmp_file_path)
        reporter2.incarnation_no = reporter.incarnation_no + 1
        reporter2.publish_event(
            events.ReportingEvent('foo', 'name3', 'description'))
        reporter2.q.join()

        self.assertEqual(2, len(list(reporter2._iterate_kvps(0))))
Ejemplo n.º 9
0
def report_compressed_event(event_name, event_content):
    """Report a compressed event"""
    compressed_data = base64.encodebytes(zlib.compress(event_content))
    event_data = {"encoding": "gz+b64",
                  "data": compressed_data.decode('ascii')}
    evt = events.ReportingEvent(
        COMPRESSED_EVENT_TYPE, event_name,
        json.dumps(event_data),
        events.DEFAULT_EVENT_ORIGIN)
    events.report_event(evt,
                        excluded_handler_types={"log", "print", "webhook"})

    # return the event for unit testing purpose
    return evt
Ejemplo n.º 10
0
    def test_event_type_can_be_filtered(self):
        reporter = handlers.HyperVKvpReportingHandler(
            kvp_file_path=self.tmp_file_path, event_types=['foo', 'bar'])

        reporter.publish_event(
            events.ReportingEvent('foo', 'name', 'description'))
        reporter.publish_event(
            events.ReportingEvent('some_other', 'name', 'description3'))
        reporter.q.join()

        kvps = list(reporter._iterate_kvps(0))
        self.assertEqual(1, len(kvps))

        reporter.publish_event(
            events.ReportingEvent('bar', 'name', 'description2'))
        reporter.q.join()
        kvps = list(reporter._iterate_kvps(0))
        self.assertEqual(2, len(kvps))

        self.assertIn('foo', kvps[0]['key'])
        self.assertIn('bar', kvps[1]['key'])
        self.assertNotIn('some_other', kvps[0]['key'])
        self.assertNotIn('some_other', kvps[1]['key'])
Ejemplo n.º 11
0
def get_system_info():
    """Collect and report system information"""
    info = util.system_info()
    evt = events.ReportingEvent(
        SYSTEMINFO_EVENT_TYPE, 'system information',
        "cloudinit_version=%s, kernel_version=%s, variant=%s, "
        "distro_name=%s, distro_version=%s, flavor=%s, "
        "python_version=%s" %
        (version.version_string(), info['release'], info['variant'],
         info['dist'][0], info['dist'][1], info['dist'][2], info['python']),
        events.DEFAULT_EVENT_ORIGIN)
    events.report_event(evt)

    # return the event for unit testing purpose
    return evt
    def test_as_dict(self):
        event_type, name, desc = "test_type", "test_name", "test_desc"
        event = events.ReportingEvent(event_type, name, desc)
        expected = {
            "event_type": event_type,
            "name": name,
            "description": desc,
            "origin": "cloudinit",
        }

        # allow for timestamp to differ, but must be present
        as_dict = event.as_dict()
        self.assertIn("timestamp", as_dict)
        del as_dict["timestamp"]

        self.assertEqual(expected, as_dict)
Ejemplo n.º 13
0
def get_boot_telemetry():
    """Report timestamps related to kernel initialization and systemd
       activation of cloud-init"""
    if not distros.uses_systemd():
        raise RuntimeError("distro not using systemd, skipping boot telemetry")

    LOG.debug("Collecting boot telemetry")
    try:
        kernel_start = float(time.time()) - float(util.uptime())
    except ValueError:
        raise RuntimeError("Failed to determine kernel start timestamp")

    try:
        out, _ = util.subp(
            ['/bin/systemctl', 'show', '-p', 'UserspaceTimestampMonotonic'],
            capture=True)
        tsm = None
        if out and '=' in out:
            tsm = out.split("=")[1]

        if not tsm:
            raise RuntimeError("Failed to parse "
                               "UserspaceTimestampMonotonic from systemd")

        user_start = kernel_start + (float(tsm) / 1000000)
    except util.ProcessExecutionError as e:
        raise RuntimeError("Failed to get UserspaceTimestampMonotonic: %s" % e)
    except ValueError as e:
        raise RuntimeError("Failed to parse "
                           "UserspaceTimestampMonotonic from systemd: %s" % e)

    try:
        out, _ = util.subp([
            '/bin/systemctl', 'show', 'cloud-init-local', '-p',
            'InactiveExitTimestampMonotonic'
        ],
                           capture=True)
        tsm = None
        if out and '=' in out:
            tsm = out.split("=")[1]
        if not tsm:
            raise RuntimeError("Failed to parse "
                               "InactiveExitTimestampMonotonic from systemd")

        cloudinit_activation = kernel_start + (float(tsm) / 1000000)
    except util.ProcessExecutionError as e:
        raise RuntimeError("Failed to get InactiveExitTimestampMonotonic: %s" %
                           e)
    except ValueError as e:
        raise RuntimeError("Failed to parse "
                           "InactiveExitTimestampMonotonic from systemd: %s" %
                           e)

    evt = events.ReportingEvent(
        BOOT_EVENT_TYPE, 'boot-telemetry',
        "kernel_start=%s user_start=%s cloudinit_activation=%s" %
        (datetime.utcfromtimestamp(kernel_start).isoformat() + 'Z',
         datetime.utcfromtimestamp(user_start).isoformat() + 'Z',
         datetime.utcfromtimestamp(cloudinit_activation).isoformat() + 'Z'),
        events.DEFAULT_EVENT_ORIGIN)
    events.report_event(evt)

    # return the event for unit testing purpose
    return evt
Ejemplo n.º 14
0
 def test_as_string(self):
     event_type, name, description = 'test_type', 'test_name', 'test_desc'
     event = events.ReportingEvent(event_type, name, description)
     expected_string_representation = ': '.join(
         [event_type, name, description])
     self.assertEqual(expected_string_representation, event.as_string())
Ejemplo n.º 15
0
 def test_log_message_uses_event_as_string(self, getLogger):
     event = events.ReportingEvent('type', 'name', 'description')
     reporting.handlers.LogHandler(level="INFO").publish_event(event)
     self.assertIn(event.as_string(),
                   getLogger.return_value.log.call_args[0][1])
Ejemplo n.º 16
0
 def test_single_log_message_at_info_published(self, getLogger):
     event = events.ReportingEvent('type', 'name', 'description')
     reporting.handlers.LogHandler().publish_event(event)
     self.assertEqual(1, getLogger.return_value.log.call_count)