Convert fast manual unit tests to automatic

This commit is contained in:
Scott Schurr
2016-01-20 18:27:29 -08:00
committed by Nik Bougalis
parent 7315d9c300
commit 9063953ee7
8 changed files with 5 additions and 401 deletions

View File

@@ -3584,10 +3584,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\test\mao\impl\Net_test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\test\mao\Net.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\unity\app_ledger.cpp">

View File

@@ -4167,9 +4167,6 @@
<ClCompile Include="..\..\src\ripple\test\mao\impl\Net.cpp">
<Filter>ripple\test\mao\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\test\mao\impl\Net_test.cpp">
<Filter>ripple\test\mao\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\test\mao\Net.h">
<Filter>ripple\test\mao</Filter>
</ClInclude>

View File

@@ -95,6 +95,6 @@ public:
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(Journal,utility,beast);
BEAST_DEFINE_TESTSUITE(Journal,utility,beast);
} // beast

View File

@@ -39,6 +39,6 @@ public:
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(OfferStream,tx,ripple);
BEAST_DEFINE_TESTSUITE(OfferStream,tx,ripple);
}

View File

@@ -562,7 +562,7 @@ public:
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(import,NodeStore,ripple);
BEAST_DEFINE_TESTSUITE(import,NodeStore,ripple);
#endif
@@ -748,255 +748,7 @@ public:
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(rekey,NodeStore,ripple);
//------------------------------------------------------------------------------
namespace legacy {
using namespace beast::nudb;
using namespace beast::nudb::detail;
struct dat_file_header
{
static std::size_t BEAST_CONSTEXPR size =
8 + // Type
2 + // Version
8 + // Appnum
8 + // Salt
2 + // KeySize
64; // (Reserved)
char type[8];
std::size_t version;
std::uint64_t appnum;
std::uint64_t salt;
std::size_t key_size;
};
struct key_file_header
{
static std::size_t BEAST_CONSTEXPR size =
8 + // Type
2 + // Version
8 + // Appnum
8 + // Salt
8 + // Pepper
2 + // KeySize
2 + // BlockSize
2 + // LoadFactor
64; // (Reserved)
char type[8];
std::size_t version;
std::uint64_t appnum;
std::uint64_t salt;
std::uint64_t pepper;
std::size_t key_size;
std::size_t block_size;
std::size_t load_factor;
// Computed values
std::size_t capacity;
std::size_t bucket_size;
std::size_t buckets;
std::size_t modulus;
};
// Read data file header from stream
template <class = void>
void
read (istream& is, dat_file_header& dh)
{
read (is, dh.type, sizeof(dh.type));
read<std::uint16_t>(is, dh.version);
read<std::uint64_t>(is, dh.appnum);
read<std::uint64_t>(is, dh.salt);
read<std::uint16_t>(is, dh.key_size);
std::array <std::uint8_t, 64> zero;
read (is, zero.data(), zero.size());
}
// Read data file header from file
template <class File>
void
read (File& f, dat_file_header& dh)
{
std::array<std::uint8_t,
dat_file_header::size> buf;
try
{
f.read(0, buf.data(), buf.size());
}
catch (file_short_read_error const&)
{
Throw<store_corrupt_error> (
"short data file header");
}
istream is(buf);
read (is, dh);
}
// Read key file header from stream
template <class = void>
void
read (istream& is, std::size_t file_size,
key_file_header& kh)
{
read(is, kh.type, sizeof(kh.type));
read<std::uint16_t>(is, kh.version);
read<std::uint64_t>(is, kh.appnum);
read<std::uint64_t>(is, kh.salt);
read<std::uint64_t>(is, kh.pepper);
read<std::uint16_t>(is, kh.key_size);
read<std::uint16_t>(is, kh.block_size);
read<std::uint16_t>(is, kh.load_factor);
std::array <std::uint8_t, 64> zero;
read (is, zero.data(), zero.size());
// VFALCO These need to be checked to handle
// when the file size is too small
kh.capacity = bucket_capacity(kh.block_size);
kh.bucket_size = bucket_size(kh.capacity);
if (file_size > kh.block_size)
{
// VFALCO This should be handled elsewhere.
// we shouldn't put the computed fields in this header.
if (kh.block_size > 0)
kh.buckets = (file_size - kh.bucket_size)
/ kh.block_size;
else
// VFALCO Corruption or logic error
kh.buckets = 0;
}
else
{
kh.buckets = 0;
}
kh.modulus = ceil_pow2(kh.buckets);
}
// Read key file header from file
template <class File>
void
read (File& f, key_file_header& kh)
{
std::array <std::uint8_t,
key_file_header::size> buf;
try
{
f.read(0, buf.data(), buf.size());
}
catch (file_short_read_error const&)
{
Throw<store_corrupt_error> (
"short key file header");
}
istream is(buf);
read (is, f.actual_size(), kh);
}
} // detail
class update_test : public beast::unit_test::suite
{
public:
void
run() override
{
testcase(abort_on_fail) << arg();
using namespace beast::nudb;
using namespace beast::nudb::detail;
pass();
auto const args = parse_args(arg());
bool usage = args.empty();
if (! usage &&
args.find("path") == args.end())
{
log <<
"Missing parameter: path";
usage = true;
}
if (usage)
{
log <<
"Usage:\n" <<
"--unittest-arg=path=<dat>\n" <<
"path: NuDB path to update (without extensions)";
return;
}
auto const path = args.at("path");
using hash_type = beast::xxhasher;
auto const dp = path + ".dat";
auto const kp = path + ".key";
log <<
"path: " << path;
native_file df;
native_file kf;
df.open(file_mode::write, dp);
kf.open(file_mode::write, kp);
legacy::dat_file_header dh0;
legacy::key_file_header kh0;
read(df, dh0);
read(kf, kh0);
dat_file_header dh;
std::memcpy(dh.type, "nudb.dat", 8);
dh.version = dh0.version;;
dh.uid = make_uid();
dh.appnum = dh0.appnum;
dh.key_size = dh0.key_size;
key_file_header kh;
std::memcpy(kh.type, "nudb.key", 8);
kh.version = dh.version;
kh.uid = dh.uid;
kh.appnum = dh.appnum;
kh.key_size = dh.key_size;
kh.salt = kh0.salt;
kh.pepper = kh0.pepper;
kh.block_size = kh0.block_size;
kh.load_factor = kh0.load_factor;
// VFALCO These need to be checked to handle
// when the file size is too small
kh.capacity = bucket_capacity(kh.block_size);
kh.bucket_size = bucket_size(kh.capacity);
auto const kf_size = kf.actual_size();
if (kf_size > kh.block_size)
{
// VFALCO This should be handled elsewhere.
// we shouldn't put the computed fields
// in this header.
if (kh.block_size > 0)
kh.buckets = (kf_size - kh.bucket_size)
/ kh.block_size;
else
// VFALCO Corruption or logic error
kh.buckets = 0;
}
else
{
kh.buckets = 0;
}
kh.modulus = ceil_pow2(kh.buckets);
beast::nudb::detail::verify(dh);
beast::nudb::detail::verify<hash_type>(dh, kh);
write(df, dh);
write(kf, kh);
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(update,NodeStore,ripple);
BEAST_DEFINE_TESTSUITE(rekey,NodeStore,ripple);
}
}

