def test_username(self, stage, op, pipeline_config):
        assert not hasattr(op, "username")
        stage.run_op(op)

        expected_username = "******".format(
            id_scope=pipeline_config.id_scope,
            registration_id=pipeline_config.registration_id,
            api_version=pkg_constant.PROVISIONING_API_VERSION,
            user_agent=urllib.parse.quote(
                user_agent.get_provisioning_user_agent(), safe=""),
        )
        assert op.username == expected_username
    def test_get_provisioning_user_agent_str(self):
        user_agent_str = user_agent.get_provisioning_user_agent()

        assert PROVISIONING_IDENTIFIER in user_agent_str
        assert VERSION in user_agent_str
        assert platform.python_version() in user_agent_str
        assert platform.system() in user_agent_str
        assert platform.version() in user_agent_str
        assert platform.machine() in user_agent_str

        expected_part_agent = check_agent_format.format(
            identifier=PROVISIONING_IDENTIFIER,
            version=VERSION,
            python_runtime=platform.python_version(),
            os_type=platform.system(),
            os_release=platform.version(),
            architecture=platform.machine(),
        )
        assert expected_part_agent == user_agent_str
    def _run_op(self, op):

        if isinstance(op, pipeline_ops_base.InitializePipelineOperation):

            client_id = self.pipeline_root.pipeline_configuration.registration_id
            query_param_seq = [
                ("api-version", pkg_constant.PROVISIONING_API_VERSION),
                ("ClientVersion", user_agent.get_provisioning_user_agent()),
            ]
            username = "******".format(
                id_scope=self.pipeline_root.pipeline_configuration.id_scope,
                registration_id=self.pipeline_root.pipeline_configuration.
                registration_id,
                query_params=version_compat.urlencode(
                    query_param_seq, quote_via=urllib.parse.quote),
            )

            # Dynamically attach the derived MQTT values to the InitalizePipelineOperation
            # to be used later down the pipeline
            op.username = username
            op.client_id = client_id

            self.send_op_down(op)

        elif isinstance(op, pipeline_ops_base.RequestOperation):
            if op.request_type == pipeline_constant.REGISTER:
                topic = mqtt_topic_provisioning.get_register_topic_for_publish(
                    request_id=op.request_id)
                worker_op = op.spawn_worker_op(
                    worker_op_type=pipeline_ops_mqtt.MQTTPublishOperation,
                    topic=topic,
                    payload=op.request_body,
                )
                self.send_op_down(worker_op)
            elif op.request_type == pipeline_constant.QUERY:
                topic = mqtt_topic_provisioning.get_query_topic_for_publish(
                    request_id=op.request_id,
                    operation_id=op.query_params["operation_id"])
                worker_op = op.spawn_worker_op(
                    worker_op_type=pipeline_ops_mqtt.MQTTPublishOperation,
                    topic=topic,
                    payload=op.request_body,
                )
                self.send_op_down(worker_op)
            else:
                raise pipeline_exceptions.OperationError(
                    "RequestOperation request_type {} not supported".format(
                        op.request_type))

        elif isinstance(op, pipeline_ops_base.EnableFeatureOperation):
            # The only supported feature is REGISTER
            if not op.feature_name == pipeline_constant.REGISTER:
                raise pipeline_exceptions.OperationError(
                    "Trying to enable/disable invalid feature - {}".format(
                        op.feature_name))
            # Enabling for register gets translated into an MQTT subscribe operation
            topic = mqtt_topic_provisioning.get_register_topic_for_subscribe()
            worker_op = op.spawn_worker_op(
                worker_op_type=pipeline_ops_mqtt.MQTTSubscribeOperation,
                topic=topic)
            self.send_op_down(worker_op)

        elif isinstance(op, pipeline_ops_base.DisableFeatureOperation):
            # The only supported feature is REGISTER
            if not op.feature_name == pipeline_constant.REGISTER:
                raise pipeline_exceptions.OperationError(
                    "Trying to enable/disable invalid feature - {}".format(
                        op.feature_name))
            # Disabling a register response gets turned into an MQTT unsubscribe operation
            topic = mqtt_topic_provisioning.get_register_topic_for_subscribe()
            worker_op = op.spawn_worker_op(
                worker_op_type=pipeline_ops_mqtt.MQTTUnsubscribeOperation,
                topic=topic)
            self.send_op_down(worker_op)

        else:
            # All other operations get passed down
            super(ProvisioningMQTTTranslationStage, self)._run_op(op)