class DjangoClient(object):
    def __init__(self):
        auklet_config = settings.AUKLET_CONFIG
        self.apikey = auklet_config.get("api_key", None)
        self.app_id = auklet_config.get("application", None)
        self.release = auklet_config.get("release", None)
        self.version = auklet_config.get("version", None)
        self.org_id = auklet_config.get("organization", None)
        self.broker_url = auklet_config.get("broker", "mq.feeds.auklet.io")
        self.port = auklet_config.get("port", 8883)
        self.base_url = auklet_config.get("base_url", "https://api.auklet.io/")

        if self.apikey is None:
            raise AukletConfigurationError(
                "Please set api_key in AUKLET_CONFIG settings")
        if self.app_id is None:
            raise AukletConfigurationError(
                "Please set application in AUKLET_CONFIG settings")
        if self.org_id is None:
            raise AukletConfigurationError(
                "Please set organization in AUKLET_CONFIG settings")
        self.auklet_dir = create_dir()
        self.mac_hash = get_mac()
        self.device_ip = get_device_ip()
        self.agent_version = get_agent_version()
        self.broker = MQTTClient(self.broker_url, self.port, self.app_id,
                                 self.org_id, self.apikey, self.base_url,
                                 self.auklet_dir)
        self.broker._get_certs()
        self.file_cache = FilenameCaches()

    def build_event_data(self, type, traceback):
        event = Event(type, traceback, self.file_cache)
        event_dict = dict(event)
        event_dict['application'] = self.app_id
        event_dict['publicIP'] = get_device_ip()
        event_dict['id'] = str(uuid4())
        event_dict['timestamp'] = int(round(time() * 1000))
        event_dict['systemMetrics'] = dict(SystemMetrics())
        event_dict['macAddressHash'] = self.mac_hash
        event_dict['release'] = self.release
        event_dict['version'] = self.version
        event_dict['agentVersion'] = get_agent_version()
        event_dict['device'] = None
        return event_dict

    def build_msgpack_event_data(self, type, traceback):
        event_data = self.build_event_data(type, traceback)
        return msgpack.packb(event_data, use_bin_type=False)

    def produce_event(self, type, traceback):
        self.broker.produce(self.build_msgpack_event_data(type, traceback))
class TestMQTTBroker(unittest.TestCase):
    data = ast.literal_eval(str(data_factory.MonitoringDataFactory()))
    config = ast.literal_eval(str(data_factory.ConfigFactory()))

    def setUp(self):
        with patch("auklet.monitoring.processing.Client._register_device",
                   new=self.__register_device):
            self.client = Client(apikey="",
                                 app_id="",
                                 base_url="https://api-staging.auklet.io/")
            with patch('auklet.broker.MQTTClient._get_conf') as _get_conf:
                _get_conf.side_effect = self.get_conf
                self.broker = MQTTClient(self.client)

    def test_write_conf(self):
        self.broker._write_conf(self.config)
        self.assertGreater(os.path.getsize(self.client.com_config_filename), 0)
        open(self.client.com_config_filename, "w").close()

    def test_get_certs(self):
        class urlopen:
            @staticmethod
            def read():
                with open("key.pem.zip", "rb") as file:
                    return file.read()

        self.assertFalse(self.broker._get_certs())
        with patch('auklet.broker.urlopen') as _urlopen:
            _urlopen.return_value = urlopen
            self.assertTrue(self.broker._get_certs())

    def test_read_from_conf(self):
        self.broker._read_from_conf({
            "brokers": "mqtt",
            "port": "8333",
            "prof_topic": "",
            "event_topic": "",
            "log_topic": ""
        })
        self.assertIsNotNone(self.broker.brokers)
        self.assertIsNotNone(self.broker.port)
        self.assertIsNotNone(self.broker.producer_types)

    def test_on_disconnect(self):
        def debug(msg):
            global debug_msg
            debug_msg = msg

        with patch('logging.debug') as _debug:
            _debug.side_effect = debug
            self.broker.on_disconnect(None, "", 1)
            self.assertIsNotNone(debug_msg)

    def test_create_producer(self):
        global create_producer_pass
        create_producer_pass = False

        with patch('auklet.broker.MQTTClient._get_certs') as get_certs:
            with patch('paho.mqtt.client.Client') as _Client:
                _Client.side_effect = self.MockClient
                get_certs.return_value = True
                os.system("touch .auklet/ck_ca.pem")
                self.broker.create_producer()
                self.assertTrue(create_producer_pass)

    def test_produce(self):
        with patch('paho.mqtt.client.Client.publish') as _publish:
            with patch('auklet.broker.MQTTClient._get_certs') as get_certs:
                with patch('paho.mqtt.client.Client') as _MQTT_Client:
                    _MQTT_Client.side_effect = self.MockClient
                    get_certs.return_value = True
                    _publish.side_effect = self.publish
                    self.broker.create_producer()
                    self.broker.produce(str(self.data))
                    self.assertIsNotNone(test_produce_payload)

    def test_get_conf(self):
        with patch('auklet.broker.open_auklet_url', new=self._open_auklet_url):
            with patch('auklet.broker.json.loads', new=self._loads):
                self.broker._get_conf()

    class MockClient:
        def __init__(self, client_id, protocol, transport):
            pass

        def tls_set(self, ca_certs):
            pass

        def tls_set_context(self):
            pass

        def connect_async(self, broker, port):
            pass

        def enable_logger(self):
            pass

        def username_pw_set(self, username, password):
            pass

        def publish(self, topic, payload):
            global test_produce_payload
            test_produce_payload = payload

        def loop_start(self):
            global create_producer_pass
            create_producer_pass = True

    @staticmethod
    def publish(data_type, payload):
        global test_produce_payload
        test_produce_payload = payload

    @staticmethod
    def get_conf():
        return True

    @staticmethod
    def _open_auklet_url(url, apikey):
        class MyObject:
            def read(self):
                return b"test_str"

        return MyObject()

    @staticmethod
    def _loads(data):
        return {"brokers": "mqtt", "port": "8883"}

    @staticmethod
    def __register_device(self):
        return True
