From f381e4988c1562f0f64533146c9b9cb7c0823b3e Mon Sep 17 00:00:00 2001 From: Alex Shabalin Date: Thu, 15 Feb 2024 11:41:34 +0100 Subject: [PATCH 1/2] Use Catch2 v3 --- .devcontainer/Dockerfile | 9 + .devcontainer/devcontainer.json | 36 ++++ .github/workflows/test.yml | 27 ++- .gitignore | 2 + default.nix | 66 +++--- flake.lock | 146 +++++++++++++ flake.nix | 131 ++++++++++++ immer/experimental/detail/dvektor_impl.hpp | 17 +- immer/heap/gc_heap.hpp | 2 +- nix/benchmarks.nix | 36 ++-- nix/catch2_3.nix | 49 +++++ nix/docs.nix | 47 +++-- nix/immer.nix | 23 ++ shell-compat.nix | 14 ++ shell.nix | 235 ++++++++++++++------- test/CMakeLists.txt | 6 +- test/algorithm.cpp | 2 +- test/atom/generic.ipp | 2 +- test/box/generic.ipp | 2 +- test/box/recursive.cpp | 2 +- test/box/vector-of-boxes-transient.cpp | 2 +- test/detail/type_traits.cpp | 2 +- test/experimental/dvektor.cpp | 7 +- test/flex_vector/fuzzed-0.cpp | 2 +- test/flex_vector/fuzzed-1.cpp | 2 +- test/flex_vector/fuzzed-2.cpp | 2 +- test/flex_vector/fuzzed-3.cpp | 2 +- test/flex_vector/fuzzed-4.cpp | 2 +- test/flex_vector/generic.ipp | 14 +- test/flex_vector/issue-45.cpp | 7 +- test/flex_vector_transient/generic.ipp | 26 ++- test/map/generic.ipp | 39 ++-- test/map/issue-56.cpp | 2 +- test/map_transient/generic.ipp | 4 +- test/memory/heaps.cpp | 2 +- test/memory/refcounts.cpp | 2 +- test/oss-fuzz/array-0.cpp | 2 +- test/oss-fuzz/array-gc-0.cpp | 2 +- test/oss-fuzz/flex-vector-0.cpp | 2 +- test/oss-fuzz/flex-vector-bo-0.cpp | 2 +- test/oss-fuzz/flex-vector-gc-0.cpp | 2 +- test/oss-fuzz/map-gc-0.cpp | 2 +- test/oss-fuzz/map-st-0.cpp | 2 +- test/oss-fuzz/map-st-1.cpp | 2 +- test/oss-fuzz/map-st-2.cpp | 2 +- test/oss-fuzz/map-st-str-0.cpp | 2 +- test/oss-fuzz/set-gc-0.cpp | 2 +- test/oss-fuzz/set-gc-1.cpp | 2 +- test/oss-fuzz/set-st-0.cpp | 2 +- test/oss-fuzz/set-st-str-0.cpp | 2 +- test/set/generic.ipp | 33 ++- test/set_transient/generic.ipp | 4 +- test/table/generic.ipp | 24 ++- test/table_transient/generic.ipp | 4 +- test/vector/generic.ipp | 20 +- test/vector/issue-177.cpp | 2 +- test/vector/issue-46.cpp | 2 +- test/vector_transient/generic.ipp | 11 +- 58 files changed, 834 insertions(+), 265 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/catch2_3.nix create mode 100644 nix/immer.nix create mode 100644 shell-compat.nix diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..fb730ad6 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,9 @@ +FROM mcr.microsoft.com/devcontainers/base:ubuntu + +# cache /nix +VOLUME /nix + +RUN curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux \ + --extra-conf "sandbox = false" \ + --init none \ + --no-confirm diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..fe40e987 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,36 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "Ubuntu", + "dockerFile": "Dockerfile", + "context": "${localWorkspaceFolder}", + "runArgs": [ + "--security-opt", + "label=disable" + ], + "mounts": [ + "source=nix-ubuntu-container,target=/nix,type=volume" + ], + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + // "image": "mcr.microsoft.com/devcontainers/base:${templateOption:imageVariant}" + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": [ + "xaver.clang-format", + "arrterian.nix-env-selector", + "ms-vscode.cpptools", + "kamadorueda.alejandra" + ] + } + }, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // We need root because nix without systemd works only as root. + "remoteUser": "root" +} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 253215f1..ff577814 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,22 +4,19 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # needed for fetchGit in default.nix - - uses: cachix/install-nix-action@v20 - with: - nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@v12 + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v25 + - uses: cachix/cachix-action@v14 with: name: arximboldi signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' - - run: nix-build + - run: nix build + - run: nix flake check -L build-spm: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - run: swift build @@ -27,13 +24,13 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - uses: cachix/install-nix-action@v20 + - uses: cachix/install-nix-action@v25 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@v12 + - uses: cachix/cachix-action@v14 with: name: arximboldi signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' @@ -92,11 +89,11 @@ jobs: opts: ['benchmark'] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v20 + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v25 with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@v12 + - uses: cachix/cachix-action@v14 with: name: arximboldi signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' diff --git a/.gitignore b/.gitignore index 46c3c7c2..09b6a02c 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ tools/clojure/.lein* .build .swiftpm +.vscode +.pre-commit-config.yaml diff --git a/default.nix b/default.nix index b2ab20d0..3e33fb56 100644 --- a/default.nix +++ b/default.nix @@ -1,36 +1,36 @@ -{ pkgs ? import {} }: - -with pkgs; - -let - inherit (import (pkgs.fetchFromGitHub { - owner = "hercules-ci"; - repo = "gitignore.nix"; - rev = "80463148cd97eebacf80ba68cf0043598f0d7438"; - sha256 = "1l34rmh4lf4w8a1r8vsvkmg32l1chl0p593fl12r28xx83vn150v"; - }) {}) gitignoreSource; +{pkgs ? import {}}: +with pkgs; let + inherit + (import (pkgs.fetchFromGitHub { + owner = "hercules-ci"; + repo = "gitignore.nix"; + rev = "80463148cd97eebacf80ba68cf0043598f0d7438"; + sha256 = "1l34rmh4lf4w8a1r8vsvkmg32l1chl0p593fl12r28xx83vn150v"; + }) {}) + gitignoreSource + ; nixFilter = name: type: !(lib.hasSuffix ".nix" name); - srcFilter = src: lib.cleanSourceWith { - filter = nixFilter; - src = gitignoreSource src; - }; - + srcFilter = src: + lib.cleanSourceWith { + filter = nixFilter; + src = gitignoreSource src; + }; in -stdenv.mkDerivation rec { - name = "immer-git"; - version = "git"; - src = srcFilter ./.; - nativeBuildInputs = [ cmake ]; - dontBuild = true; - dontUseCmakeBuildDir = true; - cmakeFlags = [ - "-Dimmer_BUILD_TESTS=OFF" - "-Dimmer_BUILD_EXAMPLES=OFF" - ]; - meta = { - homepage = "https://github.com/arximboldi/immer"; - description = "Postmodern immutable data structures for C++"; - license = lib.licenses.boost; - }; -} + stdenv.mkDerivation rec { + name = "immer-git"; + version = "git"; + src = srcFilter ./.; + nativeBuildInputs = [cmake]; + dontBuild = true; + dontUseCmakeBuildDir = true; + cmakeFlags = [ + "-Dimmer_BUILD_TESTS=OFF" + "-Dimmer_BUILD_EXAMPLES=OFF" + ]; + meta = { + homepage = "https://github.com/arximboldi/immer"; + description = "Postmodern immutable data structures for C++"; + license = lib.licenses.boost; + }; + } diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..523601b0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,146 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1706925685, + "narHash": "sha256-hVInjWMmgH4yZgA4ZtbgJM1qEAel72SYhP5nOWX4UIM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "79a13f1437e149dc7be2d1290c74d378dad60814", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "flake-utils": [ + "flake-utils" + ], + "gitignore": [ + "gitignore" + ], + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1706424699, + "narHash": "sha256-Q3RBuOpZNH2eFA1e+IHgZLAOqDD9SKhJ/sszrL8bQD4=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..0f67ca16 --- /dev/null +++ b/flake.nix @@ -0,0 +1,131 @@ +{ + description = "Immutable data structures"; + + inputs = { + nixpkgs.url = github:NixOS/nixpkgs/nixpkgs-unstable; + flake-utils.url = "github:numtide/flake-utils"; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + gitignore = { + url = "github:hercules-ci/gitignore.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + pre-commit-hooks = { + url = "github:cachix/pre-commit-hooks.nix"; + inputs = { + flake-compat.follows = "flake-compat"; + flake-utils.follows = "flake-utils"; + gitignore.follows = "gitignore"; + nixpkgs.follows = "nixpkgs"; + }; + }; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + flake-compat, + pre-commit-hooks, + gitignore, + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + withLLVM = drv: + if pkgs.stdenv.isLinux + # Use LLVM for Linux to build fuzzers + then drv.override {stdenv = pkgs.llvmPackages_latest.stdenv;} + # macOS uses LLVM by default + else drv; + in { + checks = + { + pre-commit-check = pre-commit-hooks.lib.${system}.run { + src = ./.; + hooks = { + alejandra.enable = true; + }; + }; + + inherit (self.packages.${system}) unit-tests; + } + // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux { + unit-tests-valgrind = self.packages.${system}.unit-tests.overrideAttrs (prev: { + nativeBuildInputs = with pkgs; prev.nativeBuildInputs ++ [valgrind]; + name = "immer-unit-tests-valgrind"; + ninjaFlags = ["tests"]; + checkPhase = '' + ctest -D ExperimentalMemCheck + ''; + }); + }; + + devShells.default = (withLLVM pkgs.mkShell) { + NIX_HARDENING_ENABLE = ""; + inputsFrom = [ + (import ./shell.nix { + inherit system nixpkgs; + }) + ]; + + packages = [ + # for the llvm-symbolizer binary, that allows to show stacks in ASAN and LeakSanitizer. + pkgs.llvmPackages_latest.bintools-unwrapped + ]; + + shellHook = + self.checks.${system}.pre-commit-check.shellHook; + }; + + packages = { + immer = let + inherit (gitignore.lib) gitignoreSource; + nixFilter = name: type: !(pkgs.lib.hasSuffix ".nix" name); + srcFilter = src: + pkgs.lib.cleanSourceWith { + filter = nixFilter; + src = gitignoreSource src; + }; + in + pkgs.callPackage nix/immer.nix {src = srcFilter ./.;}; + + default = self.packages.${system}.immer; + + fuzzers-debug = (withLLVM self.packages.${system}.immer).overrideAttrs (prev: { + buildInputs = with pkgs; [catch2_3 boehmgc boost fmt]; + nativeBuildInputs = with pkgs; [cmake ninja]; + dontBuild = false; + dontStrip = true; + # fuzzers target is not built by default + ninjaFlags = ["fuzzers"]; + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Debug" + "-Dimmer_BUILD_TESTS=OFF" + "-Dimmer_BUILD_EXAMPLES=OFF" + "-Dimmer_INSTALL_FUZZERS=ON" + "-DENABLE_ASAN=ON" + ]; + }); + + unit-tests = (withLLVM self.packages.${system}.immer).overrideAttrs (prev: { + name = "immer-unit-tests"; + buildInputs = with pkgs; [catch2_3 boehmgc boost fmt]; + nativeBuildInputs = with pkgs; [cmake ninja]; + dontBuild = false; + doCheck = true; + # Building fuzzers but not running them, just to ensure they compile + ninjaFlags = ["fuzzers tests"]; + checkPhase = '' + ninja test + ''; + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Debug" + "-Dimmer_BUILD_TESTS=ON" + "-Dimmer_BUILD_EXAMPLES=OFF" + ]; + }); + }; + }); +} diff --git a/immer/experimental/detail/dvektor_impl.hpp b/immer/experimental/detail/dvektor_impl.hpp index 4f697337..7a21f1f9 100644 --- a/immer/experimental/detail/dvektor_impl.hpp +++ b/immer/experimental/detail/dvektor_impl.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -36,8 +37,8 @@ template constexpr T mask = branches - 1; template -constexpr auto - max_depth = fast_log2(std::numeric_limits::max()) / B; +constexpr auto max_depth = + fast_log2(std::numeric_limits::max()) / B; template struct node; @@ -71,10 +72,12 @@ struct node inner_node_t inner; data_t(leaf_node_t n) : leaf(std::move(n)) - {} + { + } data_t(inner_node_t n) : inner(std::move(n)) - {} + { + } ~data_t() {} } data; @@ -93,12 +96,14 @@ struct node node(leaf_node n) : kind{leaf_kind} , data{std::move(n)} - {} + { + } node(inner_node n) : kind{inner_kind} , data{std::move(n)} - {} + { + } inner_node_t& inner() & { diff --git a/immer/heap/gc_heap.hpp b/immer/heap/gc_heap.hpp index 8fc7754e..bc7508fd 100644 --- a/immer/heap/gc_heap.hpp +++ b/immer/heap/gc_heap.hpp @@ -26,7 +26,7 @@ namespace immer { #ifdef IMMER_GC_REQUIRE_INIT #define IMMER_GC_REQUIRE_INIT_ IMMER_GC_REQUIRE_INIT -#elifdef __APPLE__ +#elif defined __APPLE__ #define IMMER_GC_REQUIRE_INIT_ 1 #else #define IMMER_GC_REQUIRE_INIT_ 0 diff --git a/nix/benchmarks.nix b/nix/benchmarks.nix index 905ff034..0555e7c0 100644 --- a/nix/benchmarks.nix +++ b/nix/benchmarks.nix @@ -1,8 +1,10 @@ -{ nixpkgs ? }: - -with import nixpkgs {}; - -rec { +{ + stdenv, + lib, + autoreconfHook, + boehmgc, + fetchFromGitHub, +}: { c_rrb = stdenv.mkDerivation rec { name = "c-rrb-${version}"; version = "git-${commit}"; @@ -13,12 +15,12 @@ rec { rev = commit; sha256 = "0zmha3xi80vgdcwzb4vwdllf97dvggjpjfgahrpsb5f5qi3yshxa"; }; - nativeBuildInputs = [ autoreconfHook ]; - propagatedBuildInputs = [ boehmgc ]; - meta = with lib; { + nativeBuildInputs = [autoreconfHook]; + propagatedBuildInputs = [boehmgc]; + meta = { homepage = "http://hypirion.com/thesis"; description = "RRB-tree implemented as a library in C. "; - license = licenses.mit; + license = lib.licenses.mit; }; }; @@ -34,10 +36,10 @@ rec { }; dontBuild = true; installPhase = "mkdir -vp $out/include; cp -vr $src/steady $out/include/"; - meta = with lib; { + meta = { homepage = "https://github.com/marcusz/steady"; description = "This is a fast and reliable persistent (immutable) vector class for C++"; - license = licenses.asl20; + license = lib.licenses.asl20; }; }; @@ -53,10 +55,10 @@ rec { }; dontBuild = true; installPhase = "mkdir -vp $out/include/chunkedseq; cp -vr $src/include/* $out/include/chunkedseq/"; - meta = with lib; { + meta = { homepage = "http://deepsea.inria.fr/chunkedseq"; description = "Container data structure for representing sequences by many fixed-capacity heap-allocated buffers--chunks"; - license = licenses.mit; + license = lib.licenses.mit; }; }; @@ -72,10 +74,10 @@ rec { }; dontBuild = true; installPhase = "mkdir -vp $out/include; cp -vr $src/immutable $out/include/"; - meta = with lib; { + meta = { homepage = "https://github.com/rsms/immutable-cpp"; description = "Persistent immutable data structures for C++"; - license = licenses.mit; + license = lib.licenses.mit; }; }; @@ -91,10 +93,10 @@ rec { }; dontBuild = true; installPhase = "mkdir -vp $out/include; cp -vr $src/hash_trie.hpp $out/include/"; - meta = with lib; { + meta = { homepage = "https://github.com/rsms/immutable-cpp"; description = "Persistent immutable data structures for C++"; - license = licenses.mit; + license = lib.licenses.mit; }; }; } diff --git a/nix/catch2_3.nix b/nix/catch2_3.nix new file mode 100644 index 00000000..d6db9e2b --- /dev/null +++ b/nix/catch2_3.nix @@ -0,0 +1,49 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + python3, +}: +stdenv.mkDerivation rec { + pname = "catch2"; + version = "3.5.2"; + + src = fetchFromGitHub { + owner = "catchorg"; + repo = "Catch2"; + rev = "v${version}"; + hash = "sha256-xGPfXjk+oOnR7JqTrZd2pKJxalrlS8CMs7HWDClXaS8="; + }; + + nativeBuildInputs = [ + cmake + python3 + ]; + + cmakeFlags = + [ + "-DCATCH_DEVELOPMENT_BUILD=ON" + "-DCATCH_BUILD_TESTING=${ + if doCheck + then "ON" + else "OFF" + }" + ] + ++ lib.optionals (stdenv.isDarwin && doCheck) [ + # test has a faulty path normalization technique that won't work in + # our darwin build environment https://github.com/catchorg/Catch2/issues/1691 + "-DCMAKE_CTEST_ARGUMENTS=-E;ApprovalTests" + ]; + + doCheck = true; + + meta = { + description = "Modern, C++-native, test framework for unit-tests"; + homepage = "https://github.com/catchorg/Catch2"; + changelog = "https://github.com/catchorg/Catch2/blob/${src.rev}/docs/release-notes.md"; + license = lib.licenses.boost; + maintainers = with lib.maintainers; [dotlambda]; + platforms = with lib.platforms; unix ++ windows; + }; +} diff --git a/nix/docs.nix b/nix/docs.nix index f885e6d9..ca8471cd 100644 --- a/nix/docs.nix +++ b/nix/docs.nix @@ -1,27 +1,28 @@ -{ nixpkgs ? }: - -with import nixpkgs {}; - -rec { - breathe = with python27Packages; buildPythonPackage rec { - version = "git-arximboldi-${commit}"; - pname = "breathe"; - name = "${pname}-${version}"; - commit = "5074aecb5ad37bb70f50216eaa01d03a375801ec"; - src = fetchFromGitHub { - owner = "arximboldi"; - repo = "breathe"; - rev = commit; - sha256 = "10kkh3wb0ggyxx1a7x50aklhhw0cq269g3jddf2gb3pv9gpbj7sa"; - }; - propagatedBuildInputs = [ docutils sphinx ]; - meta = with stdenv.lib; { - homepage = https://github.com/michaeljones/breathe; - license = licenses.bsd3; - description = "Sphinx Doxygen renderer"; - inherit (sphinx.meta) platforms; +{ + python27Packages, + stdenv, + fetchFromGitHub, +}: rec { + breathe = with python27Packages; + buildPythonPackage rec { + version = "git-arximboldi-${commit}"; + pname = "breathe"; + name = "${pname}-${version}"; + commit = "5074aecb5ad37bb70f50216eaa01d03a375801ec"; + src = fetchFromGitHub { + owner = "arximboldi"; + repo = "breathe"; + rev = commit; + sha256 = "10kkh3wb0ggyxx1a7x50aklhhw0cq269g3jddf2gb3pv9gpbj7sa"; + }; + propagatedBuildInputs = [docutils sphinx]; + meta = with stdenv.lib; { + homepage = https://github.com/michaeljones/breathe; + license = licenses.bsd3; + description = "Sphinx Doxygen renderer"; + inherit (sphinx.meta) platforms; + }; }; - }; recommonmark = python27Packages.recommonmark; } diff --git a/nix/immer.nix b/nix/immer.nix new file mode 100644 index 00000000..77dc7736 --- /dev/null +++ b/nix/immer.nix @@ -0,0 +1,23 @@ +{ + stdenv, + cmake, + lib, + src, +}: +stdenv.mkDerivation { + name = "immer-git"; + version = "git"; + inherit src; + nativeBuildInputs = [cmake]; + dontBuild = true; + dontUseCmakeBuildDir = true; + cmakeFlags = [ + "-Dimmer_BUILD_TESTS=OFF" + "-Dimmer_BUILD_EXAMPLES=OFF" + ]; + meta = { + homepage = "https://github.com/arximboldi/immer"; + description = "Postmodern immutable data structures for C++"; + license = lib.licenses.boost; + }; +} diff --git a/shell-compat.nix b/shell-compat.nix new file mode 100644 index 00000000..e6d91731 --- /dev/null +++ b/shell-compat.nix @@ -0,0 +1,14 @@ +( + import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + {src = ./.;} +) +.shellNix diff --git a/shell.nix b/shell.nix index 1dfbe1eb..cc2c4c8f 100644 --- a/shell.nix +++ b/shell.nix @@ -1,76 +1,165 @@ -{ toolchain ? "", - rev ? "08ef0f28e3a41424b92ba1d203de64257a9fca6a", - sha256 ? "1mql1gp86bk6pfsrp0lcww6hw5civi6f8542d4nh356506jdxmcy", - nixpkgs ? builtins.fetchTarball { - name = "nixpkgs-${rev}"; - url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz"; - sha256 = sha256; - }, -}: - -with import nixpkgs {}; - -let +{ + toolchain ? "", + rev ? "08ef0f28e3a41424b92ba1d203de64257a9fca6a", + sha256 ? "1mql1gp86bk6pfsrp0lcww6hw5civi6f8542d4nh356506jdxmcy", + nixpkgs ? + builtins.fetchTarball { + name = "nixpkgs-${rev}"; + url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz"; + sha256 = sha256; + }, + ... +} @ args: let # For the documentation tools we use an older Nixpkgs since the # newer versions seem to be not working great... - oldNixpkgsSrc = fetchFromGitHub { - owner = "NixOS"; - repo = "nixpkgs"; - rev = "d0d905668c010b65795b57afdf7f0360aac6245b"; - sha256 = "1kqxfmsik1s1jsmim20n5l4kq6wq8743h5h17igfxxbbwwqry88l"; - }; - oldNixpkgs = import oldNixpkgsSrc {}; - docs = import ./nix/docs.nix { nixpkgs = oldNixpkgsSrc; }; - benchmarks = import ./nix/benchmarks.nix { inherit nixpkgs; }; - tc = - if toolchain == "" then { stdenv = stdenv; cc = stdenv.cc; } else - if toolchain == "gnu-6" then { stdenv = gcc6Stdenv; cc = gcc6; } else - if toolchain == "gnu-7" then { stdenv = gcc7Stdenv; cc = gcc7; } else - if toolchain == "gnu-8" then { stdenv = gcc8Stdenv; cc = gcc8; } else - if toolchain == "gnu-9" then { stdenv = gcc9Stdenv; cc = gcc9; } else - if toolchain == "gnu-10" then { stdenv = gcc10Stdenv; cc = gcc10; } else - if toolchain == "gnu-11" then { stdenv = gcc11Stdenv; cc = gcc11; } else - if toolchain == "llvm-39" then { stdenv = llvmPackages_39.libcxxStdenv; cc = llvmPackages_39.libcxxClang; } else - if toolchain == "llvm-4" then { stdenv = llvmPackages_4.libcxxStdenv; cc = llvmPackages_4.libcxxClang; } else - if toolchain == "llvm-5" then { stdenv = llvmPackages_5.libcxxStdenv; cc = llvmPackages_5.libcxxClang; } else - if toolchain == "llvm-6" then { stdenv = llvmPackages_6.libcxxStdenv; cc = llvmPackages_6.libcxxClang; } else - if toolchain == "llvm-7" then { stdenv = llvmPackages_7.libcxxStdenv; cc = llvmPackages_7.libcxxClang; } else - if toolchain == "llvm-8" then { stdenv = llvmPackages_8.libcxxStdenv; cc = llvmPackages_8.libcxxClang; } else - if toolchain == "llvm-9" then { stdenv = llvmPackages_9.stdenv; cc = llvmPackages_9.clang; } else - if toolchain == "llvm-10" then { stdenv = llvmPackages_10.stdenv; cc = llvmPackages_10.clang; } else - if toolchain == "llvm-11" then { stdenv = llvmPackages_11.stdenv; cc = llvmPackages_11.clang; } else - if toolchain == "llvm-12" then { stdenv = llvmPackages_12.stdenv; cc = llvmPackages_12.clang; } else - if toolchain == "llvm-13" then { stdenv = llvmPackages_13.stdenv; cc = llvmPackages_13.clang; } else - abort "unknown toolchain"; - + pkgs = import nixpkgs ( + if args ? system + then {inherit (args) system;} + else {} + ); + catch2_3 = + if pkgs ? catch2_3 + then pkgs.catch2_3 + else + pkgs.callPackage ./nix/catch2_3.nix { + stdenv = tc.stdenv; + }; + oldNixpkgsSrc = pkgs.fetchFromGitHub { + owner = "NixOS"; + repo = "nixpkgs"; + rev = "d0d905668c010b65795b57afdf7f0360aac6245b"; + sha256 = "1kqxfmsik1s1jsmim20n5l4kq6wq8743h5h17igfxxbbwwqry88l"; + }; + oldNixpkgs = import oldNixpkgsSrc ( + if args ? system + then {inherit (args) system;} + else {} + ); + docs = oldNixpkgs.callPackage ./nix/docs.nix {}; + benchmarks = pkgs.callPackage ./nix/benchmarks.nix {}; + tc = + if toolchain == "" + then { + stdenv = pkgs.stdenv; + cc = pkgs.stdenv.cc; + } + else if toolchain == "gnu-6" + then { + stdenv = pkgs.gcc6Stdenv; + cc = pkgs.gcc6; + } + else if toolchain == "gnu-7" + then { + stdenv = pkgs.gcc7Stdenv; + cc = pkgs.gcc7; + } + else if toolchain == "gnu-8" + then { + stdenv = pkgs.gcc8Stdenv; + cc = pkgs.gcc8; + } + else if toolchain == "gnu-9" + then { + stdenv = pkgs.gcc9Stdenv; + cc = pkgs.gcc9; + } + else if toolchain == "gnu-10" + then { + stdenv = pkgs.gcc10Stdenv; + cc = pkgs.gcc10; + } + else if toolchain == "gnu-11" + then { + stdenv = pkgs.gcc11Stdenv; + cc = pkgs.gcc11; + } + else if toolchain == "llvm-39" + then { + stdenv = pkgs.llvmPackages_39.libcxxStdenv; + cc = pkgs.llvmPackages_39.libcxxClang; + } + else if toolchain == "llvm-4" + then { + stdenv = pkgs.llvmPackages_4.libcxxStdenv; + cc = pkgs.llvmPackages_4.libcxxClang; + } + else if toolchain == "llvm-5" + then { + stdenv = pkgs.llvmPackages_5.libcxxStdenv; + cc = pkgs.llvmPackages_5.libcxxClang; + } + else if toolchain == "llvm-6" + then { + stdenv = pkgs.llvmPackages_6.libcxxStdenv; + cc = pkgs.llvmPackages_6.libcxxClang; + } + else if toolchain == "llvm-7" + then { + stdenv = pkgs.llvmPackages_7.libcxxStdenv; + cc = pkgs.llvmPackages_7.libcxxClang; + } + else if toolchain == "llvm-8" + then { + stdenv = pkgs.llvmPackages_8.libcxxStdenv; + cc = pkgs.llvmPackages_8.libcxxClang; + } + else if toolchain == "llvm-9" + then { + stdenv = pkgs.llvmPackages_9.stdenv; + cc = pkgs.llvmPackages_9.clang; + } + else if toolchain == "llvm-10" + then { + stdenv = pkgs.llvmPackages_10.stdenv; + cc = pkgs.llvmPackages_10.clang; + } + else if toolchain == "llvm-11" + then { + stdenv = pkgs.llvmPackages_11.stdenv; + cc = pkgs.llvmPackages_11.clang; + } + else if toolchain == "llvm-12" + then { + stdenv = pkgs.llvmPackages_12.stdenv; + cc = pkgs.llvmPackages_12.clang; + } + else if toolchain == "llvm-13" + then { + stdenv = pkgs.llvmPackages_13.stdenv; + cc = pkgs.llvmPackages_13.clang; + } + else abort "unknown toolchain"; in -tc.stdenv.mkDerivation rec { - name = "immer-env"; - buildInputs = [ - tc.cc - git - catch2 - cmake - pkgconfig - ninja - gdb - lldb - ccache - boost - boehmgc - fmt - valgrind - benchmarks.c_rrb - benchmarks.steady - benchmarks.chunkedseq - benchmarks.immutable_cpp - benchmarks.hash_trie - oldNixpkgs.doxygen - (oldNixpkgs.python.withPackages (ps: [ - ps.sphinx - docs.breathe - docs.recommonmark - ])) - ]; - hardeningDisable = [ "fortify" ]; -} + tc.stdenv.mkDerivation rec { + name = "immer-env"; + buildInputs = with pkgs; + [ + tc.cc + git + catch2_3 + cmake + pkg-config + ninja + lldb + boost + boehmgc + fmt + ] + ++ lib.optionals stdenv.isLinux [ + gdb + ccache + valgrind + benchmarks.c_rrb + benchmarks.steady + benchmarks.chunkedseq + benchmarks.immutable_cpp + benchmarks.hash_trie + oldNixpkgs.doxygen + (oldNixpkgs.python.withPackages (ps: [ + ps.sphinx + docs.breathe + docs.recommonmark + ])) + ]; + hardeningDisable = ["fortify"]; + } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7fec6adb..590dc775 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,8 +15,8 @@ foreach(_file IN LISTS immer_unit_tests) set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) add_dependencies(tests ${_target}) target_compile_definitions(${_target} PUBLIC - -DIMMER_OSS_FUZZ_DATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/oss-fuzz/data" - CATCH_CONFIG_MAIN) - target_link_libraries(${_target} PUBLIC immer-dev Catch2::Catch2) + -DIMMER_OSS_FUZZ_DATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/oss-fuzz/data") + target_link_libraries(${_target} PUBLIC immer-dev Catch2::Catch2WithMain) + set_target_properties(${_target} PROPERTIES CXX_VISIBILITY_PRESET hidden) add_test("test/${_output}" ${_output}) endforeach() diff --git a/test/algorithm.cpp b/test/algorithm.cpp index 6a785dbd..1be14730 100644 --- a/test/algorithm.cpp +++ b/test/algorithm.cpp @@ -7,7 +7,7 @@ #include -#include +#include struct thing { diff --git a/test/atom/generic.ipp b/test/atom/generic.ipp index 648da315..90c12df1 100644 --- a/test/atom/generic.ipp +++ b/test/atom/generic.ipp @@ -10,7 +10,7 @@ #error "define the box template to use in ATOM_T" #endif -#include +#include template using BOX_T = typename ATOM_T::box_type; diff --git a/test/box/generic.ipp b/test/box/generic.ipp index 72ab9c8b..4e7345a9 100644 --- a/test/box/generic.ipp +++ b/test/box/generic.ipp @@ -10,7 +10,7 @@ #error "define the box template to use in BOX_T" #endif -#include +#include TEST_CASE("construction and copy") { diff --git a/test/box/recursive.cpp b/test/box/recursive.cpp index 46d12043..9635f6e3 100644 --- a/test/box/recursive.cpp +++ b/test/box/recursive.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include struct rec_vec { diff --git a/test/box/vector-of-boxes-transient.cpp b/test/box/vector-of-boxes-transient.cpp index 399be547..386be84c 100644 --- a/test/box/vector-of-boxes-transient.cpp +++ b/test/box/vector-of-boxes-transient.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include TEST_CASE("issue-33") { diff --git a/test/detail/type_traits.cpp b/test/detail/type_traits.cpp index 632a25c9..d46d773b 100644 --- a/test/detail/type_traits.cpp +++ b/test/detail/type_traits.cpp @@ -6,7 +6,7 @@ // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt // -#include +#include #include #include #include diff --git a/test/experimental/dvektor.cpp b/test/experimental/dvektor.cpp index ffdd2e0f..242434fb 100644 --- a/test/experimental/dvektor.cpp +++ b/test/experimental/dvektor.cpp @@ -11,11 +11,11 @@ #include #include +#include #include #include -#include -#include +#include using namespace immer; @@ -158,7 +158,8 @@ TEST_CASE("iterator") { auto s = std::vector(n); std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); + const auto unused = std::equal(v.begin(), v.end(), s.begin(), s.end()); + (void) unused; } SECTION("can go back from end") { CHECK(n - 1 == *--v.end()); } diff --git a/test/flex_vector/fuzzed-0.cpp b/test/flex_vector/fuzzed-0.cpp index ed0c5a66..6737e108 100644 --- a/test/flex_vector/fuzzed-0.cpp +++ b/test/flex_vector/fuzzed-0.cpp @@ -8,7 +8,7 @@ #include "extra/fuzzer/fuzzer_input.hpp" #include -#include +#include #include #include diff --git a/test/flex_vector/fuzzed-1.cpp b/test/flex_vector/fuzzed-1.cpp index 162c78eb..706418d3 100644 --- a/test/flex_vector/fuzzed-1.cpp +++ b/test/flex_vector/fuzzed-1.cpp @@ -8,7 +8,7 @@ #include "extra/fuzzer/fuzzer_input.hpp" #include -#include +#include #include #include diff --git a/test/flex_vector/fuzzed-2.cpp b/test/flex_vector/fuzzed-2.cpp index a058ad61..aa0baa2f 100644 --- a/test/flex_vector/fuzzed-2.cpp +++ b/test/flex_vector/fuzzed-2.cpp @@ -8,7 +8,7 @@ #include "extra/fuzzer/fuzzer_input.hpp" #include -#include +#include #include #include diff --git a/test/flex_vector/fuzzed-3.cpp b/test/flex_vector/fuzzed-3.cpp index 422497d3..0a42a2be 100644 --- a/test/flex_vector/fuzzed-3.cpp +++ b/test/flex_vector/fuzzed-3.cpp @@ -8,7 +8,7 @@ #include "extra/fuzzer/fuzzer_input.hpp" #include -#include +#include #include #include diff --git a/test/flex_vector/fuzzed-4.cpp b/test/flex_vector/fuzzed-4.cpp index 0a726bef..df7830d4 100644 --- a/test/flex_vector/fuzzed-4.cpp +++ b/test/flex_vector/fuzzed-4.cpp @@ -8,7 +8,7 @@ #include "extra/fuzzer/fuzzer_input.hpp" #include -#include +#include #include #include #include diff --git a/test/flex_vector/generic.ipp b/test/flex_vector/generic.ipp index f01f48ca..299e55a8 100644 --- a/test/flex_vector/generic.ipp +++ b/test/flex_vector/generic.ipp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -482,7 +482,8 @@ TEST_CASE("iterator relaxed") { auto s = std::vector(n); std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); + const auto unused = std::equal(v.begin(), v.end(), s.begin(), s.end()); + (void) unused; } SECTION("can go back from end") @@ -552,7 +553,8 @@ TEST_CASE("exception safety relaxed") try { v = v.push_back({i}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS(v, boost::irange(0u, i)); } CHECK(d.happenings > 0); @@ -568,7 +570,8 @@ TEST_CASE("exception safety relaxed") try { v = v.update(i, [](auto x) { return dada(), x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS( v, boost::join(boost::irange(1u, 1u + i), boost::irange(i, n))); } @@ -605,7 +608,8 @@ TEST_CASE("exception safety relaxed") try { v = lhs + rhs; ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS(v, boost::irange(0u, n)); } CHECK(d.happenings > 0); diff --git a/test/flex_vector/issue-45.cpp b/test/flex_vector/issue-45.cpp index 3ff670e7..1d70123d 100644 --- a/test/flex_vector/issue-45.cpp +++ b/test/flex_vector/issue-45.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #if IMMER_CXX_STANDARD >= 17 @@ -33,3 +33,8 @@ TEST_CASE("error when erasing an element from a " } #endif + +TEST_CASE( + "empty test because it's not allowed to have no tests in the cpp file") +{ +} diff --git a/test/flex_vector_transient/generic.ipp b/test/flex_vector_transient/generic.ipp index 200e7d0a..8ba3fbb0 100644 --- a/test/flex_vector_transient/generic.ipp +++ b/test/flex_vector_transient/generic.ipp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -127,7 +127,8 @@ TEST_CASE("exception safety relaxed") else t.vp = t.vp.push_back({i}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.step()) li = i; if (t.transient) { @@ -161,7 +162,8 @@ TEST_CASE("exception safety relaxed") t.vp = t.vp.update(i, [](auto x) { return dada(), x + 1; }); } ++i; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.step()) li = i; if (t.transient) { @@ -201,7 +203,8 @@ TEST_CASE("exception safety relaxed") if (i < delta) break; i -= delta; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i + delta)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); @@ -234,7 +237,8 @@ TEST_CASE("exception safety relaxed") } delta = deltas.next(); i += delta; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(i - delta, n)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(li, n)); @@ -272,7 +276,8 @@ TEST_CASE("exception safety relaxed") li = i; } delta = deltas.next() * 3; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); @@ -310,7 +315,8 @@ TEST_CASE("exception safety relaxed") li = i; } delta = deltas.next() * 3; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); @@ -349,7 +355,8 @@ TEST_CASE("exception safety relaxed") li = i; } delta = deltas.next() * 3; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(i, n)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(li, n)); @@ -388,7 +395,8 @@ TEST_CASE("exception safety relaxed") li = i; } delta = deltas.next() * 3; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(i, n)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(li, n)); diff --git a/test/map/generic.ipp b/test/map/generic.ipp index e9b6cf58..7d1796ec 100644 --- a/test/map/generic.ipp +++ b/test/map/generic.ipp @@ -18,7 +18,7 @@ #include "test/dada.hpp" #include "test/util.hpp" -#include +#include #include #include @@ -439,7 +439,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.update(i, [](auto x) { return x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(i) == i + 1); for (auto i : test_irange(i, n)) @@ -460,7 +461,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.update_if_exists(i, [](auto x) { return x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(i) == i + 1); for (auto i : test_irange(i, n)) @@ -482,7 +484,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.update(vals[i].first, [](auto x) { return x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first) == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -505,7 +508,8 @@ TEST_CASE("exception safety") v = v.update_if_exists(vals[i].first, [](auto x) { return x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first) == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -528,7 +532,8 @@ TEST_CASE("exception safety") auto x = vals[i].second; v = v.set(vals[i].first, x + 1); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first) == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -551,7 +556,8 @@ TEST_CASE("exception safety") auto x = vals[i].second; v = std::move(v).set(vals[i].first, x + 1); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first) == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -574,7 +580,8 @@ TEST_CASE("exception safety") v = std::move(v).update(vals[i].first, [](auto x) { return x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first) == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -597,7 +604,8 @@ TEST_CASE("exception safety") v = std::move(v).update_if_exists(vals[i].first, [](auto x) { return x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first) == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -619,7 +627,8 @@ TEST_CASE("exception safety") // auto s = d.next(); v = std::move(v).erase(vals[i].first); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.count(vals[i].first) == 0); for (auto i : test_irange(i, n)) @@ -635,7 +644,8 @@ struct KeyType { explicit KeyType(unsigned v) : value(v) - {} + { + } unsigned value; }; @@ -643,7 +653,8 @@ struct LookupType { explicit LookupType(unsigned v) : value(v) - {} + { + } unsigned value; }; @@ -740,7 +751,9 @@ void test_diff(unsigned old_num, // remove auto shuffle = old_keys; - std::random_shuffle(shuffle.begin(), shuffle.end()); + std::random_device rd{}; + auto g = std::mt19937{rd()}; + std::shuffle(shuffle.begin(), shuffle.end(), g); std::vector remove_keys(shuffle.begin(), shuffle.begin() + remove_num); std::vector rest_keys(shuffle.begin() + remove_num, diff --git a/test/map/issue-56.cpp b/test/map/issue-56.cpp index 8658121c..cf45aff2 100644 --- a/test/map/issue-56.cpp +++ b/test/map/issue-56.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include TEST_CASE("const map") { diff --git a/test/map_transient/generic.ipp b/test/map_transient/generic.ipp index 5d0a1540..e8c673a2 100644 --- a/test/map_transient/generic.ipp +++ b/test/map_transient/generic.ipp @@ -8,7 +8,9 @@ #include "test/util.hpp" -#include +#include + +#include #ifndef MAP_T #error "define the map template to use in MAP_T" diff --git a/test/memory/heaps.cpp b/test/memory/heaps.cpp index a43c99b7..f3c47548 100644 --- a/test/memory/heaps.cpp +++ b/test/memory/heaps.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include void do_stuff_to(void* buf, std::size_t size) diff --git a/test/memory/refcounts.cpp b/test/memory/refcounts.cpp index f8a82e82..ea451da0 100644 --- a/test/memory/refcounts.cpp +++ b/test/memory/refcounts.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include TEST_CASE("no refcount has no data") { diff --git a/test/oss-fuzz/array-0.cpp b/test/oss-fuzz/array-0.cpp index 162b0154..07a2107d 100644 --- a/test/oss-fuzz/array-0.cpp +++ b/test/oss-fuzz/array-0.cpp @@ -10,7 +10,7 @@ #include -#include +#include namespace { diff --git a/test/oss-fuzz/array-gc-0.cpp b/test/oss-fuzz/array-gc-0.cpp index 74806653..e11b71e5 100644 --- a/test/oss-fuzz/array-gc-0.cpp +++ b/test/oss-fuzz/array-gc-0.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include using gc_memory = immer::memory_policy, immer::no_refcount_policy, diff --git a/test/oss-fuzz/flex-vector-0.cpp b/test/oss-fuzz/flex-vector-0.cpp index 2ce52917..02bf27c3 100644 --- a/test/oss-fuzz/flex-vector-0.cpp +++ b/test/oss-fuzz/flex-vector-0.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #define IMMER_FUZZED_TRACE_ENABLE 0 diff --git a/test/oss-fuzz/flex-vector-bo-0.cpp b/test/oss-fuzz/flex-vector-bo-0.cpp index f9526cac..a6b16232 100644 --- a/test/oss-fuzz/flex-vector-bo-0.cpp +++ b/test/oss-fuzz/flex-vector-bo-0.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #define IMMER_FUZZED_TRACE_ENABLE 1 diff --git a/test/oss-fuzz/flex-vector-gc-0.cpp b/test/oss-fuzz/flex-vector-gc-0.cpp index 0b9e6d6a..8fe4ce97 100644 --- a/test/oss-fuzz/flex-vector-gc-0.cpp +++ b/test/oss-fuzz/flex-vector-gc-0.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #define IMMER_FUZZED_TRACE_ENABLE 0 diff --git a/test/oss-fuzz/map-gc-0.cpp b/test/oss-fuzz/map-gc-0.cpp index fd0540da..3e7e7476 100644 --- a/test/oss-fuzz/map-gc-0.cpp +++ b/test/oss-fuzz/map-gc-0.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include using gc_memory = immer::memory_policy, immer::no_refcount_policy, diff --git a/test/oss-fuzz/map-st-0.cpp b/test/oss-fuzz/map-st-0.cpp index 59aa0c6f..83a5b1ff 100644 --- a/test/oss-fuzz/map-st-0.cpp +++ b/test/oss-fuzz/map-st-0.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include using st_memory = immer::memory_policy, immer::unsafe_refcount_policy, diff --git a/test/oss-fuzz/map-st-1.cpp b/test/oss-fuzz/map-st-1.cpp index 4041ea96..be7824e5 100644 --- a/test/oss-fuzz/map-st-1.cpp +++ b/test/oss-fuzz/map-st-1.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include using st_memory = immer::memory_policy, immer::unsafe_refcount_policy, diff --git a/test/oss-fuzz/map-st-2.cpp b/test/oss-fuzz/map-st-2.cpp index 782e2af4..99d5deec 100644 --- a/test/oss-fuzz/map-st-2.cpp +++ b/test/oss-fuzz/map-st-2.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #define IMMER_FUZZED_TRACE_ENABLE 0 diff --git a/test/oss-fuzz/map-st-str-0.cpp b/test/oss-fuzz/map-st-str-0.cpp index fdf5204c..7ff8a6a3 100644 --- a/test/oss-fuzz/map-st-str-0.cpp +++ b/test/oss-fuzz/map-st-str-0.cpp @@ -16,7 +16,7 @@ #include -#include +#include #define IMMER_FUZZED_TRACE_ENABLE 1 diff --git a/test/oss-fuzz/set-gc-0.cpp b/test/oss-fuzz/set-gc-0.cpp index c6abebcc..d1022b30 100644 --- a/test/oss-fuzz/set-gc-0.cpp +++ b/test/oss-fuzz/set-gc-0.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include using gc_memory = immer::memory_policy, immer::no_refcount_policy, diff --git a/test/oss-fuzz/set-gc-1.cpp b/test/oss-fuzz/set-gc-1.cpp index d07901a2..afa7afbc 100644 --- a/test/oss-fuzz/set-gc-1.cpp +++ b/test/oss-fuzz/set-gc-1.cpp @@ -16,7 +16,7 @@ #include -#include +#include #define IMMER_FUZZED_TRACE_ENABLE 0 diff --git a/test/oss-fuzz/set-st-0.cpp b/test/oss-fuzz/set-st-0.cpp index 4e56f211..29191468 100644 --- a/test/oss-fuzz/set-st-0.cpp +++ b/test/oss-fuzz/set-st-0.cpp @@ -16,7 +16,7 @@ #include -#include +#include using st_memory = immer::memory_policy, immer::unsafe_refcount_policy, diff --git a/test/oss-fuzz/set-st-str-0.cpp b/test/oss-fuzz/set-st-str-0.cpp index 538abf70..e13d3a0e 100644 --- a/test/oss-fuzz/set-st-str-0.cpp +++ b/test/oss-fuzz/set-st-str-0.cpp @@ -16,7 +16,7 @@ #include -#include +#include namespace { diff --git a/test/set/generic.ipp b/test/set/generic.ipp index d8bde725..b9e467ad 100644 --- a/test/set/generic.ipp +++ b/test/set/generic.ipp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -105,7 +105,8 @@ struct unaligned_str } unaligned_str(const char* in) : unaligned_str{std::string{in}} - {} + { + } std::string str() const { return m_data.data(); } @@ -475,7 +476,8 @@ TEST_CASE("iterator") { auto s = std::vector(N); std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); + const auto unused = std::equal(v.begin(), v.end(), s.begin(), s.end()); + (void) unused; } SECTION("iterator and collisions") @@ -494,7 +496,8 @@ struct non_default unsigned value; non_default(unsigned v) : value{v} - {} + { + } non_default() = delete; operator unsigned() const { return value; } @@ -576,7 +579,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.insert({i}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.count({i}) == 1); } @@ -594,7 +598,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.insert({vals[i]}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.count({vals[i]}) == 1); } @@ -613,7 +618,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.erase({i}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.count({i}) == 0); for (auto i : test_irange(i, n)) @@ -635,7 +641,8 @@ TEST_CASE("exception safety") auto s = d.next(); v = v.erase({vals[i]}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.count({vals[i]}) == 0); for (auto i : test_irange(i, n)) @@ -651,7 +658,8 @@ struct KeyType { explicit KeyType(unsigned v) : value(v) - {} + { + } unsigned value; }; @@ -659,7 +667,8 @@ struct LookupType { explicit LookupType(unsigned v) : value(v) - {} + { + } unsigned value; }; @@ -710,7 +719,9 @@ void test_diff(unsigned old_num, unsigned add_num, unsigned remove_num) // remove auto shuffle = initial_values; - std::random_shuffle(shuffle.begin(), shuffle.end()); + std::random_device rd{}; + auto g = std::mt19937{rd()}; + std::shuffle(shuffle.begin(), shuffle.end(), g); std::vector remove_keys(shuffle.begin(), shuffle.begin() + remove_num); diff --git a/test/set_transient/generic.ipp b/test/set_transient/generic.ipp index 29f7b0b9..09fac526 100644 --- a/test/set_transient/generic.ipp +++ b/test/set_transient/generic.ipp @@ -8,7 +8,9 @@ #include "test/util.hpp" -#include +#include + +#include #ifndef SET_T #error "define the set template to use in SET_T" diff --git a/test/table/generic.ipp b/test/table/generic.ipp index f943e51f..2ab6791a 100644 --- a/test/table/generic.ipp +++ b/test/table/generic.ipp @@ -17,7 +17,7 @@ #include "test/dada.hpp" #include "test/util.hpp" -#include +#include #include #include @@ -63,7 +63,8 @@ using table_map = immer::table, SETUP_T::memory_policy, SETUP_T::bits>; -IMMER_RANGES_CHECK(std::ranges::forward_range>); +IMMER_RANGES_CHECK( + std::ranges::forward_range>); template auto make_generator() @@ -330,7 +331,8 @@ TEST_CASE("exception safety") return make_pair(x.value.first, x.value.second + 1); }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(i).value.second == i + 1); for (auto i : test_irange(i, n)) @@ -362,7 +364,8 @@ TEST_CASE("exception safety") return make_pair(x.value.first, x.value.second + 1); }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first).value.second == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -386,7 +389,8 @@ TEST_CASE("exception safety") return make_pair(x.value.first, x.value.second + 1); }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } for (auto i : test_irange(0u, i)) CHECK(v.at(vals[i].first).value.second == vals[i].second + 1); for (auto i : test_irange(i, n)) @@ -403,7 +407,8 @@ struct KeyType { explicit KeyType(uint32_t v) : value(v) - {} + { + } uint32_t value; }; @@ -411,7 +416,8 @@ struct LookupType { explicit LookupType(uint32_t v) : value(v) - {} + { + } uint32_t value; }; @@ -508,7 +514,9 @@ void test_diff(uint32_t old_num, // remove auto shuffle = old_keys; - std::random_shuffle(shuffle.begin(), shuffle.end()); + std::random_device rd{}; + auto g = std::mt19937{rd()}; + std::shuffle(shuffle.begin(), shuffle.end(), g); std::vector remove_keys(shuffle.begin(), shuffle.begin() + remove_num); std::vector rest_keys(shuffle.begin() + remove_num, diff --git a/test/table_transient/generic.ipp b/test/table_transient/generic.ipp index 73725be5..d10c350a 100644 --- a/test/table_transient/generic.ipp +++ b/test/table_transient/generic.ipp @@ -8,7 +8,9 @@ #include "test/util.hpp" -#include +#include + +#include #ifndef SETUP_T #error "define the table types via SETUP_T macro" diff --git a/test/vector/generic.ipp b/test/vector/generic.ipp index ccce07ae..51a242a3 100644 --- a/test/vector/generic.ipp +++ b/test/vector/generic.ipp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -245,7 +245,8 @@ TEST_CASE("iterator") { auto s = std::vector(n); std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); + const auto unused = std::equal(v.begin(), v.end(), s.begin(), s.end()); + (void) unused; } SECTION("can go back from end") @@ -406,7 +407,8 @@ struct non_default unsigned value; non_default(unsigned value_) : value{value_} - {} + { + } non_default() = delete; operator unsigned() const { return value; } @@ -469,7 +471,8 @@ TEST_CASE("exception safety") try { v = v.push_back({i}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS(v, boost::irange(0u, i)); } CHECK(d.happenings > 0); @@ -485,7 +488,8 @@ TEST_CASE("exception safety") try { v = std::move(v).push_back({i}); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS(v, boost::irange(0u, i)); } CHECK(d.happenings > 0); @@ -501,7 +505,8 @@ TEST_CASE("exception safety") try { v = v.update(i, [](auto x) { return dada(), x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS( v, boost::join(boost::irange(1u, 1u + i), boost::irange(i, n))); } @@ -519,7 +524,8 @@ TEST_CASE("exception safety") v = std::move(v).update(i, [](auto x) { return dada(), x + 1; }); ++i; - } catch (dada_error) {} + } catch (dada_error) { + } CHECK_VECTOR_EQUALS( v, boost::join(boost::irange(1u, 1u + i), boost::irange(i, n))); } diff --git a/test/vector/issue-177.cpp b/test/vector/issue-177.cpp index ac953d86..d61b3774 100644 --- a/test/vector/issue-177.cpp +++ b/test/vector/issue-177.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include struct object; diff --git a/test/vector/issue-46.cpp b/test/vector/issue-46.cpp index 0032b71f..36a9529e 100644 --- a/test/vector/issue-46.cpp +++ b/test/vector/issue-46.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include TEST_CASE("operator==() may return bad result") { diff --git a/test/vector_transient/generic.ipp b/test/vector_transient/generic.ipp index 6b3e6dad..9d9b5d74 100644 --- a/test/vector_transient/generic.ipp +++ b/test/vector_transient/generic.ipp @@ -10,7 +10,7 @@ #include "test/transient_tester.hpp" #include "test/util.hpp" -#include +#include #ifndef VECTOR_T #error "define the vector template to use in VECTOR_T" @@ -185,7 +185,8 @@ TEST_CASE("exception safety") ++i; if (t.step()) li = i; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); @@ -217,7 +218,8 @@ TEST_CASE("exception safety") ++i; if (t.step()) li = i; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, join(irange(1u, 1u + i), irange(i, n))); @@ -254,7 +256,8 @@ TEST_CASE("exception safety") if (i < delta) break; i -= delta; - } catch (dada_error) {} + } catch (dada_error) { + } if (t.transient) { CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i + delta)); CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); From 0f24d396f362bc4709ff73c7cf7fb09910adb4ff Mon Sep 17 00:00:00 2001 From: Alex Shabalin Date: Thu, 15 Feb 2024 12:35:08 +0100 Subject: [PATCH 2/2] Fuzzers do not require Catch2 --- CMakeLists.txt | 15 ++++++++------- extra/fuzzer/CMakeLists.txt | 3 +++ flake.nix | 11 ++++++----- test/CMakeLists.txt | 1 + 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 091f2b99..386cc725 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ option(immer_BUILD_TESTS "Build tests" ON) option(immer_BUILD_EXAMPLES "Build examples" ON) option(immer_BUILD_DOCS "Build docs" ON) option(immer_BUILD_EXTRAS "Build extras" ON) +option(immer_INSTALL_FUZZERS "Install fuzzers" off) set(CXX_STANDARD 14 CACHE STRING "c++ standard number") @@ -136,16 +137,16 @@ endif() # Testing # ======= +if (immer_BUILD_TESTS OR immer_BUILD_EXAMPLES OR immer_BUILD_EXTRAS) + add_custom_target(check + COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Build and run all the tests and examples.") +endif() + if (immer_BUILD_TESTS) enable_testing() - find_package(Catch2 REQUIRED) - - add_custom_target(check - COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Build and run all the tests and examples.") - add_subdirectory(test) add_subdirectory(benchmark) endif() diff --git a/extra/fuzzer/CMakeLists.txt b/extra/fuzzer/CMakeLists.txt index 777289f8..2c160f79 100644 --- a/extra/fuzzer/CMakeLists.txt +++ b/extra/fuzzer/CMakeLists.txt @@ -26,4 +26,7 @@ foreach(_file IN LISTS immer_fuzzers) if (CHECK_FUZZERS) add_test("fuzzer/${_output}" ${_output} -max_total_time=1) endif() + if (immer_INSTALL_FUZZERS) + install(TARGETS ${_target} DESTINATION bin) + endif() endforeach() diff --git a/flake.nix b/flake.nix index 0f67ca16..18247fff 100644 --- a/flake.nix +++ b/flake.nix @@ -49,7 +49,7 @@ }; }; - inherit (self.packages.${system}) unit-tests; + inherit (self.packages.${system}) unit-tests fuzzers-debug; } // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux { unit-tests-valgrind = self.packages.${system}.unit-tests.overrideAttrs (prev: { @@ -94,18 +94,19 @@ default = self.packages.${system}.immer; fuzzers-debug = (withLLVM self.packages.${system}.immer).overrideAttrs (prev: { - buildInputs = with pkgs; [catch2_3 boehmgc boost fmt]; + name = "immer-fuzzers"; + # Fuzzers should be built with minimal dependencies to use them easily with OSS-Fuzz + buildInputs = with pkgs; [boehmgc]; nativeBuildInputs = with pkgs; [cmake ninja]; dontBuild = false; dontStrip = true; # fuzzers target is not built by default ninjaFlags = ["fuzzers"]; + cmakeBuildType = "Debug"; cmakeFlags = [ - "-DCMAKE_BUILD_TYPE=Debug" + "-DENABLE_ASAN=ON" "-Dimmer_BUILD_TESTS=OFF" - "-Dimmer_BUILD_EXAMPLES=OFF" "-Dimmer_INSTALL_FUZZERS=ON" - "-DENABLE_ASAN=ON" ]; }); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 590dc775..1812e9ed 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,6 +6,7 @@ add_custom_target(tests COMMENT "Build all the unit tests.") add_dependencies(check tests) +find_package(Catch2 REQUIRED) include(CTest) file(GLOB_RECURSE immer_unit_tests "*.cpp")