aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.fuzzbuzz.yml16
-rw-r--r--src/random.cpp16
-rw-r--r--src/random.h16
-rw-r--r--src/test/random_tests.cpp7
-rw-r--r--src/test/validationinterface_tests.cpp2
-rwxr-xr-xtest/functional/test_framework/test_framework.py14
6 files changed, 50 insertions, 21 deletions
diff --git a/.fuzzbuzz.yml b/.fuzzbuzz.yml
new file mode 100644
index 0000000000..d44ac27eb9
--- /dev/null
+++ b/.fuzzbuzz.yml
@@ -0,0 +1,16 @@
+base: ubuntu:16.04
+language: c++
+engine: libFuzzer
+environment:
+ - CXXFLAGS=-fcoverage-mapping -fno-omit-frame-pointer -fprofile-instr-generate -gline-tables-only -O1
+setup:
+ - sudo apt-get update
+ - sudo apt-get install -y autoconf bsdmainutils clang git libboost-all-dev libboost-program-options-dev libc++1 libc++abi1 libc++abi-dev libc++-dev libclang1 libclang-dev libdb5.3++ libevent-dev libllvm-ocaml-dev libomp5 libomp-dev libprotobuf-dev libqt5core5a libqt5dbus5 libqt5gui5 libssl-dev libtool llvm llvm-dev llvm-runtime pkg-config protobuf-compiler qttools5-dev qttools5-dev-tools software-properties-common
+ - ./autogen.sh
+ - CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
+ - make
+ - git clone https://github.com/bitcoin-core/qa-assets
+auto_targets:
+ find_targets_command: find src/test/fuzz/ -executable -type f ! -name "*.cpp" ! -name "*.h"
+ base_corpus_dir: qa-assets/fuzz_seed_corpus/
+ memory_limit: none
diff --git a/src/random.cpp b/src/random.cpp
index 5b8782d1ce..9c9a35709a 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -14,16 +14,14 @@
#include <wincrypt.h>
#endif
#include <logging.h> // for LogPrintf()
+#include <randomenv.h>
+#include <support/allocators/secure.h>
#include <sync.h> // for Mutex
#include <util/time.h> // for GetTimeMicros()
#include <stdlib.h>
#include <thread>
-#include <randomenv.h>
-
-#include <support/allocators/secure.h>
-
#ifndef WIN32
#include <fcntl.h>
#include <sys/time.h>
@@ -590,16 +588,6 @@ uint64_t GetRand(uint64_t nMax) noexcept
return FastRandomContext(g_mock_deterministic_tests).randrange(nMax);
}
-std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
-{
- return std::chrono::microseconds{GetRand(duration_max.count())};
-}
-
-std::chrono::milliseconds GetRandMillis(std::chrono::milliseconds duration_max) noexcept
-{
- return std::chrono::milliseconds{GetRand(duration_max.count())};
-}
-
int GetRandInt(int nMax) noexcept
{
return GetRand(nMax);
diff --git a/src/random.h b/src/random.h
index 690125079b..0c6dc24983 100644
--- a/src/random.h
+++ b/src/random.h
@@ -67,9 +67,21 @@
* Thread-safe.
*/
void GetRandBytes(unsigned char* buf, int num) noexcept;
+/** Generate a uniform random integer in the range [0..range). Precondition: range > 0 */
uint64_t GetRand(uint64_t nMax) noexcept;
-std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept;
-std::chrono::milliseconds GetRandMillis(std::chrono::milliseconds duration_max) noexcept;
+/** Generate a uniform random duration in the range [0..max). Precondition: max.count() > 0 */
+template <typename D>
+D GetRandomDuration(typename std::common_type<D>::type max) noexcept
+// Having the compiler infer the template argument from the function argument
+// is dangerous, because the desired return value generally has a different
+// type than the function argument. So std::common_type is used to force the
+// call site to specify the type of the return value.
+{
+ assert(max.count() > 0);
+ return D{GetRand(max.count())};
+};
+constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
+constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
int GetRandInt(int nMax) noexcept;
uint256 GetRandHash() noexcept;
diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp
index d1f60e8972..978a7bee4d 100644
--- a/src/test/random_tests.cpp
+++ b/src/test/random_tests.cpp
@@ -28,6 +28,8 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests)
for (int i = 10; i > 0; --i) {
BOOST_CHECK_EQUAL(GetRand(std::numeric_limits<uint64_t>::max()), uint64_t{10393729187455219830U});
BOOST_CHECK_EQUAL(GetRandInt(std::numeric_limits<int>::max()), int{769702006});
+ BOOST_CHECK_EQUAL(GetRandMicros(std::chrono::hours{1}).count(), 2917185654);
+ BOOST_CHECK_EQUAL(GetRandMillis(std::chrono::hours{1}).count(), 2144374);
}
BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32());
BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32());
@@ -47,6 +49,8 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests)
for (int i = 10; i > 0; --i) {
BOOST_CHECK(GetRand(std::numeric_limits<uint64_t>::max()) != uint64_t{10393729187455219830U});
BOOST_CHECK(GetRandInt(std::numeric_limits<int>::max()) != int{769702006});
+ BOOST_CHECK(GetRandMicros(std::chrono::hours{1}) != std::chrono::microseconds{2917185654});
+ BOOST_CHECK(GetRandMillis(std::chrono::hours{1}) != std::chrono::milliseconds{2144374});
}
{
FastRandomContext ctx3, ctx4;
@@ -87,7 +91,7 @@ BOOST_AUTO_TEST_CASE(stdrandom_test)
BOOST_CHECK(x >= 3);
BOOST_CHECK(x <= 9);
- std::vector<int> test{1,2,3,4,5,6,7,8,9,10};
+ std::vector<int> test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::shuffle(test.begin(), test.end(), ctx);
for (int j = 1; j <= 10; ++j) {
BOOST_CHECK(std::find(test.begin(), test.end(), j) != test.end());
@@ -97,7 +101,6 @@ BOOST_AUTO_TEST_CASE(stdrandom_test)
BOOST_CHECK(std::find(test.begin(), test.end(), j) != test.end());
}
}
-
}
/** Test that Shuffle reaches every permutation with equal probability. */
diff --git a/src/test/validationinterface_tests.cpp b/src/test/validationinterface_tests.cpp
index d2fc20e625..ceba689e52 100644
--- a/src/test/validationinterface_tests.cpp
+++ b/src/test/validationinterface_tests.cpp
@@ -23,7 +23,7 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
// Start thread to generate notifications
std::thread gen{[&] {
const CBlock block_dummy;
- const BlockValidationState state_dummy;
+ BlockValidationState state_dummy;
while (generate) {
GetMainSignals().BlockChecked(block_dummy, state_dummy);
}
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 11c96deefb..c84a7e7c12 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -185,8 +185,18 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
config = configparser.ConfigParser()
config.read_file(open(self.options.configfile))
self.config = config
- self.options.bitcoind = os.getenv("BITCOIND", default=config["environment"]["BUILDDIR"] + '/src/bitcoind' + config["environment"]["EXEEXT"])
- self.options.bitcoincli = os.getenv("BITCOINCLI", default=config["environment"]["BUILDDIR"] + '/src/bitcoin-cli' + config["environment"]["EXEEXT"])
+ fname_bitcoind = os.path.join(
+ config["environment"]["BUILDDIR"],
+ "src",
+ "bitcoind" + config["environment"]["EXEEXT"]
+ )
+ fname_bitcoincli = os.path.join(
+ config["environment"]["BUILDDIR"],
+ "src",
+ "bitcoin-cli" + config["environment"]["EXEEXT"]
+ )
+ self.options.bitcoind = os.getenv("BITCOIND", default=fname_bitcoind)
+ self.options.bitcoincli = os.getenv("BITCOINCLI", default=fname_bitcoincli)
self.options.previous_releases_path = os.getenv("PREVIOUS_RELEASES_DIR") or os.getcwd() + "/releases"