diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml deleted file mode 100644 index 1fa56a5..0000000 --- a/.github/workflows/haskell-ci.yml +++ /dev/null @@ -1,208 +0,0 @@ -# This GitHub workflow config has been generated by a script via -# -# haskell-ci 'github' 'quickcheck-lockstep.cabal' -# -# To regenerate the script (for example after adjusting tested-with) run -# -# haskell-ci regenerate -# -# For more information, see https://github.com/haskell-CI/haskell-ci -# -# version: 0.15.202211107 -# -# REGENDATA ("0.15.202211107",["github","quickcheck-lockstep.cabal"]) -# -name: Haskell-CI -on: - - push - - pull_request -jobs: - linux: - name: Haskell-CI - Linux - ${{ matrix.compiler }} - runs-on: ubuntu-20.04 - timeout-minutes: - 60 - container: - image: buildpack-deps:bionic - continue-on-error: ${{ matrix.allow-failure }} - strategy: - matrix: - include: - - compiler: ghc-9.8.1 - compilerKind: ghc - compilerVersion: 9.8.1 - setup-method: ghcup - allow-failure: false - - compiler: ghc-9.6.4 - compilerKind: ghc - compilerVersion: 9.6.4 - setup-method: ghcup - allow-failure: false - - compiler: ghc-9.4.8 - compilerKind: ghc - compilerVersion: 9.4.8 - setup-method: ghcup - allow-failure: false - - compiler: ghc-9.2.8 - compilerKind: ghc - compilerVersion: 9.2.8 - setup-method: ghcup - allow-failure: false - - compiler: ghc-9.0.2 - compilerKind: ghc - compilerVersion: 9.0.2 - setup-method: ghcup - allow-failure: false - - compiler: ghc-8.10.7 - compilerKind: ghc - compilerVersion: 8.10.7 - setup-method: ghcup - allow-failure: false - fail-fast: false - steps: - - name: apt - run: | - apt-get update - apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 - mkdir -p "$HOME/.ghcup/bin" - curl -sL https://downloads.haskell.org/ghcup/0.1.18.0/x86_64-linux-ghcup-0.1.18.0 > "$HOME/.ghcup/bin/ghcup" - chmod a+x "$HOME/.ghcup/bin/ghcup" - "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) - "$HOME/.ghcup/bin/ghcup" install cabal 3.6.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false) - env: - HCKIND: ${{ matrix.compilerKind }} - HCNAME: ${{ matrix.compiler }} - HCVER: ${{ matrix.compilerVersion }} - - name: Set PATH and environment variables - run: | - echo "$HOME/.cabal/bin" >> $GITHUB_PATH - echo "LANG=C.UTF-8" >> "$GITHUB_ENV" - echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV" - echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV" - HCDIR=/opt/$HCKIND/$HCVER - HC=$HOME/.ghcup/bin/$HCKIND-$HCVER - echo "HC=$HC" >> "$GITHUB_ENV" - echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV" - echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV" - echo "CABAL=$HOME/.ghcup/bin/cabal-3.6.2.0 -vnormal+nowrap" >> "$GITHUB_ENV" - HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))') - echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" - echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" - echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV" - echo "HEADHACKAGE=false" >> "$GITHUB_ENV" - echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV" - echo "GHCJSARITH=0" >> "$GITHUB_ENV" - env: - HCKIND: ${{ matrix.compilerKind }} - HCNAME: ${{ matrix.compiler }} - HCVER: ${{ matrix.compilerVersion }} - - name: env - run: | - env - - name: write cabal config - run: | - mkdir -p $CABAL_DIR - cat >> $CABAL_CONFIG <> $CABAL_CONFIG < cabal-plan.xz - echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c - - xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan - rm -f cabal-plan.xz - chmod a+x $HOME/.cabal/bin/cabal-plan - cabal-plan --version - - name: checkout - uses: actions/checkout@v2 - with: - path: source - - name: initial cabal.project for sdist - run: | - touch cabal.project - echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project - cat cabal.project - - name: sdist - run: | - mkdir -p sdist - $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist - - name: unpack - run: | - mkdir -p unpacked - find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \; - - name: generate cabal.project - run: | - PKGDIR_quickcheck_lockstep="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/quickcheck-lockstep-[0-9.]*')" - echo "PKGDIR_quickcheck_lockstep=${PKGDIR_quickcheck_lockstep}" >> "$GITHUB_ENV" - rm -f cabal.project cabal.project.local - touch cabal.project - touch cabal.project.local - echo "packages: ${PKGDIR_quickcheck_lockstep}" >> cabal.project - echo "package quickcheck-lockstep" >> cabal.project - echo " ghc-options: -Werror=missing-methods" >> cabal.project - cat >> cabal.project <> cabal.project.local - cat cabal.project - cat cabal.project.local - - name: dump install plan - run: | - $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all - cabal-plan - - name: cache - uses: actions/cache@v2 - with: - key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} - path: ~/.cabal/store - restore-keys: ${{ runner.os }}-${{ matrix.compiler }}- - - name: install dependencies - run: | - $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all - $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all - - name: build w/o tests - run: | - $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all - - name: build - run: | - $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always - - name: tests - run: | - $CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct - - name: cabal check - run: | - cd ${PKGDIR_quickcheck_lockstep} || false - ${CABAL} -vnormal check - - name: haddock - run: | - $CABAL v2-haddock --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all - - name: unconstrained build - run: | - rm -f cabal.project.local - $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml new file mode 100644 index 0000000..7c1481a --- /dev/null +++ b/.github/workflows/haskell.yml @@ -0,0 +1,90 @@ +name: Haskell CI + +on: + push: + branches: [ "main" ] + pull_request: + merge_group: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + + +permissions: + contents: read + +jobs: + # Build and test + build: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + ghc: ["8.10.7", "9.0.2", "9.2.8", "9.4.8", "9.6.6", "9.8.2", "9.10.1"] + cabal: ["3.10.2.1"] + os: [ubuntu-latest] + + timeout-minutes: 60 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Haskell + id: setup-haskell + uses: haskell-actions/setup@v2 + with: + ghc-version: ${{ matrix.ghc }} + cabal-version: ${{ matrix.cabal }} + cabal-update: true + + - name: Configure the build + run: | + cabal configure --enable-tests --enable-benchmark --ghc-options="-Werror" + cat cabal.project.local + + - name: Record cabal dependencies + id: record-deps + run: | + cabal build all --dry-run + + - name: "Restore cache" + uses: actions/cache/restore@v4 + id: restore-cabal-cache + env: + cache-name: cache-cabal-build-130824 + with: + path: ${{ steps.setup-haskell.outputs.cabal-store }} + key: ${{ runner.os }}-${{ matrix.ghc }}-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }} + restore-keys: | + ${{ runner.os }}-${{ matrix.ghc }}-${{ env.cache-name }}- + + - name: Install cabal dependencies + id: build-dependencies + run: cabal build --only-dependencies all + + - name: "Save cache" + uses: actions/cache/save@v4 + id: save-cabal-cache + # Note: cache-hit will be set to true only when cache hit occurs for the + # exact key match. For a partial key match via restore-keys or a cache + # miss, it will be set to false. + if: steps.build-dependencies.outcome == 'success' && steps.restore-cabal-cache.outputs.cache-hit != 'true' + with: + path: ${{ steps.setup-haskell.outputs.cabal-store }} + key: ${{ steps.restore-cabal-cache.outputs.cache-primary-key }} + + - name: Build + run: cabal build all + + # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable + - name: Set test timeout (Unix) + if: ${{ startsWith(matrix.os, 'ubuntu') || startsWith(matrix.os, 'macOS') }} + run: | + echo "TASTY_TIMEOUT=5m" >> "$GITHUB_ENV" + + - name: Run tests + run: | + cabal test -j1 --test-show-details=direct all diff --git a/quickcheck-lockstep.cabal b/quickcheck-lockstep.cabal index be01b2f..358af9a 100644 --- a/quickcheck-lockstep.cabal +++ b/quickcheck-lockstep.cabal @@ -8,87 +8,88 @@ maintainer: edsko@well-typed.com, joris@well-typed.com extra-doc-files: README.md extra-source-files: CHANGELOG.md category: Testing -synopsis: Library for lockstep-style testing with 'quickcheck-dynamic' -description: Lockstep-style testing is a particular approach for blackbox - testing of stateful APIs: we generate a random sequence of - APIs calls, then execute them both against the system under - test and against a model, and compare responses up to some - notion of observability. -tested-with: GHC ==8.10 || ==9.0 || ==9.2 || ==9.4 || ==9.6 || ==9.8 +synopsis: + Library for lockstep-style testing with 'quickcheck-dynamic' + +description: + Lockstep-style testing is a particular approach for blackbox + testing of stateful APIs: we generate a random sequence of + APIs calls, then execute them both against the system under + test and against a model, and compare responses up to some + notion of observability. + +tested-with: + GHC ==8.10 || ==9.0 || ==9.2 || ==9.4 || ==9.6 || ==9.8 || ==9.10 source-repository head type: git location: https://github.com/well-typed/quickcheck-lockstep common lang - default-language: - Haskell2010 + default-language: Haskell2010 default-extensions: - FlexibleContexts - FlexibleInstances - GADTs - ImportQualifiedPost - LambdaCase - MultiParamTypeClasses - QuantifiedConstraints - RankNTypes - ScopedTypeVariables - StandaloneDeriving - TupleSections - TypeApplications - TypeFamilies - other-extensions: - UndecidableInstances + FlexibleContexts + FlexibleInstances + GADTs + ImportQualifiedPost + LambdaCase + MultiParamTypeClasses + QuantifiedConstraints + RankNTypes + ScopedTypeVariables + StandaloneDeriving + TupleSections + TypeApplications + TypeFamilies + + other-extensions: UndecidableInstances ghc-options: - -Wall - -Wprepositive-qualified-module - -Wredundant-constraints + -Wall -Wprepositive-qualified-module -Wredundant-constraints library - import: - lang + import: lang exposed-modules: - Test.QuickCheck.StateModel.Lockstep - Test.QuickCheck.StateModel.Lockstep.Defaults - Test.QuickCheck.StateModel.Lockstep.Op - Test.QuickCheck.StateModel.Lockstep.Op.Identity - Test.QuickCheck.StateModel.Lockstep.Op.SumProd - Test.QuickCheck.StateModel.Lockstep.Run + Test.QuickCheck.StateModel.Lockstep + Test.QuickCheck.StateModel.Lockstep.Defaults + Test.QuickCheck.StateModel.Lockstep.Op + Test.QuickCheck.StateModel.Lockstep.Op.Identity + Test.QuickCheck.StateModel.Lockstep.Op.SumProd + Test.QuickCheck.StateModel.Lockstep.Run + other-modules: - Test.QuickCheck.StateModel.Lockstep.API - Test.QuickCheck.StateModel.Lockstep.EnvF - Test.QuickCheck.StateModel.Lockstep.GVar + Test.QuickCheck.StateModel.Lockstep.API + Test.QuickCheck.StateModel.Lockstep.EnvF + Test.QuickCheck.StateModel.Lockstep.GVar + + -- quickcheck-dynamic requires ghc 8.10 minimum build-depends: - -- quickcheck-dynamic requires ghc 8.10 minimum - base >= 4.14 && < 4.20 - , constraints >= 0.13 && < 0.15 - , mtl >= 2.2 && < 2.4 - , containers >= 0.6 && < 0.7 - , QuickCheck >= 2.14 && < 2.15 - , quickcheck-dynamic >= 3.4.1 && < 3.5 - hs-source-dirs: - src + , base >=4.14 && <4.21 + , constraints ^>=0.13 || ^>=0.14 + , containers ^>=0.6 || ^>=0.7 + , mtl ^>=2.2 || ^>=2.3 + , QuickCheck ^>=2.14 || ^>=2.15 + , quickcheck-dynamic ^>=3.4.1 + + hs-source-dirs: src test-suite test-quickcheck-lockstep - import: - lang - type: - exitcode-stdio-1.0 - hs-source-dirs: - test - main-is: - Main.hs + import: lang + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs other-modules: - Test.MockFS - Test.MockFS.Mock - Test.IORef.Full - Test.IORef.Simple + Test.IORef.Full + Test.IORef.Simple + Test.MockFS + Test.MockFS.Mock + default-extensions: - DeriveGeneric - EmptyCase + DeriveGeneric + EmptyCase + + -- Version bounds determined by main lib build-depends: - -- Version bounds determined by main lib - base + , base , constraints , containers , directory