Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pre-compilation of exercises and graders #481

Merged
merged 41 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b03bdfe
feat!: Implement pre-compilation of exercises and graders
AltGr Apr 1, 2022
47d5a06
feat: Enable downloading for only the relevant artifacts (bc or js)
AltGr Mar 31, 2022
2792faf
refactor: Get rid of the pseudo-cipher
AltGr Apr 1, 2022
87ee902
fix: Fix a small race condition in builder
AltGr Apr 1, 2022
eaad14c
perf: Make `learn-ocaml build` parallel by default
AltGr Apr 1, 2022
787840b
feat: Include Prelude/Prepare and shadow them
AltGr Apr 6, 2022
a97f813
fix: Properly type samplers
AltGr Apr 6, 2022
7422ca4
fix: Avoid double-printing of internal grader errors
AltGr Apr 7, 2022
e63359e
perf: Dump the cmis for grading only once
AltGr Apr 7, 2022
c61a4d0
fix: Fix segfault on graders using samplers returning newly defined e…
AltGr Apr 8, 2022
7825a6b
fix: Be more precise on the definition and lookup of samplers
AltGr Apr 8, 2022
46631d8
build: Make `make testrun` parallel
AltGr Apr 8, 2022
3cd75f5
feat(ppx-metaquot): Add transformation introducing the `register_samp…
hernoufM Apr 3, 2022
f0e8346
feat: Restore compatibility with static deployment
AltGr Apr 12, 2022
99e913d
refactor: Rename and generalise `recorder` to `ppx_autoregister`
AltGr Apr 13, 2022
d22a788
feat: Add support for a `test_libs.txt` file in exercises
AltGr Apr 15, 2022
e768616
feat: Preprocessing and typing of samplers and printers
AltGr Apr 21, 2022
3fc41ca
feat: Provide lib to compile grader helper libraries
AltGr Apr 19, 2022
7d27523
fix: Fix printer registration in the grader
AltGr Apr 20, 2022
c432909
fix: Do some cleanup & Fix `mutation_testing` test lib
AltGr Apr 20, 2022
264db4c
refactor: Generalize sampler typing
AltGr Apr 21, 2022
1ec3af6
fix: Allow printer registration in prepare/prelude & Fix print callba…
AltGr Apr 21, 2022
54851dd
refactor: Disable debug flags
AltGr Apr 22, 2022
f028b75
docs: Update French translation
AltGr Apr 22, 2022
9155145
docs!: Remove doc tutorial on `depend.txt` (it will need rewriting)
AltGr Apr 22, 2022
2c89d9e
docs: Update doc for pre-compiled exercises + `test_libs.txt`
AltGr Apr 22, 2022
32ad13e
fix: Fix dune dependency glitch on recompilation of `mutation_test`
AltGr Apr 22, 2022
466e80c
fix(docker): Include jsoo in Dockerfile, which is now needed
AltGr Apr 22, 2022
fa2cd23
fix(ci): Fix permission issues
AltGr Apr 22, 2022
5b4e0ab
docs: Add/Update copyright headers
AltGr Apr 22, 2022
365cbb7
fix: Expose `prepare.ml` file
yurug Jul 27, 2022
57ca10b
fix(partition-view): Reactivate the feature
yurug Jul 27, 2022
ee57ac1
fix(CLI): Report JSON parse error origin and locations
AltGr Oct 26, 2023
cb417d1
strengthening(grader): Add a safeguard against grading workers going …
AltGr Oct 26, 2023
ead187e
fix(grader): allow exercises to use vg, gg
AltGr Oct 26, 2023
942edc2
fix(teacher_tab): use newer asak compatible with precompilation
nobrakal Sep 11, 2023
f572990
doc: update index.md
AltGr Oct 26, 2023
f1abb7d
fix(build): update lockfiles
AltGr Oct 26, 2023
b94f053
fix(CI): attempt to fix running the docker image on the corpus
AltGr Oct 26, 2023
91a418e
fix(CI): disable compat tests with 0.12, 0.13
AltGr Oct 27, 2023
6ce797f
fix(docker): install more libs in server image
AltGr Oct 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ jobs:
uses: actions/checkout@v3
- name: Build Docker images
run: "make docker-images"
- name: Fix permissions
run: "chmod -R a+wX demo-repository"
- name: Run learn-ocaml build on demo-repository
run: "docker run --rm -v $(pwd)/demo-repository:/repository learn-ocaml -- build"
- name: Clone learn-ocaml-corpus inside tests/corpuses
run: "mkdir tests/corpuses && cd tests/corpuses && git clone --depth=1 https://github.com/ocaml-sf/learn-ocaml-corpus.git && cd ../.."
run: "git clone --depth=1 https://github.com/ocaml-sf/learn-ocaml-corpus.git tests/corpuses/learn-ocaml-corpus"
- name: Run tests
run: "cd tests && bash -c ./runtests.sh"
run: "tests/runtests.sh"

client_using_other_server:
name: Build learn-ocaml-client and run quick tests
Expand All @@ -36,8 +38,8 @@ jobs:
fail-fast: false
matrix:
server_image:
- 'ocamlsf/learn-ocaml:0.12'
- 'ocamlsf/learn-ocaml:0.13.0'
# - 'ocamlsf/learn-ocaml:0.12'
# - 'ocamlsf/learn-ocaml:0.13.0'
- 'learn-ocaml' # use learn-ocaml image built from master
env:
USE_CLIENT_IMAGE: 'true'
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ tests/corpuses/*
detect-libs.*

docs/odoc.html

demo-repository/exercises/**/*.cmo
demo-repository/exercises/**/*.cmi
demo-repository/exercises/**/*.cma
demo-repository/exercises/**/*.js
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ ARG opam_switch="/home/opam/.opam/4.12"
COPY --from=compilation /home/opam/install-prefix /usr
COPY --from=compilation "$opam_switch/bin"/ocaml* "$opam_switch/bin/"
COPY --from=compilation "$opam_switch/lib/ocaml" "$opam_switch/lib/ocaml/"
COPY --from=compilation "$opam_switch/bin/js_of_ocaml" "$opam_switch/bin/"
COPY --from=compilation "$opam_switch/lib/js_of_ocaml" "$opam_switch/lib/js_of_ocaml"
COPY --from=compilation "$opam_switch/lib/vg" "$opam_switch/lib/vg"
COPY --from=compilation "$opam_switch/lib/gg" "$opam_switch/lib/gg"

# Fixes for ocamlfind
COPY --from=compilation "$opam_switch/lib/findlib.conf" "$opam_switch/lib/"
COPY --from=compilation "$opam_switch/lib/stdlib" "$opam_switch/lib/stdlib"
ENV PATH="${opam_switch}/bin:${PATH}"
ENV OCAMLPATH="/usr/lib"
RUN ln -sf "$opam_switch/lib/vg" "/usr/lib"
RUN ln -sf "$opam_switch/lib/gg" "/usr/lib"

ENTRYPOINT ["dumb-init","/usr/bin/learn-ocaml","--sync-dir=/sync","--repo=/repository"]
CMD ["build","serve"]
7 changes: 7 additions & 0 deletions META.learn-ocaml.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package "test_lib" (
directory = "test_lib"
version = "0.13.2"
description = "Learn-ocaml dependencies for automatic graders"
requires = "compiler-libs"
)
# DUNE_GEN
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ REPO ?= demo-repository

testrun: build install
rm -rf www/css
learn-ocaml build --repo $(REPO) -j1
learn-ocaml build --repo $(REPO)
rm -rf www/css
ln -s ../static/css www
LEARNOCAML_SERVER_NOCACHE=1 learn-ocaml serve
Expand All @@ -82,7 +82,7 @@ docker-images: Dockerfile learn-ocaml.opam
@docker build -t learn-ocaml-compilation --target compilation docker
@docker build -t learn-ocaml --target program docker
@docker build -t learn-ocaml-client --target client docker
@echo "Use with 'docker run --rm -v \$$PWD/sync:/sync -v \$$PWD:/repository -p PORT:8080 learn-ocaml -- ARGS'"
@echo "Use with 'docker run --rm -v learn-ocaml-sync:/sync -v \$$PWD:/repository -p PORT:8080 learn-ocaml -- ARGS'"

VERSION = $(shell opam show ./learn-ocaml.opam -f version)

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ The Inconsolata font is released under the Open Font License.
See [http://www.levien.com/type/myfonts/inconsolata.html](http://www.levien.com/type/myfonts/inconsolata.html).

The Biolinum font is licensed under the GNU General Public License with
a the 'Font-Exception'.
a 'Font-Exception'.
See [http://www.linuxlibertine.org](http://www.linuxlibertine.org).

The public instance of Learn OCaml uses the Fontin font instead of
Expand All @@ -78,9 +78,9 @@ It was written by OCamlPro from 2015 to 2018.

The current main contributors are Érik Martin-Dorel, Yann Régis-Gianas, and Louis Gesbert.

The initial authors were Benjamin Canou, Çağdaş Bozman, and Grégoire Henry.
The initial authors were Benjamin Canou, Çağdaş Bozman, Grégoire Henry, and Louis Gesbert.

It builds on the previous experience of Try OCaml, by Çağdaş Bozman, and Fabrice Le Fessant.
It builds on the previous experience of Try OCaml, by Çağdaş Bozman and Fabrice Le Fessant.

We heavily use js_of_ocaml, so thanks to the Ocsigen team.

Expand Down
1 change: 1 addition & 0 deletions demo-repository/exercises/demo/test_libs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
learn-ocaml.mutation_testing
30 changes: 30 additions & 0 deletions docs/exercises_format.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ An exercise is described by a directory containing at most the following files:
- solution.ml
- test.ml
- max_score.txt
- test_libs.txt

> Note: as of learn-ocaml 1.0, the `.ml` files get compiled into the exercise.
> It is therefore not possible to use directives like `#install_printer`.
> However, you can still define your own printers in a way similar to defining
> custom `sample_<type>` functions:
>
> ```ocaml
> (* Custom printer for a pre-defined type *)
> let print_float ppf x = Format.fprintf ppf "%.2f" x
>
> (* Name the alias to define a printer for a specific instanciation of a
> generic type *)
> type int_list = int list
> let print_int_list ppf l = ...
>
> (* Define a generic printer for a generic type *)
> let print_result ppok pperr ppf = function
> | Ok ok -> Format.fprintf ppf "OK(%a)" ppok ok
> | Error err -> Format.fprintf ppf "ERR(%a)" pperr err
> ```
>
> Printers defined in `prelude.ml` or `prepare.ml` affect the toplevel and the
> grader. Printers defined in `test.ml`, obviously, affect only the grader.

### meta.json

Expand Down Expand Up @@ -130,6 +154,12 @@ code, which will be described and detailed in another section.
Maximum score that is possible to get for this exercise, even if the grader
grades more. Overridden by the field `max_score`, if present in `meta.json`.

### test_libs.txt

List of additional libraries (one per line) to be used by the grader. The
libraries will be looked up using `ocamlfind`, available to `test.ml` during its
compilation, and bundled in the exercise grader.

# Metadata

When building the corpus and extracting the metadatas of all exercises, the
Expand Down
34 changes: 27 additions & 7 deletions docs/exercises_tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ A classic `test.ml` file is as follows:
open Test_lib
open Report

let exercise_1 = ..
let exercise_1 () = ..

let exercise_2 = ..
let exercise_2 () = ..

let exercise_3 = ..
let exercise_3 () = ..


let () =
set_result @@
ast_sanity_check code_ast @@ fun () ->
[ exercise_1 ; exercise_2 ; exercise_3 ]
[ exercise_1 (); exercise_2 (); exercise_3 () ]

```

The values `exercise_x` are values of type `Learnocaml_report.report`, which is
The return values of `exercise_x` are of type `Learnocaml_report.report`, which is
a representation of the report given by the grader. In this example, each of
these values are referring to a specific question from the exercise. Their
these values is referring to a specific question from the exercise. Their
content is detailed in the next section. These reports are then given to the
function `ast_sanity_check`, which ensures that some modules are never used
(`Obj`, `Marshall`, all the modules from `compiler-libs` or the library that
Expand All @@ -46,7 +46,7 @@ allows introspection), and also excludes some syntactic features of the language

# Writing tests and reports

The format of reports can be found in `src/state/learnocaml_report.ml`. A report
The format of reports can be found in `src/grader/learnocaml_report.ml`. A report
describes the result of what should be outputted and interpreted by the
grader. It can be classified into sections for lisibility, and return many kind
of messages:
Expand Down Expand Up @@ -252,3 +252,23 @@ forbidden or required. The two functions `ast_check_expr` and
pattern-matching on some specific patterns into the code. The function
`find_binding` look for a toplevel value and apply a given function on its
syntax tree.

### Using helper libraries for testing

Using a `test_libs.txt` file, it is possible to include libraries that define
helpers for grading.

The file should contain the ocamlfind names of the libraries, one per line.

Example of such libs include
[mutation_testing](https://github.com/ocaml-sf/learn-ocaml/blob/master/src/grader-plugins/mutation_test.ml)
(from McGill University, included in this repository), or
[easy-check](https://github.com/lsylvestre/easy-check) from University Paris 6.

See `src/grader-plugins/dune` to get how to build such libraries. Like
`test.ml`, they can access the `Introspection` and `Test_lib` interfaces. They
cannot, at the time of writing, define new samplers or printers, but if you need
that feature and are ready to contribute, all that is missing is the inclusion
of their `cmi` files in the grading-toplevel environment (these features rely
on dynamic typing, and the `cma` library doesn't include the required typing
information).
4 changes: 1 addition & 3 deletions docs/howto-setup-exercise-development-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ GNU/Linux and MacOS X are supported.
> use:
>
> docker version # If this fails, find out how to run Docker, first
> docker login
> docker run --rm \
> -v $REPOSITORY:/repository:ro \
> -v learn-ocaml-sync:/sync \
Expand Down Expand Up @@ -63,7 +62,6 @@ ready:

```
opam switch create . --deps-only --locked
opam install opam-installer
eval $(opam env)
```

Expand All @@ -74,7 +72,7 @@ your current opam switch, without creating a dedicated one.)
Second, compile and install the platform:

```
make && make opaminstall
make && make install
```

At this point, you should get a working `learn-ocaml` program in
Expand Down
6 changes: 0 additions & 6 deletions docs/howto-write-exercises.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,3 @@ get the files for the second step, and so on and so forth.
[Step 6 : Grading functions for variables](tutorials/step-6.md)

[Step 7 : Modifying the comparison functions (testers) with the optional arguments [~test], [~test_stdout], [~test_stderr]](tutorials/step-7.md)

[Step 8 : Reusing the grader code](tutorials/step-8.md)

- Separating the grader code

[Step 9 : Introspection of students code](tutorials/step-9.md)
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ The Inconsolata font is released under the Open Font License.
See [http://www.levien.com/type/myfonts/inconsolata.html](http://www.levien.com/type/myfonts/inconsolata.html).

The Biolinum font is licensed under the GNU General Public License with
a the 'Font-Exception'.
a 'Font-Exception'.
See [http://www.linuxlibertine.org](http://www.linuxlibertine.org).

The public instance of Learn OCaml uses the Fontin font instead of
Expand All @@ -78,9 +78,9 @@ It was written by OCamlPro from 2015 to 2018.

The current main contributors are Érik Martin-Dorel, Yann Régis-Gianas, and Louis Gesbert.

The initial authors were Benjamin Canou, Çağdaş Bozman, and Grégoire Henry.
The initial authors were Benjamin Canou, Çağdaş Bozman, Grégoire Henry, and Louis Gesbert.

It builds on the previous experience of Try OCaml, by Çağdaş Bozman, and Fabrice Le Fessant.
It builds on the previous experience of Try OCaml, by Çağdaş Bozman and Fabrice Le Fessant.

We heavily use js_of_ocaml, so thanks to the Ocsigen team.

Expand Down
5 changes: 4 additions & 1 deletion docs/tutorials/step-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ specific shape, illustrated by the following ascii art:
│   │   ├── prepare.ml
│   │   ├── solution.ml
│   │   ├── template.ml
│   │   └── test.ml
│   │   ├── test.ml
│   │   └── test_libs.txt
│   ├── exercise2
│   │   ├── ...
│   ├── index.json
Expand Down Expand Up @@ -68,6 +69,8 @@ The complete format specification for exercise description is given in

- `test.ml` is the grader code.

- `test_libs.txt` optionally lists grader-helper libraries used by `test.ml`

- `lessons` and `tutorials` are ignored in this tutorial.

## Do it yourself!
Expand Down