static void test_ctypes_xml_round_trip( ProtobufCMessage *pb1) { XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* module = model->load_module("ctype-test"); ASSERT_TRUE(module); // Convert PB to DOM rw_yang_netconf_op_status_t ncrs; XMLDocument::uptr_t dom1(mgr->create_document_from_pbcm(pb1, ncrs)); EXPECT_EQ(RW_YANG_NETCONF_OP_STATUS_OK, ncrs); ASSERT_TRUE(dom1.get()); // Convert DOM to XML std::string xml1 = dom1->to_string(); ASSERT_TRUE(xml1.length()); // Convert XML back into DOM std::string error_out; XMLDocument::uptr_t dom2(mgr->create_document_from_string(xml1.c_str(), error_out, false/*validate*/)); ASSERT_TRUE(dom2.get()); // Convert the DOM back into PB. UniquePtrProtobufCMessage<>::uptr_t pb2( protobuf_c_message_create( NULL, pb1->descriptor )); ASSERT_TRUE(pb2.get()); ncrs = dom2->to_pbcm( pb2.get() ); EXPECT_EQ(RW_YANG_NETCONF_OP_STATUS_OK, ncrs); EXPECT_TRUE(protobuf_c_message_is_equal_deep( NULL, pb1, pb2.get() )); }
TEST (RwXML,XMLWalkerTest) { TEST_DESCRIPTION("Verify the functioning of XMLWalker/XMLCopier"); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("company"); EXPECT_TRUE(ydom_top); std::ifstream fp; std::string file_name = get_rift_root() + std::string("/modules/core/util/yangtools/test/company.xml"); XMLDocument::uptr_t doc(mgr->create_document_from_file(file_name.c_str(), false)); ASSERT_TRUE(doc.get()); XMLNode* root = doc->get_root_node()->get_first_child(); EXPECT_TRUE(root); EXPECT_STREQ(root->get_local_name().c_str(), "company"); std::string error_out; XMLDocument::uptr_t to_doc(mgr->create_document_from_string("<data/>", error_out, false/*validate*/)); ASSERT_TRUE(to_doc.get()); ASSERT_TRUE(to_doc->get_root_node()); XMLCopier copier(to_doc->get_root_node()); XMLWalkerInOrder walker(root); walker.walk(&copier); to_doc->to_stdout(); std::cout << std::endl; // Now walk the copied tree along side the original tree and make sure they match // // root = to_doc->get_root_node(); EXPECT_STREQ(root->get_local_name().c_str(), "data"); XMLNode *old_node = doc->get_root_node(); old_node = old_node->get_first_child(); XMLNode *new_node = root->get_first_child(); EXPECT_STREQ(old_node->get_local_name().c_str(), new_node->get_local_name().c_str()); ASSERT_NO_FATAL_FAILURE(compare_xml_trees(old_node, new_node)); }
virtual void SetUp() { mgr = XMLManager::uptr_t(xml_manager_create_xerces()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("company"); ASSERT_TRUE(ydom_top); model->register_ypbc_schema( (const rw_yang_pb_schema_t*)RWPB_G_SCHEMA_YPBCSD(Company)); ASSERT_EQ((const rw_yang_pb_schema_t*)RWPB_G_SCHEMA_YPBCSD(Company), model->get_ypbc_schema()); ydom_top = model->load_module("company-augment"); ASSERT_TRUE(ydom_top); model->register_ypbc_schema( (const rw_yang_pb_schema_t*)RWPB_G_SCHEMA_YPBCSD(CompanyAugment)); ASSERT_EQ((const rw_yang_pb_schema_t*)RWPB_G_SCHEMA_YPBCSD(CompanyAugment), model->get_ypbc_schema()); schema = mgr->get_yang_model()->get_ypbc_schema(); ASSERT_TRUE(schema); std::string const delta_xml = "<data>" " <company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" " <employee>" " <id>0</id>" " <name>foo</name>" " </employee>" " <employee>" " <id>1</id>" " <name>bar</name>" " </employee>" " <wacky-interests>" " <name>foo</name>" " <id>0</id>" " </wacky-interests>" " <wacky-interests>" " <name>bar</name>" " <id>1</id>" " </wacky-interests>" " </company>" " <mangle-base xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" " <mangle>" " <name>asdf</name>" " <id>13</id>" " <bucket xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company-augment\">" " <contents>water</contents>" " </bucket>" " <bucket-list xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company-augment\">" " <place>victoria falls</place>" " </bucket-list>" " <bucket-list xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company-augment\">" " <place>angkor wat</place>" " </bucket-list>" " </mangle>" " </mangle-base>" "</data>"; std::string error_out; dom = XMLDocument::uptr_t(mgr->create_document_from_string(delta_xml.c_str(), error_out, false)); ASSERT_TRUE(dom.get()) << error_out; root = dom->get_root_node(); ASSERT_TRUE(root); }
TEST (RwXML, XMLSubtreeFilter) { TEST_DESCRIPTION ("XML subtree filtering"); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("company"); EXPECT_TRUE(ydom_top); std::string error; std::string file_name = get_rift_root() + std::string("/modules/core/util/yangtools/test/company.xml"); XMLDocument::uptr_t doc(mgr->create_document_from_file(file_name.c_str(), false)); ASSERT_TRUE(doc.get()); std::string filter = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<contact-info></contact-info>" "</company>" "</data>"; XMLDocument::uptr_t fdoc(mgr->create_document_from_string(filter.c_str(), error, false)); rw_status_t res; res = doc->subtree_filter(fdoc.get()); EXPECT_EQ(res, RW_STATUS_SUCCESS); std::cout << doc->to_string() << std::endl; std::string expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <contact-info>\n <name>RIFT.io Inc</name>\n <address>24, New England State Park, Burlington, MA</address>\n <phone-number>123-456-7890</phone-number>\n </contact-info>\n \n \n \n \n \n \n </company>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); // error.clear(); fdoc.release(); filter = "<data>" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<contact-info>" "<name/>" "</contact-info>" "</company>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); EXPECT_EQ(res, RW_STATUS_SUCCESS); std::cout << doc->to_string() << std::endl; auto root = doc->get_root_node(); ASSERT_TRUE(root); auto node = root->find("company", "http://riftio.com/ns/core/util/yangtools/tests/company"); ASSERT_TRUE(node); auto contact_info_node = node->find("contact-info", nullptr); EXPECT_TRUE(contact_info_node); auto contact_info_name = contact_info_node->find("name", nullptr); EXPECT_TRUE(contact_info_name); expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <contact-info>\n <name>RIFT.io Inc</name>\n \n \n </contact-info>\n \n \n \n \n \n \n </company>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); //------ error.clear(); fdoc.release(); filter = "<data>" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<employee xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "</employee>" "</company>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); std::cout << doc->get_root_node()->to_string() << std::endl; EXPECT_EQ(res, RW_STATUS_SUCCESS); root = doc->get_root_node(); ASSERT_TRUE(root); node = root->find("company", "http://riftio.com/ns/core/util/yangtools/tests/company"); ASSERT_TRUE(node); node = node->find("employee", nullptr); ASSERT_TRUE(node); size_t employee_count = 0; while (node) { employee_count++; node = node->get_next_sibling(node->get_local_name(), node->get_name_space()); } EXPECT_EQ(employee_count, 6); //---- error.clear(); fdoc.release(); filter = "<data>" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<employee xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<id/>" "<name/>" "</employee>" "</company>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); std::cout << doc->to_string() << std::endl; EXPECT_EQ(res, RW_STATUS_SUCCESS); root = doc->get_root_node(); node = root->find("company", "http://riftio.com/ns/core/util/yangtools/tests/company"); ASSERT_TRUE(node); node = node->find("employee", nullptr); ASSERT_TRUE(node); employee_count = 0; while (node) { employee_count++; auto id = node->find("id", nullptr); EXPECT_TRUE(id); auto name = node->find("name", nullptr); EXPECT_TRUE(name); node = node->get_next_sibling(node->get_local_name(), node->get_name_space()); } EXPECT_EQ(employee_count, 6); //----- error.clear(); fdoc.release(); filter = "<data>" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<employee xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<id>100</id>" "</employee>" "</company>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); std::cout << doc->to_string() << std::endl; EXPECT_EQ(res, RW_STATUS_SUCCESS); expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n \n <employee>\n <id>100</id>\n <name>name100</name>\n <title>Engineer</title>\n <start-date>01/01/2014</start-date>\n </employee>\n \n \n \n \n \n </company>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); //------ error.clear(); fdoc.release(); filter = "<data>" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<employee xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<start-date/>" "</employee>" "</company>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); std::cout << doc->to_string() << std::endl; EXPECT_EQ(res, RW_STATUS_SUCCESS); expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n \n <employee>\n <id>100</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n <employee>\n <id>101</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n <employee>\n <id>102</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n <employee>\n <id>103</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n <employee>\n <id>104</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n <employee>\n <id>105</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n </company>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); //------ error.clear(); fdoc.release(); filter = "<data>" "<company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<employee xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">" "<id>105</id>" "<start-date/>" "</employee>" "</company>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); std::cout << doc->to_string() << std::endl; EXPECT_EQ(res, RW_STATUS_SUCCESS); expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n <company xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/company\">\n \n \n \n \n \n \n <employee>\n <id>105</id>\n \n \n <start-date>01/01/2014</start-date>\n </employee>\n </company>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); //------ error.clear(); fdoc.release(); model = mgr->get_yang_model(); ASSERT_TRUE(model); ydom_top = model->load_module("flat-conversion"); EXPECT_TRUE(ydom_top); file_name = get_rift_root() + std::string("/modules/core/util/yangtools/test/conversion-1.xml"); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); ASSERT_TRUE(doc.get()); filter = "<data>" "<container-1 xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">" "<container_1-1 xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\"/>" "</container-1>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); res = doc->subtree_filter(fdoc.get()); EXPECT_EQ(res, RW_STATUS_SUCCESS); std::cout << doc->to_string() << std::endl; expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">\n <container-1 xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">\n <conv:container_1-1 xmlns:conv=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">\n <conv:leaf-1_1.1>leaf_1_1_1 - ONE</conv:leaf-1_1.1>\n <conv:list-1.1_2>\n <conv:int_1.1.2_1>11201121</conv:int_1.1.2_1>\n </conv:list-1.1_2>\n <conv:list-1.1_2>\n <conv:int_1.1.2_1>11211121</conv:int_1.1.2_1>\n </conv:list-1.1_2>\n </conv:container_1-1>\n \n \n \n \n \n \n \n \n </container-1>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); //------ error.clear(); fdoc.release(); filter = "<data>" "<container-1 xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">" "<conv:leaf.list.1.2 xmlns:conv=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">" "</conv:leaf.list.1.2>" "</container-1>" "</data>"; fdoc = std::move(mgr->create_document_from_string(filter.c_str(), error, false)); doc = std::move(mgr->create_document_from_file(file_name.c_str(), false)); res = doc->subtree_filter(fdoc.get()); EXPECT_EQ(res, RW_STATUS_SUCCESS); std::cout << doc->to_string() << std::endl; root = doc->get_root_node(); ASSERT_TRUE (root); node = root->find("container-1", "http://riftio.com/ns/core/util/yangtools/tests/conversion"); ASSERT_TRUE (node); node = node->find("leaf.list.1.2", "http://riftio.com/ns/core/util/yangtools/tests/conversion"); ASSERT_TRUE (node); size_t ll_count = 1; // found one just above while ((node = node->get_next_sibling("leaf.list.1.2", "http://riftio.com/ns/core/util/yangtools/tests/conversion"))) { ll_count++; } EXPECT_EQ(ll_count, 4); expected_op = "<data xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">\n <container-1 xmlns=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">\n \n <conv:leaf.list.1.2 xmlns:conv=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">Leaf List First</conv:leaf.list.1.2>\n <conv:leaf.list.1.2 xmlns:conv=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">Second Leaf in the List</conv:leaf.list.1.2>\n <conv:leaf.list.1.2 xmlns:conv=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">?Three Leaf in a List?</conv:leaf.list.1.2>\n <conv:leaf.list.1.2 xmlns:conv=\"http://riftio.com/ns/core/util/yangtools/tests/conversion\">The leaf broke the branch</conv:leaf.list.1.2>\n \n \n \n \n </container-1>\n</data>"; EXPECT_STREQ(doc->to_string().c_str(), expected_op.c_str()); mgr.release(); }
TEST(ConfdUtTranslation, DynamicSchema) { TEST_DESCRIPTION("Verify Dynamic Schema loading.."); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* comp = model->load_module("rw-composite-d"); EXPECT_TRUE(comp); comp->mark_imports_explicit(); ConfdUnittestHarness::uptr_t harness = ConfdUnittestHarness::create_harness_autostart("Dynamic", model); ASSERT_TRUE(harness.get()); EXPECT_TRUE(harness->is_running()); ConfdUnittestHarness::context_t* ctx= harness->get_confd_context(); UNUSED (ctx); ConfdUnittestHarness::sockaddr_t sa; harness->make_confd_sockaddr(&sa); EXPECT_TRUE(harness->wait_till_phase2(&sa)); { ASSERT_EQ (CONFD_OK, confd_load_schemas ((struct sockaddr *)&sa, sizeof(sa)) ); namespace_map_t ns_map; struct confd_nsinfo *listp; uint32_t ns_count = confd_get_nslist(&listp); RW_ASSERT (ns_count); // for now for (uint32_t i = 0; i < ns_count; i++) { ns_map[listp[i].uri] = listp[i].hash; } const rw_yang_pb_schema_t *dynamic = nullptr; create_dynamic_composite_d(&dynamic); ASSERT_TRUE(dynamic); YangModelNcx* model1 = YangModelNcx::create_model(); YangModel::ptr_t p(model1); ASSERT_TRUE(model1); bool ret = model1->app_data_get_token (YANGMODEL_ANNOTATION_KEY,YANGMODEL_ANNOTATION_CONFD_NS , &model1->adt_confd_ns_); RW_ASSERT(ret); ret = model1->app_data_get_token (YANGMODEL_ANNOTATION_KEY, YANGMODEL_ANNOTATION_CONFD_NAME, &model1->adt_confd_name_); RW_ASSERT(ret); rw_status_t s = model1->load_schema_ypbc(dynamic); EXPECT_EQ(s, RW_STATUS_SUCCESS); s = model1->register_ypbc_schema(dynamic); EXPECT_EQ(s, RW_STATUS_SUCCESS); s = rw_confd_annotate_ynodes (model1, ns_map, confd_str2hash, YANGMODEL_ANNOTATION_CONFD_NS, YANGMODEL_ANNOTATION_CONFD_NAME ); EXPECT_EQ(s, RW_STATUS_SUCCESS); } harness->stop(); }
TEST(ConfdUtTranslation, KeylessLists) { TEST_DESCRIPTION("Translate a RWXML DOM with keyless lists to confd"); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("base-conversion"); EXPECT_TRUE(ydom_top); ydom_top = 0; ydom_top = model->load_module("flat-conversion"); EXPECT_TRUE(ydom_top); ConfdUnittestHarness::uptr_t harness = ConfdUnittestHarness::create_harness_autostart("keyless-lists", model); ASSERT_TRUE(harness.get()); EXPECT_TRUE(harness->is_running()); ConfdUnittestHarness::context_t* ctx= harness->get_confd_context(); UNUSED (ctx); ConfdUnittestHarness::sockaddr_t sa; harness->make_confd_sockaddr(&sa); EXPECT_TRUE(harness->wait_till_phase2(&sa)); { bool ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY,YANGMODEL_ANNOTATION_CONFD_NS , &model->adt_confd_ns_); RW_ASSERT(ret); ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY, YANGMODEL_ANNOTATION_CONFD_NAME, &model->adt_confd_name_); RW_ASSERT(ret); ASSERT_EQ (CONFD_OK, confd_load_schemas ((struct sockaddr *)&sa, sizeof(sa)) ); namespace_map_t ns_map; struct confd_nsinfo *listp; uint32_t ns_count = confd_get_nslist(&listp); RW_ASSERT (ns_count); // for now for (uint32_t i = 0; i < ns_count; i++) { ns_map[listp[i].uri] = listp[i].hash; } rw_confd_annotate_ynodes (model, ns_map, confd_str2hash, YANGMODEL_ANNOTATION_CONFD_NS, YANGMODEL_ANNOTATION_CONFD_NAME ); // Create a DOM model->register_ypbc_schema( (const rw_yang_pb_schema_t*)RWPB_G_SCHEMA_YPBCSD(FlatConversion)); RWPB_M_MSG_DECL_INIT(FlatConversion_data_Flat, flat); RWPB_T_MSG (FlatConversion_data_Flat_Keyless)* kf = &flat.keyless[0]; flat.n_keyless = 4; sprintf (kf->str, "%s", "First One in the keyless list"); kf->has_str = 1; kf->has_cont = 1; kf->cont.has_bool_ = 1; kf->has_number = 1; kf->number = 1234; kf = &flat.keyless[1]; sprintf (kf->str, "%s", "More no keys"); kf->has_str = 1; kf->has_enum_ = 1; kf->enum_ = FLAT_CONVERSION_ENUM_FOO_BAR; kf = &flat.keyless[2]; kf->has_number = 1; kf->number = 12; kf->has_enum_ = 1; kf->enum_ = FLAT_CONVERSION_ENUM_FOO; kf = &flat.keyless[3]; sprintf (kf->str, "%s", "First One in the keyless list"); kf->has_str = 1; kf->has_cont = 1; kf->cont.has_bool_ = 1; kf->has_number = 1; kf->number = 1234; rw_yang_netconf_op_status_t ncrs; XMLDocument::uptr_t dom(mgr->create_document()); ASSERT_TRUE(dom.get()); XMLNode* root_node = dom->get_root_node(); ASSERT_TRUE (root_node); XMLNode *first_elt = root_node->add_child("flat", 0, "http://riftio.com/ns/core/util/yangtools/tests/conversion"); ASSERT_TRUE (first_elt); ncrs = first_elt->merge ((ProtobufCMessage *)&flat); ASSERT_EQ(ncrs, RW_YANG_NETCONF_OP_STATUS_OK); ASSERT_EQ(4, first_elt->get_children()->length()); confd_hkeypath_t path; memset (&path, 0, sizeof (confd_hkeypath_t)); // Build a confd hkeypath size_t length = 3; path.len = length; length --; CONFD_SET_XMLTAG (&path.v[length][0], flat_conversion_flat, flat_conversion__ns); length --; CONFD_SET_XMLTAG (&path.v[length][0], flat_conversion_keyless, flat_conversion__ns); length--; first_elt = first_elt->get_first_child(); ASSERT_FALSE (length); CONFD_SET_INT64 (&path.v[length][0] , (int64_t) first_elt); path.v[length][1].type = C_NOEXISTS; XMLNode *node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_TRUE (node); ASSERT_EQ (first_elt, node); struct confd_cs_node *cs_node = confd_find_cs_node(&path, 2); ASSERT_TRUE (cs_node); confd_value_t keys[5]; int key_count = 0; XMLNode *next_node; ASSERT_EQ (get_current_key_and_next_node (node, cs_node, &next_node, keys, &key_count), RW_STATUS_SUCCESS); EXPECT_EQ (1, key_count); EXPECT_EQ ((int64_t) first_elt, keys[0].val.i64); // Get object with the key set to the pointer ASSERT_NE (next_node, nullptr); ASSERT_EQ (get_current_key_and_next_node (next_node, cs_node, &next_node, keys, &key_count), RW_STATUS_SUCCESS); EXPECT_EQ (1, key_count); } }
TEST(ConfdUtTranslation, ConfdNewBuilder) { TEST_DESCRIPTION("Translate a RWXML DOM to Confd and back without list filter and new builder"); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("base-conversion"); EXPECT_TRUE(ydom_top); ydom_top = 0; ydom_top = model->load_module("flat-conversion"); EXPECT_TRUE(ydom_top); model->register_ypbc_schema( (const rw_yang_pb_schema_t*)RWPB_G_SCHEMA_YPBCSD(FlatConversion)); std::ifstream fp; ConfdUnittestHarness::uptr_t harness = ConfdUnittestHarness::create_harness_autostart("ConfdDOM", model); ASSERT_TRUE(harness.get()); EXPECT_TRUE(harness->is_running()); ConfdUnittestHarness::context_t* ctx= harness->get_confd_context(); UNUSED (ctx); ConfdUnittestHarness::sockaddr_t sa; harness->make_confd_sockaddr(&sa); EXPECT_TRUE(harness->wait_till_phase2(&sa)); { bool ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY,YANGMODEL_ANNOTATION_CONFD_NS , &model->adt_confd_ns_); RW_ASSERT(ret); ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY, YANGMODEL_ANNOTATION_CONFD_NAME, &model->adt_confd_name_); RW_ASSERT(ret); ASSERT_EQ (CONFD_OK, confd_load_schemas ((struct sockaddr *)&sa, sizeof(sa)) ); namespace_map_t ns_map; struct confd_nsinfo *listp; uint32_t ns_count = confd_get_nslist(&listp); RW_ASSERT (ns_count); // for now for (uint32_t i = 0; i < ns_count; i++) { ns_map[listp[i].uri] = listp[i].hash; } rw_confd_annotate_ynodes (model, ns_map, confd_str2hash, YANGMODEL_ANNOTATION_CONFD_NS, YANGMODEL_ANNOTATION_CONFD_NAME ); // Create a DOM std::string file_name = get_rift_root() + std::string("/modules/core/util/yangtools/test/confd.xml"); XMLDocument::uptr_t dom(mgr->create_document_from_file (file_name.c_str(), false/*validate*/)); ASSERT_TRUE(dom.get()); XMLNode* root_node = dom->get_root_node(); ASSERT_TRUE (root_node); root_node = root_node->get_first_child(); // associated confd structures struct confd_cs_node *cs_node = confd_find_cs_root(flat_conversion__ns); // Translate the DOM to confd ConfdTLVBuilder builder(cs_node,true); XMLTraverser traverser(&builder,root_node); traverser.traverse(); ASSERT_TRUE (builder.length()); size_t length = builder.length(); // Add 3 more - to add a delete keyspec confd_tag_value_t *array = (confd_tag_value_t *) RW_MALLOC (sizeof (confd_tag_value_t) * (length + 3)); builder.copy_and_destroy_tag_array(array); // Array is of the following form for the test // The nodes with C++ comments added to test deletion /* 1 C_XMLBEGIN "container_1-1" */ /* 2 C_BUF "leaf-1_1.1" */ /* 3 C_XMLBEGIN "list-1.1_2" */ /* 4 C_INT32 "int_1.1.2_1" */ /* 5 C_XMLEND "list-1.1_2" */ /* 6 C_XMLBEGIN "list-1.1_2" */ /* 7 C_XMLTAG "grey-goose" */ /* 8 C_INT32 "int_1.1.2_1" */ /* 9 C_XMLEND "list-1.1_2" */ // 10 C_XMLBEGINDEL "list-1.1_2" */ // 11 C_INT32 "int_1.1.2_1" */ // 12 C_XMLEND "list-1.1_2" */ /* 13 C_XMLEND "container_1-1" */ /* 14 C_LIST "leaf.list.1.2" */ /* 15 C_XMLBEGIN "two-keys" */ /* 16 C_ENUM_VALUE "prim-enum" */ /* 17 C_BUF "sec-string" */ /* 18 C_XMLEND "two-keys" */ /* 19 C_XMLBEGIN "two-keys" */ /* 20 C_ENUM_VALUE "prim-enum" */ /* 21 C_BUF "sec-string" */ /* 22 C_XMLEND "two-keys" */ /* 23 C_XMLTAG "empty-1_3" */ /* 24 C_LIST "enum_1-4" */ /* 25 C_ENUM_VALUE "enum_1.5" */ // add 3 lines in the middle memmove (&array[12], &array[9], sizeof (confd_tag_value_t) * 13); memcpy (&array[9], &array[2], sizeof (confd_tag_value_t) * 3); array[9].v.type = C_XMLBEGINDEL; array[10].v.val.i32 = 0xdeadbeef; length += 3; // Translate the confd to DOM rw_yang::XMLDocument::uptr_t converted = std::move(mgr->create_document(model->get_root_node())); XMLNode *root = converted->get_root_node(); YangNode *container_1 = ydom_top->get_first_node(); XMLNode *build_node = root->add_child (container_1); XMLBuilder xml_builder(build_node); ConfdTLVTraverser tlv_traverser(&xml_builder, array, length ); tlv_traverser.traverse(); std::string orig = dom->get_root_node()->get_first_element()->to_string(); std::string copy = xml_builder.current_node_->to_string(); ASSERT_EQ (1, xml_builder.delete_ks_.size()); for (size_t i = 0; i < length; i++) { confd_free_value(CONFD_GET_TAG_VALUE(&array[i])); } RW_FREE (array); } }
TEST(ConfdUtTranslation, FindHkeyPath) { TEST_DESCRIPTION("Translate a RWXML DOM to Confd and back"); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("base-conversion"); EXPECT_TRUE(ydom_top); ydom_top = 0; ydom_top = model->load_module("flat-conversion"); EXPECT_TRUE(ydom_top); std::ifstream fp; ConfdUnittestHarness::uptr_t harness = ConfdUnittestHarness::create_harness_autostart("harness_test4", model); ASSERT_TRUE(harness.get()); EXPECT_TRUE(harness->is_running()); ConfdUnittestHarness::context_t* ctx= harness->get_confd_context(); UNUSED (ctx); ConfdUnittestHarness::sockaddr_t sa; harness->make_confd_sockaddr(&sa); EXPECT_TRUE(harness->wait_till_phase2(&sa)); { bool ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY,YANGMODEL_ANNOTATION_CONFD_NS , &model->adt_confd_ns_); RW_ASSERT(ret); ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY, YANGMODEL_ANNOTATION_CONFD_NAME, &model->adt_confd_name_); RW_ASSERT(ret); ASSERT_EQ (CONFD_OK, confd_load_schemas ((struct sockaddr *)&sa, sizeof(sa)) ); namespace_map_t ns_map; struct confd_nsinfo *listp; uint32_t ns_count = confd_get_nslist(&listp); RW_ASSERT (ns_count); // for now for (uint32_t i = 0; i < ns_count; i++) { ns_map[listp[i].uri] = listp[i].hash; } rw_confd_annotate_ynodes (model, ns_map, confd_str2hash, YANGMODEL_ANNOTATION_CONFD_NS, YANGMODEL_ANNOTATION_CONFD_NAME ); // Create a DOM std::string file_name = get_rift_root() + std::string("/modules/core/util/yangtools/test/confd.xml"); XMLDocument::uptr_t dom(mgr->create_document_from_file (file_name.c_str(), false/*validate*/)); ASSERT_TRUE(dom.get()); XMLNode* root_node = dom->get_root_node(); ASSERT_TRUE (root_node); // Build a confd hkeypath size_t length = 4; confd_hkeypath_t path; memset (&path, 0, sizeof (confd_hkeypath_t)); path.len = length; length --; CONFD_SET_XMLTAG (&path.v[length][0],flat_conversion_container_1, flat_conversion__ns); length --; CONFD_SET_XMLTAG (&path.v[length][0], flat_conversion_container_1_1, flat_conversion__ns); length --; CONFD_SET_XMLTAG (&path.v[length][0],flat_conversion_list_10x2e1_2, flat_conversion__ns); length --; ASSERT_FALSE (length); CONFD_SET_INT32 (&path.v[length][0], 11211121); path.v[length][1].type = C_NOEXISTS; XMLNode *node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_TRUE (node); // Look for vodka - path of 0 memset (&path, 0, sizeof (confd_hkeypath_t)); confd_value_t choice[10], drink; memset (choice, 0, sizeof (confd_value_t) * 10); memset (&drink, 0, sizeof (confd_value_t)); CONFD_SET_XMLTAG (&choice[0], flat_conversion_drink, flat_conversion__ns); choice[1].type = C_NOEXISTS; rw_status_t status = get_confd_case (node, &path, choice, &drink); ASSERT_EQ (RW_STATUS_SUCCESS, status); ASSERT_EQ (CONFD_GET_XMLTAG(&drink), flat_conversion_vodka); memset (&path, 0, sizeof (confd_hkeypath_t)); length = 2; path.len = length; length --; CONFD_SET_XMLTAG (&path.v[length][0], flat_conversion_container_1, flat_conversion__ns); length --; CONFD_SET_XMLTAG (&path.v[length][0],flat_conversion_empty_1_3, flat_conversion__ns); node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_TRUE (node); // Multi key list - success // Build a confd hkeypath length = 3; memset (&path, 0, sizeof (confd_hkeypath_t)); path.len = length; length --; CONFD_SET_XMLTAG (&path.v[length][0], flat_conversion_container_1, flat_conversion__ns); length --; CONFD_SET_XMLTAG (&path.v[length][0], flat_conversion_two_keys, flat_conversion__ns); length --; ASSERT_FALSE (length); const char *entry = "entry"; const char *entree = "entree"; CONFD_SET_ENUM_VALUE (&path.v[length][0], 1); CONFD_SET_CBUF (&path.v[length][1], entry, strlen(entry)); path.v[length][2].type = C_NOEXISTS; node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_TRUE (node); struct confd_cs_node *cs_node = confd_find_cs_node(&path, 2); ASSERT_TRUE (cs_node); // Test getting keys and next entry confd_value_t keys[5]; int key_count = 0; XMLNode *next_node; ASSERT_EQ (get_current_key_and_next_node (node, cs_node, &next_node, keys, &key_count), RW_STATUS_SUCCESS); EXPECT_EQ (2, key_count); ASSERT_NE (next_node, nullptr); ASSERT_EQ (get_current_key_and_next_node (next_node, cs_node, &next_node, keys, &key_count), RW_STATUS_SUCCESS); EXPECT_EQ (2, key_count); EXPECT_EQ (next_node, nullptr); CONFD_SET_CBUF (&path.v[length][1], entree, strlen(entree)); node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_FALSE (node); CONFD_SET_ENUM_VALUE (&path.v[length][0], 7); node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_TRUE (node); // Traverse the largest path rw_yang::XMLDocument::uptr_t req = std::move(mgr->create_document(mgr->get_yang_model()->get_root_node())); XMLNode *root = req->get_root_node(); XMLBuilder build(root); ConfdKeypathTraverser traver(&build, &path); traver.traverse(); CONFD_SET_CBUF (&path.v[length][1], entry, strlen(entry)); node = get_node_by_hkeypath (root_node, &path, 0); ASSERT_FALSE (node); // associated confd structures cs_node = confd_find_cs_root(flat_conversion__ns); // Translate the DOM to confd ConfdTLVBuilder builder(cs_node); XMLTraverser traverser(&builder,root_node->get_first_element()); traverser.traverse(); ASSERT_TRUE (builder.length()); length = builder.length(); confd_tag_value_t *array = (confd_tag_value_t *) RW_MALLOC (sizeof (confd_tag_value_t) * length); ASSERT_NE (nullptr, array); } harness->stop(); }
TEST(ConfdUtTranslation, DomToConfd) { TEST_DESCRIPTION("Translate a RWXML DOM to Confd and back"); XMLManager::uptr_t mgr(xml_manager_create_xerces()); ASSERT_TRUE(mgr.get()); YangModel* model = mgr->get_yang_model(); ASSERT_TRUE(model); YangModule* ydom_top = model->load_module("base-conversion"); EXPECT_TRUE(ydom_top); ydom_top = 0; ydom_top = model->load_module("flat-conversion"); EXPECT_TRUE(ydom_top); YangNode *container_1 = ydom_top->get_first_node(); std::ifstream fp; ConfdUnittestHarness::uptr_t harness = ConfdUnittestHarness::create_harness_autostart("ConfdDOM", model); ASSERT_TRUE(harness.get()); EXPECT_TRUE(harness->is_running()); ConfdUnittestHarness::context_t* ctx= harness->get_confd_context(); UNUSED (ctx); ConfdUnittestHarness::sockaddr_t sa; harness->make_confd_sockaddr(&sa); EXPECT_TRUE(harness->wait_till_phase2(&sa)); { bool ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY,YANGMODEL_ANNOTATION_CONFD_NS , &model->adt_confd_ns_); RW_ASSERT(ret); ret = model->app_data_get_token (YANGMODEL_ANNOTATION_KEY, YANGMODEL_ANNOTATION_CONFD_NAME, &model->adt_confd_name_); RW_ASSERT(ret); ASSERT_EQ (CONFD_OK, confd_load_schemas ((struct sockaddr *)&sa, sizeof(sa)) ); namespace_map_t ns_map; struct confd_nsinfo *listp; uint32_t ns_count = confd_get_nslist(&listp); RW_ASSERT (ns_count); // for now for (uint32_t i = 0; i < ns_count; i++) { ns_map[listp[i].uri] = listp[i].hash; } rw_confd_annotate_ynodes (model, ns_map, confd_str2hash, YANGMODEL_ANNOTATION_CONFD_NS, YANGMODEL_ANNOTATION_CONFD_NAME ); // Create a DOM std::string file_name = get_rift_root() + std::string("/modules/core/util/yangtools/test/confd.xml"); XMLDocument::uptr_t dom(mgr->create_document_from_file (file_name.c_str(), false/*validate*/)); ASSERT_TRUE(dom.get()); XMLNode* root_node = dom->get_root_node(); ASSERT_TRUE (root_node); root_node = root_node->get_first_child(); // The DOMs should be similar - EXCEPT that the new one will not have // the list children.. And only YANG nodes assocaited nodes will be present rw_yang::XMLDocument::uptr_t filtered = std::move(mgr->create_document(model->get_root_node())); XMLNode* filter_root = filtered->get_root_node(); XMLNoListCopier copier (filter_root); XMLWalkerInOrder walker (root_node); walker.walk(&copier); // associated confd structures struct confd_cs_node *cs_node = confd_find_cs_root(flat_conversion__ns); // Translate the DOM to confd ConfdTLVBuilder builder(cs_node); XMLTraverser traverser(&builder,root_node); traverser.traverse(); ASSERT_TRUE (builder.length()); size_t length = builder.length(); confd_tag_value_t *array = (confd_tag_value_t *) RW_MALLOC (sizeof (confd_tag_value_t) * length); builder.copy_and_destroy_tag_array(array); // Translate the confd to DOM rw_yang::XMLDocument::uptr_t converted = std::move(mgr->create_document(model->get_root_node())); XMLNode *root = converted->get_root_node(); XMLNode *build_node = root->add_child (container_1); XMLBuilder xml_builder(build_node); ConfdTLVTraverser tlv_traverser(&xml_builder, array, length ); tlv_traverser.traverse(); for (size_t i = 0; i < length; i++) { confd_free_value(CONFD_GET_TAG_VALUE(&array[i])); } RW_FREE (array); std::string orig = filter_root->to_string(); std::string copied = root->to_string(); ASSERT_STREQ (orig.c_str(), copied.c_str()); } harness->stop(); }