Beispiel #3
0
class TestMQTTBroker(unittest.TestCase):
    data = ast.literal_eval(str(data_factory.MonitoringDataFactory()))
    config = ast.literal_eval(str(data_factory.ConfigFactory()))

    def setUp(self):
        with patch("auklet.monitoring.processing.Client._register_device",
                   new=self.__register_device):
            self.client = Client(api_key="",
                                 app_id="",
                                 base_url="https://api-staging.auklet.io/",
                                 auklet_dir=".auklet")
            with patch('auklet.broker.MQTTClient._get_conf') as _get_conf:
                with patch("os.path.isfile") as is_file_mock:
                    is_file_mock.return_value = False
                    _get_conf.side_effect = self.get_conf
                    self.broker = MQTTClient(self.client)

    def test_write_conf(self):
        self.broker._write_conf(self.config)
        self.assertGreater(os.path.getsize(self.client.com_config_filename), 0)
        open(self.client.com_config_filename, "w").close()

    def test_get_certs(self):
        pubnub_cert_filename = ".auklet/pubnub.json"
        with open("key.pem.zip", "wb"):
            pass

        class urlopen:
            @staticmethod
            def read():
                with open("key.pem.zip", "rb") as file:
                    return file.read()

        if os.path.exists(pubnub_cert_filename):
            os.remove(pubnub_cert_filename)
        self.assertFalse(self.broker._get_certs())
        with patch('auklet.broker.urlopen') as _urlopen:
            _urlopen.return_value = urlopen
            with open(pubnub_cert_filename, "wb") as f:
                f.write(
                    json.dumps({
                        "publish_key": "",
                        "subscribe_key": ""
                    },
                               ensure_ascii=False).encode("gbk"))
            self.assertTrue(self.broker._get_certs())

    def test_read_from_conf(self):
        self.broker._read_from_conf({
            "brokers": "mqtt",
            "port": "8333",
            "prof_topic": "",
            "event_topic": "",
            "log_topic": ""
        })
        self.assertIsNotNone(self.broker.brokers)
        self.assertIsNotNone(self.broker.port)
        self.assertIsNotNone(self.broker.producer_types)

    def test_on_disconnect(self):
        def debug(msg):
            global debug_msg
            debug_msg = msg

        with patch('logging.debug') as _debug:
            _debug.side_effect = debug
            self.broker.on_disconnect(None, "", 1)
            self.assertIsNotNone(debug_msg)

    def test_create_producer(self):
        global create_producer_pass
        create_producer_pass = False

        with patch('auklet.broker.MQTTClient._get_certs') as get_certs:
            with patch('pubnub.pubnub.PubNub') as _Client:
                _Client.side_effect = self.MockClient
                get_certs.return_value = True
                os.system("touch .auklet/pubnub.json")
                self.broker.create_producer()

    def test_produce(self):
        with patch('pubnub.pubnub.PubNub.publish') as _publish:
            with patch('auklet.broker.MQTTClient._get_certs') as get_certs:
                with patch('pubnub.pubnub.PubNub') as _PubNub_Client:
                    _PubNub_Client.side_effect = self.MockClient
                    get_certs.return_value = True
                    _publish.side_effect = self.publish
                    self.broker.create_producer()
                    self.broker.produce(str(self.data), "event")
                    self.assertIsNotNone(test_produce_payload)

    def test_get_conf(self):
        with patch('auklet.broker.open_auklet_url', new=self._open_auklet_url):
            with patch('auklet.broker.json.loads', new=self._loads):
                self.broker._get_conf()

    class MockClient:
        def __init__(self, config):
            global create_producer_pass
            create_producer_pass = True

        def tls_set(self, ca_certs):
            pass

        def tls_set_context(self, context):
            pass

        def connect_async(self, broker, port):
            pass

        def enable_logger(self):
            pass

        def username_pw_set(self, username, password):
            pass

        def publish(self):
            global test_produce_payload
            test_produce_payload = True

    @staticmethod
    def publish():
        global test_produce_payload
        test_produce_payload = True

        class Channel:
            def channel(self, channel):
                class Message:
                    def message(self, message):
                        class Sync:
                            def sync(self):
                                pass

                        return Sync()

                return Message()

        return Channel()

    @staticmethod
    def get_conf():
        return True

    @staticmethod
    def _open_auklet_url(url, apikey):
        class MyObject:
            def read(self):
                return b"test_str"

        return MyObject()

    @staticmethod
    def _loads(data):
        return {"brokers": "mqtt", "port": "8883"}

    @staticmethod
    def __register_device(self):
        return True