aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt41
-rw-r--r--cmake/CheckLinkerFlag.cmake1
-rw-r--r--cmake/FindLibUSB.cmake2
-rw-r--r--contrib/depends/Makefile4
-rw-r--r--contrib/epee/include/storages/portable_storage.h2
-rw-r--r--contrib/epee/src/CMakeLists.txt12
-rw-r--r--external/easylogging++/CMakeLists.txt6
-rw-r--r--src/CMakeLists.txt24
-rw-r--r--src/cryptonote_core/blockchain.cpp7
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp4
-rw-r--r--src/device_trezor/trezor/transport.cpp2
-rw-r--r--src/rpc/core_rpc_server.cpp2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h4
-rw-r--r--src/wallet/CMakeLists.txt13
-rw-r--r--src/wallet/wallet2.cpp18
-rw-r--r--tests/README.md21
-rw-r--r--tests/core_tests/chaingen.h2
17 files changed, 108 insertions, 57 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fecea318b..b35eb2b7a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -168,11 +168,13 @@ endfunction()
#
# Parameters:
# - headers_found: Output variable, which will hold the found headers
-# - module_root_dir: The search path for the headers. Typically it will be the module's root dir.
+# - module_root_dir: The search path for the headers. Typically it will be the module's root dir, so "${CMAKE_CURRENT_SOURCE_DIR}" or a derivative of it.
macro (monero_find_all_headers headers_found module_root_dir)
file(GLOB ${headers_found}
"${module_root_dir}/*.h*" # h* will include hpps as well.
"${module_root_dir}/**/*.h*" # Any number of subdirs will be included.
+ "${module_root_dir}/*.inl" # .inl is typically template code and is being treated as headers (it's being included).
+ "${module_root_dir}/**/*.inl"
)
endmacro()
@@ -538,6 +540,29 @@ macro (monero_enable_coverage)
endif()
endmacro()
+function (monero_add_library name)
+ monero_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
+endfunction()
+
+function (monero_add_library_with_deps)
+ cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
+ source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
+
+ # Define a ("virtual") object library and an actual library that links those
+ # objects together. The virtual libraries can be arbitrarily combined to link
+ # any subset of objects into one library archive. This is used for releasing
+ # libwallet, which combines multiple components.
+ set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
+ add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
+ add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
+ monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
+ if (MONERO_ADD_LIBRARY_DEPENDS)
+ add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
+ endif()
+ set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
+ target_compile_definitions(${objlib}
+ PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
+endfunction ()
# Generate header for embedded translations
# Generate header for embedded translations, use target toolchain if depends, otherwise use the
@@ -749,7 +774,12 @@ else()
# PIE executables randomly crash at startup with ASAN
# Windows binaries die on startup with PIE when compiled with GCC <9.x
# Windows dynamically-linked binaries die on startup with PIE regardless of GCC version
- add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ # Clang does not support -pie flag
+ add_linker_flag_if_supported("-Wl,-pie" LD_SECURITY_FLAGS)
+ else()
+ add_linker_flag_if_supported("-pie" LD_SECURITY_FLAGS)
+ endif()
endif()
add_linker_flag_if_supported(-Wl,-z,relro LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,-z,now LD_SECURITY_FLAGS)
@@ -775,6 +805,13 @@ else()
add_linker_flag_if_supported(-Wl,--high-entropy-va LD_SECURITY_FLAGS)
endif()
+ # Warnings, that when ignored are so severe, that they can segfault or even UB any application.
+ # Treat them as errors.
+ add_c_flag_if_supported( -Werror=switch C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported(-Werror=switch CXX_SECURITY_FLAGS)
+ add_c_flag_if_supported( -Werror=return-type C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported(-Werror=return-type CXX_SECURITY_FLAGS)
+
message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
diff --git a/cmake/CheckLinkerFlag.cmake b/cmake/CheckLinkerFlag.cmake
index 2b507ab71..7ecf5f610 100644
--- a/cmake/CheckLinkerFlag.cmake
+++ b/cmake/CheckLinkerFlag.cmake
@@ -15,6 +15,7 @@ macro(CHECK_LINKER_FLAG flag VARIABLE)
${_cle_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${flag}
CMAKE_FLAGS
+ "-DCMAKE_EXE_LINKER_FLAGS=${flag}"
OUTPUT_VARIABLE OUTPUT)
unset(_cle_source)
set(CMAKE_C_FLAGS ${saved_CMAKE_C_FLAGS})
diff --git a/cmake/FindLibUSB.cmake b/cmake/FindLibUSB.cmake
index 79d8fba75..6944c6c45 100644
--- a/cmake/FindLibUSB.cmake
+++ b/cmake/FindLibUSB.cmake
@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
try_compile(LibUSB_COMPILE_TEST_PASSED
${CMAKE_BINARY_DIR}
- "${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
+ "${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
diff --git a/contrib/depends/Makefile b/contrib/depends/Makefile
index 28ec972e4..0d71ddb13 100644
--- a/contrib/depends/Makefile
+++ b/contrib/depends/Makefile
@@ -10,8 +10,8 @@ HOST ?= $(BUILD)
PATCHES_PATH = $(BASEDIR)/patches
BASEDIR = $(CURDIR)
HASH_LENGTH:=11
-DOWNLOAD_CONNECT_TIMEOUT:=10
-DOWNLOAD_RETRIES:=3
+DOWNLOAD_CONNECT_TIMEOUT:=30
+DOWNLOAD_RETRIES:=5
HOST_ID_SALT ?= salt
BUILD_ID_SALT ?= salt
diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h
index 655a2eb12..60f3e672f 100644
--- a/contrib/epee/include/storages/portable_storage.h
+++ b/contrib/epee/include/storages/portable_storage.h
@@ -31,6 +31,8 @@
#include "misc_log_ex.h"
#include "span.h"
+#include <boost/mpl/contains.hpp>
+
namespace epee
{
class byte_slice;
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index 0f0a6ecad..7bc75caf3 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -31,7 +31,7 @@ set(EPEE_INCLUDE_DIR_BASE "${CMAKE_CURRENT_SOURCE_DIR}/../include")
# Add headers to the file list, to be able to search for them and autosave in IDEs.
monero_find_all_headers(EPEE_HEADERS_PUBLIC "${EPEE_INCLUDE_DIR_BASE}")
-add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
+monero_add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
int-util.cpp portable_storage.cpp
misc_language.cpp
@@ -44,7 +44,7 @@ add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_cli
)
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
- add_library(epee_readline STATIC readline_buffer.cpp)
+ monero_add_library(epee_readline readline_buffer.cpp)
endif()
if(HAVE_C11)
@@ -72,8 +72,9 @@ target_link_libraries(epee
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
- PRIVATE
+ ${Boost_REGEX_LIBRARY}
${OPENSSL_LIBRARIES}
+ PRIVATE
${EXTRA_LIBRARIES})
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
@@ -84,5 +85,8 @@ if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
${GNU_READLINE_LIBRARY})
endif()
-target_include_directories(epee PUBLIC "${EPEE_INCLUDE_DIR_BASE}")
+target_include_directories(epee
+ PUBLIC
+ "${EPEE_INCLUDE_DIR_BASE}"
+ "${OPENSSL_INCLUDE_DIR}")
diff --git a/external/easylogging++/CMakeLists.txt b/external/easylogging++/CMakeLists.txt
index 28c2945b1..9aa4c08bc 100644
--- a/external/easylogging++/CMakeLists.txt
+++ b/external/easylogging++/CMakeLists.txt
@@ -36,8 +36,12 @@ monero_enable_coverage()
find_package(Threads)
find_package(Backtrace)
+monero_find_all_headers(EASYLOGGING_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}")
+
add_library(easylogging
- easylogging++.cc)
+ easylogging++.cc
+ ${EASYLOGGING_HEADERS}
+ )
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9904c5de7..1f89faf98 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -79,30 +79,6 @@ function (monero_add_executable name)
monero_set_target_no_relink("${name}")
endfunction ()
-function (monero_add_library name)
- monero_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
-endfunction()
-
-function (monero_add_library_with_deps)
- cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
- source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
-
- # Define a ("virtual") object library and an actual library that links those
- # objects together. The virtual libraries can be arbitrarily combined to link
- # any subset of objects into one library archive. This is used for releasing
- # libwallet, which combines multiple components.
- set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
- add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
- add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
- monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
- if (MONERO_ADD_LIBRARY_DEPENDS)
- add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
- endif()
- set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
- target_compile_definitions(${objlib}
- PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
-endfunction ()
-
include(Version)
monero_add_library(version SOURCES ${CMAKE_BINARY_DIR}/version.cpp DEPENDS genversion)
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index a3d695b85..db707bb65 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -566,6 +566,8 @@ void Blockchain::pop_blocks(uint64_t nblocks)
return;
}
+ CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
+
if (stop_batch)
m_db->batch_stop();
}
@@ -643,7 +645,6 @@ block Blockchain::pop_block_from_blockchain()
m_scan_table.clear();
m_blocks_txs_check.clear();
- CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
uint64_t top_block_height;
crypto::hash top_block_hash = get_tail_id(top_block_height);
m_tx_pool.on_blockchain_dec(top_block_height, top_block_hash);
@@ -1110,6 +1111,7 @@ bool Blockchain::rollback_blockchain_switching(std::list<block>& original_chain,
{
pop_block_from_blockchain();
}
+ CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
// make sure the hard fork object updates its current version
m_hardfork->reorganize_from_chain_height(rollback_height);
@@ -1160,6 +1162,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
block b = pop_block_from_blockchain();
disconnected_chain.push_front(b);
}
+ CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
auto split_height = m_db->height();
@@ -5150,7 +5153,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
if (m_cancel)
return false;
- for (const auto &tx_blob : entry.txs)
+ for (size_t i = 0; i < entry.txs.size(); ++i)
{
if (tx_index >= txes.size())
SCAN_TABLE_QUIT("tx_index is out of sync");
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index 7400c4328..f41c63a4b 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -622,8 +622,10 @@ namespace cryptonote
if (need_additional_txkeys)
{
additional_tx_keys.clear();
- for (const auto &d: destinations)
+ for (size_t i = 0; i < destinations.size(); ++i)
+ {
additional_tx_keys.push_back(keypair::generate(sender_account_keys.get_device()).sec);
+ }
}
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout);
diff --git a/src/device_trezor/trezor/transport.cpp b/src/device_trezor/trezor/transport.cpp
index be95868d0..194176413 100644
--- a/src/device_trezor/trezor/transport.cpp
+++ b/src/device_trezor/trezor/transport.cpp
@@ -157,7 +157,7 @@ namespace trezor{
#define PROTO_HEADER_SIZE 6
static size_t message_size(const google::protobuf::Message &req){
- return static_cast<size_t>(req.ByteSize());
+ return req.ByteSizeLong();
}
static size_t serialize_message_buffer_size(size_t msg_size) {
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index ded545efa..8d8a68efb 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1044,6 +1044,7 @@ namespace cryptonote
if (e.in_pool)
{
e.block_height = e.block_timestamp = std::numeric_limits<uint64_t>::max();
+ e.confirmations = 0;
auto it = per_tx_pool_tx_info.find(tx_hash);
if (it != per_tx_pool_tx_info.end())
{
@@ -1062,6 +1063,7 @@ namespace cryptonote
else
{
e.block_height = m_core.get_blockchain_storage().get_db().get_tx_block_height(tx_hash);
+ e.confirmations = m_core.get_current_blockchain_height() - e.block_height;
e.block_timestamp = m_core.get_blockchain_storage().get_db().get_block_timestamp(e.block_height);
e.received_timestamp = 0;
e.double_spend_seen = false;
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 5ebe4f654..ff8c98b98 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -88,7 +88,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 3
-#define CORE_RPC_VERSION_MINOR 6
+#define CORE_RPC_VERSION_MINOR 7
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
@@ -350,6 +350,7 @@ namespace cryptonote
bool in_pool;
bool double_spend_seen;
uint64_t block_height;
+ uint64_t confirmations;
uint64_t block_timestamp;
uint64_t received_timestamp;
std::vector<uint64_t> output_indices;
@@ -367,6 +368,7 @@ namespace cryptonote
if (!this_ref.in_pool)
{
KV_SERIALIZE(block_height)
+ KV_SERIALIZE(confirmations)
KV_SERIALIZE(block_timestamp)
KV_SERIALIZE(output_indices)
}
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index 47555d9c8..2dd64a38f 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -40,18 +40,7 @@ set(wallet_sources
wallet_rpc_payments.cpp
)
-set(wallet_private_headers
- wallet2.h
- wallet_args.h
- wallet_errors.h
- wallet_rpc_server.h
- wallet_rpc_server_commands_defs.h
- wallet_rpc_server_error_codes.h
- ringdb.h
- node_rpc_proxy.h
- message_store.h
- message_transporter.h
- wallet_rpc_helpers.h)
+monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(wallet
${wallet_private_headers})
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 0b310111e..1f12689fb 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -11516,6 +11516,9 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations)
{
+ uint32_t rpc_version;
+ THROW_WALLET_EXCEPTION_IF(!check_connection(&rpc_version), error::wallet_internal_error, "Failed to connect to daemon: " + get_daemon_address());
+
COMMAND_RPC_GET_TRANSACTIONS::request req;
COMMAND_RPC_GET_TRANSACTIONS::response res;
req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid));
@@ -11561,10 +11564,17 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de
confirmations = 0;
if (!in_pool)
{
- std::string err;
- uint64_t bc_height = get_daemon_blockchain_height(err);
- if (err.empty())
- confirmations = bc_height - res.txs.front().block_height;
+ if (rpc_version < MAKE_CORE_RPC_VERSION(3, 7))
+ {
+ std::string err;
+ uint64_t bc_height = get_daemon_blockchain_height(err);
+ if (err.empty() && bc_height > res.txs.front().block_height)
+ confirmations = bc_height - res.txs.front().block_height;
+ }
+ else
+ {
+ confirmations = res.txs.front().confirmations;
+ }
}
}
diff --git a/tests/README.md b/tests/README.md
index c4ad1ce37..908482c99 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -50,7 +50,7 @@ To run the same tests on a release build, replace `debug` with `release`.
# Functional tests
[TODO]
-Functional tests are located under the `tests/functional` directory.
+Functional tests are located under the `tests/functional_tests` directory.
Building all the tests requires installing the following dependencies:
```bash
@@ -70,6 +70,25 @@ velvet lymph giddy number token physics poetry unquoted nibs useful sabotage lim
Open the wallet file with `monero-wallet-rpc` with RPC port 18083. Finally, start tests by invoking ./blockchain.py or ./speed.py
+## Parameters
+
+Configuration of individual tests.
+
+### Mining test
+
+The following environment variables may be set to control the mining test:
+
+- `MINING_NO_MEASUREMENT` - set to anything to use large enough and fixed mining timeouts (use case: very slow PCs and no intention to change the mining code)
+- `MINING_SILENT` - set to anything to disable mining logging
+
+For example, to customize the run of the functional tests, you may run the following commands from the build directory:
+
+```bash
+export MINING_NO_MEASUREMENT=1
+ctest -V -R functional_tests_rpc
+unset MINING_NO_MEASUREMENT
+```
+
# Fuzz tests
Fuzz tests are written using American Fuzzy Lop (AFL), and located under the `tests/fuzz` directory.
diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h
index a5fd35028..dbb8bd3be 100644
--- a/tests/core_tests/chaingen.h
+++ b/tests/core_tests/chaingen.h
@@ -1084,7 +1084,7 @@ inline bool do_replay_file(const std::string& filename)
}
#define QUOTEME(x) #x
-#define DEFINE_TESTS_ERROR_CONTEXT(text) const char* perr_context = text;
+#define DEFINE_TESTS_ERROR_CONTEXT(text) const char* perr_context = text; (void) perr_context;
#define CHECK_TEST_CONDITION(cond) CHECK_AND_ASSERT_MES(cond, false, "[" << perr_context << "] failed: \"" << QUOTEME(cond) << "\"")
#define CHECK_EQ(v1, v2) CHECK_AND_ASSERT_MES(v1 == v2, false, "[" << perr_context << "] failed: \"" << QUOTEME(v1) << " == " << QUOTEME(v2) << "\", " << v1 << " != " << v2)
#define CHECK_NOT_EQ(v1, v2) CHECK_AND_ASSERT_MES(!(v1 == v2), false, "[" << perr_context << "] failed: \"" << QUOTEME(v1) << " != " << QUOTEME(v2) << "\", " << v1 << " == " << v2)