1 // -*- Mode: C++ -*- 2 // 3 4 /// @file 5 /// 6 /// This file declares the common functionality for tests in 7 /// CTF and DWARF readers, it declares abstractions for `act` test 8 /// stage. 9 10 #ifndef __TEST_READ_COMMON_H__ 11 #define __TEST_READ_COMMON_H__ 12 13 #include <string> 14 #include "abg-ir.h" 15 #include "abg-corpus.h" 16 #include "abg-workers.h" 17 #include "abg-writer.h" 18 #include "test-utils.h" 19 #include "abg-tools-utils.h" 20 21 using std::string; 22 23 using abigail::xml_writer::type_id_style_kind; 24 using abigail::ir::corpus_sptr; 25 26 namespace abigail 27 { 28 namespace tests 29 { 30 namespace read_common 31 { 32 33 /// This is an aggregate that specifies where a test shall get its 34 /// input from, and where it shall write its output to. 35 struct InOutSpec 36 { 37 const char* in_elf_path; 38 const char* in_suppr_spec_path; 39 const char* in_public_headers_path; 40 type_id_style_kind type_id_style; 41 const char* in_abi_path; 42 const char* out_abi_path; 43 const char* options; 44 };// end struct InOutSpec 45 46 /// The task that performs the tests. 47 struct test_task : public abigail::workers::task 48 { 49 bool is_ok; 50 InOutSpec spec; 51 string error_message; 52 string out_abi_base; 53 string in_elf_base; 54 string in_abi_base; 55 56 string in_elf_path; 57 string in_abi_path; 58 string in_suppr_spec_path; 59 string in_public_headers_path; 60 string out_abi_path; 61 62 63 /// A setter for `in_elf_path` field. 64 /// The `in_elf_path` is the full path for input object 65 /// in the tests container @ref 66 /// abigail::tests::read_common::InOutSpec. 67 void set_in_elf_pathtest_task68 set_in_elf_path() 69 { 70 in_elf_path = in_elf_base + spec.in_elf_path; 71 } 72 73 /// A setter for `in_suppr_spec_path` field. 74 /// The `in_suppr_spec_path` is the full path for suppression 75 /// entry in the tests container @ref 76 /// abigail::tests::read_common::InOutSpec. 77 void set_in_suppr_spec_pathtest_task78 set_in_suppr_spec_path() 79 { 80 if (spec.in_suppr_spec_path) 81 in_suppr_spec_path = in_elf_base + spec.in_suppr_spec_path; 82 else 83 in_suppr_spec_path.clear(); 84 } 85 86 /// A setter for `in_public_headers_path` field. 87 /// The `in_public_headers_path` is the full path for headers 88 /// entry in the tests container @ref 89 /// abigail::tests::read_common::InOutSpec. 90 void set_in_public_headers_pathtest_task91 set_in_public_headers_path() 92 { 93 if (spec.in_public_headers_path) 94 in_public_headers_path = spec.in_public_headers_path; 95 if (!in_public_headers_path.empty()) 96 in_public_headers_path = in_elf_base + spec.in_public_headers_path; 97 } 98 99 /// A setter for `out_abi_path` field. 100 /// The `out_abi_path` is the full path for output of abixml file. 101 /// @return true if `out_abi_path` is a valid directory. 102 bool set_out_abi_pathtest_task103 set_out_abi_path() 104 { 105 if (!spec.out_abi_path) 106 // No output abi path was specified in the spec, so get out. 107 return false; 108 109 out_abi_path = out_abi_base + spec.out_abi_path; 110 if (!abigail::tools_utils::ensure_parent_dir_created(out_abi_path)) 111 { 112 error_message = 113 string("Could not create parent directory for ") + out_abi_path; 114 return false; 115 } 116 return true; 117 } 118 119 /// A setter for `in_abi_path` field. 120 /// The `in_abi_path` is the full path for the expected abixml file. 121 void set_in_abi_pathtest_task122 set_in_abi_path() 123 { 124 in_abi_path = in_abi_base + spec.in_abi_path; 125 } 126 127 test_task(const InOutSpec &s, 128 string& a_out_abi_base, 129 string& a_in_elf_base, 130 string& a_in_abi_base); 131 bool 132 serialize_corpus(const string& out_abi_path, 133 corpus_sptr corp); 134 bool 135 run_abidw(const string& extargs = ""); 136 137 bool 138 run_diff(); 139 140 virtual ~test_tasktest_task141 ~test_task() 142 {} 143 }; // end struct test_task 144 145 typedef shared_ptr<test_task> test_task_sptr; 146 147 /// An abstraction for valid test options. 148 struct options 149 { 150 // saves a wrong option string passed to test-harness. 151 string wrong_option; 152 // parallel test execution. 153 bool parallel; 154 optionsoptions155 options() 156 : parallel(true) 157 {} 158 ~optionsoptions159 ~options() 160 { 161 } 162 }; // end struct options 163 164 void 165 display_usage(const string& prog_name, ostream& out); 166 167 bool 168 parse_command_line(int argc, char* argv[], options& opts); 169 170 /// A convenience typedef for a callback to create_new_test 171 /// instances. 172 typedef test_task* (*create_new_test)(const InOutSpec* s, 173 string& a_out_abi_base, 174 string& a_in_elf_base, 175 string& a_in_abi_base); 176 bool 177 run_tests(const size_t num_test, const InOutSpec* specs, 178 const options& opts, create_new_test new_test); 179 180 }//end namespace read_common 181 }//end namespace tests 182 }//end namespace abigail 183 184 #endif //__TEST_READ_COMMON_H__ 185