Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2d24cae
[ build ] the test runner
gallais Nov 19, 2025
68f96e5
[ fix ] building the data/appending test
gallais Nov 19, 2025
6e6f3f7
[ fix ] building the data/colist test
gallais Nov 19, 2025
06cc339
[ fix ] another big batch of tests
gallais Nov 19, 2025
7c220d3
[ fix ] cabal exec should not print extra output
gallais Nov 19, 2025
3fabdc3
[ done ] with skeletons for all the tests in v2.0
gallais Nov 19, 2025
49dc268
[ ci ] run revamped testsuite
gallais Nov 19, 2025
3cacdde
[ ci ] enable build on v2.0-joss-submission branch
gallais Nov 19, 2025
e3f483e
[ update ] test case
gallais Nov 19, 2025
6dff4de
[ fix ] this test takes extra arguments
gallais Nov 19, 2025
171bdcb
[ ci ] bump cache version
gallais Nov 19, 2025
8dbf96c
[ ci ] haskell/actions/setup -> haskell-actions/setup
gallais Nov 19, 2025
86612f5
[ refactor ] share more code
gallais Nov 19, 2025
4c746a3
[ refactor ] removing a lot of duplicate code
gallais Nov 19, 2025
7e48fd0
[ ci ] fix GHC call
gallais Nov 19, 2025
b75de2a
[ fix ] regex test case
gallais Nov 19, 2025
8149656
[ cleanup ] Increase sharing
gallais Nov 20, 2025
d2b49a0
[ cosmetic ] switch it up
gallais Nov 20, 2025
8985324
[ ci ] Don't pre-install clock
gallais Nov 20, 2025
61714c3
[ cleanup ] Even more sharing!
gallais Nov 20, 2025
74114fb
[ doc ] adding a README file
gallais Nov 20, 2025
8318806
[ ci ] whyyyyy?!
gallais Nov 20, 2025
b544933
[ ci ] grmbl
gallais Nov 20, 2025
3d3726d
[ ci ] all the tests require text?
gallais Nov 20, 2025
ae83967
[ fix ] remove useless option
gallais Nov 20, 2025
cc608e4
[ fix ] add generic support for input files
gallais Nov 20, 2025
236fd5f
[ test ] eagerly print test name
gallais Nov 20, 2025
f8c17d4
[ misc ] various fixes & using a unique cabal file
gallais Nov 20, 2025
2f9a5a3
[ fix ] various escaping things
gallais Nov 20, 2025
b53aa9c
[ doc ] for various bits
gallais Nov 21, 2025
0749e7d
[ admin ] removing debug tracing
gallais Nov 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
branches:
- master
- experimental
- v2.0-joss-submission
merge_group:

########################################################################
Expand Down Expand Up @@ -47,7 +48,7 @@ on:
########################################################################

env:
GHC_VERSION: 8.10.7
GHC_VERSION: 9.2.8
CABAL_VERSION: 3.6.2.0
CABAL_INSTALL: cabal v1-install --ghc-options='-O1 +RTS -M6G -RTS'
# CABAL_INSTALL: cabal install --overwrite-policy=always --ghc-options='-O1 +RTS -M6G -RTS'
Expand Down Expand Up @@ -98,7 +99,7 @@ jobs:
# i.e. if we change either the version of Agda, ghc, or cabal that we want
# to use for the build.
- name: Cache ~/.cabal directories
uses: actions/cache@v2
uses: actions/cache@v4
id: cache-cabal
with:
path: |
Expand All @@ -113,7 +114,7 @@ jobs:
########################################################################

- name: Install ghc & cabal
uses: haskell/actions/setup@v1
uses: haskell-actions/setup@v2
with:
ghc-version: ${{ env.GHC_VERSION }}
cabal-version: ${{ env.CABAL_VERSION }}
Expand Down Expand Up @@ -168,8 +169,7 @@ jobs:

- name: Golden testing
run: |
${{ env.CABAL_INSTALL }} clock
make testsuite INTERACTIVE='' AGDA_EXEC='~/.cabal/bin/agda'
make testsuite INTERACTIVE='' AGDA_EXEC='agda' GHC_EXEC='ghc'


