• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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