#include #include #include #include #include #include "../ag_gen/asset.h" #include "../ag_gen/assetgroup.h" #include "../ag_gen/edge.h" #include "../ag_gen/exploit.h" #include "../ag_gen/factbase.h" #include "../ag_gen/network_state.h" #include "../ag_gen/ag_gen.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mpi = boost::mpi; void save_quality(const Quality &q, const char * filename){ std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << q; } void restore_quality(Quality &q, const char * filename){ std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> q; } int quality_check(Quality &q1, Quality &q2){ if (q1.get_asset_id() == q2.get_asset_id() && q1.get_name() == q2.get_name() && q1.get_op() == q2.get_op() && q1.get_value() == q2.get_value()) { return 1; } else return 0; } int param_quality_check(ParameterizedQuality &pq1, ParameterizedQuality &pq2){ if (pq1.param == pq2.param && pq1.name == pq2.name && pq1.value == pq1.value && pq1.op == pq2.op) { return 1; } else return 0; } int param_topology_check(ParameterizedTopology &pt1, ParameterizedTopology &pt2){ if (pt1.get_from_param() == pt2.get_from_param() && pt1.get_to_param() == pt2.get_to_param() && pt1.get_dir() == pt2.get_dir() && pt1.get_property() == pt2.get_property() && pt1.get_operation() == pt2.get_operation() && pt1.get_value() == pt2.get_value()) { return 1; } else return 0; } int postcond_quality_check(PostconditionQ &pq1, PostconditionQ &pq2){ auto preq1 = std::get<1>(pq1); auto preq2 = std::get<1>(pq2); if(param_quality_check(preq1, preq2) == 1 && std::get<0>(pq1) == std::get<0>(pq2)) { return 1; } else return 0; } int postcond_topology_check(PostconditionT &pt1, PostconditionT &pt2){ auto pret1 = std::get<1>(pt1); auto pret2 = std::get<1>(pt2); if(param_topology_check(pret1, pret2) == 1 && std::get<0>(pt1) == std::get<0>(pt2)) { return 1; } else return 0; } int exploit_check(Exploit &exp1, Exploit &exp2){ int base_corr = 0; //Precondition counters int pre_qual_corr = 0; int pre_qual_count = 0; int pre_topo_corr = 0; int pre_topo_count = 0; //Postcondition counters int post_qual_corr = 0; int post_qual_count = 0; int post_topo_corr = 0; int post_topo_count = 0; //Base member check correctness if (exp1.get_id() == exp2.get_id() && exp1.get_name() == exp2.get_name() && exp1.get_group() == exp2.get_group() && exp1.get_num_params() == exp2.get_num_params()) { base_corr = 1; } //Init lists for pre and post conditions for quals and topos auto exp1_pre_quals = exp1.precond_list_q(); auto exp2_pre_quals = exp2.precond_list_q(); auto exp1_pre_topos = exp1.precond_list_t(); auto exp2_pre_topos = exp2.precond_list_t(); auto exp1_post_quals = exp1.postcond_list_q(); auto exp2_post_quals = exp2.postcond_list_q(); auto exp1_post_topos = exp1.postcond_list_t(); auto exp2_post_topos = exp2.postcond_list_t(); //Init iterators for preconds auto itq1 = exp1_pre_quals.begin(); auto itq2 = exp2_pre_quals.begin(); auto itt1 = exp1_pre_topos.begin(); auto itt2 = exp2_pre_topos.begin(); //Check Precondition Qualities while(itq1 != exp1_pre_quals.end() || itq2 != exp2_pre_quals.end()) { pre_qual_corr += param_quality_check(*itq1, *itq2); pre_qual_count++; if(itq1 != exp1_pre_quals.end()) ++itq1; if(itq2 != exp2_pre_quals.end()) ++itq2; } //Check Precondition Topologies while(itt1 != exp1_pre_topos.end() || itt2 != exp2_pre_topos.end()) { pre_topo_corr += param_topology_check(*itt1, *itt2); pre_topo_count++; if(itt1 != exp1_pre_topos.end()) ++itt1; if(itt2 != exp2_pre_topos.end()) ++itt2; } //Init iterators for postconds auto itpq1 = exp1_post_quals.begin(); auto itpq2 = exp2_post_quals.begin(); auto itpt1 = exp1_post_topos.begin(); auto itpt2 = exp2_post_topos.begin(); //Check Postcondition Qualities while(itpq1 != exp1_post_quals.end() || itpq2 != exp2_post_quals.end()) { post_qual_corr += postcond_quality_check(*itpq1, *itpq2); post_qual_count++; if(itpq1 != exp1_post_quals.end()) ++itpq1; if(itpq2 != exp2_post_quals.end()) ++itpq2; } //Check Postcondition Topologies while(itpt1 != exp1_post_topos.end() || itpt2 != exp2_post_topos.end()) { post_topo_corr += postcond_topology_check(*itpt1, *itpt2); post_topo_count++; if(itpt1 != exp1_post_topos.end()) ++itpt1; if(itpt2 != exp2_post_topos.end()) ++itpt2; } if( base_corr == 1 && pre_qual_count == pre_qual_corr && pre_topo_count == pre_topo_corr && post_qual_count == post_qual_corr && post_topo_count == post_topo_corr) { return 1; } else return 0; } void save_topology(const Topology &t, const char * filename){ std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << t; } void restore_topology(Topology &t, const char * filename){ std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> t; } int topology_check(Topology &t1, Topology &t2){ if (t1.get_from_asset_id() == t2.get_from_asset_id() && t1.get_to_asset_id() == t2.get_to_asset_id() && t1.get_dir() == t2.get_dir() && t1.get_property() == t2.get_property() && t1.get_op() == t2.get_op() && t1.get_value() == t2.get_value()) { return 1; } else return 0; } int ag_check(AssetGroup &ag1, AssetGroup &ag2){ int qual_count = 0; int qual_corr = 0; int topo_count = 0; int topo_corr = 0; auto ag1_quals = ag1.get_hypo_quals(); auto ag2_quals = ag2.get_hypo_quals(); auto ag1_topos = ag1.get_hypo_topos(); auto ag2_topos = ag2.get_hypo_topos(); auto itq1 = ag1_quals.begin(); auto itq2 = ag2_quals.begin(); auto itt1 = ag1_topos.begin(); auto itt2 = ag2_topos.begin(); while(itq1 != ag1_quals.end() || itq2 != ag2_quals.end()) { qual_corr += quality_check(*itq1, *itq2); qual_count++; if(itq1 != ag1_quals.end()) ++itq1; if(itq2 != ag2_quals.end()) ++itq2; } while(itt1 != ag1_topos.end() || itt2 != ag2_topos.end()) { topo_corr += topology_check(*itt1, *itt2); topo_count++; if(itt1 != ag1_topos.end()) ++itt1; if(itt2 != ag2_topos.end()) ++itt2; } if(ag1.get_perm() == ag2.get_perm() && qual_count == qual_corr && topo_count == topo_corr) { return 1; } else return 0; } void save_factbase(const Factbase &fb, const char * filename){ std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << fb; } void restore_factbase(Factbase &fb, const char * filename){ std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> fb; } int factbase_check(Factbase &fb1, Factbase &fb2){ int qual_count = 0; int qual_corr = 0; int topo_count = 0; int topo_corr = 0; auto fb1_tuple = fb1.get_facts_tuple(); auto fb1_quals = std::get<0>(fb1_tuple); auto fb1_topos = std::get<1>(fb1_tuple); auto fb2_tuple = fb2.get_facts_tuple(); auto fb2_quals = std::get<0>(fb2_tuple); auto fb2_topos = std::get<1>(fb2_tuple); auto itq1 = fb1_quals.begin(); auto itq2 = fb2_quals.begin(); auto itt1 = fb1_topos.begin(); auto itt2 = fb2_topos.begin(); while(itq1 != fb1_quals.end() || itq2 != fb2_quals.end()) { qual_corr += quality_check(*itq1, *itq2); qual_count++; if(itq1 != fb1_quals.end()) ++itq1; if(itq2 != fb2_quals.end()) ++itq2; } while(itt1 != fb1_topos.end() || itt2 != fb2_topos.end()) { topo_corr += topology_check(*itt1, *itt2); topo_count++; if(itt1 != fb1_topos.end()) ++itt1; if(itt2 != fb2_topos.end()) ++itt2; } if(fb1.get_id() == fb2.get_id() && qual_count == qual_corr && topo_count == topo_corr) { return 1; } else return 0; } void save_network_state(const NetworkState &ns, const char * filename){ std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << ns; } void restore_network_state(NetworkState &ns, const char * filename){ std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> ns; } int network_state_check(NetworkState &ns1, NetworkState &ns2){ auto fb1 = ns1.get_factbase(); auto fb2 = ns2.get_factbase(); return factbase_check(fb1, fb2); } void serialization_unit_testing(AGGenInstance &instance, boost::mpi::communicator &world){ char hammer_host[256]; gethostname(hammer_host, 256); std::string str_host(hammer_host); if(world.rank() == 0){ printf("\n"); std::cout << "---------STARTING SERIALIZATION UNIT TESTING---------" << std::endl; } world.barrier(); std::string rollcall = "Hello from process " + std::to_string(world.rank())\ + " of " + std::to_string(world.size()) + " running on "\ + str_host + "."; if(world.rank() != 0) world.send(0, 0, rollcall); else{ std::cout << rollcall << std::endl; for(int i = 0; i < world.size()-1; i++){ world.recv(mpi::any_source, 0, rollcall); std::cout << rollcall << std::endl; } std::cout << "" << std::endl; } world.barrier(); std::string filename(boost::archive::tmpdir()); filename += "/qualfile.txt"; auto init_quals = instance.initial_qualities; auto init_topos = instance.initial_topologies; NetworkState init_state(init_quals, init_topos);//instantiate an obj init_state with initial input int e_flag = 0; int qual_count = 0; int qual_corr = 0; int top_count = 0; int top_corr = 0; int fb_count = 0; int fb_corr = 0; int ns_count = 0; int ns_corr = 0; int ag_count = 0; int ag_corr = 0; int exp_corr = 0; int exp_count = 0; std::vector asset_groups; std::vector asset_group_quals; std::vector asset_group_topos; if(world.rank() == 0){ std::cout << "Performing Unit Testing on Exploit Serialization." << std::endl; } for (auto exp : instance.exploits) { Exploit new_exp; if(world.rank() == 0) new_exp = exp; mpi::request req; broadcast(world, new_exp, 0); exp_count++; exp_corr += exploit_check(exp, new_exp); } int total_exp_corr; reduce(world, exp_corr, total_exp_corr, std::plus(), 0); if (world.rank() == 0){ std::cout << "Exploit Unit Testing: " << std::to_string(total_exp_corr) << "/" << std::to_string(world.size() * exp_count) << std::endl; printf("\n"); std::cout << "Performing Unit Testing on Quality Serialization." << std::endl; } for (auto qual : instance.initial_qualities) { Quality new_qual; if(world.rank() == 0) new_qual = qual; mpi::request req; broadcast(world, new_qual, 0); qual_count++; qual_corr += quality_check(qual, new_qual); asset_group_quals.emplace_back(qual); } int total_qual_corr; reduce(world, qual_corr, total_qual_corr, std::plus(), 0); if (world.rank() == 0){ std::cout << "Quality Unit Testing: " << std::to_string(total_qual_corr) << "/" << std::to_string(world.size() * qual_count) << std::endl; printf("\n"); std::cout << "Performing Unit Testing on Topology Serialization." << std::endl; } for (auto topo : instance.initial_topologies) { Topology new_top; if(world.rank() == 0) new_top = topo; mpi::request req; broadcast(world, new_top, 0); top_count++; top_corr += topology_check(topo, new_top); asset_group_topos.emplace_back(topo); } std::vector perm; perm.emplace_back(2); int total_top_corr; reduce(world, top_corr, total_top_corr, std::plus(), 0); if (world.rank() == 0){ std::cout << "Topology Unit Testing: " << std::to_string(total_top_corr) << "/" << std::to_string(world.size() * top_count) << std::endl; printf("\n"); std::cout << "Performing Unit Testing on AssetGroup Serialization." << std::endl; } int total_ag_corr; std::vector vec; vec.resize(2); std::fill(vec.begin(),vec.end(),0); AssetGroup default_ag = AssetGroup(asset_group_quals, asset_group_topos, vec); for (int i = 0; i < 3; i++) { AssetGroup new_ag; if(world.rank() == 0){ new_ag = AssetGroup(asset_group_quals, asset_group_topos, vec); } mpi::request req; broadcast(world, new_ag, 0); ag_count++; ag_corr += ag_check(new_ag, default_ag); } reduce(world, ag_corr, total_ag_corr, std::plus(), 0); if (world.rank() == 0){ std::cout << "AssetGroup Unit Testing: " << std::to_string(total_ag_corr) << "/" << std::to_string(world.size() * ag_count) << std::endl; printf("\n"); std::cout << "Performing Unit Testing on Factbase Serialization." << std::endl; } for (auto fb : instance.factbases) { Factbase new_fb; int id; if(world.rank() == 0){ new_fb = fb; id = fb.get_id(); } mpi::request req; broadcast(world, new_fb, 0); broadcast(world, id, 0); new_fb.force_set_id(id); fb_count++; fb_corr += factbase_check(fb, new_fb); } int total_fb_corr; reduce(world, fb_corr, total_fb_corr, std::plus(), 0); if (world.rank() == 0){ std::cout << "Factbase Unit Testing: " << std::to_string(total_fb_corr) << "/" << std::to_string(world.size() * fb_count) << std::endl; printf("\n"); std::cout << "Performing Unit Testing on Network State Serialization." << std::endl; } NetworkState new_ns; int id; if(world.rank() == 0){ new_ns = init_state; id = init_state.get_id(); } mpi::request req; broadcast(world, new_ns, 0); broadcast(world, id, 0); new_ns.force_set_id(id); ns_count++; ns_corr += network_state_check(init_state, new_ns); int total_ns_corr; reduce(world, ns_corr, total_ns_corr, std::plus(), 0); if (world.rank() == 0){ std::cout << "Network State Unit Testing: " << std::to_string(total_ns_corr) << "/" << std::to_string(world.size() * ns_count) << std::endl; printf("\n"); } if(world.rank() == 0){ if(total_exp_corr == world.size() * exp_count) { std::cout << "100% Success Rate for Exploit Serialization." << std::endl; } else{ std::cout << "Errors occurred in the Exploit Serialization." << std::endl; e_flag = 1; } if(total_qual_corr == world.size() * qual_count) { std::cout << "100% Success Rate for Quality Serialization." << std::endl; } else{ std::cout << "Errors occurred in the Quality Serialization." << std::endl; e_flag = 1; } if(total_top_corr == world.size() * top_count) { std::cout << "100% Success Rate for Topology Serialization." << std::endl; } else{ std::cout << "Errors occurred in the Topology Serialization." << std::endl; e_flag = 1; } if(total_ag_corr == world.size() * ag_count) { std::cout << "100% Success Rate for AssetGroup Serialization." << std::endl; } else{ std::cout << "Errors occurred in the AssetGroup Serialization." << std::endl; e_flag = 1; } if(total_fb_corr == world.size() * fb_count) { std::cout << "100% Success Rate for Factbase Serialization." << std::endl; } else{ std::cout << "Errors occurred in the Factbase Serialization." << std::endl; e_flag = 1; } if(total_ns_corr == world.size() * ns_count) { std::cout << "100% Success Rate for Network State Serialization." << std::endl; } else{ std::cout << "Errors occurred in the Network State Serialization." << std::endl; e_flag = 1; } std::cout << "" << std::endl; if(e_flag == 1) std::cout << "-------------ERRORS OCCURRED DURING SERIALIZATION UNIT TESTING---------------" << std::endl; std::cout << "---------FINISHED SERIALIZATION UNIT TESTING---------" << std::endl; printf("\n"); } //MPI Clean-up //MPI_Finalize(); return; }