########################################################################
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ GenerateEverything
Haskell
html
log
logs/
MAlonzo
output
runtests
3 changes: 2 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
GHC_EXEC ?= ghc
AGDA_EXEC ?= agda
AGDA_OPTIONS=-Werror
AGDA_RTS_OPTIONS=+RTS -M4.0G -H3.5G -A128M -RTS
Expand All @@ -12,7 +13,7 @@ test: Everything.agda check-whitespace
cd doc && $(AGDA) README.agda

testsuite:
$(MAKE) -C tests test AGDA="$(AGDA)" AGDA_EXEC="$(AGDA_EXEC)" only=$(only)
$(MAKE) -C tests test GHC_EXEC="$(GHC_EXEC)" AGDA="$(AGDA)" only=$(only)

fix-whitespace:
cabal exec -- fix-whitespace
Expand Down
7 changes: 4 additions & 3 deletions src/Test/Golden.agda
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,10 @@ runTest opts testPath = do
true ← doesDirectoryExist (mkFilePath testPath)
where false → fail directoryNotFound

putStr $ concat (testPath ∷ ": " ∷ [])
time ← time′ $ callCommand $ unwords
$ "cd" ∷ testPath
∷ "&&" ∷ "sh ./run" ∷ opts .exeUnderTest
∷ "&&" ∷ "sh ./run" ∷ (concat $ "\"" ∷ opts .exeUnderTest ∷ "\"" ∷ [])
∷ "| tr -d '\\r' > output"
∷ []

Expand Down Expand Up @@ -303,14 +304,14 @@ runTest opts testPath = do
when b $ writeFile (testPath String.++ "/expected") out

printTiming : Bool → Time → String → IO _
printTiming false _ msg = putStrLn $ concat (testPath ∷ ": " ∷ msg ∷ [])
printTiming false _ msg = putStrLn msg
printTiming true time msg =
let time = ℕ.show (time .seconds) String.++ "s"
spent = 9 + List.sum (List.map String.length (testPath ∷ time ∷ []))
-- ^ hack: both "success" and "FAILURE" have the same length
-- can't use `String.length msg` because the msg contains escape codes
pad = String.replicate (72 ∸ spent) ' '
in putStrLn (concat (testPath ∷ ": " ∷ msg ∷ pad ∷ time ∷ []))
in putStrLn (concat (msg ∷ pad ∷ time ∷ []))

-- A test pool is characterised by
-- + a name
Expand Down
27 changes: 18 additions & 9 deletions tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
INTERACTIVE ?= --interactive
INTERACTIVE ?= --interactive
GHC_EXEC ?= ghc
CABAL ?= cabal
CABAL_OPTIONS ?= --with-compiler $(GHC_EXEC)

runtests: runtests.agda
rm -f _build/runtests
rm -f _build/MAlonzo/Code/Qruntests*
$(AGDA) --compile-dir=_build/ -c runtests.agda
AGDA_BUILD_DIR = _config/_build
CABAL_BUILD_DIR = _config/dist-newstyle

test: runtests
./_build/runtests $(AGDA_EXEC) $(INTERACTIVE) --timing --failure-file failures --only $(only)
./runtests: admin/runtests/Main.agda
cd admin/runtests && AGDA="$(AGDA)" sh run

test: ./runtests
./runtests "$(AGDA)" $(INTERACTIVE) --timing --failure-file failures --only $(only)

retest: runtests
./_build/runtests $(AGDA_EXEC) $(INTERACTIVE) --timing --failure-file failures --only-file failures --only $(only)

retest: ./runtests
./runtests "$(AGDA)" $(INTERACTIVE) --timing --failure-file failures --only-file failures --only $(only)

clean:
rm -rf runtests
rm -rf _config/_build
rm -rf _config/dist-newstyle
56 changes: 56 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Running the test suite

You can run the test suite by going back to the main project directory
and running (change accordingly if you have the right versions of Agda
& GHC installed but the executable names are different).

```shell
AGDA_EXEC=agda-2.6.4 GHC_EXEC=ghc-9.2.8 make testsuite
```

# Structure of the test suite

## Test case

Each test case is under 2 levels of nesting (this is hard-coded)
and should comprise:

