X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Funit_test_admission_policy.cc;fp=test%2Funit_test_admission_policy.cc;h=81ab0adb196b9fea13bcac2cbd8f8af216432e78;hb=4e545a8b013e60f2ff59254cb3fe435012d8fe5a;hp=88cb3a523a60c6227cb57abf1bea91dec66a39a2;hpb=82ba4b9999ca8e09461315a919b36a66641a6c7d;p=ric-app%2Fadmin.git diff --git a/test/unit_test_admission_policy.cc b/test/unit_test_admission_policy.cc index 88cb3a5..81ab0ad 100644 --- a/test/unit_test_admission_policy.cc +++ b/test/unit_test_admission_policy.cc @@ -27,10 +27,11 @@ #include -#define SCHEMA_FILE "../schemas/adm-ctrl-xapp-policy-schema.json" +#define SCHEMA_FILE "../schemas/rate-control-policy.json" #define SAMPLE_FILE "../schemas/samples.json" #define VES_FILE "../schemas/ves_schema.json" - +#define INVALID_JSON "./test-data/invalid.json" +#define VALID_JSON "./test-data/valid.json" bool report_mode_only = false; @@ -40,99 +41,274 @@ TEST_CASE("Admission Policy Wrapper", "[acxapp]"){ mdclog_attr_init(&attr); mdclog_attr_set_ident(attr, "UNIT TEST MESSAGE PROCESSOR "); mdclog_init(attr); - mdclog_level_set(MDCLOG_INFO); + mdclog_level_set(MDCLOG_DEBUG); mdclog_attr_destroy(attr); + std::string xapp_id = "ac-xapp-test123"; + + SECTION("Invalid number of instances requested"){ + REQUIRE_THROWS( admission(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 0, xapp_id)); + REQUIRE_THROWS( admission(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, -1, xapp_id)); + REQUIRE_THROWS( admission(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1000, xapp_id)); + } + + SECTION("Invalid AC xAPP Schema file "){ + REQUIRE_THROWS( admission("hello there", SAMPLE_FILE, VES_FILE, 1, xapp_id)); + } + + SECTION("Invalid sample file"){ + REQUIRE_THROWS(admission(SCHEMA_FILE, "hello there", VES_FILE, 1, xapp_id)); + } - SECTION("Invalid AC xAPP Schema"){ - REQUIRE_THROWS( admission("hello there", SAMPLE_FILE, VES_FILE, 1)); + SECTION("Invalid VES schema file "){ + REQUIRE_THROWS(admission(SCHEMA_FILE, SAMPLE_FILE, "hello there", 1, xapp_id)); } - SECTION("Invalid sample file"){ - REQUIRE_THROWS(admission(SCHEMA_FILE, "hello there", VES_FILE, 1)); - REQUIRE_THROWS(admission(SCHEMA_FILE, "random.txt", VES_FILE, 1)); + SECTION("Invalid JSON in a schema"){ + REQUIRE_THROWS(admission(INVALID_JSON, SAMPLE_FILE, VES_FILE, 1, xapp_id)); } - SECTION("Invalid VES schema"){ - REQUIRE_THROWS(admission(SCHEMA_FILE, SAMPLE_FILE, "hello there", 1)); + SECTION("Valid JSON, but no valid schema key"){ + REQUIRE_THROWS(admission(VALID_JSON, SAMPLE_FILE, VES_FILE, 1, xapp_id)); + REQUIRE_THROWS(admission(SCHEMA_FILE, VALID_JSON, VES_FILE, 1, xapp_id)); + } - - SECTION("Set policy : invalid"){ - std::string invalid_policy1 = "{\"blocking_rate\":20\"}"; - std::string invalid_policy2 = "{\"blocking_rate\":120, \"enforce\":\"true\", \"window_length\":50, \"trigger_threshold\":10}"; + + SECTION("Test policy schema validation"){ bool res; std::string response; - admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1); - res = adm_plugin.setPolicy(invalid_policy1.c_str(), invalid_policy1.length(), response); + std::string valid_policy = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"CREATE\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10, \"class\":14}}"; + + std::string invalid_policy1 = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"CREATE\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10, \"class\":5000}}"; + + std::string invalid_policy2 = "{\"policy_instance_id\":\"hello-there\", \"operation\":\"CREATE\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10, \"class\":14}}"; + + std::string invalid_policy3 = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"CREATED\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10, \"class\":14}}"; + std::string invalid_policy4 = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"CREATE\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10}}"; + + std::string invalid_policy5 = "hello-there"; + + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, xapp_id); + + REQUIRE_THAT(adm_plugin.getName(), Catch::Matchers::Equals("admission control policy")); + + res = adm_plugin.setPolicy(invalid_policy1.c_str(), invalid_policy1.length(), response); REQUIRE(res == false); - REQUIRE_THAT(response, Catch::Matchers::Contains("FAIL")); res = adm_plugin.setPolicy(invalid_policy2.c_str(), invalid_policy2.length(), response); REQUIRE(res == false); - REQUIRE_THAT(response, Catch::Matchers::Contains("FAIL")); - } + res = adm_plugin.setPolicy(invalid_policy3.c_str(), invalid_policy3.length(), response); + REQUIRE(res == false); + + res = adm_plugin.setPolicy(invalid_policy4.c_str(), invalid_policy4.length(), response); + REQUIRE(res == false); + + res = adm_plugin.setPolicy(invalid_policy5.c_str(), invalid_policy5.length(), response); + REQUIRE(res == false); - SECTION("Set policy : valid"){ - std::string valid_policy = "{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10}"; - bool res; - std::string response; - - admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1); res = adm_plugin.setPolicy(valid_policy.c_str(), valid_policy.length(), response); - std::cout <<"Response = " << response << " for " << valid_policy << std::endl; REQUIRE(res == true); - REQUIRE_THAT(response, Catch::Matchers::Contains("SUCCESS")); + + } + + SECTION("Test Set/configure/delete policy"){ + std::string policy = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"CREATE\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10, \"class\":14}}"; + std::string delete_policy = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"DELETE\"}"; + + + bool res; + std::string response, test_policy, policy_instance_id; + rapidjson::Document doc; + rapidjson::StringBuffer s_buffer; + rapidjson::Writer writer(s_buffer); + + int num_policies = 10; + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, xapp_id); + doc.Parse(policy.c_str()); + for(int i = 1; i <= num_policies; i++){ + policy_instance_id = "rate_control_policy_" + std::to_string(i); + rapidjson::SetValueByPointer(doc, "/policy_instance_id", policy_instance_id.c_str()); + rapidjson::SetValueByPointer(doc, "/payload/class", i); + s_buffer.Clear(); + writer.Reset(s_buffer); + doc.Accept(writer); + test_policy.assign(s_buffer.GetString(), s_buffer.GetLength()); + + // valid policy should succeed + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + std::cout <<"Response1 = " << response << std::endl; + REQUIRE(res == true); + + // trying to add policy with same class as before should also return true + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == true); + } + + REQUIRE(adm_plugin.get_num_policies() == num_policies); + + // configure existing policy should work + rapidjson::SetValueByPointer(doc, "/operation", "UPDATE"); + for(int i = 1; i <= num_policies; i++){ + policy_instance_id = "rate_control_policy_" + std::to_string(i); + rapidjson::SetValueByPointer(doc, "/policy_instance_id", policy_instance_id.c_str()); + rapidjson::SetValueByPointer(doc, "/payload/class", i); + rapidjson::SetValueByPointer(doc, "/payload/blocking_rate", 55.0); + s_buffer.Clear(); + writer.Reset(s_buffer); + doc.Accept(writer); + test_policy.assign(s_buffer.GetString(), s_buffer.GetLength()); + + // valid policy should succeed + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == true); + + } + // configure non-existing policy should fail + policy_instance_id = "rate_control_policy_" + std::to_string(1000); + rapidjson::SetValueByPointer(doc, "/policy_instance_id", policy_instance_id.c_str()); + s_buffer.Clear(); + writer.Reset(s_buffer); + doc.Accept(writer); + test_policy.assign(s_buffer.GetString(), s_buffer.GetLength()); + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == false); + + // configure exsting policy but with non-existing class should fail + policy_instance_id = "rate_control_policy_" + std::to_string(1); + rapidjson::SetValueByPointer(doc, "/policy_instance_id", policy_instance_id.c_str()); + rapidjson::SetValueByPointer(doc, "/payload/class", 200); + s_buffer.Clear(); + writer.Reset(s_buffer); + doc.Accept(writer); + test_policy.assign(s_buffer.GetString(), s_buffer.GetLength()); + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == false); + + // delete existing policy should work + doc.Parse(delete_policy.c_str()); + for(int i = 1; i <= num_policies; i++){ + std::string policy_instance_id = "rate_control_policy_" + std::to_string(i); + rapidjson::SetValueByPointer(doc, "/policy_instance_id", policy_instance_id.c_str()); + s_buffer.Clear(); + writer.Reset(s_buffer); + doc.Accept(writer); + test_policy.assign(s_buffer.GetString(), s_buffer.GetLength()); + + // delete policy should succeed since these policies were created + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == true); + } + + REQUIRE(adm_plugin.get_num_policies() == 0); + + //delete non-existing policy should fail + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == false); + + } - SECTION("Get policy"){ + // SECTION("Get policy"){ - std::string valid_policy = "{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10}"; - bool res; - std::string response; + // std::string valid_policy = "{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10}"; + // bool res; + // std::string response; - // first apply policy - admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1); - res = adm_plugin.setPolicy(valid_policy.c_str(), valid_policy.length(), response); - std::cout <<"Response = " << response << std::endl; - REQUIRE(res == true); - REQUIRE_THAT(response, Catch::Matchers::Contains("SUCCESS")); + // // first apply policy + // admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, xapp_id); + // res = adm_plugin.setPolicy(valid_policy.c_str(), valid_policy.length(), response); + // std::cout <<"Response = " << response << std::endl; + // REQUIRE(res == true); + // REQUIRE_THAT(response, Catch::Matchers::Contains("SUCCESS")); - // now retreive policy and check - res = adm_plugin.getPolicy(valid_policy.c_str(), valid_policy.length(), response); - REQUIRE(res == true); + // // now retreive policy and check + // res = adm_plugin.getPolicy(valid_policy.c_str(), valid_policy.length(), response); + // REQUIRE(res == true); - REQUIRE_THAT(response, Catch::Matchers::Contains("\"trigger_threshold\":10")); + // REQUIRE_THAT(response, Catch::Matchers::Contains("\"trigger_threshold\":10")); - } + // } SECTION("Metrics"){ - admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1); - int res; - std::string response; + + std::string policy = "{\"policy_type_id\":21000, \"policy_instance_id\":\"hello-there\", \"operation\":\"CREATE\", \"payload\":{\"blocking_rate\":20, \"enforce\":true, \"window_length\":50, \"trigger_threshold\":10, \"class\":14}}"; + + bool res; + std::string response, test_policy, policy_instance_id; + rapidjson::Document doc; + rapidjson::StringBuffer s_buffer; + rapidjson::Writer writer(s_buffer); + + int num_policies = 10; + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, xapp_id); + doc.Parse(policy.c_str()); + // Add some policies first + for(int i = 1; i <= num_policies; i++){ + policy_instance_id = "rate_control_policy_" + std::to_string(i); + rapidjson::SetValueByPointer(doc, "/policy_instance_id", policy_instance_id.c_str()); + rapidjson::SetValueByPointer(doc, "/payload/class", i); + s_buffer.Clear(); + writer.Reset(s_buffer); + doc.Accept(writer); + test_policy.assign(s_buffer.GetString(), s_buffer.GetLength()); + + // valid policy should succeed + res = adm_plugin.setPolicy(test_policy.c_str(), test_policy.length(), response); + REQUIRE(res == true); + //REQUIRE_THAT(response, Catch::Matchers::Contains("SUCCESS")); + } + + + // now get metrics + // First time, measurementInterval should be zero + std::vector metrics; + adm_plugin.getMetrics(metrics); + REQUIRE(metrics.size() == num_policies + 1); + for(auto const e : metrics){ + std::cout << e<< std::endl; + REQUIRE_THAT(e, Catch::Matchers::Contains("\"Class Id\"")); + REQUIRE_THAT(e, Catch::Matchers::Contains("\"measurementInterval\":\"0\"")); + } + + int interval = 5; + // wait for 'x' seconds and try again + std::this_thread::sleep_for(std::chrono::seconds(interval)); + rapidjson::Pointer int_ref("/event/measurementFields/measurementInterval"); + + metrics.clear(); + adm_plugin.getMetrics(metrics); + REQUIRE(metrics.size() == num_policies + 1); + for(auto const e : metrics){ + REQUIRE(doc.Parse(e.c_str()).HasParseError() == 0); + std::cout << e<< std::endl; + REQUIRE_THAT(e, Catch::Matchers::Contains("\"Class Id\"")); + // extract measurement interval + rapidjson::Value *interval_val = int_ref.Get(doc); + REQUIRE(interval_val != NULL); + double read_interval_approx = atof(interval_val->GetString()); + REQUIRE(read_interval_approx == Approx(interval).margin(1)); + } + - res = adm_plugin.getMetrics(response); - REQUIRE(res == 0); - std::cout << "Metrics response = " << response << std::endl; - REQUIRE_THAT(response, Catch::Matchers::Contains("\"SgNB Request Rate\":\"0\"")); } - SECTION("Get plugin"){ - admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1);; +SECTION("Get plugin"){ + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, xapp_id); protector * p = NULL; p = adm_plugin.get_protector_instance(100); REQUIRE( p == NULL); p = adm_plugin.get_protector_instance(0); REQUIRE(p != NULL); - REQUIRE(p->get_requests() == 0); + REQUIRE(p->get_requests(0) == 0); }