libabigail/tests/test-abidiff-exit.cc
Dodji Seketeli b36ca1501e Bug 20180 - Support system-wide suppression specifications
This patch adds support for loading system and user level suppression
specifications for libabigail tools.

At launch time, relevant libabigail tools (abidiff, abipkgdiff
fedabipkgdiff for now) read the default system suppression
specification file, if it's present, from a file which path is the
value of the environment variable
LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE, if set, or from the file
$libdir/libabigail/default.abignore.

Then it reads the user system suppression specification file, if it's
present, from a file which path is the value of the environment
variable LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE, if set, or from the
file $HOME/.abignore.

The content of the user system suppression file is merged with the
content of default system suppression file.

That content is also merged with the content of the suppression
specification files that might be provided by the --suppressions
command line option of the invoked tools.

The resulting set of all these suppression specifications is thus used
to filter the ABI change reports that are emitted.

abidiff, abipkgdiff and abipkgdiff gain a --no-default-suppression
option to avoid loading any of these default suppression specification
files.

The patch also installs a default.abignore file into $(pkglibdir).
Note that on x86_64, that directory is /usr/lib64/libabigail.  Now we
just need to think about the content of that default.abignore file.

	* doc/manuals/abidiff.rst: Document the default suppression
	scheme, its interaction with the --supprs option and the new
	--no-default option.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* doc/manuals/fedabipkgdiff.rst: Likewise.
	* configure.ac: Generate the tests/runtestdefaultsupprs.py file
	from the new tests/runtestdefaultsupprs.py.in template.
	* default.abignore: New file.
	* Makefile.am: Add it to source distribution.
	* src/Makefile.am: Define the ABIGAIL_ROOT_SYSTEM_LIBDIR
	preprocessor macro that is set the value of the $libdir autotools
	macro.
	* include/abg-tools-utils.h: Update copyright years.
	(get_system_libdir, get_default_system_suppression_file_path)
	(get_default_user_suppression_file_path)
	(load_default_system_suppressions)
	(load_default_user_suppressions): Declare new functions
	* src/abg-tools-utils.cc (get_system_libdir)
	(get_default_system_suppression_file_path)
	(get_default_user_suppression_file_path)
	(load_default_system_suppressions)
	(load_default_user_suppressions): Define new functions.
	(is_regular_file): Amend this so that it return true for symlinks
	to regular files too.
	(is_dir): Amend this so that it returns true for symlinks to
	directories too.
	* tools/abidiff.cc (options::no_default_supprs): New data member.
	(options::options): Initialize the new data member.
	(display_usage): Display a new help string for the new
	--no-default-suppression command line option.
	(parse_command_line): Parse this new command line option.
	(set_diff_context_from_opts): Load the default suppression
	specifications, unless --no-default-suppression or --supprs was
	provided.
	* tools/abipkgdiff.cc (options::no_default_supprs): New data
	member.
	(options::options): Initialize the new data member.
	(parse_command_line): Parse the new --no-default-suppression
	command line option.
	(main): Load the default suppression specifications, unless
	--no-default-suppression or --supprs was provided.
	* tools/fedabipkgdiff (abipkgdiff): Add --no-default-suppression
	to the invocation of abipkgdiff if it was provided on the command
	line.
	(build_commandline_args_parser): Parse the new
	--no-default-suppression command line option.
	* tests/runtestdefaultsupprs.py.in: New test harness template.
	* tests/Makefile.am: Add the new runtestdefaultsupprs.py to the
	set of tests.
	* tests/data/test-default-supprs/test0-type-suppr-0.suppr: New
	test input.
	* tests/data/test-default-supprs/test0-type-suppr-report-0.txt: Likewise.
	* tests/data/test-default-supprs/test0-type-suppr-v0.o: Likewise.
	* tests/data/test-default-supprs/test0-type-suppr-v1.o: Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir-report-0.txt:
	Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir1: Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir2: Likewise.
	* tests/data/Makefile.am: Add new the new tests input above to
	Makefile.am.
	* tests/runtestcanonicalizetypes.sh.in: Pass
	--no-default-suppression to abidiff invocations.
	* tests/runtestdefaultsupprs.py.in: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tools/abidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-30 18:39:49 +02:00

179 lines
5.5 KiB
C++

