316 lines
16 KiB
C
316 lines
16 KiB
C
#include <filter.h>
|
|
#include <it2s-asn/etsi-its-v2/cam/EI2_CAM.h>
|
|
#include <it2s-asn/etsi-its-v2/cpm/EI2_CollectivePerceptionMessage.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <unity.h>
|
|
|
|
void setUp(void) {
|
|
// set stuff up here
|
|
}
|
|
|
|
void tearDown(void) {
|
|
// clean stuff up here
|
|
}
|
|
|
|
void test_ldm_filter_new(void) {
|
|
int ret;
|
|
|
|
uint64_t ref_val = 1000;
|
|
EI2_CollectivePerceptionMessage_t* cpm = calloc(1, sizeof(*cpm));
|
|
asn_uint642INTEGER(&cpm->payload.managementContainer.referenceTime, ref_val);
|
|
|
|
ldm_filter_t* filter = NULL;
|
|
|
|
// Invalid filter
|
|
EI2_Filter_t* asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_NOTHING;
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CPM);
|
|
TEST_ASSERT_MESSAGE(filter == NULL, "New filter should return NULL when type is NOTHING");
|
|
|
|
ret = ldm_filter_check(filter, cpm);
|
|
TEST_ASSERT_MESSAGE(ret == 1, "Filter check should return 1 when filter is NULL");
|
|
|
|
// Simple filter with only a statement
|
|
|
|
asn_filter->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter->choice.filterStatement.attribute, "referenceTime", -1);
|
|
asn_filter->choice.filterStatement.Operator = EI2_ComparisonOperators_equal;
|
|
asn_filter->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
// asn_fprint(stdout, &asn_DEF_EI2_Filter, asn_filter);
|
|
// filter: referenceTime = 1000
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CPM);
|
|
|
|
TEST_ASSERT_MESSAGE(filter != NULL, "New filter should not return NULL when type is CPM and filter is valid");
|
|
|
|
ret = ldm_filter_check(filter, cpm);
|
|
TEST_ASSERT_MESSAGE(ret == 1, "Filter check should return 1 when filter matches the data");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
ldm_filter_release(filter);
|
|
|
|
// filter with two statements
|
|
|
|
EI2_Filter_t* asn_filter1 = calloc(1, sizeof(*asn_filter1));
|
|
asn_filter1->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.attribute, "referenceTime", -1);
|
|
asn_filter1->choice.filterStatement.Operator = EI2_ComparisonOperators_gt;
|
|
asn_filter1->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
|
|
EI2_Filter_t* asn_filter2 = calloc(1, sizeof(*asn_filter2));
|
|
asn_filter2->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.attribute, "referenceTime", -1);
|
|
asn_filter2->choice.filterStatement.Operator = EI2_ComparisonOperators_lt;
|
|
asn_filter2->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
|
|
asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_filterExp;
|
|
asn_filter->choice.filterExp = calloc(1, sizeof(EI2_FilterExp_t));
|
|
asn_filter->choice.filterExp->logicalOperator = EI2_LogicalOperators_and;
|
|
asn_filter->choice.filterExp->filter1 = asn_filter1;
|
|
asn_filter->choice.filterExp->filter2 = asn_filter2;
|
|
// filter: (referenceTime > 1000) AND (referenceTime < 1000)
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CPM);
|
|
TEST_ASSERT_MESSAGE(filter != NULL, "New filter should not return NULL when type is CPM and filter is valid");
|
|
|
|
ret = ldm_filter_check(filter, cpm);
|
|
TEST_ASSERT_MESSAGE(ret == 0, "Filter check should return 0 when filter does not match the data");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
ldm_filter_release(filter);
|
|
|
|
// filter for an attribute that has no callback
|
|
|
|
asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter->choice.filterStatement.attribute, "unknownAttribute", -1);
|
|
asn_filter->choice.filterStatement.Operator = EI2_ComparisonOperators_equal;
|
|
asn_filter->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_intValue;
|
|
asn_filter->choice.filterStatement.refValue.choice.intValue = 1000;
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CPM);
|
|
TEST_ASSERT_MESSAGE(filter == NULL, "New filter should return NULL when attribute has no callback");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
|
|
// filter for a type that has no callback
|
|
|
|
asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter->choice.filterStatement.attribute, "referenceTime", -1);
|
|
asn_filter->choice.filterStatement.Operator = EI2_ComparisonOperators_equal;
|
|
asn_filter->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_intValue;
|
|
asn_filter->choice.filterStatement.refValue.choice.intValue = 1000;
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CAM);
|
|
TEST_ASSERT_MESSAGE(filter == NULL, "New filter should return NULL when attribute has no callback");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
|
|
// filter with two statements, but one is invalid, operator is &&
|
|
|
|
asn_filter1 = calloc(1, sizeof(*asn_filter1));
|
|
asn_filter1->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.attribute, "referenceTime", -1);
|
|
asn_filter1->choice.filterStatement.Operator = EI2_ComparisonOperators_gt;
|
|
asn_filter1->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
|
|
asn_filter2 = calloc(1, sizeof(*asn_filter2));
|
|
asn_filter2->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.attribute, "unknownAttribute", -1);
|
|
asn_filter2->choice.filterStatement.Operator = EI2_ComparisonOperators_lt;
|
|
asn_filter2->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
|
|
asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_filterExp;
|
|
asn_filter->choice.filterExp = calloc(1, sizeof(EI2_FilterExp_t));
|
|
asn_filter->choice.filterExp->logicalOperator = EI2_LogicalOperators_and;
|
|
asn_filter->choice.filterExp->filter1 = asn_filter1;
|
|
asn_filter->choice.filterExp->filter2 = asn_filter2;
|
|
// filter: (referenceTime > 1000) AND (unknownAttribute < 1000)
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CPM);
|
|
TEST_ASSERT_MESSAGE(
|
|
filter != NULL,
|
|
"New filter should not return NULL when type is CPM and filter expression is partially valid (one of the statements is invalid)");
|
|
|
|
ret = ldm_filter_check(filter, cpm);
|
|
TEST_ASSERT_MESSAGE(
|
|
ret == 0, "Filter check should return 0 when the non null part of the filter does not match the data (logical operator is &&)");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
ldm_filter_release(filter);
|
|
|
|
// filter with two statements, but one is invalid
|
|
|
|
asn_filter1 = calloc(1, sizeof(*asn_filter1));
|
|
asn_filter1->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.attribute, "referenceTime", -1);
|
|
asn_filter1->choice.filterStatement.Operator = EI2_ComparisonOperators_gt;
|
|
asn_filter1->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
|
|
asn_filter2 = calloc(1, sizeof(*asn_filter2));
|
|
asn_filter2->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.attribute, "unknownAttribute", -1);
|
|
asn_filter2->choice.filterStatement.Operator = EI2_ComparisonOperators_lt;
|
|
asn_filter2->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_octsValue;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.refValue.choice.octsValue, (char*)&ref_val, sizeof(uint64_t));
|
|
|
|
asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_filterExp;
|
|
asn_filter->choice.filterExp = calloc(1, sizeof(EI2_FilterExp_t));
|
|
asn_filter->choice.filterExp->logicalOperator = EI2_LogicalOperators_or;
|
|
asn_filter->choice.filterExp->filter1 = asn_filter1;
|
|
asn_filter->choice.filterExp->filter2 = asn_filter2;
|
|
// filter: (referenceTime > 1000) AND (unknownAttribute < 1000)
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CPM);
|
|
TEST_ASSERT_MESSAGE(
|
|
filter != NULL,
|
|
"New filter should not return NULL when type is CPM and filter expression is partially valid (one of the statements is invalid)");
|
|
|
|
ret = ldm_filter_check(filter, cpm);
|
|
TEST_ASSERT_MESSAGE(
|
|
ret == 1, "Filter check should return 1 when the non null part of the filter does not match the data (logical operator is ||)");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
ldm_filter_release(filter);
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_CollectivePerceptionMessage, cpm);
|
|
}
|
|
|
|
void test_ldm_filter_complex(void) {
|
|
int ret;
|
|
|
|
EI2_CAM_t* cam = calloc(1, sizeof(*cam));
|
|
// asn_random_fill(&asn_DEF_EI2_CAM, (void**)&cam, 1000);
|
|
cam->cam.camParameters.highFrequencyContainer.present = EI2_HighFrequencyContainer_PR_basicVehicleContainerHighFrequency;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedValue = 20;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedConfidence = 7;
|
|
|
|
ldm_filter_t* filter = NULL;
|
|
|
|
// filter: ((speed > 10) && ((speed < 100) || (speed == 123))) && (speed != 50)
|
|
// in all these check, (confidence < ref_confidence is also checked)
|
|
|
|
uint16_t ref_conf = 10;
|
|
|
|
// filter1: speed > 10
|
|
EI2_Filter_t* asn_filter1 = calloc(1, sizeof(*asn_filter1));
|
|
asn_filter1->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter1->choice.filterStatement.attribute, "speed", -1);
|
|
asn_filter1->choice.filterStatement.Operator = EI2_ComparisonOperators_gt;
|
|
asn_filter1->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_speedValue;
|
|
asn_filter1->choice.filterStatement.refValue.choice.speedValue.speedValue = 10;
|
|
asn_filter1->choice.filterStatement.refValue.choice.speedValue.speedConfidence = ref_conf;
|
|
|
|
// filter2: speed < 100
|
|
EI2_Filter_t* asn_filter2 = calloc(1, sizeof(*asn_filter2));
|
|
asn_filter2->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter2->choice.filterStatement.attribute, "speed", -1);
|
|
asn_filter2->choice.filterStatement.Operator = EI2_ComparisonOperators_lt;
|
|
asn_filter2->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_speedValue;
|
|
asn_filter2->choice.filterStatement.refValue.choice.speedValue.speedValue = 100;
|
|
asn_filter2->choice.filterStatement.refValue.choice.speedValue.speedConfidence = ref_conf;
|
|
|
|
// filter3: speed == 123
|
|
EI2_Filter_t* asn_filter3 = calloc(1, sizeof(*asn_filter3));
|
|
asn_filter3->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter3->choice.filterStatement.attribute, "speed", -1);
|
|
asn_filter3->choice.filterStatement.Operator = EI2_ComparisonOperators_equal;
|
|
asn_filter3->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_speedValue;
|
|
asn_filter3->choice.filterStatement.refValue.choice.speedValue.speedValue = 123;
|
|
asn_filter3->choice.filterStatement.refValue.choice.speedValue.speedConfidence = ref_conf;
|
|
|
|
// filter4: speed != 50
|
|
EI2_Filter_t* asn_filter4 = calloc(1, sizeof(*asn_filter4));
|
|
asn_filter4->present = EI2_Filter_PR_filterStatement;
|
|
OCTET_STRING_fromBuf(&asn_filter4->choice.filterStatement.attribute, "speed", -1);
|
|
asn_filter4->choice.filterStatement.Operator = EI2_ComparisonOperators_notequal;
|
|
asn_filter4->choice.filterStatement.refValue.present = EI2_ReferenceValue_PR_speedValue;
|
|
asn_filter4->choice.filterStatement.refValue.choice.speedValue.speedValue = 50;
|
|
asn_filter4->choice.filterStatement.refValue.choice.speedValue.speedConfidence = ref_conf;
|
|
|
|
// filter: (filter2 || filter3)
|
|
EI2_Filter_t* asn_filter5 = calloc(1, sizeof(*asn_filter5));
|
|
asn_filter5->present = EI2_Filter_PR_filterExp;
|
|
asn_filter5->choice.filterExp = calloc(1, sizeof(EI2_FilterExp_t));
|
|
asn_filter5->choice.filterExp->logicalOperator = EI2_LogicalOperators_or;
|
|
asn_filter5->choice.filterExp->filter1 = asn_filter2;
|
|
asn_filter5->choice.filterExp->filter2 = asn_filter3;
|
|
|
|
// filter: (filter1 && filter5)
|
|
EI2_Filter_t* asn_filter6 = calloc(1, sizeof(*asn_filter6));
|
|
asn_filter6->present = EI2_Filter_PR_filterExp;
|
|
asn_filter6->choice.filterExp = calloc(1, sizeof(EI2_FilterExp_t));
|
|
asn_filter6->choice.filterExp->logicalOperator = EI2_LogicalOperators_and;
|
|
asn_filter6->choice.filterExp->filter1 = asn_filter1;
|
|
asn_filter6->choice.filterExp->filter2 = asn_filter5;
|
|
|
|
// filter: (filter6 && filter4)
|
|
EI2_Filter_t* asn_filter = calloc(1, sizeof(*asn_filter));
|
|
asn_filter->present = EI2_Filter_PR_filterExp;
|
|
asn_filter->choice.filterExp = calloc(1, sizeof(EI2_FilterExp_t));
|
|
asn_filter->choice.filterExp->logicalOperator = EI2_LogicalOperators_and;
|
|
asn_filter->choice.filterExp->filter1 = asn_filter6;
|
|
asn_filter->choice.filterExp->filter2 = asn_filter4;
|
|
|
|
// asn_fprint(stdout, &asn_DEF_EI2_Filter, asn_filter);
|
|
|
|
filter = ldm_filter_new(asn_filter, ldm_data_type_CAM);
|
|
TEST_ASSERT_MESSAGE(filter != NULL, "New filter should not return NULL when type is CAM and filter is valid");
|
|
|
|
ret = ldm_filter_check(filter, cam);
|
|
TEST_ASSERT_MESSAGE(ret == 1, "Filter check should return 1 when filter matches the data");
|
|
|
|
// check with a CAM that does not match the filter due to the speed value (filter1)
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedValue = 8;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedConfidence = 7;
|
|
ret = ldm_filter_check(filter, cam);
|
|
TEST_ASSERT_MESSAGE(ret == 0, "Filter check should return 0 when filter does not match the speed (speed <= 10)");
|
|
|
|
// check with a CAM that does not match the filter due to the speed value (filter2)
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedValue = 101;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedConfidence = 7;
|
|
ret = ldm_filter_check(filter, cam);
|
|
TEST_ASSERT_MESSAGE(ret == 0, "Filter check should return 0 when filter does not match the speed (speed >= 100)");
|
|
|
|
// check with a CAM that matches the filter due to the speed value (filter3)
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedValue = 123;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedConfidence = 7;
|
|
ret = ldm_filter_check(filter, cam);
|
|
TEST_ASSERT_MESSAGE(ret == 1, "Filter check should return 1 when filter matches the speed (speed == 123)");
|
|
|
|
// check with a CAM that does not match the filter due to the speed value (filter4)
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedValue = 50;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedConfidence = 7;
|
|
ret = ldm_filter_check(filter, cam);
|
|
TEST_ASSERT_MESSAGE(ret == 0, "Filter check should return 0 when filter does not match the speed (speed == 50)");
|
|
|
|
// check with a CAM that does not match the filter due to the speed confidence
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedValue = 20;
|
|
cam->cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency.speed.speedConfidence = 11;
|
|
ret = ldm_filter_check(filter, cam);
|
|
TEST_ASSERT_MESSAGE(ret == 0, "Filter check should return 0 when speed confidence exceeds the reference value");
|
|
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_CAM, cam);
|
|
ASN_STRUCT_FREE(asn_DEF_EI2_Filter, asn_filter);
|
|
ldm_filter_release(filter);
|
|
}
|
|
|
|
int main(void) {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_ldm_filter_new);
|
|
RUN_TEST(test_ldm_filter_complex);
|
|
return UNITY_END();
|
|
}
|