• 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 };// 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