libabigail/tests/test-kmi-whitelist.cc
Matthias Maennich 4ecde9a800 KMI Whitelists: Add functionality to make whitelists additive
If multiple KMI whitelists are specified, either by passing
--kmi-whitelist several times or by having multiple whitelist sections
in the whitelist files, the generated suppressions are created as an
intersection of symbols. That is rather unusual, as whitelisting should
rather work additive. That means that the symbols (or expressions
thereof) defined across several sections or files shall be considered a
union of symbols. This patch combines the whitelist parsing to create
exactly one function_suppression and one variable suppression. A test
case has been added to ensure the functionality is working.

Please note, migrating the existing code to this new functionality is
done in a separate commit.

	* include/abg-tools-utils.h
	(gen_suppr_spec_from_kernel_abi_whitelists): New function.
	* src/abg-tools-utils.cc
	(gen_suppr_spec_from_kernel_abi_whitelists): Likewise.
	* tests/.gitignore: Ignore new test executable.
	* tests/Makefile.am: Add new test executable.
	* tests/data/test-kmi-whitelist/whitelist-with-another-single-entry:
	New test input file.
	* tests/data/test-kmi-whitelist/whitelist-with-duplicate-entry:
	Likewise.
	* tests/data/test-kmi-whitelist/whitelist-with-single-entry:
	Likewise.
	* tests/data/test-kmi-whitelist/whitelist-with-two-sections:
	Likewise.
	* tests/data/Makefile.am: Add above test material.
	* tests/test-kmi-whitelist.cc: Add new test executable.

Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-21 18:37:43 +00:00

163 lines
5.2 KiB
C++

// -*- Mode: C++ -*-
//
// Copyright (C) 2020 Google, 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: Matthias Maennich
/// @file
///
/// This program tests suppression generation from KMI whitelists.
#include <string>
#include "abg-fwd.h"
#include "abg-suppression.h"
#include "abg-tools-utils.h"
#include "test-utils.h"
using abigail::tools_utils::gen_suppr_spec_from_kernel_abi_whitelists;
using abigail::suppr::suppression_sptr;
using abigail::suppr::suppressions_type;
using abigail::suppr::function_suppression_sptr;
using abigail::suppr::variable_suppression_sptr;
using abigail::suppr::is_function_suppression;
using abigail::suppr::is_variable_suppression;
const static std::string whitelist_with_single_entry
= std::string(abigail::tests::get_src_dir())
+ "/tests/data/test-kmi-whitelist/whitelist-with-single-entry";
const static std::string whitelist_with_another_single_entry
= std::string(abigail::tests::get_src_dir())
+ "/tests/data/test-kmi-whitelist/whitelist-with-another-single-entry";
const static std::string whitelist_with_two_sections
= std::string(abigail::tests::get_src_dir())
+ "/tests/data/test-kmi-whitelist/whitelist-with-two-sections";
const static std::string whitelist_with_duplicate_entry
= std::string(abigail::tests::get_src_dir())
+ "/tests/data/test-kmi-whitelist/whitelist-with-duplicate-entry";
bool
suppressions_are_consistent(const suppressions_type& suppr,
const std::string& expr)
{
if (suppr.size() != 2)
return false;
function_suppression_sptr left = is_function_suppression(suppr[0]);
variable_suppression_sptr right = is_variable_suppression(suppr[1]);
return // correctly casted
(left && right)
// same label
&& (left->get_label() == right->get_label())
// same mode
&& (left->get_drops_artifact_from_ir()
== right->get_drops_artifact_from_ir())
// same regex
&& (left->get_symbol_name_not_regex_str()
== right->get_symbol_name_not_regex_str())
// regex as expected
&& (left->get_symbol_name_not_regex_str() == expr);
}
bool
testNoWhitelist()
{
const std::vector<std::string> abi_whitelist_paths;
suppressions_type suppr
= gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
return suppr.empty();
}
bool
testSingleEntryWhitelist()
{
std::vector<std::string> abi_whitelist_paths;
abi_whitelist_paths.push_back(whitelist_with_single_entry);
suppressions_type suppr
= gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
return !suppr.empty() && suppressions_are_consistent(suppr, "^test_symbol$");
}
bool
testWhitelistWithDuplicateEntries()
{
std::vector<std::string> abi_whitelist_paths;
abi_whitelist_paths.push_back(whitelist_with_duplicate_entry);
suppressions_type suppr
= gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
return !suppr.empty() && suppressions_are_consistent(suppr, "^test_symbol$");
}
bool
testTwoWhitelists()
{
std::vector<std::string> abi_whitelist_paths;
abi_whitelist_paths.push_back(whitelist_with_single_entry);
abi_whitelist_paths.push_back(whitelist_with_another_single_entry);
suppressions_type suppr
= gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
return !suppr.empty()
&& suppressions_are_consistent(suppr,
"^test_another_symbol$|^test_symbol$");
}
bool
testTwoWhitelistsWithDuplicates()
{
std::vector<std::string> abi_whitelist_paths;
abi_whitelist_paths.push_back(whitelist_with_duplicate_entry);
abi_whitelist_paths.push_back(whitelist_with_another_single_entry);
suppressions_type suppr
= gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
return !suppr.empty()
&& suppressions_are_consistent(suppr,
"^test_another_symbol$|^test_symbol$");
}
bool
testWhitelistWithTwoSections()
{
std::vector<std::string> abi_whitelist_paths;
abi_whitelist_paths.push_back(whitelist_with_two_sections);
suppressions_type suppr
= gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
return !suppr.empty()
&& suppressions_are_consistent(suppr,
"^test_symbol1$|^test_symbol2$");
}
int
main(int, char*[])
{
bool is_ok = true;
is_ok = is_ok && testNoWhitelist();
is_ok = is_ok && testSingleEntryWhitelist();
is_ok = is_ok && testWhitelistWithDuplicateEntries();
is_ok = is_ok && testTwoWhitelists();
is_ok = is_ok && testTwoWhitelistsWithDuplicates();
is_ok = is_ok && testWhitelistWithTwoSections();
return !is_ok;
}