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 };// end struct InOutSpec 44 45 /// The task that performs the tests. 46 struct test_task : public abigail::workers::task 47 { 48 bool is_ok; 49 InOutSpec spec; 50 string error_message; 51 string out_abi_base; 52 string in_elf_base; 53 string in_abi_base; 54 55 string in_elf_path; 56 string in_abi_path; 57 string in_suppr_spec_path; 58 string in_public_headers_path; 59 string out_abi_path; 60 61 62 /// A setter for `in_elf_path` field. 63 /// The `in_elf_path` is the full path for input object 64 /// in the tests container @ref 65 /// abigail::tests::read_common::InOutSpec. 66 void set_in_elf_pathtest_task67 set_in_elf_path() 68 { 69 in_elf_path = in_elf_base + spec.in_elf_path; 70 } 71 72 /// A setter for `in_suppr_spec_path` field. 73 /// The `in_suppr_spec_path` is the full path for suppression 74 /// entry in the tests container @ref 75 /// abigail::tests::read_common::InOutSpec. 76 void set_in_suppr_spec_pathtest_task77 set_in_suppr_spec_path() 78 { 79 if (spec.in_suppr_spec_path) 80 in_suppr_spec_path = in_elf_base + spec.in_suppr_spec_path; 81 else 82 in_suppr_spec_path.clear(); 83 } 84 85 /// A setter for `in_public_headers_path` field. 86 /// The `in_public_headers_path` is the full path for headers 87 /// entry in the tests container @ref 88 /// abigail::tests::read_common::InOutSpec. 89 void set_in_public_headers_pathtest_task90 set_in_public_headers_path() 91 { 92 if (spec.in_public_headers_path) 93 in_public_headers_path = spec.in_public_headers_path; 94 if (!in_public_headers_path.empty()) 95 in_public_headers_path = in_elf_base + spec.in_public_headers_path; 96 } 97 98 /// A setter for `out_abi_path` field. 99 /// The `out_abi_path` is the full path for output of abixml file. 100 /// @return true if `out_abi_path` is a valid directory. 101 bool set_out_abi_pathtest_task102 set_out_abi_path() 103 { 104 out_abi_path = out_abi_base + spec.out_abi_path; 105 if (!abigail::tools_utils::ensure_parent_dir_created(out_abi_path)) 106 { 107 error_message = 108 string("Could not create parent directory for ") + out_abi_path; 109 return false; 110 } 111 return true; 112 } 113 114 /// A setter for `in_abi_path` field. 115 /// The `in_abi_path` is the full path for the expected abixml file. 116 void set_in_abi_pathtest_task117 set_in_abi_path() 118 { 119 in_abi_path = in_abi_base + spec.in_abi_path; 120 } 121 122 test_task(const InOutSpec &s, 123 string& a_out_abi_base, 124 string& a_in_elf_base, 125 string& a_in_abi_base); 126 bool 127 serialize_corpus(const string& out_abi_path, 128 corpus_sptr corp); 129 bool 130 run_abidw(const string& extargs = ""); 131 132 bool 133 run_diff(); 134 135 virtual ~test_tasktest_task136 ~test_task() 137 {} 138 }; // end struct test_task 139 140 typedef shared_ptr<test_task> test_task_sptr; 141 142 /// An abstraction for valid test options. 143 struct options 144 { 145 // saves a wrong option string passed to test-harness. 146 string wrong_option; 147 // parallel test execution. 148 bool parallel; 149 optionsoptions150 options() 151 : parallel(true) 152 {} 153 ~optionsoptions154 ~options() 155 { 156 } 157 }; // end struct options 158 159 void 160 display_usage(const string& prog_name, ostream& out); 161 162 bool 163 parse_command_line(int argc, char* argv[], options& opts); 164 165 /// A convenience typedef for a callback to create_new_test 166 /// instances. 167 typedef test_task* (*create_new_test)(const InOutSpec* s, 168 string& a_out_abi_base, 169 string& a_in_elf_base, 170 string& a_in_abi_base); 171 bool 172 run_tests(const size_t num_test, const InOutSpec* specs, 173 const options& opts, create_new_test new_test); 174 175 }//end namespace read_common 176 }//end namespace tests 177 }//end namespace abigail 178 179 #endif //__TEST_READ_COMMON_H__ 180