예제 #1
0
def get_custom_algo(http_request, customized_algo_id, query_dict):
    """
    Reads the CustomizedAlgo specified
    :param http_request: the request
    :type http_request: HttpRequest
    :param customized_algo_id: the database ID of the CustomizedAlgo
    :type customized_algo_id: str of int
    :param query_dict: the query parameters
    :type query_dict: QueryDict
    :return: the Json response (nominal or error).
    :rtype: JsonResponse
    """

    # Builds the response in blocks try: or except:
    response_builder = DjangoHttpResponseFactory()
    try:
        # info-level is used to adapt the returned content of resource
        my_level = HttpCommonsIkats.get_info_level(http_request, query_dict)

        my_id = CustomizedAlgoDao.parse_dao_id(customized_algo_id)
        buzz_custom_algo = CustomizedAlgoDao.find_business_elem_with_key(
            primary_key=my_id)

        LOG_WS_CUSTOM.info("Found customized algo with id=%s: %s",
                           customized_algo_id, buzz_custom_algo)

        # CustomizedAlgoWs is wrapping the business resource
        # => manages the user rendering: json format, according to info-level
        ws_custom_algo = CustomizedAlgoWs(buzz_custom_algo)
        dict_custom_algo = ws_custom_algo.to_dict(level=my_level)

        my_response = JsonResponse(dict_custom_algo, safe=False)

    except CustomizedAlgoDao.DoesNotExist:
        # Example: customized_algo_id=99999999 is not matching a resource in database
        msg = "Does not exist: customized algo with id=%s" % customized_algo_id
        LOG_WS_CUSTOM.error(msg)
        my_response = response_builder.get_json_response_not_found(
            ikats_error=msg)

    except IkatsInputError as err:
        # Example: invalid info_level value in query params ...
        LOG_WS_CUSTOM.exception(err)
        msg = "Bad request in get_custom_algo with id={}".format(
            customized_algo_id)
        LOG_WS_CUSTOM.error(msg)
        my_response = response_builder.get_json_response_bad_request(
            ikats_error=msg, exception=err)

    except Exception as err:
        # Any unexpected error: database crash ...
        LOG_WS_CUSTOM.exception(err)
        msg = "Unexpected server error in get_custom_algo with id={}".format(
            customized_algo_id)
        LOG_WS_CUSTOM.error(msg)
        my_response = response_builder.get_json_response_internal_server_error(
            ikats_error=msg)

    return my_response
예제 #2
0
    def test_check_err_create_bad_dom(self):
        """
        Tests that CheckEngine produces expected CheckStatus, when checking domain error exists
        with the CustomizedAlgo creation Rest service.
        """

        # Re-activate checking rules
        CheckEngine.set_checking_rules(
            FactoryCatalogue.TYPE_CHECKING_FUNCTIONS)

        my_custom_outside_domain = self.init_rsrc_outside_domain()

        http_req = self.request_factory.post(
            path=reverse('pattern_custom_algos_dummy'),
            data=CustomizedAlgoWs(my_custom_outside_domain).to_json(),
            content_type="application/json_util")

        http_response = create_custom_algo(http_req)

        # Display the check result
        result = json_io.decode_json_from_http_response(http_response)

        self.info("response loaded={}".format(result))
        self.info("response status={}".format(http_response.status_code))

        self.assertTrue(http_response.status_code ==
                        HttpResponseFactory.BAD_REQUEST_HTTP_STATUS)
예제 #3
0
    def test_custo_create_200(self):
        """
        Tests the nominal Creation of CustomizedAlgo: we prepare the data and then submit creation
        """

        # Preparing the data ...
        my_new_custom_algo = self.init_resource_named(
            name="custom algo for create seq3", save_in_db=False)

        data = CustomizedAlgoWs(my_new_custom_algo).to_json()

        # ... testing the service
        http_req = self.request_factory.post(
            path=reverse('pattern_custom_algos_dummy'),
            data=data,
            content_type="application/json_util")

        http_response = create_custom_algo(http_req)

        result = json_io.decode_json_from_http_response(http_response)

        self.info("!!! response loaded={} !!!".format(result))
        self.info("!!! response status={} !!!".format(
            http_response.status_code))

        self.assertTrue(http_response.status_code ==
                        HttpResponseFactory.CREATED_HTTP_STATUS)