// -*- Mode: C++ -*-
//
// Copyright (C) 2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
// free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3, or (at your option) any
// later version.
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
// Author: Dodji Seketeli
/// @file
///
/// This program runs abidiff between input files and checks that
/// the exit code of the abidiff is the one we expect.
///
/// The set of input files and reference reports to consider should be
/// present in the source distribution.
/// This is an aggregate that specifies where a test shall get its
/// input from and where it shall write its ouput to.
#include <sys/wait.h>
#include <cstring>
#include <string>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include "abg-tools-utils.h"
#include "test-utils.h"
using abigail::tools_utils::abidiff_status;
struct InOutSpec
{
const char* in_elfv0_path;
const char* in_elfv1_path;
const char* in_suppr_path;
const char* abidiff_options;
abidiff_status status;
const char* in_report_path;
const char* out_report_path;
};// end struct InOutSpec;
InOutSpec in_out_specs[] =
{
{
"data/test-abidiff-exit/test1-voffset-change-v0.o",
"data/test-abidiff-exit/test1-voffset-change-v1.o",
"",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
"data/test-abidiff-exit/test1-voffset-change-report0.txt",
"output/test-abidiff-exit/test1-voffset-change-report0.txt"
},
{
"data/test-abidiff-exit/test1-voffset-change-v0.o",
"data/test-abidiff-exit/test1-voffset-change-v1.o",
"data/test-abidiff-exit/test1-voffset-change.abignore",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test1-voffset-change-report1.txt",
"output/test-abidiff-exit/test1-voffset-change-report1.txt"
},
{
"data/test-abidiff-exit/test2-filtered-removed-fns-v0.o",
"data/test-abidiff-exit/test2-filtered-removed-fns-v1.o",
"",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
"data/test-abidiff-exit/test2-filtered-removed-fns-report0.txt",
"output/test-abidiff-exit/test2-filtered-removed-fns-report0.txt"
},
{
"data/test-abidiff-exit/test2-filtered-removed-fns-v0.o",
"data/test-abidiff-exit/test2-filtered-removed-fns-v1.o",
"data/test-abidiff-exit/test2-filtered-removed-fns.abignore",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test2-filtered-removed-fns-report1.txt",
"output/test-abidiff-exit/test2-filtered-removed-fns-report1.txt"
},
{0, 0, 0 ,0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
};
int
main()
{
using std::string;
using std::cerr;
using abigail::tests::get_src_dir;
using abigail::tests::get_build_dir;
using abigail::tools_utils::ensure_parent_dir_created;
using abigail::tools_utils::abidiff_status;
bool is_ok = true;
string in_elfv0_path, in_elfv1_path,
in_suppression_path, abidiff_options, abidiff, cmd,
ref_diff_report_path, out_diff_report_path;
for (InOutSpec* s = in_out_specs; s->in_elfv0_path; ++s)
{
in_elfv0_path = string(get_src_dir()) + "/tests/" + s->in_elfv0_path;
in_elfv1_path = string(get_src_dir()) + "/tests/" + s->in_elfv1_path;
if (s->in_suppr_path && strcmp(s->in_suppr_path, ""))
in_suppression_path =
string(get_src_dir()) + "/tests/" + s->in_suppr_path;
else
in_suppression_path.clear();
abidiff_options = s->abidiff_options;
ref_diff_report_path =
string(get_src_dir()) + "/tests/" + s->in_report_path;
out_diff_report_path =
string(get_build_dir()) + "/tests/" + s->out_report_path;
if (!ensure_parent_dir_created(out_diff_report_path))
{
cerr << "could not create parent directory for "
<< out_diff_report_path;
is_ok = false;
continue;
}
abidiff = string(get_build_dir()) + "/tools/abidiff";
if (!abidiff_options.empty())
abidiff += " " + abidiff_options;
if (!in_suppression_path.empty())
abidiff += " --suppressions " + in_suppression_path;
cmd = abidiff + " " + in_elfv0_path + " " + in_elfv1_path;
cmd += " > " + out_diff_report_path;
bool abidiff_ok = true;
int code = system(cmd.c_str());
if (!WIFEXITED(code))
abidiff_ok = false;
else
{
abigail::tools_utils::abidiff_status status =
static_cast<abidiff_status>(WEXITSTATUS(code));
if (status != s->status)
{
cerr << "for command '"
<< cmd
<< "', expected abidiff status to be " << s->status
<< " but instead, got " << status << "\n";
abidiff_ok = false;
}
}
if (abidiff_ok)
{
cmd = "diff -u " + ref_diff_report_path
+ " " + out_diff_report_path;
if (system(cmd.c_str()))
is_ok = false;
}
else
is_ok = false;
}
return !is_ok;
}