View File

@@ -559,6 +559,6 @@ public:
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(short_read,overlay,ripple);
BEAST_DEFINE_TESTSUITE(short_read,overlay,ripple);
}

View File

@@ -1,140 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/Log.h>
#include <ripple/test/mao/Net.h>
#include <ripple/test/jtx.h>
#include <ripple/test/ManualTimeKeeper.h>
#include <ripple/net/HTTPClient.h>
#include <ripple/net/RPCCall.h>
#include <beast/unit_test/suite.h>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>
namespace ripple {
namespace test {
namespace mao {
struct TestApp
{
TestApp()
{
auto config = std::make_unique<Config>();
setupConfigForUnitTests(*config);
// Hack so we dont have to call Config::setup
HTTPClient::initializeSSLContext(*config);
auto logs = std::make_unique<Logs>();
auto timeKeeper = std::make_unique<ManualTimeKeeper>();
timeKeeper_ = timeKeeper.get();
instance = make_Application(std::move(config),
std::move(logs), std::move(timeKeeper));
instance->setup();
thread_ = std::thread(
[&]() { instance->run(); });
}
~TestApp()
{
if (thread_.joinable())
{
instance->signalStop();
thread_.join();
}
}
void
join()
{
thread_.join();
}
Application*
operator->()
{
return instance.get();
}
template <class T, class... Args>
void
rpc (T const& t, Args const&... args)
{
std::vector<std::string> v;
collect(v, t, args...);
RPCCall::fromCommandLine(
instance->config(), v,
instance->logs());
}
private:
inline
void
collect (std::vector<std::string>& v)
{
}
template <class T, class... Args>
void
collect (std::vector<std::string>& v,
T const& t, Args const&... args)
{
v.emplace_back(t);
collect(v, args...);
}
ManualTimeKeeper* timeKeeper_;
std::unique_ptr<Application> instance;
std::thread thread_;
std::mutex mutex_;
};
class Net_test : public beast::unit_test::suite
{
public:
void
testStartStop()
{
TestApp app;
pass();
}
void
testRPC()
{
TestApp app;
app.rpc("stop");
app.join();
pass();
}
void
run() override
{
testStartStop();
testRPC();
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(Net,mao,ripple)
} // mao
} // test
} // ripple

View File

@@ -46,7 +46,6 @@
#include <ripple/test/jtx/impl/utility.cpp>
#include <ripple/test/mao/impl/Net.cpp>
#include <ripple/test/mao/impl/Net_test.cpp>
#include <ripple/test/impl/BasicNetwork_test.cpp>
#include <ripple/test/impl/ManualTimeKeeper.cpp>