/* ELAPI Collection unit test. Copyright (C) Dmitri Pal 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "elapi_collection.h" #include "elapi_util.h" #include "elapi_debug.h" #include "elapi_tools.h" /* Print the collection using default serialization */ int collection_to_XML(struct collection_item *handle) { struct xml_data xml; int error = EOK; printf("COLLECTION TO XML:\n"); xml.writer = (xmlTextWriterPtr)(NULL); xml.buf = (xmlBufferPtr)(NULL); xml.given_name = NULL; xml.level = 0; /* Traverse collection */ error = traverse_collection(handle,ELAPI_TRAVERSE_DEFAULT | ELAPI_TRAVERSE_END ,xml_add,(void *)(&xml)); if(error) printf("Error converting collection to XML %d\n",error); else { xmlFreeTextWriter(xml.writer); printf("%s\n", (const char *) ((xml.buf)->content)); xmlBufferFree(xml.buf); } return error; } int ref_collection_test() { struct collection_item *peer; struct collection_item *socket; char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; int found = 0; int error = EOK; DEBUG_STRING("ref_collection_test","Entry."); printf("\n\nREF TEST!!!.\n\n\n"); printf("Creating PEER collection.\n"); if((error=create_collection(&peer,"peer")) || (error=add_str_property(peer,NULL,"hostname","peerhost.mytest.com",0)) || (error=add_str_property(peer,NULL,"IPv4","10.10.10.10",12)) || /* Expect trailing zero to be truncated */ (error=add_str_property(peer,NULL,"IPv6","bla:bla:bla:bla:bla:bla",0))) { printf("Failed to add property. Error %d",error); destroy_collection(peer); return error; } printf("Creating SOCKET collection.\n"); if((error=create_collection(&socket,"socket")) || (error=add_int_property(socket,NULL,"id",1)) || (error=add_long_property(socket,NULL,"packets",100000000L)) || (error=add_binary_property(socket,NULL,"stack",binary_dump,sizeof(binary_dump)))) { destroy_collection(peer); destroy_collection(socket); printf("Failed to add property. Error %d\n",error); return error; } debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); printf("Adding PEER collection to SOCKET collection as a reference named PEER\n"); /* Embed peer host into the socket2 as reference */ error = add_collection_to_collection(socket,NULL,"peer",peer,ELAPI_ADD_MODE_REFERENCE); if(error) { destroy_collection(peer); destroy_collection(socket); printf("Failed to add collection to collection. Error %d\n",error); return error; } debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); printf("About to destroy PEER\n"); destroy_collection(peer); debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); printf("About to extract PEER\n"); error = get_collection_reference(socket,&peer,"peer"); if(error) { destroy_collection(socket); printf("Failed to extract collection. Error %d\n",error); return error; } debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); destroy_collection(peer); debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); destroy_collection(socket); DEBUG_NUMBER("ref_collection_test. Returning",error); printf("\n\nEND OF REF TEST!!!.\n\n\n"); return error; } int single_collection_test() { struct collection_item *handle; int error = EOK; DEBUG_STRING("single_collection_test","Entry."); if((error=create_collection(&handle,"string_test")) || (error=add_str_property(handle,NULL,"property_1","some data",0)) || (error=add_str_property(handle,NULL,"property_2","some other data",2)) || (error=add_str_property(handle,NULL,"property_3","more data",7))) { printf("Failed to add property. Error %d",error); destroy_collection(handle); return error; } error = add_str_property(handle,NULL,"property 1","some data",0); if(error) printf("Expected error adding bad property to collection %d\n",error); else printf("Expected error but got success\n"); error = EOK; error=add_double_property(handle,NULL,"double",0.253545); if(error) { printf("Failed to add property. Error %d",error); destroy_collection(handle); return error; } error=update_double_property(handle,"double",ELAPI_TRAVERSE_DEFAULT,1.999999); if(error) { printf("Failed to add property. Error %d",error); destroy_collection(handle); return error; } printf("Created collection\n"); /* Traverse collection */ error = debug_collection(handle,ELAPI_TRAVERSE_DEFAULT); if(error) printf("Error debugging collection %d\n",error); error = print_collection(handle); if(error) printf("Error printing collection %d\n",error); destroy_collection(handle); DEBUG_NUMBER("single_collection_test. Error: ",error); return error; } int add_collection_test() { struct collection_item *peer; struct collection_item *socket; char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; int found = 0; int error = EOK; DEBUG_STRING("add_collection_test","Entry."); printf("\n\nADD TEST!!!.\n\n\n"); printf("Creating PEER collection.\n"); if((error=create_collection(&peer,"peer")) || (error=add_str_property(peer,NULL,"hostname","peerhost.mytest.com",0)) || (error=add_str_property(peer,NULL,"IPv4","10.10.10.10",12)) || /* Expect trailing zero to be truncated */ (error=add_str_property(peer,NULL,"IPv6","bla:bla:bla:bla:bla:bla",0))) { printf("Failed to add property. Error %d",error); destroy_collection(peer); return error; } printf("Creating SOCKET collection.\n"); if((error=create_collection(&socket,"socket")) || (error=add_int_property(socket,NULL,"id",1)) || (error=add_long_property(socket,NULL,"packets",100000000L)) || (error=add_binary_property(socket,NULL,"stack",binary_dump,sizeof(binary_dump)))) { destroy_collection(peer); destroy_collection(socket); printf("Failed to add property. Error %d\n",error); return error; } debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); printf("Adding PEER collection to SOCKET collection as a reference named PEER\n"); /* Embed peer host into the socket2 as reference */ error = add_collection_to_collection(socket,NULL,"peer",peer,ELAPI_ADD_MODE_REFERENCE); if(error) { destroy_collection(peer); destroy_collection(socket); printf("Failed to create collection. Error %d\n",error); return error; } debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); destroy_collection(peer); debug_collection(socket,ELAPI_TRAVERSE_DEFAULT); destroy_collection(socket); DEBUG_NUMBER("add_collection_test. Returning",error); return error; } int mixed_collection_test() { struct collection_item *peer; struct collection_item *socket1; struct collection_item *socket2; struct collection_item *packet; struct collection_item *event; struct collection_item *host; char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; int found = 0; int error = EOK; DEBUG_STRING("mixed_collection_test","Entry."); printf("\n\nMIXED TEST!!!.\n\n\n"); printf("Creating PEER collection.\n"); if((error=create_collection(&peer,"peer")) || (error=add_str_property(peer,NULL,"hostname","peerhost.mytest.com",0)) || (error=add_str_property(peer,NULL,"IPv4","10.10.10.10",12)) || /* Expect trailing zero to be truncated */ (error=add_str_property(peer,NULL,"IPv6","bla:bla:bla:bla:bla:bla",0))) { printf("Failed to add property. Error %d",error); destroy_collection(peer); return error; } debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); printf("Creating HOST collection.\n"); if((error=create_collection(&host,"host")) || (error=add_str_property(host,NULL,"hostname","myhost.mytest.com",0)) || (error=add_str_property(host,NULL,"IPv4","20.20.20.20",13)) || (error=add_str_property(host,NULL,"IPv6","bla:bla:bla:bla:bla:bla",0)) || (error=add_double_property(host,NULL,"double",0.253545))) { printf("Failed to add property. Error %d",error); destroy_collection(peer); destroy_collection(host); return error; } debug_collection(host,ELAPI_TRAVERSE_DEFAULT); printf("Creating SOCKET1 collection.\n"); if((error=create_collection(&socket1,"socket1")) || (error=add_int_property(socket1,NULL,"id",1)) || (error=add_long_property(socket1,NULL,"packets",100000000L)) || (error=add_binary_property(socket1,NULL,"stack",binary_dump,sizeof(binary_dump)))) { destroy_collection(peer); destroy_collection(host); destroy_collection(socket1); printf("Failed to add property. Error %d\n",error); return error; } debug_collection(socket1,ELAPI_TRAVERSE_DEFAULT); printf("Creating a copy of SOCKET1 collection named SOCKET2.\n"); error = copy_collection(&socket2,socket1,"socket2"); if(error) { destroy_collection(peer); destroy_collection(host); destroy_collection(socket1); printf("Failed to copy collection. Error %d\n",error); return error; } debug_collection(socket2,ELAPI_TRAVERSE_DEFAULT); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); printf("Adding PEER collection to SOCKET2 collection as a reference named PEER2\n"); /* Embed peer host into the socket2 as reference */ error = add_collection_to_collection(socket2,NULL,"peer2",peer,ELAPI_ADD_MODE_REFERENCE); if(error) { destroy_collection(peer); destroy_collection(host); destroy_collection(socket1); destroy_collection(socket2); printf("Failed to create collection. Error %d\n",error); return error; } debug_collection(socket2,ELAPI_TRAVERSE_DEFAULT); printf("Creating an EVENT collection.\n"); /* Construct event */ error = create_collection(&event,"event"); if(error) { destroy_collection(peer); destroy_collection(host); destroy_collection(socket1); destroy_collection(socket2); printf("Failed to create collection. Error %d\n",error); return error; } debug_collection(event,ELAPI_TRAVERSE_DEFAULT); printf("Adding HOST to EVENT.\n"); /* Add host to event */ error = add_collection_to_collection(event,NULL,NULL,host,ELAPI_ADD_MODE_REFERENCE); if(error) { destroy_collection(peer); destroy_collection(host); destroy_collection(socket1); destroy_collection(socket2); printf("Failed to add collections. Error %d\n",error); return error; } debug_collection(event,ELAPI_TRAVERSE_DEFAULT); printf("Embed SOCKET1 into EVENT.\n"); /* Donate socket1 to event */ /* Socket1 should not be used after this */ error = add_collection_to_collection(event,NULL,NULL,socket1,ELAPI_ADD_MODE_EMBED); if(error) { destroy_collection(peer); destroy_collection(host); destroy_collection(socket1); destroy_collection(socket2); printf("Failed to add collections. Error %d\n",error); return error; } printf("Traverse one level:\n"); debug_collection(event,ELAPI_TRAVERSE_ONELEVEL); printf("Traverse ignore subcollections:\n"); debug_collection(event,ELAPI_TRAVERSE_IGNORE); printf("Traverse normal:\n"); debug_collection(event,ELAPI_TRAVERSE_DEFAULT); debug_collection(socket1,ELAPI_TRAVERSE_DEFAULT); printf("SOCKET1 MUST NO BE USED AFTER THIS POINT!!!\n"); socket1 = (struct collection_item *)(NULL); printf("Add collection PEER as PEER1 to subcollection SOCKET1 of the EVENT.\n"); debug_collection(peer,ELAPI_TRAVERSE_DEFAULT); error = add_collection_to_collection(event,"socket1","peer1",peer,ELAPI_ADD_MODE_CLONE); if(error) { destroy_collection(peer); destroy_collection(host); /* No socket1 any more :) */ destroy_collection(socket2); printf("Failed to add collections. Error %d\n",error); return error; } debug_collection(event,ELAPI_TRAVERSE_DEFAULT); printf("Add property named TIMEOUT to PEER collection.\n"); /* Add new property to the peer collection */ error = add_int_property(peer,NULL,"timeout",5); if(error) { destroy_collection(peer); destroy_collection(host); /* No socket1 any more :) */ destroy_collection(socket2); printf("Failed to add property. Error %d\n",error); return error; } debug_collection(socket2,ELAPI_TRAVERSE_DEFAULT); printf("Add property named DELAY to PEER1 collection.\n"); error = add_int_property(event,"peer1","delay",10); if(error) { destroy_collection(peer); destroy_collection(host); /* No socket1 any more :) */ destroy_collection(socket2); printf("Failed to add property. Error %d\n",error); return error; } debug_collection(event,ELAPI_TRAVERSE_DEFAULT); debug_collection(host,ELAPI_TRAVERSE_DEFAULT); printf("Check if property PEER1.DELAY is in the EVENT collection.\n"); /* Check if the property in the collection */ found = 0; error = is_item_in_collection(event, "peer1.delay", ELAPI_TYPE_ANY, ELAPI_TRAVERSE_DEFAULT, &found); if(error) { destroy_collection(peer); destroy_collection(host); /* No socket1 any more :) */ destroy_collection(socket2); printf("Failed to check property. Error %d\n",error); return error; } if (found == 1) printf("Property is found!\n"); else printf("Error property is not found!\n"); print_item(event, "peer1.IPv6"); print_item(event, "event.socket1.peer1.IPv6"); print_item(event, "event.peer1.IPv6"); print_item(event, "speer1.IPv6"); print_item(event, "eer1.IPv6"); print_item(event, ".peer1.IPv6"); print_item(event, "t.peer1.IPv6"); collection_to_XML(event); printf("Delete property PEER1.DELAY from the EVENT collection.\n"); error = delete_property(event,"peer1.delay",ELAPI_TYPE_ANY, ELAPI_TRAVERSE_DEFAULT); if(error) { destroy_collection(peer); destroy_collection(host); /* No socket1 any more :) */ destroy_collection(socket2); printf("Failed to delete property. Error %d\n",error); return error; } printf("Printing EVENT.\n"); /* Traverse collection */ error = print_collection(event); if(error) printf("Error printing collection %d\n",error); printf("Debugging EVENT.\n"); error = debug_collection(event,ELAPI_TRAVERSE_DEFAULT); if(error) printf("Error printing collection %d\n",error); printf("Cleanup of the collections PEER, HOST and SOCKET2.\n"); /* Destroy a referenced collection */ destroy_collection(peer); destroy_collection(host); destroy_collection(socket2); printf("Printing EVENT again.\n"); /* Traverse collection again - peer should still be there */ error = print_collection(event); if(error) printf("Error printing collection %d\n",error); printf("Debugging EVENT again.\n"); error = debug_collection(event,ELAPI_TRAVERSE_DEFAULT); if(error) printf("Error printing collection %d\n",error); printf("Attempt to add property to a referenced collection.\n"); /* Some negative tests */ /* Can't add attributes to the referenced collection */ error = add_int_property(event,"host","session",500); if(error != 0) printf("Error was NOT able to add property to a referenced collection.\n"); printf("Attempt to delete non-existent property.\n"); /* Can't delete non exitent property */ error = delete_property(event,"host.host",ELAPI_TYPE_ANY, ELAPI_TRAVERSE_DEFAULT); if(error == 0) printf("Error was able to delete property that does not exist.\n"); printf("Expected error %d\n",error); printf("Done.Cleaning...\n"); destroy_collection(event); printf("Exit.\n"); return EOK; } /* Main function of the unit test */ int main() { int error = 0; printf("Start\n"); if((error=ref_collection_test()) || (error=single_collection_test()) || (error=add_collection_test()) || (error=mixed_collection_test())) { printf("Failed!\n"); } else printf("Success!\n"); /* Add other tests here ... */ return error; }