예제 #4
0
    def test_load_from_dict_seq4(self):
        """
        Nominal test of load_from_dict()
        """

        my_custom_ws = CustomizedAlgoWs(self.my_custom_algo_in_DB)
        normal_dict = my_custom_ws.to_dict(level=LevelInfo.NORMAL)

        self.info(
            "- Evaluating my_custom_algo_in_DB => CustomizedAlgoWs.load_from_dict(...)"
        )
        loaded_ws_resource = CustomizedAlgoWs.load_from_dict(normal_dict)

        my_business_custo = loaded_ws_resource.get_customized_algo()
        self.info(" - uploaded custom_algo={}".format(my_business_custo))

        self.assertTrue(my_business_custo == self.my_custom_algo_in_DB)
예제 #5
0
    def convert_to_ws_custom_algo(cls,
                                  business_custom_algo,
                                  level=LevelInfo.NORMAL):
        """
        Returns the json-friendly dictionary matching the content view of
          - one CustomizedAlgo resource
          - according to specified level

        :param business_custom_algo: the business resource CustomizedAlgo
        :type business_custom_algo: CustomizedAlgo
        :param level: the specified level: optional, default value is NORMAL
        :type level: LevelInfo
        :return the json-friendly dictionary
        :rtype: dict
        """
        my_rest_api_dto = CustomizedAlgoWs(business_custom_algo)

        return my_rest_api_dto.to_dict(level=level)
예제 #6
0
    def test_to_dict_summary_seq3(self):
        """
        Tests the building of SUMMARY-leveled json view
        """

        my_custom_ws = CustomizedAlgoWs(self.my_custom_algo_2_in_DB)

        self.info(
            "- Evaluating my_custom_algo_2_in_DB => to_dict(level=LevelInfo.SUMMARY): "
        )
        summary_dict = my_custom_ws.to_dict(level=LevelInfo.SUMMARY)

        ref_summary_dict = {
            "description": "Custo2 description",
            "label": "Custo2",
            "parent": {
                "description": "Python tan from math::my_tan",
                "label": "TestCustomizedAlgoWs ORM impl for CustomizedAlgo",
                "id": 11,
                "name": "TestCustomizedAlgoWs ORM impl for CustomizedAlgo"
            },
            "name": "TestCustomizedAlgoWs Custo2 of my_pseudo_impl_from_db",
            "family": "TestCustomizedAlgoWs tested family",
            "is_customized": True,
            "id": 5,
            "algo": "TestCustomizedAlgoWsmy algo",
            "visibility": True
        }

        self.info(json.dumps(obj=summary_dict, indent=2))

        self.assertEqual(summary_dict['parent']['id'],
                         self.my_custom_algo_2_in_DB.implementation.db_id)

        self.assertEqual(summary_dict['id'], self.my_custom_algo_2_in_DB.db_id)

        # Needed before comparing dict:
        #    change hard-coded ID values:
        #      hard-coded IDS can be different from IDs from prepared DB
        #
        ref_summary_dict['parent']['id'] = summary_dict['parent']['id']
        ref_summary_dict['id'] = summary_dict['id']

        self.assertDictEqual(ref_summary_dict, summary_dict)
예제 #7
0
    def convert_to_ws_list_custom_algo(cls,
                                       custom_algo_list,
                                       level=LevelInfo.SUMMARY):
        """
        Returns the list of json-friendly dictionaries:
        each dictionary is matching the content view of
          - each CustomizedAlgo resource from custom_algo_list
          - according to specified level
        :param custom_algo_list: the list of business resources CustomizedAlgo
        :type custom_algo_list: list
        :param level: the specified level: optional, default value is SUMMARY
        :type level: LevelInfo
        :return: the json string coding the list of customized algo resources
        :rtype: list
        """
        my_rest_api_list = []
        for custom in custom_algo_list:
            my_ws = CustomizedAlgoWs(custom)
            my_rest_api_list.append(my_ws.to_dict(level=level))

        return my_rest_api_list
