diff --git a/.gitignore b/.gitignore index c391d98..9c743a5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ cache/ coverage/ coverage.json bin/ -solc \ No newline at end of file +solc +*.log \ No newline at end of file diff --git a/README.md b/README.md index d83b3e1..f631751 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ Repository for the blockchain branch content and tests. ## Content πŸ“– -Exercises are progressive in difficulty. They are designed to learn the fundamentals of blockchains as well as the main technologies and tools used in the industry. +Exercises increase progressively in difficulty. They are designed to teach the fundamentals of blockchains, as well as the main technologies and tools used in the industry. + +The content is organized into *quests*, that offer several exercises on a topic, *raids*, that are larger collaborative exercises, and *projects*, to explore further. It should take two to three weeks to complete the *quests* and *raids*. - Quest 1: Experiment with basic Bitcoin transactions - Quest 2: Learn fundamental cryptography @@ -14,51 +16,54 @@ Exercises are progressive in difficulty. They are designed to learn the fundamen - Quest 4: Scripted interactions with the Ethereum blockchain - Quest 5: Create a complete decentralised application - Raid 1: Create a signing service -- Quest 6: Create a first token -- Quest 7: An NFT based DApp +- Quest 6: Create your first token +- Quest 7: Develop an NFT based DApp - Quest 8: Learn the basics of DeFi and security - Quest 9: Explore other blockchains -- Raid 1: Create a tracking service +- Raid 2: Create a tracking service + +For more details, see the [introductions](introductions.md) for each quest and the corresponding [subjects](https://github.com/01-edu/public/tree/master/subjects/blockchain). -For more details see the [introductions](introductions.md) and the [subjects](https://github.com/01-edu/public/tree/master/subjects/blockchain) ## Tests βš™οΈ -Within the `tests/` folder, `run.sh` builds a docker image and runs the tests. Solutions are expected to be in a `tests/student` folder. For each available solution file, the appropriate test will be launched individually. The docker daemon or docker desktop needs to be running. +Within the `tests/` folder, `run.sh` builds a docker image and runs the tests. Solutions are expected to be in a `tests/student` folder. For each available solution file, the appropriate test will be launched individually. The Docker daemon or Docker Desktop needs to be running. +### Run tests collectively ```shell cd tests ./run.sh ``` -The final output should be similar to: +The final output will provide a summary of your test results as well as performance indicators. For example: ```shell -artists-do-work βœ… 4, basic-swap βœ… 4, basic-wallet βœ… 0, buy-tickets βœ… 2, check-document βœ… 6, connect-to-metamask βœ… 5, donation βœ… 6, eventful-token βœ… 3, fun-and-profit βœ… 3, -tests ran:9 in avg 4261 ms +artists-do-work βœ… 4, basic-swap βœ… 4, basic-wallet βœ… 0, buy-tickets βœ… 2, check-document βœ… 6, +connect-to-metamask βœ… 5, donation βœ… 6, eventful-token βœ… 3, fun-and-profit βœ… 3 +tests ran: 9 in 4261 ms on average. ``` -It is also possible to run tests individually (with debug mode on): - +### Run tests individually +It is possible to run a test individually by specifying the exercise. Debug mode will be enabled by default. ```shell +cd tests ./run.sh retrieve-block-date ``` -### Commands - -The following underlying commands can be launched individually from `tests/` folder: +### Underlying commands +The following underlying commands can be executed from the `tests/` folder: ```shell # build the docker image docker build . -t blockchain -# Run a BTC test +# Run a specific Bitcoin test docker run --read-only --network none --memory 500M --user 1000:1000 -e DEBUG=true -e EXERCISE=retrieve-block-date --env HOME=/jail --env TMPDIR=/jail --workdir /jail --tmpfs /jail:size=100M,noatime,exec,nodev,nosuid,uid=1000,gid=1000,nr_inodes=5k,mode=1700 --volume $PWD/student.all:/jail/student:ro blockchain:latest # Explore the docker image docker run -it --entrypoint /bin/bash blockchain:latest ``` -## Authors ✍️ +## Author ✍️ Xavier LavayssiΓ¨re - [πŸ™](https://github.com/Xalava) [🐦](https://twitter.com/xavierlava) diff --git a/tests/.dockerignore b/tests/.dockerignore index c31138c..549013b 100644 --- a/tests/.dockerignore +++ b/tests/.dockerignore @@ -6,6 +6,7 @@ dft* cache artifacts node_modules +*.log # Simply unecessary files .eslintrc.json diff --git a/tests/lib/helpers.js b/tests/lib/helpers.js index 9462571..93c62db 100644 --- a/tests/lib/helpers.js +++ b/tests/lib/helpers.js @@ -27,7 +27,7 @@ const pp_options = { args: [ // This is needed to chrome with puppeteer '--no-sandbox', - // Some of the following might be applied by default by puppeteer or ineffective + // Potential optimizations, but some might be already applied by puppeteer or ineffective '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', @@ -42,9 +42,11 @@ const pp_options = { '--disable-default-apps', '--disable-features=Translate', '--no-default-browser-check', - '--ignore-certificate-errors' + '--ignore-certificate-errors', + '--disable-gl-drawing-for-tests', //--disable-extensions // Might be necessary for metamask tests - ] + ], + headless: "old" // Avoids warning for running the older headless mode on new versions of Chrome. } // Interesting idea: // const opts = process.env.D ? { headless: false, slowMo: 250 } : {}; diff --git a/tests/run.sh b/tests/run.sh index e23eecb..8e43043 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -1,18 +1,34 @@ #!/bin/bash -# Script to build the docker image and run one or all tests and display a summary of the outcome +# This script runs tests in a docker container. -## Constants that can be adapted depending on the environment. -echo $(pwd) -STORAGE_STUDENT="$(pwd)/student.all" +# Constants that can be adapted depending on the environment. +STORAGE_STUDENT="$(pwd)/student" TEMP_STUDENT="$(pwd)/student.temp" -rm -rf $TEMP_STUDENT # for debugging, the folder is left and removed a the next run +rm -rf $TEMP_STUDENT # For debugging purposes, the temporary folder is removed a the beginning of the next run +# These docker options should replicate the production environement +BaseOptions="--read-only --network none --memory 500M --cpus 2.0 --user 1000:1000 --env USERNAME=πŸ§‘β€πŸŽ“ --env HOME=/jail --env TMPDIR=/jail --workdir /jail --tmpfs /jail:size=100M,noatime,exec,nodev,nosuid,uid=1000,gid=1000,nr_inodes=5k,mode=1700 --volume $TEMP_STUDENT:/jail/student:ro" -## Summary display logic +# Initialisation of display variables (for clarity) Results="" testNumber=0 totalRuntime=0 +displayHelp() { + #Display help (as it is formated here) + echo "Script to run tests in a docker container + +Usage: $0 [clean|nuclear|testName|help] + +Commands: + clean: Remove exited docker containers and images + nuclear: Remove all stopped containers, images and volumes + testname: Run a specific test in debug mode. E.g.: $0 retrieve-block-date + help: Display this help + +If no parameters are provided, all tests are run." +} + synthesis() { if [ $? -eq 0 ]; then currentRuntime=$(($(date +%s%N) - $date)) @@ -30,61 +46,59 @@ synthesis() { testNumber=$((testNumber + 1)) } -#@ Should replicate the production environement -BaseOptions="--read-only --network none --memory 500M --cpus 2.0 --user 1000:1000 --env USERNAME=πŸ§‘β€πŸŽ“ --env HOME=/jail --env TMPDIR=/jail --workdir /jail --tmpfs /jail:size=100M,noatime,exec,nodev,nosuid,uid=1000,gid=1000,nr_inodes=5k,mode=1700 --volume $TEMP_STUDENT:/jail/student:ro" - -if [ ! -z "$1" ]; then - if [ "$1" = "clean" ]; then +## Main evaluation of the argument +# Alt: Check if there is an argument: if [ ! -z "$1" ]; then +case "$1" in + "clean") + ## Clean the docker image. Necessary during development, could be skipped later. echo "▢️ Clean (docker housekeeping)" - ## Clean and rebuild the docker image. Necessary during development, could be skipped later. # Remove exited docker containers docker rm $(docker ps -a -f status=exited -q) # docker container prune -f - # Remove docker images + # Remove unused docker images docker image prune -f # Remove temporary student folder rm -rf $TEMP_STUDENT - exit 0 - elif [ "$1" = "nuclear" ]; then - # Nuclear : Remove stopped containers, images and volumes + ;; + "nuclear") + ## Nuclear : Remove stopped containers, images and volumes. Forces a clean start + echo "▢️ Nuclear housekeeping" docker system prune -af rm -rf $TEMP_STUDENT rm -rf node_modules - exit 0 - elif [ "$1" = "help" ]; then - echo "Script to build the docker image and run one or all the tests" + ;; + "help" | "-h") + displayHelp + ;; + "") + ## No specific test has been named, run all tests with a summary at the end + echo "▢️ Docker build" + docker build . -t blockchain + echo "▢️ Running test" + mkdir -p $TEMP_STUDENT + for file in $STORAGE_STUDENT/*; do + testname=$(basename "${file%.*}") + rm $TEMP_STUDENT/* # To facilitate debugging, the folder is emptied at the beginning of the next test + cp $STORAGE_STUDENT/$testname.{sol,js,html,mjs} $TEMP_STUDENT 2>/dev/null + sleep 0.1 + date=$(date +%s%N) + # Alt: -e DEBUG=true available + docker run $BaseOptions -e EXERCISE=$testname blockchain:latest + synthesis $testname + done + sleep 1 + echo "▢️ Results" + echo $Results echo "" - echo "Usage: ./runTests.sh [ clean | help | testName ]" - echo "testName: one test is run in debug mode, e.g. retrieve-block-date" - echo "clean: clean the docker environment" - echo "help: display this help" - echo "If no parameter is provided, all tests are run" - exit 0 - fi - # A specific test has been named, we run it with the debug flag - docker build . -t blockchain --progress=plain - mkdir -p $TEMP_STUDENT - cp $STORAGE_STUDENT/$1.{sol,js,html,mjs} $TEMP_STUDENT 2>/dev/null - time docker run $BaseOptions -e DEBUG=true -e EXERCISE="$1" blockchain:latest -else - # No specific test has been named. Run all tests with a summary at the end - echo "▢️ Docker build" - docker build . -t blockchain - echo "▢️ Running test" - # -e DEBUG=true available - mkdir -p $TEMP_STUDENT - for file in $STORAGE_STUDENT/*; do - testname=$(basename "${file%.*}") - rm $TEMP_STUDENT/* # for debugging, the folder is left and removed at the next run - cp $STORAGE_STUDENT/$testname.{sol,js,html,mjs} $TEMP_STUDENT 2>/dev/null - sleep 0.1 - date=$(date +%s%N) - docker run $BaseOptions -e EXERCISE=$testname blockchain:latest - synthesis $testname - done - sleep 1 - echo "▢️ Results" - echo $Results - echo "tests ran:$testNumber in avg $(($totalRuntime / 1000000 / $testNumber)) ms" -fi + echo "$testNumber tests ran in $(($totalRuntime / 1000000 / $testNumber)) ms on avg" + echo -e "\n$(date) \n $Results \n $testNumber tests ran in $(($totalRuntime / 1000000 / $testNumber)) ms on avg" >> run.log + ;; + *) + ## A specific test has been named. We run it with the debug flag + docker build . -t blockchain --progress=plain + mkdir -p $TEMP_STUDENT + cp $STORAGE_STUDENT/$1.{sol,js,html,mjs} $TEMP_STUDENT 2>/dev/null + time docker run $BaseOptions -e DEBUG=true -e EXERCISE="$1" blockchain:latest + ;; +esac exit 0