]> sourceware.org Git - libabigail.git/commitdiff
tests: Add symtab test suite
authorMatthias Maennich <maennich@google.com>
Mon, 18 May 2020 11:50:13 +0000 (13:50 +0200)
committerDodji Seketeli <dodji@redhat.com>
Wed, 27 May 2020 09:00:51 +0000 (11:00 +0200)
Add (Catch based) test suite to test symbol table reading through the
result persisted in abigail::corpus.

The test cases are created through simple C source files targeting the
desired properties (having an undefined/export function or both). The
Makefile that comes with them recreates the test cases from the sources.

This covers reading sorted_(undefined_)var|fun_symbols as well as the
corresponding symbols maps accessible through the accessors of
abigail::corpus.

* tests/Makefile.am: add new test runtestsymtab
* tests/data/Makefile.am: add new test data for runtestsymtab
* tests/data/test-symtab/Makefile: Add this to build the binaries
below from their source code.
* tests/data/test-symtab/basic/empty.c: New test case source.
* tests/data/test-symtab/basic/link_against_me.c: Likewise.
* tests/data/test-symtab/basic/no_debug_info.c: Likewise.
* tests/data/test-symtab/basic/one_function_one_variable.c: Likewise.
* tests/data/test-symtab/basic/one_function_one_variable_undefined.c: Likewise.
* tests/data/test-symtab/basic/single_function.c: Likewise.
* tests/data/test-symtab/basic/single_undefined_function.c: Likewise.
* tests/data/test-symtab/basic/single_undefined_variable.c: Likewise.
* tests/data/test-symtab/basic/single_variable.c: Likewise.
* tests/data/test-symtab/basic/empty.so: New test data, built from
the Makefile above.
* tests/data/test-symtab/basic/link_against_me.so: Likewise.
* tests/data/test-symtab/basic/no_debug_info.so: Likewise.
* tests/data/test-symtab/basic/one_function_one_variable.so: Likewise.
* tests/data/test-symtab/basic/one_function_one_variable_undefined.so: Likewise.
* tests/data/test-symtab/basic/single_function.so: Likewise.
* tests/data/test-symtab/basic/single_undefined_function.so: Likewise.
* tests/data/test-symtab/basic/single_undefined_variable.so: Likewise.
* tests/data/test-symtab/basic/single_variable.so: Likewise.
* tests/test-symtab.cc: New test driver.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
22 files changed:
tests/Makefile.am
tests/data/Makefile.am
tests/data/test-symtab/basic/Makefile [new file with mode: 0644]
tests/data/test-symtab/basic/empty.c [new file with mode: 0644]
tests/data/test-symtab/basic/empty.so [new file with mode: 0755]
tests/data/test-symtab/basic/link_against_me.c [new file with mode: 0644]
tests/data/test-symtab/basic/link_against_me.so [new file with mode: 0755]
tests/data/test-symtab/basic/no_debug_info.c [new file with mode: 0644]
tests/data/test-symtab/basic/no_debug_info.so [new file with mode: 0755]
tests/data/test-symtab/basic/one_function_one_variable.c [new file with mode: 0644]
tests/data/test-symtab/basic/one_function_one_variable.so [new file with mode: 0755]
tests/data/test-symtab/basic/one_function_one_variable_undefined.c [new file with mode: 0644]
tests/data/test-symtab/basic/one_function_one_variable_undefined.so [new file with mode: 0755]
tests/data/test-symtab/basic/single_function.c [new file with mode: 0644]
tests/data/test-symtab/basic/single_function.so [new file with mode: 0755]
tests/data/test-symtab/basic/single_undefined_function.c [new file with mode: 0644]
tests/data/test-symtab/basic/single_undefined_function.so [new file with mode: 0755]
tests/data/test-symtab/basic/single_undefined_variable.c [new file with mode: 0644]
tests/data/test-symtab/basic/single_undefined_variable.so [new file with mode: 0755]
tests/data/test-symtab/basic/single_variable.c [new file with mode: 0644]
tests/data/test-symtab/basic/single_variable.so [new file with mode: 0755]
tests/test-symtab.cc [new file with mode: 0644]

