Skip to content
Snippets Groups Projects
Commit 5213b5d6 authored by Imdad Sardharwalla's avatar Imdad Sardharwalla Committed by GitHub Enterprise
Browse files

REFORM-1016 REFORM-1132 Add flexibility to perform checksum comparisons at the end of a test (#57)

* Move PathLink from TestReport.cc -> Paths/PathLink.hh

* Move TestFilesystem.hh -> Paths/Filesystem.hh

* Add macros (particularly BASE_TEST()) in TestCase.hh to create a
  wrapper for the Catch2 macro TEST_CASE() (or any other test macro
  that defines a void function) to allow checksum comparisons to be
  performed at the end of a test.

* Remove timing information and empty lines from checksum
  reports. Consequently, remove filter_report() from TestReport.cc and
  replace it with a simple copy.
parent cba51806
No related branches found
No related tags found
1 merge request!14Merge latest changes to Base from ReForm
......@@ -39,6 +39,7 @@ base_add_subdir(Code)
base_add_subdir(Config)
base_add_subdir(Debug)
base_add_subdir(Journal)
base_add_subdir(Paths)
base_add_subdir(Progress)
base_add_subdir(Security)
base_add_subdir(Test)
......
set(my_headers
${CMAKE_CURRENT_SOURCE_DIR}/Filesystem.hh
${CMAKE_CURRENT_SOURCE_DIR}/PathLink.hh
PARENT_SCOPE
)
set(my_sources
PARENT_SCOPE
)
// (C) Copyright 2021 by Autodesk, Inc.
#ifndef BASE_TEST_FILESYSTEM_HH_INCLUDE
#define BASE_TEST_FILESYSTEM_HH_INCLUDE
#ifdef TEST_ON
#ifndef BASE_FILESYSTEM_HH_INCLUDE
#define BASE_FILESYSTEM_HH_INCLUDE
#include <Base/Security/Mandatory.hh>
#ifdef __APPLE__
#include <boost/filesystem.hpp>
namespace Test
namespace Base
{
namespace filesystem = boost::filesystem;
typedef boost::filesystem::path Path;
typedef boost::system::error_code error_code;
} // namespace Test
} // namespace Base
#else // __APPLE__
// Include <filesystem> but silence resulting C4995 warnings
INSECURE_INCLUDE_SECTION_BEGIN
#include <filesystem>
INSECURE_INCLUDE_SECTION_END
namespace Test
namespace Base
{
namespace filesystem = std::filesystem;
typedef std::filesystem::path Path;
typedef std::error_code error_code;
} // namespace Test
} // namespace Base
#endif // __APPLE__
#endif // TEST_ON
#endif // BASE_TEST_FILESYSTEM_HH_INCLUDE
#endif // BASE_FILESYSTEM_HH_INCLUDE
// (C) Copyright 2020 by Autodesk, Inc.
#ifndef BASE_PATHLINK_HH_INCLUDED
#define BASE_PATHLINK_HH_INCLUDED
#include <Base/Paths/Filesystem.hh>
namespace Base
{
namespace fs = Base::filesystem;
class PathLink
{
public:
explicit PathLink(const fs::path& _path) : path_(_path) {}
template <class StreamT>
friend StreamT& operator<<(StreamT& _os, const PathLink& _link)
{
_os << "\""
<< "file://" << fs::weakly_canonical(_link.path_).generic_string()
<< "\"";
return _os;
}
private:
const fs::path& path_;
};
} // namespace Base
#endif // BASE_PATHLINK_HH_INCLUDED
set(my_headers
${CMAKE_CURRENT_SOURCE_DIR}/LongestCommonSubsequenceT.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestArgs.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestCase.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestChecksum.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestChecksumCompare.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestChecksumCompletion.hh
......@@ -11,7 +12,6 @@ set(my_headers
${CMAKE_CURRENT_SOURCE_DIR}/TestChecksumLevel.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestChecksumNumberT.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestChecksumOutcome.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestFilesystem.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestOutcome.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestPaths.hh
${CMAKE_CURRENT_SOURCE_DIR}/TestReport.hh
......
// (C) Copyright 2021 by Autodesk, Inc.
#ifndef BASE_TESTCASE_HH_INCLUDED
#define BASE_TESTCASE_HH_INCLUDED
#ifdef TEST_ON
/*
The BASE_TEST() macro wraps around an existing test declaration macro (e.g.
TEST_CASE() for Catch2), augmenting it with a checksum comparison. For now, the
existing test declaration macro must define a void function.
In order to use BASE_TEST(), the following macros *must* be defined (before this
file is included):
- TEST_DECLARATION: a placeholder for the existing test declaration macro;
- TEST_COMPARE_CHECKSUMS: a placeholder for a function that compares checksums
output by the currently-running test against the corresponding baseline.
As an example, to use this with Catch2, one would write:
#define TEST_DECLARATION TEST_CASE
And to compare the checksums using Test::compare_checksums(), one would write:
#define TEST_COMPARE_CHECKSUMS Test::compare_checksums()
It is not required to use BASE_TEST(), and it is straightforward to define a
custom macro with a similar function. The following macros are available for
use:
- INTERNAL_UNIQUE_NAME(STEM): uses the compiler extension __COUNTER__ to provide
a unique name that starts with STEM.
- INTERNAL_BASE_TEST_FUNCTION_STEM: A stem that can be used when defining your
own "Test and Compare" macros.
- INTERNAL_UNIQUE_BASE_TEST_FUNCTION_NAME: A unique function name that can be
utilised in your own "Test and Compare" macros.
*/
#define INTERNAL_UNIQUE_NAME3(STEM, COUNTER) STEM##COUNTER
#define INTERNAL_UNIQUE_NAME2(STEM, COUNTER) \
INTERNAL_UNIQUE_NAME3(STEM, COUNTER)
#define INTERNAL_UNIQUE_NAME(STEM) INTERNAL_UNIQUE_NAME2(STEM, __COUNTER__)
#define INTERNAL_BASE_TEST_FUNCTION_STEM ____B_A_S_E____T_E_S_T____
#define INTERNAL_UNIQUE_BASE_TEST_FUNCTION_NAME \
INTERNAL_UNIQUE_NAME(BASE_TEST_FUNCTION_STEM)
// Both TEST_DECLARATION and TEST_COMPARE_CHECKSUMS must be defined in order to
// use the BASE_TEST() macro.
#if defined(TEST_DECLARATION) && defined(TEST_COMPARE_CHECKSUMS)
#define INTERNAL_BASE_TEST_VOID(TEST_FUNCTION, ...) \
static void TEST_FUNCTION(); \
TEST_DECLARATION(__VA_ARGS__) \
{ \
TEST_FUNCTION(); \
TEST_COMPARE_CHECKSUMS; \
} \
void TEST_FUNCTION()
#define BASE_TEST(...) \
INTERNAL_BASE_TEST_VOID(INTERNAL_UNIQUE_BASE_TEST_FUNCTION_NAME, __VA_ARGS__)
#else // defined(TEST_DECLARATION) && defined(TEST_COMPARE_CHECKSUMS)
#define BASE_TEST(...) \
static_assert(false, \
"Both TEST_DECLARATION and TEST_COMPARE_CHECKSUMS must be " \
"defined in order to use the BASE_TEST() macro. Please ensure " \
"they are defined before TestCase.hh is included."); \
static void INTERNAL_UNIQUE_BASE_TEST_FUNCTION_NAME()
#endif // defined(TEST_DECLARATION) && defined(TEST_COMPARE_CHECKSUMS)
#endif // TEST_ON
#endif // BASE_TESTCASE_HH_INCLUDED
......@@ -5,6 +5,7 @@
#include "TestChecksum.hh"
#include "Base/Debug/DebCallStack.hh"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
......@@ -31,6 +32,15 @@ Registry& registry_modify()
return chksm_reg;
}
// Trim (remove whitespace) from the end of a std::string (in place)
inline void rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
[](unsigned char ch) { return !std::isspace(ch); })
.base(),
s.end());
}
}//namespace
const Registry& registry()
......@@ -165,9 +175,11 @@ void Object::add(const Result& _rslt, const String& _data)
static std::mutex mtx; // synchronize access to the checksum report stream
std::lock_guard<std::mutex> lock(mtx);
static Base::OutputStreamAdaptT<std::ofstream> test_strm(REPORT_FILENAME);
static Base::OutputStreamAdaptT<std::ofstream> rprt_strm(REPORT_FILENAME);
static bool tag_out = false;
Base::OStringStream strm;
#ifdef DEB_ON
static String prev_call_stck;
String call_stck("/");
......@@ -175,7 +187,7 @@ void Object::add(const Result& _rslt, const String& _data)
if (prev_call_stck != call_stck)
{
test_strm << call_stck << ::Base::ENDL;
strm << call_stck << ::Base::ENDL;
prev_call_stck = call_stck;
}
#endif // DEB_ON
......@@ -183,13 +195,22 @@ void Object::add(const Result& _rslt, const String& _data)
if (!tag_out)
{
tag_out = true;
test_strm << REPORT_LEVEL_TAG << LEVEL_TEXT[run_lvl] << ::Base::ENDL;
strm << REPORT_LEVEL_TAG << LEVEL_TEXT[run_lvl] << ::Base::ENDL;
}
// Write checksum data and remove trailing whitespace
strm << format_checksum(_rslt, _data);
rtrim(strm.str);
// Write stream data to the report file if non-empty
if (!strm.str.empty())
{
rprt_strm << strm.str << ::Base::ENDL;
rprt_strm.stream().flush();
}
test_strm << format_checksum(_rslt, _data);
test_strm.stream().flush();
}
}//Checksum
} // namespace Checksum
} // namespace Test
#endif//TEST_ON
......@@ -36,19 +36,12 @@ const char* const END = "END";
} // namespace
Completion::Completion()
: Object("Completion", L_STABLE),
start_time_(std::chrono::system_clock::now())
{
}
Completion::Completion() : Object("Completion", L_STABLE) {}
void Completion::record_end()
{
auto end_time = std::chrono::system_clock::now();
std::chrono::duration<double> time_diff_sec = end_time - start_time_;
std::stringstream mess;
mess << "Success: " << END << " Time: " << time_diff_sec.count();
mess << "Success: " << END;
add(Result::OK, mess.str());
}
......
......@@ -16,7 +16,7 @@ namespace Test
namespace Checksum
{
// Checks it the test has completed and, if not, detect the problem for compare.
// Writes a checksum when the test completes.
class Completion : public Object
{
public:
......@@ -27,9 +27,6 @@ public:
//! Get if the line contains the end completion checksum record
static bool end(const std::string& _line);
private:
std::chrono::time_point<std::chrono::system_clock> start_time_;
};
// Register the checksum to check test completion.
......
......@@ -50,7 +50,7 @@ void ignore_unstable_outcome(const char* const _call)
{
std::cout
<< "-----------------------\n"
"INFO: Unstable outcome from the following call has been ignored:"
"Info: Unstable outcome from the following call has been ignored:"
"\n\n " << _call << "\n\n"
"Replace IGNORE_UNSTABLE_OUTCOME() with CHECK_OUTCOME() once "
"the functionality is stable.\n"
......
......@@ -3,13 +3,13 @@
#ifdef TEST_ON
#include <Base/Security/Mandatory.hh>
#include <Base/Paths/Filesystem.hh>
#include <Base/Paths/PathLink.hh>
#include "TestChecksumCompletion.hh"
#include "TestFilesystem.hh"
#include "TestReport.hh"
#include "TestResult.hh"
#include "TestResultAnalysis.hh"
#include <algorithm>
#include <array>
#include <cctype>
#include <cstring>
......@@ -26,13 +26,16 @@
namespace Test
{
using PathLink = Base::PathLink;
namespace
{
const char* const INDENT = " ";
const char CR = (char)'\r';
namespace fs = Test::filesystem;
namespace fs = Base::filesystem;
/*!
Contains the test path and, if the CTest log is parsed, any associated error
......@@ -379,20 +382,6 @@ struct TestDiffSummary
Test::DifferenceDistribution diffs_;
};
struct PathLink
{
const fs::path& path_;
explicit PathLink(const fs::path& _path) : path_(_path) {}
template <class StreamT>
friend StreamT& operator<<(StreamT& _os, const PathLink& _link)
{
_os << "\"file:////"
<< fs::canonical(fs::absolute(_link.path_)).generic_string() << "\"";
return _os;
}
};
/*!
Reads the report information from a test output directory and:
- copies it to the output stream;
......@@ -447,77 +436,25 @@ Result parse_report(const fs::path& _test_dir, const std::string& _err_msg,
return rslt;
}
// Trim (remove whitespace) from the end of a std::string
inline std::string& rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
[](unsigned char ch) { return !std::isspace(ch); })
.base(),
s.end());
return s;
}
// Apply report content filters. For now this only removes blank lines and time
// information
void filter_report(const Test::Path& _rprt_src, const Test::Path& _rprt_trgt)
{
#if __APPLE__
std::ifstream ifs(_rprt_src.string());
#else // __APPLE__
std::ifstream ifs(_rprt_src);
#endif // __APPLE__
std::vector<std::string> rprt_lines;
// Read the report contents line-by-line (to improve performance) and filter
// out the time information
for (std::string line; std::getline(ifs, line);)
{
// Search for time information
const auto time_pos = line.find("Time:");
if (time_pos != std::string::npos)
{
// Trim the time information
line.resize(time_pos);
// Filter the line if it is only whitespace
if (std::all_of(line.begin(), line.end(), isspace))
continue;
}
rprt_lines.push_back(rtrim(line));
}
ifs.close();
// Write all of the stored lines to the target report file
#if __APPLE__
std::ofstream ofs(_rprt_trgt.string());
#else // __APPLE__
std::ofstream ofs(_rprt_trgt);
#endif // __APPLE__
for (const auto& line : rprt_lines)
ofs << line << std::endl;
ofs.close();
}
// Make a 'clean' copy of a test directory, i.e. a 'baseline', which contains
// the same directory structure as the test directory, but only the report.txt
// files (with some bits filtered out).
void make_baseline(const Path& _test_root_dir, const Path& _bsln_root_dir,
const TestList& _test_list)
// files.
void make_baseline(const fs::path& _test_root_dir,
const fs::path& _bsln_root_dir, const TestList& _test_list)
{
if (fs::exists(_bsln_root_dir))
return; // Baseline already present.
fs::create_directory(_bsln_root_dir);
// Copy a 'cleaned' version of the global report to the baseline directory.
// Copy the global report to the baseline directory.
std::cout << "Processing the global report... ";
const auto main_rep_flnm(_test_root_dir / Test::REPORT_FILENAME);
const auto bsln_rep_flnm(_bsln_root_dir / Test::REPORT_FILENAME);
filter_report(main_rep_flnm, bsln_rep_flnm);
fs::copy(main_rep_flnm, bsln_rep_flnm);
std::cout << " ...done." << std::endl;
// Copy a 'cleaned' version of each test report to the corresponding place in
// the baseline directory.
// Copy each test report to the corresponding place in the baseline directory.
size_t test_idx = 0;
size_t num_tests = _test_list.tests().size();
for (auto& test : _test_list.tests())
......@@ -531,8 +468,8 @@ void make_baseline(const Path& _test_root_dir, const Path& _bsln_root_dir,
// Create the baseline directory (and all parents if necessary)
fs::create_directories(bsln_test_dir);
// Copy and filter the report
filter_report(curr_test_dir / Test::REPORT_FILENAME,
// Copy the report to the baseline directory
fs::copy(curr_test_dir / Test::REPORT_FILENAME,
bsln_test_dir / Test::REPORT_FILENAME);
}
std::cout << std::endl;
......@@ -672,7 +609,7 @@ void copy(const fs::path& _root_from, const fs::path& _root_to,
fs::create_directories(dir_to);
// Copy the contents of dir_from to dir_to
Test::error_code err_code;
Base::error_code err_code;
fs::copy(dir_from, dir_to, err_code);
if (err_code)
{
......@@ -824,13 +761,15 @@ ExitStatus make_comparison(const char* const _dir_left,
Base::OutputStreamAdaptT<TestStream> test_log;
// Get the path to the test directory for both suites
const auto test_dir_left = test_lists[0].root_dir() / test.path_;
const auto test_dir_right = test_lists[1].root_dir() / test.path_;
// Get the path to the report for both suites
const auto report_path_left =
test_lists[0].root_dir() / test.path_ / Test::REPORT_FILENAME;
const auto report_path_right =
test_lists[1].root_dir() / test.path_ / Test::REPORT_FILENAME;
// Compare the checksums for the test between the two suites
const auto diff_stats = compare(test_dir_left, test_dir_right, test_log,
_chks_cmpr, _cot == COT_SHORT_DIFF);
const auto diff_stats = compare_reports(report_path_left, report_path_right,
test_log, _chks_cmpr, _cot == COT_SHORT_DIFF);
if (!diff_stats.empty())
{
......@@ -965,8 +904,8 @@ ExitStatus make_comparison(const char* const _dir_left,
if (create_diff_report && (found_diff || !is_subset[0] || !is_subset[1]))
{
std::cout << "\nPlease check the compare log:\n"
<< diff_path.generic_string() << std::endl;
std::cout << "\nPlease check the compare log: " << PathLink(diff_path)
<< std::endl;
// Return an error if a difference was found or if there is a test in the
// right suite that does not exist in the left suite.
......
......@@ -6,11 +6,11 @@
#ifdef TEST_ON
#include <Base/Test/TestChecksumCompare.hh>
#include <functional>
namespace Test
{
enum ExitStatus
{
ES_OK = 0,
......@@ -50,7 +50,7 @@ enum CompareOutputType
Produces a summary report (e.g. number of tests executed, which tests had
errors, how many of each error were observed, etc.) of all test outputs below
<_root_dir>/. Also produce a clean copy of the test directory (at
<_root_dir>_base/) that contains only the (cleaned up) individual test reports.
<_root_dir>_base/) that contains only the individual test reports.
*/
ExitStatus make_summary_report(const char* const _root_dir);
......
......@@ -3,13 +3,13 @@
#ifdef TEST_ON
#include <Base/Security/Mandatory.hh>
#include <Base/Paths/Filesystem.hh>
#include "TestResultAnalysis.hh"
#include "LongestCommonSubsequenceT.hh"
#include "TestChecksum.hh"
#include "TestChecksumCompletion.hh"
#include "TestChecksumFile.hh"
#include "TestFilesystem.hh"
#include <algorithm>
#include <cctype>
......@@ -23,11 +23,12 @@ namespace Test
namespace
{
namespace fs = Test::filesystem;
namespace fs = Base::filesystem;
// Remove code links from _str
// Remove code links from _str. Code links are expected to be in the format for
// Base::CodeLink used in IOutputStream.cc
void erase_code_links(std::string& _str)
{ // refers to the format for Base::CodeLink used in IOutputStream.cc
{
const char* const CODE_LINK_BEGIN = "@ [";
const char* const CODE_LINK_END = "]";
......@@ -42,6 +43,15 @@ void erase_code_links(std::string& _str)
}
}
// Trim (remove whitespace) from the end of a std::string (in place)
inline void rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
[](unsigned char ch) { return !std::isspace(ch); })
.base(),
s.end());
}
// Read and parse lines of a report to get the checksum Result, name and content.
class Report
{
......@@ -54,15 +64,22 @@ public:
explicit Entry(const std::string& _line)
: line_(_line)
{
// Ignore lines that represent (debug) callstack groups
if (group())
return;
// the line should be a checksum, extract the checksum data
// Remove whitespace and newline characters from the end of the line
rtrim(line_);
// The line should be a checksum. Extract the checksum data.
std::istringstream line_strm(line_);
line_strm >> std::noskipws >> rcrd_.rslt;
line_strm >> std::skipws >> name_;
if (!name_.empty() && name_.back() == ':')
name_.pop_back();
std::getline(line_strm, rcrd_.data);
// Erase any code links of the form "@ [ ..... ]" from the data
erase_code_links(rcrd_.data);
}
......@@ -102,27 +119,26 @@ public:
public:
Report() : lvl_(Checksum::L_ALL) {}
explicit Report(const fs::path& _test_dir) : lvl_(Checksum::L_ALL)
explicit Report(const fs::path& _rprt_path) : lvl_(Checksum::L_ALL)
{
read(_test_dir);
}
void read(const fs::path& _test_dir)
{
std::ifstream rprt((_test_dir / REPORT_FILENAME).string()); // report stream
std::ifstream rprt(_rprt_path.string()); // report stream
for (std::string line; std::getline(rprt, line); )
{
// Skip empty lines
if (line.empty())
continue;// skip empty lines
continue;
// Find the checksum run level for this report by looking for the line
// "Report Level: <LEVEL>"
const auto rprt_lvl_tag_idx = line.find(REPORT_LEVEL_TAG);
if (rprt_lvl_tag_idx != std::string::npos) // report level entry?
{// find what is the checksum run level for this report
if (rprt_lvl_tag_idx != std::string::npos)
{
// Found such a line. Parse it to extract <LEVEL>.
for (int i = (int)Checksum::L_NONE; i <= Checksum::L_ALL; ++i)
{
if (line.find(Checksum::LEVEL_TEXT[i], rprt_lvl_tag_idx) !=
std::string::npos)
{// found it!
{
lvl_ = (Checksum::Level)i;
break;
}
......@@ -145,8 +161,8 @@ private:
} // namespace
DifferenceDistribution compare(const fs::path& _old_dir,
const fs::path& _new_dir, Base::IOutputStream& _log,
DifferenceDistribution compare_reports(const fs::path& _rprt_path0,
const fs::path& _rprt_path1, Base::IOutputStream& _log,
const Checksum::Compare& _chks_cmpr, const bool _shrt_frmt)
{
using Base::ENDL;
......@@ -162,7 +178,7 @@ DifferenceDistribution compare(const fs::path& _old_dir,
const char* const DIFF_TAG = "! ";
const char* const RESULT_TAG = " ";
const Report rprts[2] = { Report(_old_dir), Report(_new_dir) };
const Report rprts[2] = {Report(_rprt_path0), Report(_rprt_path1)};
LongestCommonSubsequenceT<Report> rprt_lcs(rprts[0], rprts[1]);
rprt_lcs.trace();
......@@ -194,15 +210,16 @@ DifferenceDistribution compare(const fs::path& _old_dir,
}
else
{ // print difference
_log << NAME_TAG << old_entr.name() << ": " << diff.type_text() <<
ENDL;
_log << OLD_TAG << old_entr.record().rslt << RESULT_TAG <<
old_entr.record().data << ENDL;
_log << NEW_TAG << new_entr.record().rslt << RESULT_TAG <<
new_entr.record().data << ENDL;
_log << NAME_TAG << old_entr.name() << ": " << diff.type_text()
<< ENDL;
_log << OLD_TAG << old_entr.record().rslt << RESULT_TAG
<< old_entr.record().data << ENDL;
_log << NEW_TAG << new_entr.record().rslt << RESULT_TAG
<< new_entr.record().data << ENDL;
const char rslt_mark =
old_entr.record().rslt.type() == new_entr.record().rslt.type() ?
' ' : '!';
old_entr.record().rslt.type() == new_entr.record().rslt.type()
? ' '
: '!';
_log << DIFF_TAG << rslt_mark << RESULT_TAG << diff.description()
<< ENDL;
}
......
......@@ -6,28 +6,35 @@
#ifdef TEST_ON
#include <Base/Test/TestChecksumCompare.hh>
#include <Base/Test/TestFilesystem.hh>
#include <Base/Paths/Filesystem.hh>
#include <map>
#include <string>
namespace Test
{
namespace fs = Base::filesystem;
typedef Checksum::Difference Difference;
typedef std::map<Difference, size_t> DifferenceDistribution;
/*!
Compares two test directories to detect differences in test execution and/or
test results. Returns a map with the difference statistics (counts for each type
of difference). Equal checksums are reported if _short_frmt = false.
Compares the checksums listed in two test reports. Returns a map with the
difference statistics (counts for each type of difference). Equal checksums are
ignored if _short_frmt = true.
Arguments:
* [in] _rprt_path0: Path to the left-suite report file.
* [in] _rprt_path1: Path to the right-suite report file.
* [out] _log: Description of the differences.
* [in] _chks_cmpr: Checksum compare function.
* [in] _short_frmt: Remove identical checksums (short format) [default = false].
*/
DifferenceDistribution compare(
const Path& _test_dir0, /*< [in] Test directory. */
const Path& _test_dir1, /*< [in] Test directory. */
Base::IOutputStream& _log, /*< [out] Description of the checksums and differences. */
const Checksum::Compare& _chks_cmpr, /*<[in] Checksum compare function */
const bool _short_frmt = false /*![in] Remove identical checksums */
);
DifferenceDistribution compare_reports(const fs::path& _rprt_path0,
const fs::path& _rprt_path1, Base::IOutputStream& _log,
const Checksum::Compare& _chks_cmpr, const bool _short_frmt = false);
} // namespace Test
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment