Bug 24731 - Wrongly reporting union members order change
[platform/upstream/libabigail.git] / tests / test-diff-filter.cc
1 // -*- Mode: C++ -*-
2 //
3 // Copyright (C) 2013-2019 Red Hat, Inc.
4 //
5 // This file is part of the GNU Application Binary Interface Generic
6 // Analysis and Instrumentation Library (libabigail).  This library is
7 // free software; you can redistribute it and/or modify it under the
8 // terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option) any
10 // later version.
11
12 // This library is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Lesser Public License for more details.
16
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this program; see the file COPYING-LGPLV3.  If
19 // not, see <http://www.gnu.org/licenses/>.
20
21 // Author: Dodji Seketeli
22
23 /// @file
24 ///
25 /// This program runs a diff between input ELF files containing DWARF
26 /// debugging information and compares the resulting report with a
27 /// reference report.  If the resulting report is different from the
28 /// reference report, the test has failed.  Note that the comparison
29 /// is done using the abidiff command line comparison tool.
30 ///
31 /// The set of input files and reference reports to consider should be
32 /// present in the source distribution.
33
34 #include <sys/wait.h>
35 #include <cassert>
36 #include <string>
37 #include <fstream>
38 #include <iostream>
39 #include <cstdlib>
40 #include "abg-workers.h"
41 #include "abg-tools-utils.h"
42 #include "test-utils.h"
43
44 using std::string;
45 using std::cerr;
46
47 /// This is an aggregate that specifies where a test shall get its
48 /// input from and where it shall write its ouput to.
49 struct InOutSpec
50 {
51   const char* in_elfv0_path;
52   const char* in_elfv1_path;
53   const char* abidiff_options;
54   const char* in_report_path;
55   const char* out_report_path;
56 }; // end struct InOutSpec;
57
58 InOutSpec in_out_specs[] =
59 {
60   {
61     "data/test-diff-filter/test0-v0.o",
62     "data/test-diff-filter/test0-v1.o",
63     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
64     "data/test-diff-filter/test0-report.txt",
65     "output/test-diff-filter/test0-report.txt",
66   },
67   {
68     "data/test-diff-filter/test0-v0.o",
69     "data/test-diff-filter/test0-v1.o",
70     "--no-default-suppression --harmless --no-linkage-name "
71     "--no-show-locs --no-redundant",
72     "data/test-diff-filter/test01-report.txt",
73     "output/test-diff-filter/test01-report.txt",
74   },
75   {
76     "data/test-diff-filter/test1-v0.o",
77     "data/test-diff-filter/test1-v1.o",
78     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
79     "data/test-diff-filter/test1-report.txt",
80     "output/test-diff-filter/test1-report.txt",
81   },
82   {
83     "data/test-diff-filter/test2-v0.o",
84     "data/test-diff-filter/test2-v1.o",
85     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
86     "data/test-diff-filter/test2-report.txt",
87     "output/test-diff-filter/test2-report.txt",
88   },
89   {
90     "data/test-diff-filter/test3-v0.o",
91     "data/test-diff-filter/test3-v1.o",
92     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
93     "data/test-diff-filter/test3-report.txt",
94     "output/test-diff-filter/test3-report.txt",
95   },
96   {
97     "data/test-diff-filter/test4-v0.o",
98     "data/test-diff-filter/test4-v1.o",
99     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
100     "data/test-diff-filter/test4-report.txt",
101     "output/test-diff-filter/test4-report.txt",
102   },
103   {
104     "data/test-diff-filter/test5-v0.o",
105     "data/test-diff-filter/test5-v1.o",
106     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
107     "data/test-diff-filter/test5-report.txt",
108     "output/test-diff-filter/test5-report.txt",
109   },
110   {
111     "data/test-diff-filter/test6-v0.o",
112     "data/test-diff-filter/test6-v1.o",
113     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
114     "data/test-diff-filter/test6-report.txt",
115     "output/test-diff-filter/test6-report.txt",
116   },
117   {
118     "data/test-diff-filter/test7-v0.o",
119     "data/test-diff-filter/test7-v1.o",
120     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
121     "data/test-diff-filter/test7-report.txt",
122     "output/test-diff-filter/test7-report.txt",
123   },
124   {
125     "data/test-diff-filter/test8-v0.o",
126     "data/test-diff-filter/test8-v1.o",
127     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
128     "data/test-diff-filter/test8-report.txt",
129     "output/test-diff-filter/test8-report.txt",
130   },
131   {
132     "data/test-diff-filter/test9-v0.o",
133     "data/test-diff-filter/test9-v1.o",
134     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
135     "data/test-diff-filter/test9-report.txt",
136     "output/test-diff-filter/test9-report.txt",
137   },
138   {
139     "data/test-diff-filter/test10-v0.o",
140     "data/test-diff-filter/test10-v1.o",
141     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
142     "data/test-diff-filter/test10-report.txt",
143     "output/test-diff-filter/test10-report.txt",
144   },
145   {
146     "data/test-diff-filter/test11-v0.o",
147     "data/test-diff-filter/test11-v1.o",
148     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
149     "data/test-diff-filter/test11-report.txt",
150     "output/test-diff-filter/test11-report.txt",
151   },
152   {
153     "data/test-diff-filter/test12-v0.o",
154     "data/test-diff-filter/test12-v1.o",
155     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
156     "data/test-diff-filter/test12-report.txt",
157     "output/test-diff-filter/test12-report.txt",
158   },
159   {
160     "data/test-diff-filter/test13-v0.o",
161     "data/test-diff-filter/test13-v1.o",
162     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
163     "data/test-diff-filter/test13-report.txt",
164     "output/test-diff-filter/test13-report.txt",
165   },
166   {
167     "data/test-diff-filter/test14-v0.o",
168     "data/test-diff-filter/test14-v1.o",
169     "--no-default-suppression --no-show-locs --no-redundant",
170     "data/test-diff-filter/test14-0-report.txt",
171     "output/test-diff-filter/test14-0-report.txt",
172   },
173   {
174     "data/test-diff-filter/test14-v0.o",
175     "data/test-diff-filter/test14-v1.o",
176     "--no-default-suppression --no-show-locs --redundant",
177     "data/test-diff-filter/test14-1-report.txt",
178     "output/test-diff-filter/test14-1-report.txt",
179   },
180   {
181     "data/test-diff-filter/test15-v0.o",
182     "data/test-diff-filter/test15-v1.o",
183     "--no-default-suppression --no-show-locs --no-redundant",
184     "data/test-diff-filter/test15-0-report.txt",
185     "output/test-diff-filter/test15-0-report.txt",
186   },
187   {
188     "data/test-diff-filter/test15-v0.o",
189     "data/test-diff-filter/test15-v1.o",
190     "--no-default-suppression --no-show-locs --redundant",
191     "data/test-diff-filter/test15-1-report.txt",
192     "output/test-diff-filter/test15-1-report.txt",
193   },
194   {
195     "data/test-diff-filter/test16-v0.o",
196     "data/test-diff-filter/test16-v1.o",
197     "--no-default-suppression --no-show-locs --no-redundant",
198     "data/test-diff-filter/test16-report.txt",
199     "output/test-diff-filter/test16-report.txt",
200   },
201   {
202     "data/test-diff-filter/test16-v0.o",
203     "data/test-diff-filter/test16-v1.o",
204     "--no-default-suppression --no-show-locs --redundant",
205     "data/test-diff-filter/test16-report-2.txt",
206     "output/test-diff-filter/test16-report-2.txt",
207   },
208   {
209     "data/test-diff-filter/test17-v0.o",
210     "data/test-diff-filter/test17-v1.o",
211     "--no-default-suppression --no-show-locs --no-redundant",
212     "data/test-diff-filter/test17-0-report.txt",
213     "output/test-diff-filter/test17-0-report.txt",
214   },
215   {
216     "data/test-diff-filter/test17-v0.o",
217     "data/test-diff-filter/test17-v1.o",
218     "--no-default-suppression --no-show-locs --redundant",
219     "data/test-diff-filter/test17-1-report.txt",
220     "output/test-diff-filter/test17-1-report.txt",
221   },
222   {
223     "data/test-diff-filter/test18-v0.o",
224     "data/test-diff-filter/test18-v1.o",
225     "--no-default-suppression --no-show-locs --no-redundant",
226     "data/test-diff-filter/test18-report.txt",
227     "output/test-diff-filter/test18-report.txt",
228   },
229   {
230     "data/test-diff-filter/test19-enum-v0.o",
231     "data/test-diff-filter/test19-enum-v1.o",
232     "--no-default-suppression --no-show-locs --no-redundant",
233     "data/test-diff-filter/test19-enum-report-0.txt",
234     "output/test-diff-filter/test19-enum-report-0.txt",
235   },
236   {
237     "data/test-diff-filter/test19-enum-v0.o",
238     "data/test-diff-filter/test19-enum-v1.o",
239     "--no-default-suppression --no-show-locs --harmless",
240     "data/test-diff-filter/test19-enum-report-1.txt",
241     "output/test-diff-filter/test19-enum-report-1.txt",
242   },
243   {
244     "data/test-diff-filter/test20-inline-v0.o",
245     "data/test-diff-filter/test20-inline-v1.o",
246     "--no-default-suppression --no-show-locs --no-redundant",
247     "data/test-diff-filter/test20-inline-report-0.txt",
248     "output/test-diff-filter/test20-inline-report-0.txt",
249   },
250   {
251     "data/test-diff-filter/test20-inline-v0.o",
252     "data/test-diff-filter/test20-inline-v1.o",
253     "--no-default-suppression --no-show-locs --harmless",
254     "data/test-diff-filter/test20-inline-report-1.txt",
255     "output/test-diff-filter/test20-inline-report-1.txt",
256   },
257   {
258     "data/test-diff-filter/libtest21-compatible-vars-v0.so",
259     "data/test-diff-filter/libtest21-compatible-vars-v1.so",
260     "--no-default-suppression --no-show-locs --harmless",
261     "data/test-diff-filter/test21-compatible-vars-report-0.txt",
262     "output/test-diff-filter/test21-compatible-vars-report-0.txt",
263   },
264   {
265     "data/test-diff-filter/libtest21-compatible-vars-v0.so",
266     "data/test-diff-filter/libtest21-compatible-vars-v1.so",
267     "--no-default-suppression --no-show-locs --no-redundant",
268     "data/test-diff-filter/test21-compatible-vars-report-1.txt",
269     "output/test-diff-filter/test21-compatible-vars-report-1.txt",
270   },
271   {
272     "data/test-diff-filter/libtest22-compatible-fns-v0.so",
273     "data/test-diff-filter/libtest22-compatible-fns-v1.so",
274     "--no-default-suppression --no-show-locs --harmless",
275     "data/test-diff-filter/test22-compatible-fns-report-0.txt",
276     "output/test-diff-filter/test22-compatible-fns-report-0.txt",
277   },
278   {
279     "data/test-diff-filter/libtest22-compatible-fns-v0.so",
280     "data/test-diff-filter/libtest22-compatible-fns-v1.so",
281     "--no-default-suppression --no-show-locs --no-redundant",
282     "data/test-diff-filter/test22-compatible-fns-report-1.txt",
283     "output/test-diff-filter/test22-compatible-fns-report-1.txt",
284   },
285   {
286     "data/test-diff-filter/libtest23-redundant-fn-parm-change-v0.so",
287     "data/test-diff-filter/libtest23-redundant-fn-parm-change-v1.so",
288     "--no-default-suppression --no-show-locs",
289     "data/test-diff-filter/test23-redundant-fn-parm-change-report-0.txt ",
290     "output/test-diff-filter/test23-redundant-fn-parm-change-report-0.txt ",
291   },
292   {
293     "data/test-diff-filter/libtest24-compatible-vars-v0.so",
294     "data/test-diff-filter/libtest24-compatible-vars-v1.so",
295     "--no-default-suppression --no-show-locs",
296     "data/test-diff-filter/test24-compatible-vars-report-0.txt ",
297     "output/test-diff-filter/test24-compatible-vars-report-0.txt ",
298   },
299   {
300     "data/test-diff-filter/libtest24-compatible-vars-v0.so",
301     "data/test-diff-filter/libtest24-compatible-vars-v1.so",
302     "--no-default-suppression --no-show-locs --harmless",
303     "data/test-diff-filter/test24-compatible-vars-report-1.txt ",
304     "output/test-diff-filter/test24-compatible-vars-report-1.txt ",
305   },
306   {
307     "data/test-diff-filter/libtest25-cyclic-type-v0.so",
308     "data/test-diff-filter/libtest25-cyclic-type-v1.so",
309     "--no-default-suppression --no-show-locs",
310     "data/test-diff-filter/test25-cyclic-type-report-0.txt ",
311     "output/test-diff-filter/test25-cyclic-type-report-0.txt "
312   },
313   {
314     "data/test-diff-filter/libtest25-cyclic-type-v0.so",
315     "data/test-diff-filter/libtest25-cyclic-type-v1.so",
316     "--no-default-suppression --no-show-locs --redundant",
317     "data/test-diff-filter/test25-cyclic-type-report-1.txt ",
318     "output/test-diff-filter/test25-cyclic-type-report-1.txt "
319   },
320   {
321     "data/test-diff-filter/libtest26-qualified-redundant-node-v0.so",
322     "data/test-diff-filter/libtest26-qualified-redundant-node-v1.so",
323     "--no-default-suppression --no-show-locs",
324     "data/test-diff-filter/test26-qualified-redundant-node-report-0.txt",
325     "output/test-diff-filter/test26-qualified-redundant-node-report-0.txt"
326   },
327   {
328     "data/test-diff-filter/libtest26-qualified-redundant-node-v0.so",
329     "data/test-diff-filter/libtest26-qualified-redundant-node-v1.so",
330     "--no-default-suppression --no-show-locs --redundant",
331     "data/test-diff-filter/test26-qualified-redundant-node-report-1.txt",
332     "output/test-diff-filter/test26-qualified-redundant-node-report-1.txt"
333   },
334   {
335     "data/test-diff-filter/libtest27-redundant-and-filtered-children-nodes-v0.so",
336     "data/test-diff-filter/libtest27-redundant-and-filtered-children-nodes-v1.so",
337     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
338     "data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-0.txt",
339     "output/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-0.txt"
340   },
341   {
342     "data/test-diff-filter/libtest27-redundant-and-filtered-children-nodes-v0.so",
343     "data/test-diff-filter/libtest27-redundant-and-filtered-children-nodes-v1.so",
344     "--no-default-suppression --no-linkage-name --no-show-locs --redundant",
345     "data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt",
346     "output/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt"
347   },
348   {
349     "data/test-diff-filter/libtest27-redundant-and-filtered-children-nodes-v0.so",
350     "data/test-diff-filter/libtest27-redundant-and-filtered-children-nodes-v1.so",
351     "--no-default-suppression --no-linkage-name --redundant --no-show-locs --harmless",
352     "data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-2.txt",
353     "output/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-2.txt"
354   },
355   {
356     "data/test-diff-filter/libtest28-redundant-and-filtered-children-nodes-v0.so",
357     "data/test-diff-filter/libtest28-redundant-and-filtered-children-nodes-v1.so",
358     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
359    "data/test-diff-filter/test28-redundant-and-filtered-children-nodes-report-0.txt",
360     "output/test-diff-filter/test28-redundant-and-filtered-children-nodes-report-0.txt",
361   },
362   {
363     "data/test-diff-filter/libtest28-redundant-and-filtered-children-nodes-v0.so",
364     "data/test-diff-filter/libtest28-redundant-and-filtered-children-nodes-v1.so",
365     "--no-default-suppression --no-linkage-name --redundant --no-show-locs --harmless",
366    "data/test-diff-filter/test28-redundant-and-filtered-children-nodes-report-1.txt",
367     "output/test-diff-filter/test28-redundant-and-filtered-children-nodes-report-1.txt",
368   },
369   {
370     "data/test-diff-filter/test29-finer-redundancy-marking-v0.o",
371     "data/test-diff-filter/test29-finer-redundancy-marking-v1.o",
372     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
373     "data/test-diff-filter/test29-finer-redundancy-marking-report-0.txt",
374     "output/test-diff-filter/test29-finer-redundancy-marking-report-0.txt",
375   },
376   {
377     "data/test-diff-filter/test30-pr18904-rvalueref-liba.so",
378     "data/test-diff-filter/test30-pr18904-rvalueref-libb.so",
379     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
380     "data/test-diff-filter/test30-pr18904-rvalueref-report0.txt",
381     "output/test-diff-filter/test30-pr18904-rvalueref-report0.txt",
382   },
383   { // Just like the previous test, but emit loc info.
384     "data/test-diff-filter/test30-pr18904-rvalueref-liba.so",
385     "data/test-diff-filter/test30-pr18904-rvalueref-libb.so",
386     "--no-default-suppression --no-linkage-name --no-redundant",
387     "data/test-diff-filter/test30-pr18904-rvalueref-report1.txt",
388     "output/test-diff-filter/test30-pr18904-rvalueref-report1.txt",
389   },
390   { // Just like the previous test, but emit sizes in hex and bytes
391     "data/test-diff-filter/test30-pr18904-rvalueref-liba.so",
392     "data/test-diff-filter/test30-pr18904-rvalueref-libb.so",
393     "--no-default-suppression --no-linkage-name --no-redundant "
394     "--show-hex --show-bytes",
395     "data/test-diff-filter/test30-pr18904-rvalueref-report2.txt",
396     "output/test-diff-filter/test30-pr18904-rvalueref-report2.txt",
397   },
398   {
399     "data/test-diff-filter/test31-pr18535-libstdc++-4.8.3.so",
400     "data/test-diff-filter/test31-pr18535-libstdc++-4.9.2.so",
401     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
402     "data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt",
403     "output/test-diff-filter/test31-pr18535-libstdc++-report-0.txt",
404   },
405   { // Just like the previous test, but emit loc info.
406     "data/test-diff-filter/test31-pr18535-libstdc++-4.8.3.so",
407     "data/test-diff-filter/test31-pr18535-libstdc++-4.9.2.so",
408     "--no-default-suppression --no-linkage-name --no-redundant",
409     "data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt",
410     "output/test-diff-filter/test31-pr18535-libstdc++-report-1.txt",
411   },
412   {
413     "data/test-diff-filter/libtest32-struct-change-v0.so",
414     "data/test-diff-filter/libtest32-struct-change-v1.so",
415     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
416     "data/test-diff-filter/test32-ppc64le-struct-change-report0.txt",
417     "output/test-diff-filter/test32-ppc64le-struct-change-report0.txt",
418   },
419   {
420     "data/test-diff-filter/test33-libelf.so.0.8.13-gcc",
421     "data/test-diff-filter/test33-libelf.so.0.8.13-intel16.0.3",
422     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
423     "data/test-diff-filter/test33-report-0.txt",
424     "output/test-diff-filter/test33-report-0.txt",
425   },
426   {
427     "data/test-diff-filter/test34-libjemalloc.so.2-gcc-6.1.0",
428     "data/test-diff-filter/test34-libjemalloc.so.2-intel-16.0.3",
429     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant",
430     "data/test-diff-filter/test34-report-0.txt",
431     "output/test-diff-filter/test34-report-0.txt",
432   },
433   {
434     "data/test-diff-filter/test30-pr18904-rvalueref-liba.so",
435     "data/test-diff-filter/test30-pr18904-rvalueref-libb.so",
436     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant --no-added-syms",
437     "data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt",
438     "output/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt",
439   },
440   {
441     "data/test-diff-filter/test30-pr18904-rvalueref-liba.so",
442     "data/test-diff-filter/test30-pr18904-rvalueref-libb.so",
443     "--no-default-suppression --no-linkage-name --no-show-locs --no-redundant --deleted-fns --changed-vars --no-added-syms",
444     "data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt",
445     "output/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt",
446   },
447   {
448     "data/test-diff-filter/libtest36-v0.so",
449     "data/test-diff-filter/libtest36-v1.so",
450     "--no-default-suppression --no-linkage-name",
451     "data/test-diff-filter/test36-report-0.txt",
452     "output/test-diff-filter/test36-report-0.txt",
453   },
454   {
455     "data/test-diff-filter/libtest37-v0.so",
456     "data/test-diff-filter/libtest37-v1.so",
457     "--no-default-suppression --no-linkage-name",
458     "data/test-diff-filter/test37-report-0.txt",
459     "output/test-diff-filter/test37-report-0.txt",
460   },
461   {
462     "data/test-diff-filter/test38/test38-v0",
463     "data/test-diff-filter/test38/test38-v1",
464     "--no-default-suppression --no-linkage-name",
465     "data/test-diff-filter/test38/test38-report-0.txt",
466     "output/test-diff-filter/test38/test38-report-0.txt",
467   },
468   {
469     "data/test-diff-filter/test39/test39-v0",
470     "data/test-diff-filter/test39/test39-v1",
471     "--no-default-suppression --no-linkage-name",
472     "data/test-diff-filter/test39/test39-report-0.txt",
473     "output/test-diff-filter/test39/test39-report-0.txt",
474   },
475   {
476     "data/test-diff-filter/libtest40-v0.so",
477     "data/test-diff-filter/libtest40-v1.so",
478     "--no-default-suppression --no-linkage-name",
479     "data/test-diff-filter/test40-report-0.txt",
480     "output/test-diff-filter/test40-report-0.txt",
481   },
482   {
483     "data/test-diff-filter/test41-PR21486-abg-writer.gcc.o",
484     "data/test-diff-filter/test41-PR21486-abg-writer.llvm.o",
485     "--no-default-suppression",
486     "data/test-diff-filter/test41-report-0.txt",
487     "output/test-diff-filter/test41-report-0.txt",
488   },
489   {
490     "data/test-diff-filter/libtest42-leaf-report-v0.so",
491     "data/test-diff-filter/libtest42-leaf-report-v1.so",
492     "--no-default-suppression --leaf-changes-only --impacted-interfaces",
493     "data/test-diff-filter/test42-leaf-report-output-0.txt",
494     "output/test-diff-filter/test42-leaf-report-output-0.txt",
495   },
496   {
497     "data/test-diff-filter/libtest43-decl-only-def-change-leaf-report-v0.so",
498     "data/test-diff-filter/libtest43-decl-only-def-change-leaf-report-v1.so",
499     "--no-default-suppression --leaf-changes-only",
500     "data/test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt",
501     "output/test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt",
502   },
503   {
504     "data/test-diff-filter/libtest44-anonymous-data-member-v0.so",
505     "data/test-diff-filter/libtest44-anonymous-data-member-v1.so",
506     "--no-default-suppression",
507     "data/test-diff-filter/test44-anonymous-data-member-report-0.txt",
508     "output/test-diff-filter/test44-anonymous-data-member-report-0.txt",
509   },
510   {
511     "data/test-diff-filter/libtest44-anonymous-data-member-v0.so",
512     "data/test-diff-filter/libtest44-anonymous-data-member-v1.so",
513     "--no-default-suppression --leaf-changes-only",
514     "data/test-diff-filter/test44-anonymous-data-member-report-1.txt",
515     "output/test-diff-filter/test44-anonymous-data-member-report-1.txt",
516   },
517   {
518     "data/test-diff-filter/libtest45-basic-type-change-v0.so",
519     "data/test-diff-filter/libtest45-basic-type-change-v1.so",
520     "--no-default-suppression",
521     "data/test-diff-filter/libtest45-basic-type-change-report-0.txt",
522     "output/test-diff-filter/libtest45-basic-type-change-report-0.txt",
523   },
524   {
525     "data/test-diff-filter/libtest45-basic-type-change-v0.so",
526     "data/test-diff-filter/libtest45-basic-type-change-v1.so",
527     "--no-default-suppression --leaf-changes-only",
528     "data/test-diff-filter/libtest45-basic-type-change-report-1.txt",
529     "output/test-diff-filter/libtest45-basic-type-change-report-1.txt",
530   },
531   {
532     "data/test-diff-filter/test46-fn-return-qual-change-v0.o",
533     "data/test-diff-filter/test46-fn-return-qual-change-v1.o",
534     "--no-default-suppression",
535     "data/test-diff-filter/test46-fn-return-qual-change-report-0.txt",
536     "output/test-diff-filter/test46-fn-return-qual-change-report-0.txt",
537   },
538   {
539     "data/test-diff-filter/test47-filter-void-ptr-change-v0.o",
540     "data/test-diff-filter/test47-filter-void-ptr-change-v1.o",
541     "--no-default-suppression",
542     "data/test-diff-filter/test47-filter-void-ptr-change-report-0.txt",
543     "output/test-diff-filter/test47-filter-void-ptr-change-report-0.txt",
544   },
545   {
546     "data/test-diff-filter/PR24430-fold-qualified-array-clang",
547     "data/test-diff-filter/PR24430-fold-qualified-array-gcc",
548     "--no-default-suppression",
549     "data/test-diff-filter/PR24430-fold-qualified-array-report-0.txt",
550     "output/test-diff-filter/PR24430-fold-qualified-array-report-0.txt",
551   },
552   {
553     "data/test-diff-filter/test-PR24731-v0.o ",
554     "data/test-diff-filter/test-PR24731-v1.o ",
555     "--no-default-suppression",
556     "data/test-diff-filter/test-PR24731-report-0.txt",
557     "output/test-diff-filter/test-PR24731-report-0.txt",
558   },
559   // This should be the last entry
560   {NULL, NULL, NULL, NULL, NULL}
561 };
562
563 /// A task which launches abidiff on the binaries passed to the
564 /// constructor of the task.  The test also launches gnu diff on the
565 /// result of the abidiff to compare it against a reference abidiff
566 /// result.
567 struct test_task : public abigail::workers::task
568 {
569   InOutSpec spec;
570   bool is_ok;
571   string diff_cmd;
572   string error_message;
573
574   test_task(const InOutSpec& s)
575     : spec(s),
576       is_ok(true)
577   {}
578
579   /// This virtual function overload actually performs the job of the
580   /// task.
581   ///
582   /// It actually launches abidiff on the binaries passed to the
583   /// constructor of the task.  It also launches gnu diff on the
584   /// result of the abidiff to compare it against a reference abidiff
585   /// result.
586   virtual void
587   perform()
588   {
589     using abigail::tests::get_src_dir;
590     using abigail::tests::get_build_dir;
591     using abigail::tools_utils::ensure_parent_dir_created;
592     using abigail::tools_utils::abidiff_status;
593
594     string in_elfv0_path, in_elfv1_path,
595       abidiff_options, abidiff, cmd,
596       ref_diff_report_path, out_diff_report_path;
597
598     in_elfv0_path = string(get_src_dir()) + "/tests/" + spec.in_elfv0_path;
599     in_elfv1_path = string(get_src_dir()) + "/tests/" + spec.in_elfv1_path;
600     abidiff_options = spec.abidiff_options;
601     ref_diff_report_path =
602       string(get_src_dir()) + "/tests/" + spec.in_report_path;
603     out_diff_report_path =
604       string(get_build_dir()) + "/tests/" + spec.out_report_path;
605
606     if (!ensure_parent_dir_created(out_diff_report_path))
607       {
608         error_message = string("could not create parent directory for ")
609           + out_diff_report_path;
610         is_ok = false;
611         return;
612       }
613
614     abidiff = string(get_build_dir()) + "/tools/abidiff";
615     abidiff += " " + abidiff_options;
616
617     cmd = abidiff + " " + in_elfv0_path + " " + in_elfv1_path;
618     cmd += " > " + out_diff_report_path;
619
620     bool abidiff_ok = true;
621     int code = system(cmd.c_str());
622     if (!WIFEXITED(code))
623       abidiff_ok = false;
624     else
625       {
626         abidiff_status status =
627           static_cast<abidiff_status>(WEXITSTATUS(code));
628         if (abigail::tools_utils::abidiff_status_has_error(status))
629           abidiff_ok = false;
630       }
631
632     if (abidiff_ok)
633       {
634         cmd = "diff -u " + ref_diff_report_path
635           + " " + out_diff_report_path;
636
637         string cmd_no_out = cmd + " > /dev/null";
638         if (system(cmd_no_out.c_str()))
639           {
640             is_ok = false;
641             diff_cmd = cmd;
642           }
643       }
644     else
645       is_ok = false;
646   }
647 }; //end struct test_task.
648
649 /// A convenience typedef for shared
650 typedef shared_ptr<test_task> test_task_sptr;
651
652 int
653 main()
654 {
655   using std::vector;
656   using std::tr1::dynamic_pointer_cast;
657   using abigail::workers::queue;
658   using abigail::workers::task;
659   using abigail::workers::task_sptr;
660   using abigail::workers::get_number_of_threads;
661
662   /// Create a task queue.  The max number of worker threads of the
663   /// queue is the number of the concurrent threads supported by the
664   /// processor of the machine this code runs on.
665   const size_t num_tests = sizeof(in_out_specs) / sizeof (InOutSpec) - 1;
666   size_t num_workers = std::min(get_number_of_threads(), num_tests);
667   queue task_queue(num_workers);
668
669   bool is_ok = true;
670
671   for (InOutSpec* s = in_out_specs; s->in_elfv0_path; ++s)
672     {
673       test_task_sptr t(new test_task(*s));
674       ABG_ASSERT(task_queue.schedule_task(t));
675     }
676
677   /// Wait for all worker threads to finish their job, and wind down.
678   task_queue.wait_for_workers_to_complete();
679
680   // Now walk the results and print whatever error messages need to be
681   // printed.
682
683   const vector<task_sptr>& completed_tasks =
684     task_queue.get_completed_tasks();
685
686   ABG_ASSERT(completed_tasks.size() == num_tests);
687
688   for (vector<task_sptr>::const_iterator ti = completed_tasks.begin();
689        ti != completed_tasks.end();
690        ++ti)
691     {
692       test_task_sptr t = dynamic_pointer_cast<test_task>(*ti);
693       if (!t->is_ok)
694         {
695           is_ok = false;
696           if (!t->diff_cmd.empty())
697             system(t->diff_cmd.c_str());
698           if (!t->error_message.empty())
699             cerr << t->error_message << '\n';
700         }
701     }
702
703   return !is_ok;
704 }