1. A `Main.agda` file containing a `main` entrypoint
2. An `expected` file containing the expected output of running `Main`
3. A `run` file describing how to run `Main` (most likely implemented
using the `goldenTest` function defined in
[_config/config.sh](_config/config.sh).
4. Optionally, an `input` file for the stdin content to feed to
the executable obtained by compiling `Main`.

## Configuration

The Agda & GHC version numbers the stdlib is tested against
are specified in [_config/version-numbers.sh](_config/version-numbers.sh)

## Test runner

The test runner is defined in [admin/runtests/](admin/runtests/).
It is compiled using an ad-hoc [run](admin/runtests/run) file using
the shared configuration and the resulting executable is copied to
the root of the tests directory.

If you want to add new tests, you need to list them in
the [runtests](admin/runtests/Main.agda) program.

## Test dependencies

The external dependencies of the whole test suite are spelt out in the generic
[_config/template.cabal](_config/template.cabal) cabal file

You may need to bump these dependencies when changing
the version of the GHC compiler we build against.

# Updating the test suite

1. Update [_config/version-numbers.sh](_config/version-numbers.sh)
2. Update the shell command listing explicit version numbers in the
fenced code block at the top of this README
3. Update bounds in [_config/template.cabal](_config/template.cabal)
4. Update [../.github/workflows/ci-ubuntu.yml](../.github/workflows/ci-ubuntu.yml)
to run the continuous integration with the new GHC and/or Agda versions.
88 changes: 88 additions & 0 deletions tests/_config/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/sh

# This script is intended to be sourced from test scripts.
#
# It provides a number of default config options corresponding
# to the compiler versions the stdlib is being tested with
#
# Usage: . ../../config.sh

set -eu

# Ugh, paths are relative to the script sourcing this file!
. ../../_config/version-numbers.sh



# Main entry point to build and run an Agda program
#
# Typically called like `goldenTest "$1" "echo" "hello world"`
#
# INPUTS:
# $1 is the agda executable (typically "$1" in the ̀ run` file
# because this info is provided by the test runner
# $2 the name of the test as a string
# $3 is OPTIONAL and corresponds to the extra arguments to pass
# to the executable obtained by compiling the Agda program
#
# LOGGING:
# logs/agda-build for the trace produced by Agda
# logs/cabal-build for the trace produced by cabal+ghc
#
# OUTPUT:
# the output obtained by running the Agda program is stored in
# the file named `output`. The test runner will then diff it
# against the expected file.
goldenTest () {

AGDA=$1
TEST_NAME="stdlib-test-$2"

# Taking extra args for the executable?
if [ -z ${3-} ]; then
EXTRA_ARGS=""
else
EXTRA_ARGS="-- $3"
fi

# Remember whether the script has an input -- ugh
if [ -f input ]; then
HAS_INPUT="true"
else
touch input
HAS_INPUT="false"
fi

# Specialise template agda-lib & cabal files
sed "s/TEST_NAME/$TEST_NAME/g" ../../_config/template.agda-lib > "$TEST_NAME".agda-lib
sed "s/TEST_NAME/$TEST_NAME/g" ../../_config/template.cabal > "$TEST_NAME".cabal

# Set up clean logs directory
rm -rf logs/
mkdir logs

# Use shared directories to avoid rechecking stdlib modules
AGDA_BUILD_DIR=../../_config/_build
CABAL_BUILD_DIR=../../_config/dist-newstyle

mkdir -p "$AGDA_BUILD_DIR"
ln -sf "$AGDA_BUILD_DIR" _build
mkdir -p "$CABAL_BUILD_DIR"
ln -sf "$CABAL_BUILD_DIR" dist-newstyle

# Compile the Agda module and build the generated code
$AGDA --library-file=../../_config/libraries --compile-dir=_build -c --ghc-dont-call-ghc Main.agda > logs/agda-build
cabal build "$TEST_NAME" --with-compiler "$GHC_EXEC" > logs/cabal-build

# Run the test
cabal exec -v0 "$TEST_NAME" --with-compiler "$GHC_EXEC" $EXTRA_ARGS < input > output

# Clean up after ourselves
if ! "$HAS_INPUT"; then
rm input
fi
rm "$TEST_NAME".cabal
rm "$TEST_NAME".agda-lib
rm _build
rm dist-newstyle
}
1 change: 1 addition & 0 deletions tests/_config/libraries
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../../../standard-library.agda-lib
5 changes: 5 additions & 0 deletions tests/_config/template.agda-lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: TEST_NAME
include: .
depend: standard-library
flags:
--warning=noUnsupportedIndexedMatch
31 changes: 31 additions & 0 deletions tests/_config/template.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cabal-version: 2.4
name: TEST_NAME
version: 0.0
build-type: Simple
description: Run this test
license: MIT

common common-build-parameters
default-language:
Haskell2010

default-extensions:
PatternGuards
PatternSynonyms

build-depends:
base >= 4.12 && < 4.20
, clock >= 0.8 && <0.9
, directory >= 1.3.6 && < 1.3.7
, filemanip >= 0.3.6 && < 0.4
, filepath >= 1.4 && <1.6
, process >= 1.6 && <1.7
, text >= 2.0 && <2.2

ghc-options: -Wno-missing-home-modules

executable TEST_NAME
import: common-build-parameters
hs-source-dirs: _build
main-is: MAlonzo/Code/Main.hs
ghc-options: -main-is MAlonzo.Code.Main
16 changes: 16 additions & 0 deletions tests/_config/version-numbers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh

# This script is intended to be sourced from test scripts.
#
# It provides a number of default config options corresponding
# to the compiler versions the stdlib is being tested with
#
# Usage: . PATH/TO/version-numbers.sh

if [ -z ${AGDA_EXEC-} ]; then
export AGDA_EXEC=agda-2.6.4
fi

if [ -z ${GHC_EXEC-} ]; then
export GHC_EXEC=ghc-9.2.8
fi
2 changes: 1 addition & 1 deletion tests/runtests.agda → tests/admin/runtests/Main.agda
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# OPTIONS --guardedness #-}

module runtests where
module Main where

open import Data.List.Base as List using (_∷_; [])
open import Data.String.Base using (String; _++_)
Expand Down
34 changes: 34 additions & 0 deletions tests/admin/runtests/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
TEST_NAME=runtests

# Use the shared version numbers
. ../../_config/version-numbers.sh

# Specialise template agda-lib
sed "s/TEST_NAME/$TEST_NAME/g" ../../_config/template.agda-lib > "$TEST_NAME".agda-lib
sed "s/TEST_NAME/$TEST_NAME/g" ../../_config/template.cabal > "$TEST_NAME".cabal

# Set up clean logs directory
rm -rf logs/
mkdir logs

# Use shared directories to avoid rechecking stdlib modules
AGDA_BUILD_DIR=../../_config/_build
CABAL_BUILD_DIR=../../_config/dist-newstyle

mkdir -p "$AGDA_BUILD_DIR"
ln -sf "$AGDA_BUILD_DIR" _build
mkdir -p "$CABAL_BUILD_DIR"
ln -sf "$CABAL_BUILD_DIR" dist-newstyle

# Compile the Agda module and build the generated code
$AGDA --library-file ../../_config/libraries --compile-dir=_build -c --ghc-dont-call-ghc Main.agda > logs/agda-build
cabal build "$TEST_NAME" --with-compiler "$GHC_EXEC" > logs/cabal-build

# Copy the executable to the test root directory
cp $(find dist-newstyle/ -name "runtests" -type f) ../../

# Clean up after ourselves
rm "$TEST_NAME".agda-lib
rm "$TEST_NAME".cabal
rm _build
rm dist-newstyle
2 changes: 1 addition & 1 deletion tests/data/appending/TakeWhile.agda
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Data.Nat
open import Relation.Unary
open import Relation.Binary.PropositionalEquality as P using (_≡_)
open import Relation.Nullary
open import Relation.Nullary.Product
open import Relation.Nullary.Decidable

-- Original bug reported in #1765 by James Wood
_ : Appending (3 ∷ []) (2 ∷ []) (3 ∷ 2 ∷ [])
Expand Down
2 changes: 0 additions & 2 deletions tests/data/appending/appending.agda-lib

This file was deleted.

7 changes: 2 additions & 5 deletions tests/data/appending/run
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
$1 --compile-dir=../../_build -c Main.agda > log
./../../_build/Main < input > output

rm ../../_build/Main
rm ../../_build/MAlonzo/Code/Main*
. ../../_config/config.sh
goldenTest "$1" "appending"
2 changes: 0 additions & 2 deletions tests/data/colist/colist.agda-lib

This file was deleted.

Loading