index 2d8ab9e794a489e7f07f1740e29c41c4fb3b48e9..c2d4d1dc5d358c0f052be6e434ff501f753873db 100644 (file)
@@ -49,6 +49,7 @@ runtestini                    \
 runtestkmiwhitelist            \
 runtestlookupsyms              \
 runtestreadwrite               \
+runtestsymtab                  \
 runtesttoolsutils              \
 $(FEDABIPKGDIFF_TEST)          \
 $(ZIP_ARCHIVE_TESTS)           \
@@ -154,6 +155,9 @@ runtestelfhelpers_LDADD = libcatch.la $(top_builddir)/src/libabigail.la
 runtestcxxcompat_SOURCES = test-cxx-compat.cc
 runtestcxxcompat_LDADD = libcatch.la $(top_builddir)/src/libabigail.la
 
+runtestsymtab_SOURCES = test-symtab.cc
+runtestsymtab_LDADD = libtestutils.la libcatch.la $(top_builddir)/src/libabigail.la
+
 runtestsvg_SOURCES=test-svg.cc
 runtestsvg_LDADD=$(top_builddir)/src/libabigail.la
 
index f5b551b9724ad66debd9ad5f7f0dbedf7361781d..f454b8586bf4e09bcef5a65ec5dbba78781c1c38 100644 (file)
@@ -1748,4 +1748,24 @@ test-ini/test01-equal-in-property-string.abignore \
 test-kmi-whitelist/whitelist-with-single-entry \
 test-kmi-whitelist/whitelist-with-another-single-entry \
 test-kmi-whitelist/whitelist-with-duplicate-entry \
