Skip to content

Commit

Permalink
Merge #12775: Integration of property based testing into Bitcoin Core
Browse files Browse the repository at this point in the history
b2f49bd Integration of property based testing into Bitcoin Core (Chris Stewart)

Pull request description:

  This PR is a subset of the changes in #8469. It's meant to be easier to review. This PR contains all of the build instructions needed for travis to pass. It includes one property call `key_properties.cpp` along with a generator file called `crypto_gen.{h,cpp}`.

Tree-SHA512: 895c9d9273dcd29f696b1de8dfe1ee843095831bf1f68472844181278850bec36b20f0ba7e51e796112c5cc75cd24759f9f1771906503bbf3af16f627e18c6c9
  • Loading branch information
laanwj committed Sep 8, 2018
2 parents fb06eb4 + b2f49bd commit eea87ef
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 1 deletion.
22 changes: 22 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions depends/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -93,13 +94,19 @@ 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)

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
Expand Down
1 change: 1 addition & 0 deletions depends/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions depends/packages/packages.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 18 additions & 0 deletions depends/packages/rapidcheck.mk
Original file line number Diff line number Diff line change
@@ -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
12 changes: 11 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -95,6 +96,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/psbt_wallet_tests.cpp \
Expand All @@ -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
Expand Down
19 changes: 19 additions & 0 deletions src/test/gen/crypto_gen.cpp
Original file line number Diff line number Diff line change
@@ -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;
});
};
63 changes: 63 additions & 0 deletions src/test/gen/crypto_gen.h
Original file line number Diff line number Diff line change
@@ -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
53 changes: 53 additions & 0 deletions src/test/key_properties.cpp
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit eea87ef

Please sign in to comment.