mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-25 16:10:57 +00:00
- Added a new Invariant: `ValidPseudoAccounts` which checks that all pseudo-accounts behave consistently through creation and updates, and that no "real" accounts look like pseudo-accounts (which means they don't have a 0 sequence).
- `to_short_string(base_uint)`. Like `to_string`, but only returns the first 8 characters. (Similar to how a git commit ID can be abbreviated.) Used as a wrapped sink to prefix most transaction-related messages. More can be added later.
- `XRPL_ASSERT_PARTS`. Convenience wrapper for `XRPL_ASSERT`, which takes the `function` and `description` as separate parameters.
- `SField::sMD_PseudoAccount`. Metadata option for `SField` definitions to indicate that the field, if set in an `AccountRoot` indicates that account is a pseudo-account. Removes the need for hard-coded field lists all over the place. Added the flag to `AMMID` and `VaultID`.
- Added functionality to `SField` ctor to detect both code and name collisions using asserts. And require all SFields to have a name
- Convenience type aliases `STLedgerEntry::const_pointer` and `STLedgerEntry::const_ref`. (`SLE` is an alias to `STLedgerEntry`.)
- Generalized `feeunit.h` (`TaggedFee`) into `unit.h` (`ValueUnit`) and added new "BIPS"-related tags for future use. Also refactored the type restrictions to use Concepts.
- Restructured `transactions.macro` to do two big things
1. Include the `#include` directives for transactor header files directly in the macro file. Removes the need to update `applySteps.cpp` and the resulting conflicts.
2. Added a `privileges` parameter to the `TRANSACTION` macro, which specifies some of the operations a transaction is allowed to do. These `privileges` are enforced by invariant checks. Again, removed the need to update scattered lists of transaction types in various checks.
- Unit tests:
1. Moved more helper functions into `TestHelpers.h` and `.cpp`.
2. Cleaned up the namespaces to prevent / mitigate random collisions and ambiguous symbols, particularly in unity builds.
3. Generalized `Env::balance` to add support for `MPTIssue` and `Asset`.
4. Added a set of helper classes to simplify `Env` transaction parameter classes: `JTxField`, `JTxFieldWrapper`, and a bunch of classes derived or aliased from it. For an example of how awesome it is, check the changes `src/test/jtx/escrow.h` for how much simpler the definitions are for `finish_time`, `cancel_time`, `condition`, and `fulfillment`.
5. Generalized several of the amount-related helper classes to understand `Asset`s.
6. `env.balance` for an MPT issuer will return a negative number (or 0) for consistency with IOUs.
183 lines
4.5 KiB
C++
183 lines
4.5 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of rippled: https://github.com/ripple/rippled
|
|
Copyright (c) 2018 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.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef TEST_UNIT_TEST_DIRGUARD_H
|
|
#define TEST_UNIT_TEST_DIRGUARD_H
|
|
|
|
#include <test/jtx/TestSuite.h>
|
|
|
|
#include <xrpl/basics/contract.h>
|
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#include <fstream>
|
|
|
|
namespace ripple {
|
|
namespace detail {
|
|
|
|
/**
|
|
Create a directory and remove it when it's done
|
|
*/
|
|
class DirGuard
|
|
{
|
|
protected:
|
|
using path = boost::filesystem::path;
|
|
|
|
private:
|
|
path subDir_;
|
|
bool rmSubDir_{false};
|
|
|
|
protected:
|
|
beast::unit_test::suite& test_;
|
|
|
|
auto
|
|
rmDir(path const& toRm)
|
|
{
|
|
if (is_directory(toRm) && is_empty(toRm))
|
|
remove(toRm);
|
|
else
|
|
test_.log << "Expected " << toRm.string()
|
|
<< " to be an empty existing directory." << std::endl;
|
|
}
|
|
|
|
public:
|
|
DirGuard(beast::unit_test::suite& test, path subDir, bool useCounter = true)
|
|
: subDir_(std::move(subDir)), test_(test)
|
|
{
|
|
using namespace boost::filesystem;
|
|
|
|
static auto subDirCounter = 0;
|
|
if (useCounter)
|
|
subDir_ += std::to_string(++subDirCounter);
|
|
if (!exists(subDir_))
|
|
{
|
|
create_directory(subDir_);
|
|
rmSubDir_ = true;
|
|
}
|
|
else if (is_directory(subDir_))
|
|
rmSubDir_ = false;
|
|
else
|
|
{
|
|
// Cannot run the test. Someone created a file where we want to
|
|
// put our directory
|
|
Throw<std::runtime_error>(
|
|
"Cannot create directory: " + subDir_.string());
|
|
}
|
|
}
|
|
|
|
~DirGuard()
|
|
{
|
|
try
|
|
{
|
|
using namespace boost::filesystem;
|
|
|
|
if (rmSubDir_)
|
|
rmDir(subDir_);
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
// if we throw here, just let it die.
|
|
test_.log << "Error in ~DirGuard: " << e.what() << std::endl;
|
|
};
|
|
}
|
|
|
|
path const&
|
|
subdir() const
|
|
{
|
|
return subDir_;
|
|
}
|
|
};
|
|
|
|
/**
|
|
Write a file in a directory and remove when done
|
|
*/
|
|
class FileDirGuard : public DirGuard
|
|
{
|
|
protected:
|
|
path const file_;
|
|
bool created_ = false;
|
|
|
|
public:
|
|
FileDirGuard(
|
|
beast::unit_test::suite& test,
|
|
path subDir,
|
|
path file,
|
|
std::string const& contents,
|
|
bool useCounter = true,
|
|
bool create = true)
|
|
: DirGuard(test, subDir, useCounter)
|
|
, file_(file.is_absolute() ? file : subdir() / file)
|
|
{
|
|
if (!exists(file_))
|
|
{
|
|
if (create)
|
|
{
|
|
std::ofstream o(file_.string());
|
|
o << contents;
|
|
created_ = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Throw<std::runtime_error>(
|
|
"Refusing to overwrite existing file: " + file_.string());
|
|
}
|
|
}
|
|
|
|
~FileDirGuard()
|
|
{
|
|
try
|
|
{
|
|
using namespace boost::filesystem;
|
|
if (exists(file_))
|
|
{
|
|
remove(file_);
|
|
}
|
|
else
|
|
{
|
|
if (created_)
|
|
test_.log << "Expected " << file_.string()
|
|
<< " to be an existing file." << std::endl;
|
|
}
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
// if we throw here, just let it die.
|
|
test_.log << "Error in ~FileGuard: " << e.what() << std::endl;
|
|
};
|
|
}
|
|
|
|
path const&
|
|
file() const
|
|
{
|
|
return file_;
|
|
}
|
|
|
|
bool
|
|
fileExists() const
|
|
{
|
|
return boost::filesystem::exists(file_);
|
|
}
|
|
};
|
|
|
|
} // namespace detail
|
|
} // namespace ripple
|
|
|
|
#endif // TEST_UNIT_TEST_DIRGUARD_H
|