• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// This program runs a diff between input files and compares the
11 /// resulting report with a reference report.  If the resulting report
12 /// is different from the reference report, the test has failed.
13 ///
14 /// The set of input files and reference reports to consider should be
15 /// present in the source distribution.
16 
17 #include <string>
18 #include <fstream>
19 #include <iostream>
20 #include <cstdlib>
21 #include "abg-tools-utils.h"
22 #include "abg-reader.h"
23 #include "test-utils.h"
24 #include "abg-comparison.h"
25 #include "abg-corpus.h"
26 
27 using std::string;
28 using std::ofstream;
29 using std::cerr;
30 
31 struct InOutSpec
32 {
33   const char* first_in_path;
34   const char* second_in_path;
35   const char* ref_diff_path;
36   const char* out_path;
37 };// end struct InOutSpec
38 
39 static InOutSpec specs[] =
40 {
41   {
42     "data/test-abidiff/test-enum0-v0.cc.bi",
43     "data/test-abidiff/test-enum0-v1.cc.bi",
44     "data/test-abidiff/test-enum0-report.txt",
45     "output/test-abidiff/test-enum0-report.txt"
46   },
47   {
48     "data/test-abidiff/test-enum1-v0.cc.bi",
49     "data/test-abidiff/test-enum1-v1.cc.bi",
50     "data/test-abidiff/test-enum1-report.txt",
51     "output/test-abidiff/test-enum1-report.txt"
52   },
53   {
54     "data/test-abidiff/test-qual-type0-v0.cc.bi",
55     "data/test-abidiff/test-qual-type0-v1.cc.bi",
56     "data/test-abidiff/test-qual-type0-report.txt",
57     "output/test-abidiff/test-qual-type0-report.txt"
58   },
59   {
60     "data/test-abidiff/test-struct0-v0.cc.bi",
61     "data/test-abidiff/test-struct0-v1.cc.bi",
62     "data/test-abidiff/test-struct0-report.txt",
63     "output/test-abidiff/test-struct0-report.txt"
64   },
65   {
66     "data/test-abidiff/test-struct1-v0.cc.bi",
67     "data/test-abidiff/test-struct1-v1.cc.bi",
68     "data/test-abidiff/test-struct1-report.txt",
69     "output/test-abidiff/test-struct1-report.txt"
70   },
71   {
72     "data/test-abidiff/test-var0-v0.cc.bi",
73     "data/test-abidiff/test-var0-v1.cc.bi",
74     "data/test-abidiff/test-var0-report.txt",
75     "output/test-abidiff/test-var0-report.txt"
76   },
77   {
78     "data/test-abidiff/test-PR18166-libtirpc.so.abi",
79     "data/test-abidiff/test-PR18166-libtirpc.so.abi",
80     "data/test-abidiff/empty-report.txt",
81     "output/test-abidiff/test-PR18166-libtirpc.so.report.txt"
82   },
83   {
84     "data/test-abidiff/test-PR18791-v0.so.abi",
85     "data/test-abidiff/test-PR18791-v1.so.abi",
86     "data/test-abidiff/test-PR18791-report0.txt",
87     "output/test-abidiff/test-PR18791-report0.txt"
88   },
89   {
90     "data/test-abidiff/test-PR24552-v0.abi",
91     "data/test-abidiff/test-PR24552-v1.abi",
92     "data/test-abidiff/empty-report.txt",
93     "output/test-abidiff/test-PR24552-report0.txt"
94   },
95   {
96     "data/test-abidiff/test-empty-corpus-0.xml",
97     "data/test-abidiff/test-empty-corpus-0.xml",
98     "data/test-abidiff/empty-report.txt",
99     "output/test-abidiff/test-empty-corpus-report-0.txt"
100   },
101   {
102     "data/test-abidiff/test-empty-corpus-1.xml",
103     "data/test-abidiff/test-empty-corpus-1.xml",
104     "data/test-abidiff/empty-report.txt",
105     "output/test-abidiff/test-empty-corpus-report-1.txt"
106   },
107   {
108     "data/test-abidiff/test-empty-corpus-2.xml",
109     "data/test-abidiff/test-empty-corpus-2.xml",
110     "data/test-abidiff/empty-report.txt",
111     "output/test-abidiff/test-empty-corpus-report-1.txt"
112   },
113   {
114     "data/test-abidiff/test-crc-0.xml",
115     "data/test-abidiff/test-crc-1.xml",
116     "data/test-abidiff/test-crc-report-0-1.txt",
117     "output/test-abidiff/test-crc-report-0-1.txt"
118   },
119   {
120     "data/test-abidiff/test-crc-1.xml",
121     "data/test-abidiff/test-crc-0.xml",
122     "data/test-abidiff/test-crc-report-1-0.txt",
123     "output/test-abidiff/test-crc-report-1-0.txt"
124   },
125   {
126     "data/test-abidiff/test-crc-1.xml",
127     "data/test-abidiff/test-crc-2.xml",
128     "data/test-abidiff/test-crc-report-1-2.txt",
129     "output/test-abidiff/test-crc-report-1-2.txt"
130   },
131   {
132     "data/test-abidiff/test-namespace-0.xml",
133     "data/test-abidiff/test-namespace-1.xml",
134     "data/test-abidiff/test-namespace-report.txt",
135     "output/test-abidiff/test-namespace-report-0-1.txt"
136   },
137   {
138     "data/test-abidiff/test-PR27616-v0.xml",
139     "data/test-abidiff/test-PR27616-v1.xml",
140     "data/test-abidiff/empty-report.txt",
141     "output/test-abidiff/empty-report.txt"
142   },
143   {
144     "data/test-abidiff/test-PR27616-squished-v0.abi",
145     "data/test-abidiff/test-PR27616-squished-v1.abi",
146     "data/test-abidiff/empty-report.txt",
147     "output/test-abidiff/empty-report.txt"
148   },
149   {
150     "data/test-abidiff/test-PR27985-v0.o.abi",
151     "data/test-abidiff/test-PR27985-v1.o.abi",
152     "data/test-abidiff/test-PR27985-report.txt",
153     "output/test-abidiff/test-PR27985-report.txt"
154   },
155   // This should be the last entry.
156   {0, 0, 0, 0}
157 };
158 
159 #define  NUM_SPEC_ELEMS \
160   ((sizeof(specs) / sizeof(InOutSpec)) - 1)
161 
162 using std::string;
163 using std::cerr;
164 using std::ofstream;
165 using abigail::tools_utils::file_type;
166 using abigail::tools_utils::check_file;
167 using abigail::tools_utils::guess_file_type;
168 using abigail::ir::environment;
169 using abigail::ir::environment_sptr;
170 using abigail::corpus_sptr;
171 using abigail::corpus_group_sptr;
172 using abigail::translation_unit;
173 using abigail::translation_unit_sptr;
174 using abigail::xml_reader::read_translation_unit_from_file;
175 using abigail::xml_reader::read_corpus_from_native_xml_file;
176 using abigail::xml_reader::read_corpus_group_from_native_xml_file;
177 using abigail::comparison::corpus_diff_sptr;
178 using abigail::comparison::translation_unit_diff_sptr;
179 using abigail::comparison::compute_diff;
180 using abigail::comparison::diff_context_sptr;
181 using abigail::comparison::diff_context;
182 
183 int
main(int,char * [])184 main(int, char*[])
185 {
186   bool is_ok = true;
187 
188   string out_path =
189     string(abigail::tests::get_build_dir()) + "/tests/" + specs->out_path;
190   if (!abigail::tools_utils::ensure_parent_dir_created(out_path))
191     {
192       cerr << "Could not create parent director for " << out_path;
193       return 1;
194     }
195 
196   string first_in_path, second_in_path, ref_diff_path;
197   for (InOutSpec *s = specs; s->first_in_path; ++s)
198     {
199       first_in_path =
200 	string(abigail::tests::get_src_dir()) + "/tests/" + s->first_in_path;
201       second_in_path =
202 	string(abigail::tests::get_src_dir()) + "/tests/" + s->second_in_path;
203       ref_diff_path =
204 	string(abigail::tests::get_src_dir()) + "/tests/" + s->ref_diff_path;
205       out_path =
206 	string(abigail::tests::get_build_dir()) + "/tests/" + s->out_path;
207 
208       if (!abigail::tools_utils::ensure_parent_dir_created(out_path))
209 	{
210 	  cerr << "Could not create parent directory for " << out_path;
211 	  continue;
212 	}
213 
214       environment_sptr env(new environment);
215       translation_unit_sptr tu1, tu2;
216       corpus_sptr corpus1, corpus2;
217       corpus_group_sptr corpus_group1, corpus_group2;
218       file_type t = guess_file_type(first_in_path);
219       if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
220 	tu1 = read_translation_unit_from_file(first_in_path, env.get());
221       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
222 	corpus1 = read_corpus_from_native_xml_file(first_in_path, env.get());
223       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS_GROUP)
224 	corpus_group1 = read_corpus_group_from_native_xml_file(first_in_path,
225 							       env.get());
226       else
227 	abort();
228       if (!tu1 && !corpus1 && !corpus_group1)
229 	{
230 	  cerr << "failed to read " << first_in_path << "\n";
231 	  is_ok = false;
232 	  continue;
233 	}
234 
235       t = guess_file_type(second_in_path);
236       if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
237 	tu2 = read_translation_unit_from_file(second_in_path, env.get());
238       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
239 	corpus2 = read_corpus_from_native_xml_file(second_in_path, env.get());
240       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS_GROUP)
241 	corpus_group2 = read_corpus_group_from_native_xml_file(first_in_path,
242 							       env.get());
243       else
244 	abort();
245       if (!tu2 && !corpus2 && !corpus_group2)
246 	{
247 	  cerr << "failed to read " << second_in_path << "\n";
248 	  is_ok = false;
249 	  continue;
250 	}
251 
252       translation_unit_diff_sptr d1;
253       corpus_diff_sptr d2;
254       diff_context_sptr ctxt(new diff_context);
255       ctxt->show_locs(false);
256       if (tu1)
257 	d1= compute_diff(tu1, tu2, ctxt);
258       else if (corpus1)
259 	d2 = compute_diff(corpus1, corpus2, ctxt);
260       else if (corpus_group1)
261 	d2 = compute_diff(corpus_group1, corpus_group2, ctxt);
262       ofstream of(out_path.c_str(), std::ios_base::trunc);
263       if (!of.is_open())
264 	{
265 	  cerr << "failed to read " << s->out_path << "\n";
266 	  is_ok = false;
267 	  continue;
268 	}
269 
270       if (d1)
271 	d1->report(of);
272       else
273 	d2->report(of);
274       of.close();
275 
276       string cmd = "diff -u " + ref_diff_path + " " + out_path;
277       if (system(cmd.c_str()))
278 	is_ok = false;
279     }
280 
281   return !is_ok;
282 }
283