예제 #8
0
    def test_checked_exec_errors_seq2(self):
        """
        Test run with
        - customized algo inconsistent with its implementation: 2 wrong specified values
        - run args: angle (no value overriding)
        => CheckEngine detects errors
        Note: this unit test is testing the expected error code.
        """
        angle = 1.58

        # Wrong type : string for factor
        #
        # Wrong value for phase: 5.0 is outside of the domain defined in
        # my_pseudo_impl_with_domain_from_db: [0, 1.1, 2 ]
        #
        # ... checking rule are not activated here:
        my_custom = self.init_resource_named("Custom for created at {}".format(time.time()),
                                             save_in_db=True,
                                             implem=self.my_pseudo_impl_with_domain_from_db,
                                             factor="3",
                                             phase=5.0)

        my_id = my_custom.name

        my_async = False
        my_opts = {'async': my_async, 'custo_algo': True, 'debug': True}

        # case where
        # => no parameter value is redefined
        # => only argument angle is specified
        my_args = {'angle': angle}

        my_data = {'opts': my_opts, 'args': my_args}

        # self.info("- Implem ={}".format( my_custom.implementation ) )
        self.info("- Custom ={}".format(CustomizedAlgoWs(my_custom).to_json(indent=2, level=LevelInfo.DETAIL)))
        self.info("- data ={}".format(json.dumps(obj=my_data, indent=2)))

        http_req = self.request_factory.post(path=reverse(viewname='algo_run', args=[my_id]),
                                             data=json.dumps(my_data),
                                             content_type="application/json")

        self.info("- data ={}".format(json.dumps(obj=my_data, indent=2)))
        http_response = views_algo_run(http_req, my_id)

        # Display the check result
        result = json_io.decode_json_from_http_response(http_response)

        self.info("response loaded={}".format(result))
        self.info("response status={}".format(http_response.status_code))

        self.assertTrue(http_response.status_code == HttpResponseFactory.BAD_REQUEST_HTTP_STATUS)
예제 #9
0
    def test_custo_create_409(self):
        """
        Tests the Creation failure case: CONFLICT_HTTP_STATUS
        """

        http_req = self.request_factory.post(
            path=reverse('pattern_custom_algos_dummy'),
            data=CustomizedAlgoWs(self.my_custom_algo_in_DB).to_json(),
            content_type="application/json_util")

        http_response = create_custom_algo(http_req)

        self.assertTrue(http_response.status_code ==
                        HttpResponseFactory.CONFLICT_HTTP_STATUS)
예제 #10
0
    def test_custo_update_404(self):
        """
        Tests the not found case, updating a CustomizedAlgo resource
          - returned status is 404
        """

        my_ws_modif = CustomizedAlgoWs(self.my_custom_algo_in_DB).to_dict()
        unknown = 99999
        my_ws_modif['id'] = unknown
        my_json_data = json.dumps(obj=my_ws_modif)

        client = Client()
        http_response_bis = client.put(
            '/ikats/algo/custom/custom_algos/{}'.format(unknown),
            data=my_json_data)

        self.assertTrue(http_response_bis.status_code ==
                        HttpResponseFactory.NOT_FOUND_HTTP_STATUS)
예제 #11
0
    def test_custo_update_400(self):
        """
        Tests the CustomizedAlgo Update failure case with BAD_REQUEST_HTTP_STATUS:
          - case when the CustomizedAlgo ID is unknown by database
        """

        # TEST: bad id in the URL => input error
        my_modif = self.my_custom_algo_in_DB

        http_req = self.request_factory.put(
            path=reverse(viewname='pattern_custom_algos_with_id',
                         args=["9999999"]),
            data=CustomizedAlgoWs(my_modif).to_json(),
            content_type="application/json_util")

        http_response = update_custom_algo(http_request=http_req,
                                           customized_algo_id="9999999")

        self.assertTrue(http_response.status_code ==
                        HttpResponseFactory.BAD_REQUEST_HTTP_STATUS)
예제 #12
0
    def test_custo_update_200(self):
        """
        Tests the nominal Update of CustomizedAlgo
        """

        my_modif = self.my_custom_algo_in_DB

        my_modif.label = "Modified label"

        http_req = self.request_factory.put(
            path=reverse(viewname='pattern_custom_algos_with_id',
                         args=[my_modif.db_id]),
            data=CustomizedAlgoWs(my_modif).to_json(),
            content_type="application/json_util")

        http_response = update_custom_algo(http_req,
                                           customized_algo_id=my_modif.db_id)

        self.assertTrue(
            http_response.status_code == HttpResponseFactory.OK_HTTP_STATUS)