-test-kmi-whitelist/whitelist-with-two-sections
+test-kmi-whitelist/whitelist-with-two-sections \
+\
+test-symtab/basic/Makefile \
+test-symtab/basic/empty.c \
+test-symtab/basic/empty.so \
+test-symtab/basic/link_against_me.c \
+test-symtab/basic/link_against_me.so \
+test-symtab/basic/no_debug_info.c \
+test-symtab/basic/no_debug_info.so \
+test-symtab/basic/one_function_one_variable.c \
+test-symtab/basic/one_function_one_variable.so \
+test-symtab/basic/one_function_one_variable_undefined.c \
+test-symtab/basic/one_function_one_variable_undefined.so \
+test-symtab/basic/single_function.c \
+test-symtab/basic/single_function.so \
+test-symtab/basic/single_undefined_function.c \
+test-symtab/basic/single_undefined_function.so \
+test-symtab/basic/single_undefined_variable.c \
+test-symtab/basic/single_undefined_variable.so \
+test-symtab/basic/single_variable.c \
+test-symtab/basic/single_variable.so
diff --git a/tests/data/test-symtab/basic/Makefile b/tests/data/test-symtab/basic/Makefile
new file mode 100644 (file)
index 0000000..c84d128
--- /dev/null
@@ -0,0 +1,19 @@
+srcs = $(wildcard *.c)
+libs = $(srcs:.c=.so)
+
+flags = -fPIC
+
+all:   $(libs)
+
+clean:
+       rm $(libs)
+
+no_debug_info.so: no_debug_info.c Makefile
+       $(CC) $< -shared $(flags) -o $@
+
+link_against_me.so: link_against_me.c
+       $(CC) $< -shared $(flags) -o $@
+
+%.so: %.c Makefile link_against_me.so
+       $(CC) $< -shared $(flags) -g -o $@ link_against_me.so
+
diff --git a/tests/data/test-symtab/basic/empty.c b/tests/data/test-symtab/basic/empty.c
new file mode 100644 (file)
index 0000000..5bb380b
--- /dev/null
@@ -0,0 +1 @@
+// empty!
diff --git a/tests/data/test-symtab/basic/empty.so b/tests/data/test-symtab/basic/empty.so
new file mode 100755 (executable)
index 0000000..28a5474
Binary files /dev/null and b/tests/data/test-symtab/basic/empty.so differ
diff --git a/tests/data/test-symtab/basic/link_against_me.c b/tests/data/test-symtab/basic/link_against_me.c
new file mode 100644 (file)
index 0000000..42d6a46
--- /dev/null
@@ -0,0 +1,2 @@
+int undefined_variable =1;
+void undefined_function() { }
diff --git a/tests/data/test-symtab/basic/link_against_me.so b/tests/data/test-symtab/basic/link_against_me.so
new file mode 100755 (executable)
index 0000000..33c8b5d
Binary files /dev/null and b/tests/data/test-symtab/basic/link_against_me.so differ
diff --git a/tests/data/test-symtab/basic/no_debug_info.c b/tests/data/test-symtab/basic/no_debug_info.c
new file mode 100644 (file)
index 0000000..5bb380b
--- /dev/null
@@ -0,0 +1 @@
+// empty!
diff --git a/tests/data/test-symtab/basic/no_debug_info.so b/tests/data/test-symtab/basic/no_debug_info.so
new file mode 100755 (executable)
index 0000000..827c1ee
Binary files /dev/null and b/tests/data/test-symtab/basic/no_debug_info.so differ
diff --git a/tests/data/test-symtab/basic/one_function_one_variable.c b/tests/data/test-symtab/basic/one_function_one_variable.c
new file mode 100644 (file)
index 0000000..f31122a
--- /dev/null
@@ -0,0 +1,3 @@
+void exported_function(){}
+
+int exported_variable;
diff --git a/tests/data/test-symtab/basic/one_function_one_variable.so b/tests/data/test-symtab/basic/one_function_one_variable.so
new file mode 100755 (executable)
index 0000000..51d918c
Binary files /dev/null and b/tests/data/test-symtab/basic/one_function_one_variable.so differ
diff --git a/tests/data/test-symtab/basic/one_function_one_variable_undefined.c b/tests/data/test-symtab/basic/one_function_one_variable_undefined.c
new file mode 100644 (file)
index 0000000..53ff5d8
--- /dev/null
@@ -0,0 +1,7 @@
+extern int undefined_variable;
+void undefined_function(int);
+
+
+static void local_function(){
+       undefined_function(undefined_variable);
+}
diff --git a/tests/data/test-symtab/basic/one_function_one_variable_undefined.so b/tests/data/test-symtab/basic/one_function_one_variable_undefined.so
new file mode 100755 (executable)
index 0000000..fc2356c
Binary files /dev/null and b/tests/data/test-symtab/basic/one_function_one_variable_undefined.so differ
diff --git a/tests/data/test-symtab/basic/single_function.c b/tests/data/test-symtab/basic/single_function.c
new file mode 100644 (file)
index 0000000..8ac0901
--- /dev/null
@@ -0,0 +1 @@
+void exported_function(){}
diff --git a/tests/data/test-symtab/basic/single_function.so b/tests/data/test-symtab/basic/single_function.so
new file mode 100755 (executable)
index 0000000..9b7e45d
Binary files /dev/null and b/tests/data/test-symtab/basic/single_function.so differ
diff --git a/tests/data/test-symtab/basic/single_undefined_function.c b/tests/data/test-symtab/basic/single_undefined_function.c
new file mode 100644 (file)
index 0000000..484d6a5
--- /dev/null
@@ -0,0 +1,5 @@
+void undefined_function();
+
+static void local_function() {
+  undefined_function();
+}
diff --git a/tests/data/test-symtab/basic/single_undefined_function.so b/tests/data/test-symtab/basic/single_undefined_function.so
new file mode 100755 (executable)
index 0000000..96d19e3
Binary files /dev/null and b/tests/data/test-symtab/basic/single_undefined_function.so differ
diff --git a/tests/data/test-symtab/basic/single_undefined_variable.c b/tests/data/test-symtab/basic/single_undefined_variable.c
new file mode 100644 (file)
index 0000000..b0602c2
--- /dev/null
@@ -0,0 +1,7 @@
+extern int undefined_variable;
+
+static void other_local_function(int variable) { (void)variable; }
+
+static void local_function(){
+       other_local_function(undefined_variable);
+}
diff --git a/tests/data/test-symtab/basic/single_undefined_variable.so b/tests/data/test-symtab/basic/single_undefined_variable.so
new file mode 100755 (executable)
index 0000000..7188667
Binary files /dev/null and b/tests/data/test-symtab/basic/single_undefined_variable.so differ
diff --git a/tests/data/test-symtab/basic/single_variable.c b/tests/data/test-symtab/basic/single_variable.c
new file mode 100644 (file)
index 0000000..620e156
--- /dev/null
@@ -0,0 +1 @@
+int exported_variable;
diff --git a/tests/data/test-symtab/basic/single_variable.so b/tests/data/test-symtab/basic/single_variable.so
new file mode 100755 (executable)
index 0000000..6ba3f43
Binary files /dev/null and b/tests/data/test-symtab/basic/single_variable.so differ
diff --git a/tests/test-symtab.cc b/tests/test-symtab.cc
new file mode 100644 (file)
index 0000000..62f8998
--- /dev/null
@@ -0,0 +1,205 @@
+// -*- 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 2, 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 symtab invariants through abg-corpus.
+
+#include <iostream>
+#include <limits>
+#include <vector>
+
+#include "abg-corpus.h"
+#include "abg-dwarf-reader.h"
+#include "abg-ir.h"
+#include "lib/catch.hpp"
+#include "test-utils.h"
+
+using namespace abigail;
+
+using dwarf_reader::create_read_context;
+using dwarf_reader::read_context_sptr;
+using dwarf_reader::read_corpus_from_elf;
+using ir::environment;
+using ir::environment_sptr;
+
+static const std::string test_data_dir =
+    std::string(abigail::tests::get_src_dir()) + "/tests/data/test-symtab/";
+
+dwarf_reader::status
+read_corpus(const std::string path, corpus_sptr& result)
+{
+  const std::string& absolute_path = test_data_dir + path;
+
+  environment_sptr         env(new environment);
+  const std::vector<char**> debug_info_root_paths;
+  read_context_sptr        ctxt =
+      create_read_context(absolute_path, debug_info_root_paths, env.get());
+
+  dwarf_reader::status status = dwarf_reader::STATUS_UNKNOWN;
+  result = read_corpus_from_elf(*ctxt, status);
+
+  REQUIRE(status != dwarf_reader::STATUS_UNKNOWN);
+  return status;
+}
+
+TEST_CASE("Symtab::Empty", "[symtab, basic]")
+{
+  const std::string         binary = "basic/empty.so";
+  corpus_sptr               corpus_ptr;
+  const dwarf_reader::status status = read_corpus(binary, corpus_ptr);
+  REQUIRE(corpus_ptr);
+
+  REQUIRE((status & dwarf_reader::STATUS_OK));
+
+  // TODO: Those two assertions are currently not met. Empty symtabs are
+  //       currently treated like the error case.
+  // REQUIRE((status & dwarf_reader::STATUS_OK));
+  // REQUIRE((status & dwarf_reader::STATUS_NO_SYMBOLS_FOUND));
+}
+
+TEST_CASE("Symtab::NoDebugInfo", "[symtab, basic]")
+{
+  const std::string         binary = "basic/no_debug_info.so";
+  corpus_sptr               corpus_ptr;
+  const dwarf_reader::status status = read_corpus(binary, corpus_ptr);
+  REQUIRE(corpus_ptr);
+
+  REQUIRE(status
+         == (dwarf_reader::STATUS_OK
+             | dwarf_reader::STATUS_DEBUG_INFO_NOT_FOUND));
+}
+
+// this value indicates in the following helper method, that we do not want to
+// assert for this particular value. In other words, N is a placeholder for an
+// arbitrary value.
+#define N std::numeric_limits<size_t>::max()
+
+corpus_sptr
+assert_symbol_count(const std::string& path,
+                   size_t             function_symbols = 0,
+                   size_t             variable_symbols = 0,
+                   size_t             undefined_function_symbols = 0,
+                   size_t             undefined_variable_symbols = 0)
+{
+  corpus_sptr               corpus_ptr;
+  const dwarf_reader::status status = read_corpus(path, corpus_ptr);
+  REQUIRE(corpus_ptr);
+
+  REQUIRE(status == dwarf_reader::STATUS_OK);
+  const corpus& corpus = *corpus_ptr;
+
+  if (function_symbols != N)
+    {
+      CHECK(corpus.get_sorted_fun_symbols().size() == function_symbols);
+      CHECK(corpus.get_fun_symbol_map().size() == function_symbols);
+      CHECK(corpus.get_fun_symbol_map_sptr()->size() == function_symbols);
+    }
+  if (variable_symbols != N)
+    {
+      CHECK(corpus.get_sorted_var_symbols().size() == variable_symbols);
+      CHECK(corpus.get_var_symbol_map().size() == variable_symbols);
+      CHECK(corpus.get_var_symbol_map_sptr()->size() == variable_symbols);
+    }
+  if (undefined_variable_symbols != N)
+    {
+      CHECK(corpus.get_sorted_undefined_fun_symbols().size()
+           == undefined_function_symbols);
+      CHECK(corpus.get_undefined_fun_symbol_map().size()
+           == undefined_function_symbols);
+      CHECK(corpus.get_undefined_fun_symbol_map_sptr()->size()
+           == undefined_function_symbols);
+    }
+  if (undefined_function_symbols != N)
+    {
+      CHECK(corpus.get_sorted_undefined_var_symbols().size()
+           == undefined_variable_symbols);
+      CHECK(corpus.get_undefined_var_symbol_map().size()
+           == undefined_variable_symbols);
+      CHECK(corpus.get_undefined_var_symbol_map_sptr()->size()
+           == undefined_variable_symbols);
+    }
+
+  return corpus_ptr;
+}
+
+TEST_CASE("Symtab::SimpleSymtabs", "[symtab, basic]")
+{
+  GIVEN("a binary with no exported symbols")
+  {
+    // TODO: should pass, but does currently not as empty tables are treated
+    //       like the error case, but this is an edge case anyway.
+    // assert_symbol_count("empty.so");
+  }
+
+  GIVEN("a binary with a single exported function")
+  {
+    const std::string     binary = "basic/single_function.so";
+    const corpus_sptr&    corpus = assert_symbol_count(binary, 1, 0);
+    const elf_symbol_sptr& symbol =
+       corpus->lookup_function_symbol("exported_function");
+    REQUIRE(symbol);
+    CHECK(!corpus->lookup_variable_symbol("exported_function"));
+    CHECK(symbol == corpus->lookup_function_symbol(*symbol));
+    CHECK(symbol != corpus->lookup_variable_symbol(*symbol));
+  }
+
+  GIVEN("a binary with a single exported variable")
+  {
+    const std::string     binary = "basic/single_variable.so";
+    const corpus_sptr&    corpus = assert_symbol_count(binary, 0, 1);
+    const elf_symbol_sptr& symbol =
+       corpus->lookup_variable_symbol("exported_variable");
+    REQUIRE(symbol);
+    CHECK(!corpus->lookup_function_symbol("exported_variable"));
+    CHECK(symbol == corpus->lookup_variable_symbol(*symbol));
+    CHECK(symbol != corpus->lookup_function_symbol(*symbol));
+  }
+
+  GIVEN("a binary with one function and one variable exported")
+  {
+    const std::string  binary = "basic/one_function_one_variable.so";
+    const corpus_sptr& corpus = assert_symbol_count(binary, 1, 1);
+    CHECK(corpus->lookup_function_symbol("exported_function"));
+    CHECK(!corpus->lookup_variable_symbol("exported_function"));
+    CHECK(corpus->lookup_variable_symbol("exported_variable"));
+    CHECK(!corpus->lookup_function_symbol("exported_variable"));
+  }
+
+  GIVEN("a binary with a single undefined function")
+  {
+    const std::string  binary = "basic/single_undefined_function.so";
+    const corpus_sptr& corpus = assert_symbol_count(binary, 0, 0, 1, 0);
+  }
+
+  GIVEN("a binary with a single undefined variable")
+  {
+    const std::string  binary = "basic/single_undefined_variable.so";
+    const corpus_sptr& corpus = assert_symbol_count(binary, 0, 0, 0, 1);
+  }
+
+  GIVEN("a binary with one function and one variable undefined")
+  {
+    const std::string  binary = "basic/one_function_one_variable_undefined.so";
+    const corpus_sptr& corpus = assert_symbol_count(binary, 0, 0, 1, 1);
+  }
+}
This page took 0.048836 seconds and 5 git commands to generate.