libabigail/tests/test-core-diff.cc

194 lines
4.8 KiB
C++
Raw Normal View History

// -*- Mode: C++ -*-
Use worker threads pattern to speed up some tests We are going to need to speed up more and more tests, and coding directly with libpthread for that can be tedious and bug-prone. So I devised an implementation for the worker threads design pattern instead, and used it to speed up some tests. * include/Makefile.am: Add the new abg-workers.h to source distribution. * include/abg-workers.h: New file. * src/Makefile.am: Add the new abg-worker.cc to source distribution. * src/abg-workers.cc: New file. * tests/test-utils.cc: Update copyright. Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. Make that const char reside in thread local storage, so that two concurrent threads can safely call these functions in parallel, without any race. * tests/test-utils.h: Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. * tests/test-abicompat.cc: Update copyright. Adjust for get_src_dir() and get_build_dir() change. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-types-stability.cc: Likewise. Use the new task queue type to run these tests in parallel. * tests/test-diff-filter.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-15 12:34:16 +00:00
// Copyright (C) 2013-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
#include <string>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include "abg-tools-utils.h"
#include "abg-diff-utils.h"
#include "test-utils.h"
using std::string;
using std::ofstream;
using std::cerr;
/// This structure describes the set of strings we want to diff
/// against each other as well as the reports we expect from these
/// diffs.
struct SESInOutSpec
{
// This is the path to the report we expect from the diff algorithm
// applied to second_string (below) diffed against first_string.
const char* in_path;
// This is the path where to store the report of the diff algorithm
// applied to second_string (below) diffed against first_string.
const char* out_path;
// This is the first string to feed the diff algorithm with.
const char* first_string;
// This is the second string to feed the diff algorithm with.
const char* second_string;
};// end struct SESInOutSpec
SESInOutSpec in_out_specs[] =
{
{
"data/test-core-diff/report0.txt",
"output/test-core-diff/report0.txt",
"abcabba",
"cbabac"
},
{
"data/test-core-diff/report1.txt",
"output/test-core-diff/report1.txt",
"xxabxx",
"xbx"
},
{
"data/test-core-diff/report2.txt",
"output/test-core-diff/report2.txt",
"xxabxx",
"xbcx"
},
{
"data/test-core-diff/report3.txt",
"output/test-core-diff/report3.txt",
"abc",
"abdecfgc"
},
{
"data/test-core-diff/report4.txt",
"output/test-core-diff/report4.txt",
"xxx",
"xxx"
},
{
"data/test-core-diff/report5.txt",
"output/test-core-diff/report5.txt",
"xabx",
"xbx"
},
{
"data/test-core-diff/report6.txt",
"output/test-core-diff/report6.txt",
"fou",
"fubar"
},
{
"data/test-core-diff/report7.txt",
"output/test-core-diff/report7.txt",
"sqkdjfjdsql",
"sqdmlkjfmljdsqf"
},
Re-write middle snakes management in core diff algorithms * include/abg-diff-utils.h (point::set): New overload.. (point::{add, operator<, operator>, operator<=, operator>=}): New methods. (point::operator!=): Constify. (point::operator==): Constify. Cleanup. (point::operator=): Keep emptiness. (class snake): New class definition (d_path_vec::{over_bounds, offset}): New methods. (d_path_vec::check_index_against_bound): Don't take a bound parameter anymore. Use the new over_bound method above. Fix up error reporting. (d_path_vec::d_path_vec): Fix d_path_vec size allocation. (d_path_vec::operator[]): Use the d_path_vec::at method to check all accesses against the bounds. This is slower, but at least we can expect to have something that is more robust. We can remove the bound checking later when we are sure the code has been tested enough. Also use the new offset() method. (d_path_vec::at): Take long long. (ends_of_furthest_d_paths_overlap): Constify input parameters. (end_of_fr_d_path_in_k, end_of_frr_d_path_in_k_plus_delta): Take an instance of the new snake in parameter, rather than a bare end point that wasn't carrying enough information about the snake. Record the snake which consists of up to four points: a begin point, an intermediate point, a diagonal start point and an end point. Return that snake upon successful completion. (compute_middle_snake): Take an instance of snake, rather than the two points that were supposed to represent a snake and with which we were loosing information before. Revisit/simplify the logic of this function; this literally goes forward or in reverse, gets the resulting snake returned by the end_of_fr_d_path_in_k and end_of_frr_d_path_in_k_plus_delta functions, detect if these snakes overlap and just return the current snake. Much simpler. The caller now gets a snake, which has much more information than the previous snake approximation made of just two points. Bonus point, this follows almost to the word, what the paper says. (maybe_record_match_point, find_snake_start_point): Remove these as there are not used by compute_middle_snake anymore. (print_snake, ses_len): Update these to take/handle a snake. (snake_end_points): New declaration. (compute_diff): When we are getting an empty first sequence, this means that we are inserting the second sequence *before* the beginning of the first sequence; keep this information by setting the insertion point index to -1, rather than zero. Update this to get/handle snakes, rather than free points vaguely representing snakes. Now that compute_middle_snake returns real snakes, handle the information we are getting. Basically for edit scripts of length equal to 1, as the snake carries all the necessary information about the non-diagonal edge (as well as the diagonal edges), we (can) now precisely update the current edit script (as well as the longest common sub-sequence). For edit scripts of length greater than 1, better at which points to divide the problem and consequently, at which points to conquer it back -- better following The Paper to the letter. (display_edit_script): Update this for the use of instances of snake. * src/abg-diff-utils.cc (ends_of_furthest_d_paths_overlap): Update for constification of inputs. (snake_end_points): Define new function. (compute_middle_snake): Adapt for the taking an instance of snake. * tests/test-diff2.cc (main): Update for using instances of snake. * tests/test-core-diff.cc: Add new tests. * tests/data/test-core-diff/report0.txt: Update for output adaptation. * tests/data/test-core-diff/report6.txt: Likewise. * tests/data/test-core-diff/report7.txt: Likewise. * tests/data/test-core-diff/report8.txt: New test data. * tests/data/test-core-diff/report9.txt: Likewise. * tests/data/test-core-diff/report10.txt: Likewise. * tests/data/test-core-diff/report11.txt: Likewise. * tests/data/test-core-diff/report12.txt: Likewise. * tests/data/test-core-diff/report3.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-10-23 22:39:04 +00:00
{
"data/test-core-diff/report8.txt",
"output/test-core-diff/report8.txt",
"abcdef",
"bcghai"
},
{
"data/test-core-diff/report9.txt",
"output/test-core-diff/report9.txt",
"abcdef",
"bjcghai"
},
{
"data/test-core-diff/report10.txt",
"output/test-core-diff/report10.txt",
"a",
"ab"
},
{
"data/test-core-diff/report11.txt",
"output/test-core-diff/report11.txt",
"a",
"abd"
},
{
"data/test-core-diff/report12.txt",
"output/test-core-diff/report12.txt",
"a",
"cba"
},
{
"data/test-core-diff/report13.txt",
"output/test-core-diff/report13.txt",
"abcdefghi",
"jklmnopqrstadubvfwxgh"
},
// This should be the last entry.
{NULL, NULL, NULL, NULL}
};
using abigail::diff_utils::edit_script;
using abigail::diff_utils::compute_ses;
using abigail::diff_utils::display_edit_script;
int
main()
{
unsigned result = 1;
bool problem = false;
string in_path, out_path;
for (SESInOutSpec *s = in_out_specs; s->in_path; ++s)
{
string input_suffix(s->in_path);
Use worker threads pattern to speed up some tests We are going to need to speed up more and more tests, and coding directly with libpthread for that can be tedious and bug-prone. So I devised an implementation for the worker threads design pattern instead, and used it to speed up some tests. * include/Makefile.am: Add the new abg-workers.h to source distribution. * include/abg-workers.h: New file. * src/Makefile.am: Add the new abg-worker.cc to source distribution. * src/abg-workers.cc: New file. * tests/test-utils.cc: Update copyright. Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. Make that const char reside in thread local storage, so that two concurrent threads can safely call these functions in parallel, without any race. * tests/test-utils.h: Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. * tests/test-abicompat.cc: Update copyright. Adjust for get_src_dir() and get_build_dir() change. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-types-stability.cc: Likewise. Use the new task queue type to run these tests in parallel. * tests/test-diff-filter.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-15 12:34:16 +00:00
in_path =
string(abigail::tests::get_src_dir()) + "/tests/" + input_suffix;
string output_suffix(s->out_path);
Use worker threads pattern to speed up some tests We are going to need to speed up more and more tests, and coding directly with libpthread for that can be tedious and bug-prone. So I devised an implementation for the worker threads design pattern instead, and used it to speed up some tests. * include/Makefile.am: Add the new abg-workers.h to source distribution. * include/abg-workers.h: New file. * src/Makefile.am: Add the new abg-worker.cc to source distribution. * src/abg-workers.cc: New file. * tests/test-utils.cc: Update copyright. Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. Make that const char reside in thread local storage, so that two concurrent threads can safely call these functions in parallel, without any race. * tests/test-utils.h: Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. * tests/test-abicompat.cc: Update copyright. Adjust for get_src_dir() and get_build_dir() change. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-types-stability.cc: Likewise. Use the new task queue type to run these tests in parallel. * tests/test-diff-filter.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-15 12:34:16 +00:00
out_path =
string(abigail::tests::get_build_dir()) + "/tests/" + output_suffix;
Expose a new libabigail::tools_utils namespace The utilities present in this namespace were previously living in tools/abg-tools-utils.h and tools/abg-tools-utils.cc. They were not exported and were meant to be useful to the tools writting in the tools/ directory. I realized that these utilities might be useful to clients of the libabigail library in general so I am making them available generally. Note that the initial name of the namespace was libabigail::tools; so renaming it to libabigail::tools_utils required that I adjust some client code. I have also cleaned up the code, interfaces and their apidoc a little bit. * include/abg-tools-utils.h: Moved tools/abg-tools-utils.h in here. Renamed the namespace tools into tools_utils. Inject std::ostream, std::istream, std::ifstream, and std::string types into the tools_utils namespace. Adjust the function declarations accordingly. Remove the useless dirname() function declaration. * include/Makefile.am: Add abg-tools-utils.h to the list of exported headers. * src/abg-tools-utils.cc: Moved tools/abg-tools-utils.cc in here. Renamed the namespace tools into tools_utils. (get_stat): Add apidoc. (is_dir): Cleanup apidoc. (dir_name); Cleanup parameter name. (guess_file_type): Cleanup parameter type. * src/Makefile.am: Add abg-tools-utils.cc to the list of exported headers. * tools/Makefile.am: Do not build the temporary library libtoolsutils.la anymore as abg-tools-utils.{h,cc} have moved out of this directory. * tools/abicompat.cc (parse_command_line, main): Adjust for tools -> tools_utils namespace change. * tools/abidiff.cc (parse_command_line, main): Likewise. * tools/abidw.cc (parse_command_line, main): Likewise. * tools/abilint.cc (parse_command_line, main): Likewise. * tests/test-abicompat.cc (main): Adjust for tools -> tools_utils namespace change. * tests/test-abidiff.cc (main): Likewise. * tests/test-alt-dwarf-file.cc (main): Likewise. * tests/test-core-diff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-diff-filter.cc (main): Likewise. * tests/test-diff-suppr.cc (main): Likewise. * tests/test-lookup-syms.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/test-read-write.cc (main): Likewise. * tests/Makefile.am: Do not reference the libtoolsutils.la private library anymore. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-08 10:34:03 +00:00
if (!abigail::tools_utils::ensure_parent_dir_created(out_path))
{
cerr << "Could not create parent director for " << out_path;
problem = true;
return result;
}
ofstream of(out_path.c_str(), std::ios_base::trunc);
if (!of.is_open())
{
cerr << "failed to read " << out_path << "\n";
problem = true;
continue;
}
edit_script ses;
// Compute the Shortest Edit Script (aka diff) that changes
// s->first_string into s->second_string.
compute_ses(s->first_string, s->second_string, ses);
// Emit a report about that edit script
display_edit_script(ses, s->first_string, s->second_string, of);
of.close();
// Diff that report against what we expect.
string cmd = "diff -u " + in_path + " " + out_path;
if (system(cmd.c_str()))
problem= true;
}
return problem;
}