예제 #13
0
    def test_custo_read_200(self):
        """
        Tests the nominal reading of resource initialized in test DB: self.my_custom_algo_in_DB
        """

        my_id = self.my_custom_algo_in_DB.db_id

        http_response = get_custom_algo(http_request=HttpRequest(),
                                        customized_algo_id=my_id,
                                        query_dict=None)

        self.assertTrue(
            http_response.status_code == HttpResponseFactory.OK_HTTP_STATUS)

        # Check result content: ... self.my_custom_algo_in_DB == biz_result
        dict_result = json_io.decode_json_from_http_response(http_response)

        ws_result = CustomizedAlgoWs.load_from_dict(dict_result)

        biz_result = ws_result.get_customized_algo()

        self.assertTrue(self.my_custom_algo_in_DB == biz_result)
예제 #14
0
    def test_checked_exec_nominal_seq1(self):
        """
        Tests that the nominal execution on one CustomizedAlgo consistent with its Implementation:
          - is executed in nominal mode (no tests about Python execution: tested by another Test unit)
        Note: this unit test is testing the expected error code.
        TODO: complete this test: evaluate that response body is empty
        """
        angle = 1.58

        my_custom = self.init_resource_named("Custom for created at {}".format(time.time()),
                                             save_in_db=True)

        my_name = my_custom.name

        my_async = False
        my_opts = {'async': my_async, 'custo_algo': my_name, 'debug': True}

        my_args = {'angle': angle}

        my_data = {'opts': my_opts, 'args': my_args}

        # self.info("- Implem ={}".format( my_custom.implementation ) )
        self.info("- Custom ={}".format(CustomizedAlgoWs(my_custom).to_json(indent=2, level=LevelInfo.DETAIL)))
        self.info("- data ={}".format(json.dumps(obj=my_data, indent=2)))

        http_req = self.request_factory.post(path=reverse(viewname='algo_run', args=[my_name]),
                                             data=json.dumps(my_data),
                                             content_type="application/json")

        self.info("- data ={}".format(json.dumps(obj=my_data, indent=2)))
        http_response = views_algo_run(http_req, my_name)

        # Display the check result
        result = json_io.decode_json_from_http_response(http_response)

        self.info("response loaded={}".format(result))
        self.info("response status={}".format(http_response.status_code))

        self.assertTrue(http_response.status_code == HttpResponseFactory.OK_HTTP_STATUS)
예제 #15
0
    def convert_to_business_custo_algo(cls, custom_algo_from_json):
        """
        Returns the business CustomizedAlgo resource from the equivalent json string.
        the customized algorithm

        :param custom_algo_from_json: json input encoding the resource
        :type custom_algo_from_json: str or equivalent json-friendly dict
        :return: the business resource CustomizedAlgo
        :rtype: CustomizedAlgo
        """
        if type(custom_algo_from_json) is str:
            my_dict = json.loads(custom_algo_from_json)
        elif type(custom_algo_from_json) is dict:
            my_dict = custom_algo_from_json
        else:
            msg = "Unexpected type={} for arg custom_algo_from_json in convert_to_business_custo_algo()"
            raise IkatsException(
                msg.format(type(custom_algo_from_json).__name__))

        my_ws_custo_algo = CustomizedAlgoWs.load_from_dict(my_dict)

        return my_ws_custo_algo.get_customized_algo()
