Skip to content

Commit 999051a

Browse files
Verify exercises in docker (#478)
Limits the number of parallel-letter-frequency processes
1 parent 491c018 commit 999051a

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

bin/verify-exercises-in-docker

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env bash
2+
3+
# Synopsis:
4+
# Verify that each exercise's example/exemplar solution passes the tests
5+
# using the track's test runner Docker image.
6+
# You can either verify all exercises or a single exercise.
7+
8+
# Example: verify all exercises in Docker
9+
# bin/verify-exercises-in-docker
10+
11+
# Example: verify single exercise in Docker
12+
# bin/verify-exercises-in-docker two-fer
13+
14+
set -eo pipefail
15+
16+
die() { echo "$*" >&2; exit 1; }
17+
18+
required_tool() {
19+
command -v "${1}" >/dev/null 2>&1 ||
20+
die "${1} is required but not installed. Please install it and make sure it's in your PATH."
21+
}
22+
23+
required_tool docker
24+
25+
copy_example_or_examplar_to_solution() {
26+
jq -c '[.files.solution, .files.exemplar // .files.example] | transpose | map({src: .[1], dst: .[0]}) | .[]' .meta/config.json \
27+
| while read -r src_and_dst; do
28+
cp "$(jq -r '.src' <<< "${src_and_dst}")" "$(jq -r '.dst' <<< "${src_and_dst}")"
29+
done
30+
}
31+
32+
pull_docker_image() {
33+
docker pull exercism/emacs-lisp-test-runner ||
34+
die $'Could not find the `exercism/emacs-lisp-test-runner` Docker image.\nCheck the test runner docs at https://exercism.org/docs/building/tooling/test-runners for more information.'
35+
}
36+
37+
run_tests() {
38+
local slug
39+
slug="${1}"
40+
41+
docker run \
42+
--rm \
43+
--network none \
44+
--read-only \
45+
--mount type=bind,src="${PWD}",dst=/solution \
46+
--mount type=bind,src="${PWD}",dst=/output \
47+
--mount type=tmpfs,dst=/tmp \
48+
exercism/emacs-lisp-test-runner "${slug}" /solution /output
49+
jq -re '.message // .status' "${PWD}/results.json"
50+
jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
51+
}
52+
53+
verify_exercise() {
54+
local dir
55+
local slug
56+
local tmp_dir
57+
dir=$(realpath "${1}")
58+
slug=$(basename "${dir}")
59+
tmp_dir=$(mktemp -d -t "exercism-verify-${slug}-XXXXX")
60+
61+
echo "Verifying ${slug} exercise..."
62+
63+
(
64+
trap 'rm -rf "$tmp_dir"' EXIT # remove tempdir when subshell ends
65+
cp -r "${dir}/." "${tmp_dir}"
66+
cd "${tmp_dir}"
67+
68+
copy_example_or_examplar_to_solution
69+
run_tests "${slug}"
70+
)
71+
}
72+
73+
verify_exercises() {
74+
local exercise_slug
75+
exercise_slug="${1}"
76+
77+
shopt -s nullglob
78+
count=0
79+
for exercise_dir in ./exercises/{concept,practice}/${exercise_slug}/; do
80+
if [[ -d "${exercise_dir}" ]]; then
81+
verify_exercise "${exercise_dir}"
82+
((++count))
83+
fi
84+
done
85+
((count > 0)) || die 'no matching exercises found!'
86+
}
87+
88+
pull_docker_image
89+
90+
exercise_slug="${1:-*}"
91+
verify_exercises "${exercise_slug}"

exercises/practice/parallel-letter-frequency/.meta/example.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
(let ((cleaned-texts (mapcar #'clean-text texts)))
2525
(if (cl-every #'string-empty-p cleaned-texts)
2626
(make-hash-table :test 'equal)
27-
(let* ((num-processes (min (length cleaned-texts) (max 1 (string-to-number (shell-command-to-string "nproc")))))
27+
(let* ((num-processes (min (length cleaned-texts) 8 (max 1 (string-to-number (shell-command-to-string "nproc")))))
2828
(texts-per-process (ceiling (/ (float (length cleaned-texts)) num-processes)))
2929
(results (make-hash-table :test 'equal))
3030
(pending num-processes)

0 commit comments

Comments
 (0)