aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Stewart <stewart.chris1234@gmail.com>2018-03-24 18:37:10 -0500
committerChris Stewart <stewart.chris1234@gmail.com>2018-08-27 08:51:51 -0500
commitb2f49bd7325989267017260a9e7c843588a8c237 (patch)
treef1ffe8bfbb8f3ff6cf210e24b3e9250097892f15
parentca4510c15da2f42a1769b9cab0e26d3f855a93b3 (diff)
downloadbitcoin-b2f49bd7325989267017260a9e7c843588a8c237.tar.xz
Integration of property based testing into Bitcoin Core
update copyright headers attempt to fix linting errors Fixing issue with make check classifying generator files as actual unit tests Wrapping gen files in ENABLE_PROPERTY_TESTS macro Make macro better
-rw-r--r--configure.ac22
-rw-r--r--depends/Makefile7
-rw-r--r--depends/README.md1
-rw-r--r--depends/packages/packages.mk2
-rw-r--r--depends/packages/rapidcheck.mk18
-rw-r--r--src/Makefile.test.include12
-rw-r--r--src/test/gen/crypto_gen.cpp19
-rw-r--r--src/test/gen/crypto_gen.h63
-rw-r--r--src/test/key_properties.cpp53
9 files changed, 196 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 4275796b50..0b96e15b9e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,12 @@ AC_ARG_ENABLE(gui-tests,
[use_gui_tests=$enableval],
[use_gui_tests=$use_tests])
+AC_ARG_WITH([rapidcheck],
+ [AS_HELP_STRING([--with-rapidcheck],
+ [enable RapidCheck property based tests (default is yes if librapidcheck is found)])],
+ [use_rapidcheck=$withval],
+ [use_rapidcheck=auto])
+
AC_ARG_ENABLE(bench,
AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]),
[use_bench=$enableval],
@@ -1134,6 +1140,22 @@ AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT
])
CXXFLAGS="${save_CXXFLAGS}"
+dnl RapidCheck Property Based Testing
+
+enable_property_tests=no
+if test "x$use_rapidcheck" = xauto; then
+ AC_CHECK_HEADERS([rapidcheck.h], [enable_property_tests=yes])
+elif test "x$use_rapidcheck" != xno; then
+ enable_property_tests=yes
+fi
+
+RAPIDCHECK_LIBS=
+if test "x$enable_property_tests" = xyes; then
+ RAPIDCHECK_LIBS=-lrapidcheck
+fi
+AC_SUBST(RAPIDCHECK_LIBS)
+AM_CONDITIONAL([ENABLE_PROPERTY_TESTS], [test x$enable_property_tests = xyes])
+
dnl univalue check
need_bundled_univalue=yes
diff --git a/depends/Makefile b/depends/Makefile
index 3686aaf1f8..da81c4c7ee 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -5,6 +5,7 @@ WORK_PATH = $(BASEDIR)/work
BASE_CACHE ?= $(BASEDIR)/built
SDK_PATH ?= $(BASEDIR)/SDKs
NO_QT ?=
+RAPIDCHECK ?=
NO_WALLET ?=
NO_UPNP ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
@@ -93,6 +94,8 @@ qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch
wallet_packages_$(NO_WALLET) = $(wallet_packages)
upnp_packages_$(NO_UPNP) = $(upnp_packages)
+rapidcheck_packages_$(RAPIDCHECK) = $(rapidcheck_packages)
+
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
@@ -100,6 +103,10 @@ ifneq ($(qt_packages_),)
native_packages += $(qt_native_packages)
endif
+ifeq ($(rapidcheck_packages_),)
+packages += $(rapidcheck_packages)
+endif
+
all_packages = $(packages) $(native_packages)
meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
diff --git a/depends/README.md b/depends/README.md
index fd343f7010..73bfc8b726 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -63,6 +63,7 @@ The following can be set when running make: make FOO=bar
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
DEBUG: disable some optimizations and enable more runtime checking
+ RAPIDCHECK: build rapidcheck (experimental)
HOST_ID_SALT: Optional salt to use when generating host package ids
BUILD_ID_SALT: Optional salt to use when generating build package ids
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
index 5fe6f98da2..38329d16d7 100644
--- a/depends/packages/packages.mk
+++ b/depends/packages/packages.mk
@@ -5,6 +5,8 @@ qt_packages = qrencode protobuf zlib
qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
+rapidcheck_packages = rapidcheck
+
qt_darwin_packages=qt
qt_mingw32_packages=qt
diff --git a/depends/packages/rapidcheck.mk b/depends/packages/rapidcheck.mk
new file mode 100644
index 0000000000..19cf1cae2e
--- /dev/null
+++ b/depends/packages/rapidcheck.mk
@@ -0,0 +1,18 @@
+package=rapidcheck
+$(package)_version=10fc0cb
+$(package)_download_path=https://github.com/MarcoFalke/rapidcheck/archive
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=9640926223c00af45bce4c7df8b756b5458a89b2ba74cfe3e404467f13ce26df
+
+define $(package)_config_cmds
+ cmake -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true .
+endef
+
+define $(package)_build_cmds
+ $(MAKE) && \
+ mkdir -p $($(package)_staging_dir)$(host_prefix)/include && \
+ cp -a include/* $($(package)_staging_dir)$(host_prefix)/include/ && \
+ cp -a extras/boost_test/include/rapidcheck/* $($(package)_staging_dir)$(host_prefix)/include/rapidcheck/ && \
+ mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \
+ cp -a librapidcheck.a $($(package)_staging_dir)$(host_prefix)/lib/
+endef
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 9e7d0dc745..f515774b79 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -8,6 +8,7 @@ TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
JSON_TEST_FILES = \
+ test/data/script_tests.json \
test/data/base58_encode_decode.json \
test/data/blockfilters.json \
test/data/key_io_valid.json \
@@ -94,6 +95,15 @@ BITCOIN_TESTS =\
test/validation_block_tests.cpp \
test/versionbits_tests.cpp
+if ENABLE_PROPERTY_TESTS
+BITCOIN_TESTS += \
+ test/key_properties.cpp
+
+BITCOIN_TEST_SUITE += \
+ test/gen/crypto_gen.cpp \
+ test/gen/crypto_gen.h
+endif
+
if ENABLE_WALLET
BITCOIN_TESTS += \
wallet/test/accounting_tests.cpp \
@@ -118,7 +128,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
-test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
+test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS)
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
if ENABLE_ZMQ
diff --git a/src/test/gen/crypto_gen.cpp b/src/test/gen/crypto_gen.cpp
new file mode 100644
index 0000000000..ca8c65806f
--- /dev/null
+++ b/src/test/gen/crypto_gen.cpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <test/gen/crypto_gen.h>
+
+#include <key.h>
+
+#include <rapidcheck/gen/Arbitrary.h>
+#include <rapidcheck/Gen.h>
+#include <rapidcheck/gen/Predicate.h>
+#include <rapidcheck/gen/Container.h>
+
+/** Generates 1 to 20 keys for OP_CHECKMULTISIG */
+rc::Gen<std::vector<CKey>> MultisigKeys()
+{
+ return rc::gen::suchThat(rc::gen::arbitrary<std::vector<CKey>>(), [](const std::vector<CKey>& keys) {
+ return keys.size() >= 1 && keys.size() <= 15;
+ });
+};
diff --git a/src/test/gen/crypto_gen.h b/src/test/gen/crypto_gen.h
new file mode 100644
index 0000000000..7c2fb0350f
--- /dev/null
+++ b/src/test/gen/crypto_gen.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_TEST_GEN_CRYPTO_GEN_H
+#define BITCOIN_TEST_GEN_CRYPTO_GEN_H
+
+#include <key.h>
+#include <random.h>
+#include <uint256.h>
+#include <rapidcheck/gen/Arbitrary.h>
+#include <rapidcheck/Gen.h>
+#include <rapidcheck/gen/Create.h>
+#include <rapidcheck/gen/Numeric.h>
+
+/** Generates 1 to 15 keys for OP_CHECKMULTISIG */
+rc::Gen<std::vector<CKey>> MultisigKeys();
+
+namespace rc
+{
+/** Generator for a new CKey */
+template <>
+struct Arbitrary<CKey> {
+ static Gen<CKey> arbitrary()
+ {
+ return rc::gen::map<int>([](int x) {
+ CKey key;
+ key.MakeNewKey(true);
+ return key;
+ });
+ };
+};
+
+/** Generator for a CPrivKey */
+template <>
+struct Arbitrary<CPrivKey> {
+ static Gen<CPrivKey> arbitrary()
+ {
+ return gen::map(gen::arbitrary<CKey>(), [](const CKey& key) {
+ return key.GetPrivKey();
+ });
+ };
+};
+
+/** Generator for a new CPubKey */
+template <>
+struct Arbitrary<CPubKey> {
+ static Gen<CPubKey> arbitrary()
+ {
+ return gen::map(gen::arbitrary<CKey>(), [](const CKey& key) {
+ return key.GetPubKey();
+ });
+ };
+};
+/** Generates a arbitrary uint256 */
+template <>
+struct Arbitrary<uint256> {
+ static Gen<uint256> arbitrary()
+ {
+ return rc::gen::just(GetRandHash());
+ };
+};
+} //namespace rc
+#endif
diff --git a/src/test/key_properties.cpp b/src/test/key_properties.cpp
new file mode 100644
index 0000000000..14e3c85359
--- /dev/null
+++ b/src/test/key_properties.cpp
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <key.h>
+
+#include <base58.h>
+#include <script/script.h>
+#include <uint256.h>
+#include <util.h>
+#include <utilstrencodings.h>
+#include <test/test_bitcoin.h>
+#include <string>
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+#include <rapidcheck/boost_test.h>
+#include <rapidcheck/gen/Arbitrary.h>
+#include <rapidcheck/Gen.h>
+
+#include <test/gen/crypto_gen.h>
+
+BOOST_FIXTURE_TEST_SUITE(key_properties, BasicTestingSetup)
+
+/** Check CKey uniqueness */
+RC_BOOST_PROP(key_uniqueness, (const CKey& key1, const CKey& key2))
+{
+ RC_ASSERT(!(key1 == key2));
+}
+
+/** Verify that a private key generates the correct public key */
+RC_BOOST_PROP(key_generates_correct_pubkey, (const CKey& key))
+{
+ CPubKey pubKey = key.GetPubKey();
+ RC_ASSERT(key.VerifyPubKey(pubKey));
+}
+
+/** Create a CKey using the 'Set' function must give us the same key */
+RC_BOOST_PROP(key_set_symmetry, (const CKey& key))
+{
+ CKey key1;
+ key1.Set(key.begin(), key.end(), key.IsCompressed());
+ RC_ASSERT(key1 == key);
+}
+
+/** Create a CKey, sign a piece of data, then verify it with the public key */
+RC_BOOST_PROP(key_sign_symmetry, (const CKey& key, const uint256& hash))
+{
+ std::vector<unsigned char> vchSig;
+ key.Sign(hash, vchSig, 0);
+ const CPubKey& pubKey = key.GetPubKey();
+ RC_ASSERT(pubKey.Verify(hash, vchSig));
+}
+BOOST_AUTO_TEST_SUITE_END()