• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2022 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file compare the ABI of an an elf binary and an abixml file.
9 
10 #include <sys/wait.h>
11 #include <string>
12 #include <fstream>
13 #include <iostream>
14 #include <cstdlib>
15 #include "abg-tools-utils.h"
16 #include "test-utils.h"
17 
18 
19 using std::string;
20 using std::ofstream;
21 using std::cerr;
22 using abigail::tests::get_build_dir;
23 using abigail::tests::emit_test_status_and_update_counters;
24 using abigail::tests::emit_test_summary;
25 
26 /// Specifies where a test should get its inputs from, and where it
27 /// should write its output to.
28 struct InOutSpec
29 {
30   const char* in_elf_path;
31   const char* in_abi_path;
32   const char* in_report_path;
33   const char* out_report_path;
34 };
35 
36 InOutSpec in_out_specs[] =
37 {
38   {
39     "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1",
40     "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi",
41     "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt",
42     "output/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt",
43   },
44   {
45     "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0",
46     "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi",
47     "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt",
48     "output/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt"
49   },
50   // This should be the last entry
51   {0, 0, 0, 0}
52 };
53 
54 int
main()55 main()
56 {
57   using abigail::tests::get_src_dir;
58   using abigail::tests::get_build_dir;
59   using abigail::tools_utils::ensure_parent_dir_created;
60   using abigail::tools_utils::abidiff_status;
61 
62   unsigned int total_count = 0, passed_count = 0, failed_count = 0;
63 
64   string in_elf_path, in_abi_path,
65     abidiff, cmd, diff_cmd, ref_diff_report_path, out_diff_report_path;
66 
67   for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
68     {
69       bool is_ok = true;
70       in_elf_path = string(get_src_dir()) + "/tests/" + s->in_elf_path;
71       in_abi_path = string(get_src_dir()) + "/tests/"+ s->in_abi_path;
72       ref_diff_report_path =
73 	string(get_src_dir()) + "/tests/" + s->in_report_path;
74       out_diff_report_path =
75 	string(get_build_dir()) + "/tests/" + s->out_report_path;
76 
77       if (!ensure_parent_dir_created(out_diff_report_path))
78 	{
79 	  cerr << "could not create parent directory for "
80 	       << out_diff_report_path;
81 	  is_ok = false;
82 	  continue;
83 	}
84 
85       abidiff = string(get_build_dir()) + "/tools/abidiff";
86       cmd = abidiff + " --no-default-suppression --no-architecture "
87 	+ in_elf_path + " " + in_abi_path;
88       cmd += " > " + out_diff_report_path;
89 
90       bool abidiff_ok = true;
91       int code = system(cmd.c_str());
92       if (!WIFEXITED(code))
93 	{
94 	  cerr << "test failed: '" << cmd << "'\n";
95 	  abidiff_ok = false;
96 	}
97       else
98 	{
99 	  abidiff_status status =
100 	    static_cast<abidiff_status>(WEXITSTATUS(code));
101 	  if (abigail::tools_utils::abidiff_status_has_error(status))
102 	    {
103 	      cerr << "test failed: '" << cmd << "'\n";
104 	      abidiff_ok = false;
105 	    }
106 	}
107       if (abidiff_ok)
108 	{
109 	  diff_cmd = "diff -u " + ref_diff_report_path
110 	    + " " + out_diff_report_path;
111 	  if (system(diff_cmd.c_str()))
112 	    is_ok = false;
113 	}
114       else
115 	is_ok = false;
116 
117       emit_test_status_and_update_counters(is_ok, cmd, passed_count,
118 					   failed_count, total_count);
119     }
120 
121   emit_test_summary(total_count, passed_count, failed_count);
122 
123   return failed_count;
124 }
125