예제 #16
0
    def test_to_dict_normal_seq1(self):
        """
        Tests the building of Normal-leveled json view of CustomizedAlgoWs
        """

        my_custom_ws = CustomizedAlgoWs(self.my_custom_algo_in_DB)

        self.info(
            "- Evaluating my_custom_ws => to_dict(level=LevelInfo.NORMAL): ")
        normal_dict = my_custom_ws.to_dict(level=LevelInfo.NORMAL)
        my_dict_str = json.dumps(obj=normal_dict, indent=2)
        self.info(my_dict_str)

        # Hard-defined reference: a bit long
        # --> start definition of ref_normal_dict ...
        ref_normal_dict = {
            "is_customized":
            True,
            "name":
            "Custo1 of my_pseudo_impl_from_db",
            "description":
            "Custo1 description",
            "inputs": [{
                "domain": None,
                "name": "angle",
                "description": "angle (rad)",
                "type": None,
                "label": "angle",
                "order_index": 0
            }],
            "parameters": [{
                "domain": None,
                "name": "factor",
                "description": "factor on angle",
                "default_value": None,
                "type": "number",
                "label": "factor",
                "value": 0.5,
                "order_index": 1
            }, {
                "domain": None,
                "name": "phase",
                "description": "added phase constant",
                "default_value": 0,
                "type": "number",
                "label": "phase",
                "value": 1.5,
                "order_index": 2
            }],
            "label":
            "Custo1",
            "family":
            "TestCustomizedAlgoWs tested family",
            "parent": {
                "label": "TestCustomizedAlgoWs ORM impl for CustomizedAlgo",
                "name": "TestCustomizedAlgoWs ORM impl for CustomizedAlgo",
                "description": "Python tan from math::my_tan",
                "id": 11
            },
            "outputs": [{
                "domain": None,
                "name": "result",
                "description": "tan(factor*angle+phase)",
                "type": None,
                "label": "result",
                "order_index": 0
            }],
            "algo":
            "TestCustomizedAlgoWsmy algo",
            "id":
            4,
            "visibility":
            True
        }
        # ... end definition of ref_normal_dict

        self.assertEqual(normal_dict['parent']['id'],
                         self.my_custom_algo_in_DB.implementation.db_id)

        self.assertEqual(normal_dict['id'], self.my_custom_algo_in_DB.db_id)

        # Needed before comparing dict:
        #    change hard-coded ID values: hard-coded values may be different from IDs from prepared DB
        #
        ref_normal_dict['parent']['id'] = normal_dict['parent']['id']
        ref_normal_dict['id'] = normal_dict['id']
        self.assertDictEqual(ref_normal_dict, normal_dict)
예제 #17
0
    def test_to_dict_detailed_seq2(self):
        """
        Tests the building of DETAIL-leveled json view
        """

        my_custom_ws = CustomizedAlgoWs(self.my_custom_algo_2_in_DB)

        self.info(
            "- Evaluating my_custom_algo_2_in_DB => to_dict(level=LevelInfo.DETAIL): "
        )
        detailed_dict = my_custom_ws.to_dict(level=LevelInfo.DETAIL)

        my_dict_str = json.dumps(obj=detailed_dict, indent=2)
        self.info(my_dict_str)

        # Hard-defined reference: a bit long
        # --> start definition of ref_dict ...
        ref_dict = {
            "is_customized":
            True,
            "execution_plugin":
            "apps.algo.execute.models.business.python_local_exec_engine::PythonLocalExecEngine",
            "outputs": [{
                "label": "result",
                "domain": None,
                "type": None,
                "name": "result",
                "order_index": 0,
                "description": "tan(factor*angle+phase)"
            }],
            "family":
            "TestCustomizedAlgoWs tested family",
            "label":
            "Custo2",
            "library_address":
            "ikats.processing.ikats_processing.tests.test_contrib::my_tan",
            "name":
            "TestCustomizedAlgoWs Custo2 of my_pseudo_impl_from_db",
            "algo":
            "TestCustomizedAlgoWsmy algo",
            "inputs": [{
                "label": "angle",
                "domain": None,
                "type": None,
                "name": "angle",
                "order_index": 0,
                "description": "angle (rad)"
            }],
            "parameters": [{
                "label": "factor",
                "value": 0.885,
                "default_value": None,
                "domain": None,
                "type": "number",
                "name": "factor",
                "order_index": 1,
                "description": "factor on angle"
            }, {
                "label": "phase",
                "value": 0.33,
                "default_value": 0,
                "domain": None,
                "type": "number",
                "name": "phase",
                "order_index": 2,
                "description": "added phase constant"
            }],
            "id":
            5,
            "description":
            "Custo2 description",
            "visibility":
            True,
            "parent": {
                "id": 11,
                "label": "TestCustomizedAlgoWs ORM impl for CustomizedAlgo",
                "name": "TestCustomizedAlgoWs ORM impl for CustomizedAlgo",
                "description": "Python tan from math::my_tan"
            }
        }
        # ... end definition of ref_dict

        self.assertEqual(detailed_dict['parent']['id'],
                         self.my_custom_algo_2_in_DB.implementation.db_id)

        self.assertEqual(detailed_dict['id'],
                         self.my_custom_algo_2_in_DB.db_id)

        # Needed before comparing dict:
        #    change hard-coded ID values:
        #      hard-coded IDS can be different from IDs from prepared DB
        #
        ref_dict['parent']['id'] = detailed_dict['parent']['id']
        ref_dict['id'] = detailed_dict['id']
        self.assertDictEqual(ref_dict, detailed_dict)