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