cyber-dojo web server start-points


The web server's default start-points are as follows:
  • --languages=languages
    This start-point is created from the cyber-dojo-languages github repo.
    The --languages start-point holds the choices where you select your language and test-framework, eg C# and Moq. A languages start-point contains manifest.json files.

  • --exercises=exercises
    This start-point is created from the cyber-dojo-exercises github repo.
    The --exercises start-point holds the choices where you select your exercises, eg Fizz Buzz. An exercises start-point contains instructions files.

  • --custom=custom
    This start-point is created from the cyber-dojo-custom github repo.
    The --custom start-point holds the choices displayed when you switch to custom choices. A custom start-point contains manifest.json files.

creating new defaults

To use a different default start-point simply bring down the server, delete the one you wish to replace, create a new one with that name, and bring the server back up. For example, to create a new --languages start-point default:
$ sudo ./cyber-dojo down $ sudo ./cyber-dojo start-point rm languages $ sudo ./cyber-dojo start-point create languages --dir=... $ sudo ./cyber-dojo up

$ ./cyber-dojo start-point ...

Start-points are controlled using the start-point command of the cyber-dojo script (see step 2 of running your own web server).
$ sudo ./cyber-dojo start-point Use: cyber-dojo start-point [COMMAND] Manage cyber-dojo start-points Commands: create Creates a new start-point rm Removes a start-point ls Lists the names of all start-points inspect Displays details of a start-point pull Pulls all the images named inside a start-point Run 'cyber-dojo start-point COMMAND --help' for more information on a command

For example:
$ sudo ./cyber-dojo start-point ls NAME TYPE SRC custom custom exercises exercises languages languages

For example:
$ sudo ./cyber-dojo start-point inspect languages MAJOR_NAME MINOR_NAME IMAGE_NAME PULLED? Asm assert cyberdojofoundation/nasm_assert no BCPL all_tests_passed cyberdojofoundation/bcpl_all_tests_passed no Bash bash_unit cyberdojofoundation/bash_unit yes ... C (clang) Cgreen cyberdojofoundation/clang_cgreen no ... C (gcc) Cgreen cyberdojofoundation/gcc_cgreen no ... C# Moq cyberdojofoundation/csharp_moq yes ... C++ (clang++) Cgreen cyberdojofoundation/clangpp_cgreen no ... C++ (g++) Boost.Test cyberdojofoundation/gpp_boosttest no ... Clojure Midje cyberdojofoundation/clojure_midje no ... CoffeeScript jasmine cyberdojofoundation/coffeescript_jasmine no D unittest cyberdojofoundation/d_unittest no Erlang eunit cyberdojofoundation/erlang_eunit no F# NUnit cyberdojofoundation/fsharp_nunit no Fortran FUnit cyberdojofoundation/fortran_funit no Go testing cyberdojofoundation/go_testing no Groovy JUnit cyberdojofoundation/groovy_junit no ... Haskell hunit cyberdojofoundation/haskell_hunit no Java Cucumber cyberdojofoundation/java_cucumber no ... Javascript Mocha+chai+sinon cyberdojofoundation/javascript-node_mocha_chai_sinon no ... PHP PHPUnit cyberdojofoundation/php_phpunit no Perl Test::Simple cyberdojofoundation/perl_test_simple no Python py.test cyberdojofoundation/python_pytest no Python unittest cyberdojofoundation/python_unittest yes R RUnit cyberdojofoundation/r_runit no Ruby Cucumber cyberdojofoundation/ruby_cucumber no ... Rust test cyberdojofoundation/rust_test no Scala scalatest cyberdojofoundation/scala_scalatest no Swift XCTest cyberdojofoundation/swift_xctest yes VHDL assert cyberdojofoundation/vhdl_assert no VisualBasic NUnit cyberdojofoundation/visual-basic_nunit no

$ sudo ./cyber-dojo start-point create Use: cyber-dojo start-point create NAME --git=URL Use: cyber-dojo start-point create NAME --dir=PATH Creates a start-point named NAME from a git clone of URL Creates a start-point named NAME from a copy of PATH

cyber-dojo new release

The new release of cyber-dojo just went live :-)

creating your own web server start-points

cyber-dojo's new architecture has customisable start-points.
If you want to use your own start-points you do not need to build a new web server image.

preparing your custom/languages start-point

  • Create a folder for the start-point
    $ md douglas
  • In the top-level folder create a setup.json
    $ touch douglas/setup.json
    This file must specify the type of start-point.
    • custom
      { 'type' : 'custom' }
    • languages
      { 'type' : 'languages' }
  • Create a sub-folder for each start-point entry
    $ md douglas/first
  • Create a manifest.json file in each folder
    $ nano douglas/first/manifest.json
  • Here's an example. Here's an explanation of the manifest.json format.
  • In each folder create the visible files named in manifest.json
    Here's an example

preparing your exercises start-point

  • Create a folder for the start-point
    $ md arthur
  • In the top-level folder create a setup.json
    $ touch arthur/setup.json
    This file must specify the type of start-point.
    { 'type' : 'exercises' }
  • Create a sub-folder for each exercise
    $ md arthur/first
  • Create an instructions file in each folder
    $ nano arthur/first/instructions
    Here's an example

checking your start-point

starting your server with your start-point

$ sudo ./cyber-dojo up --custom=adams
$ sudo ./cyber-dojo up --languages=adams
$ sudo ./cyber-dojo up --exercises=arthur

adding a new language and unit-test-framework to cyber-dojo

0. make sure docker is installed

  • Linux users: install docker-engine, docker-machine, and docker-compose.
    To do all three in one go:
    $ curl -O $ chmod +x $ sudo ./
  • Mac and Windows users: install Docker Toolbox and open a Docker-Quickstart-Terminal

1. create a docker-image for just the language

Make this docker-image unit-test-framework agnostic.
If you are adding a new unit-test-framework to an existing language skip this step.
For example, suppose you were building Lisp
  • create a new folder for your language
    $ md lisp
  • in your language's folder, create a file called Dockerfile
    $ cd Lisp $ touch Dockerfile
    If you can, base your new image on Alpine-linux as this will help keep images small. To do this make the first line of Dockerfile as follows
    FROM cyberdojofoundation/language-base
    Here's one based on Alpine-linux (95 MB: C, assert) C (gcc)/assert/Dockerfile
    Here's one not based on Alpine (Ubuntu 845 MB: C#, NUnit) C#/NUnit/Dockerfile
  • use the Dockerfile to try and build your docker-image.
    For example
    $ docker build -t cyberdojo/lisp .
    which, if it completes, creates a new docker-image called cyberdojo/lisp using the Dockerfile (and build context) in . (the current folder).

2. create a docker-image for the language and unit-test-framework

Repeat the same process, building FROM the docker-image you created in the previous step.
For example, suppose your Lisp unit-test framework is called lunit
  • create a new folder underneath your language folder
    $ cd lisp $ md lunit
  • in your new test folder, create a file called Dockerfile
    $ cd lisp/lunit $ touch Dockerfile
    The first line of this file must name the docker image you built for your language in the previous step.
    Add lines for all the commands needed to install your unit-test framework prefixed with RUN.
    FROM cyberdojo/lisp RUN apt-get install -y lispy-lunit RUN apt-get install -y ...
    If you do not need any commands you should still create a Dockerfile with the single FROM line.
  • use the Dockerfile to try and build your image.
    The name of an image takes the form hub-name/image-name. Do not include a version number in the image-name. For example
    $ docker build -t cyberdojo/lisp_lunit .
    which, if it completes, creates a new docker image called cyberdojo/lisp_lunit using the Dockerfile in . (the current folder).
  • do not put any version numbers in the image name.

3. use the image in a new start-point

Use the new image name (eg cyberdojo/lisp_lunit) in a new manifest.json file in a new start-point.

cyber-dojo start-points manifest.json entries explained

Example: the manifest.json file for Java/JUnit looks like this:

{ "display_name": "Java, JUnit", "visible_filenames": [ "", "", "" ], "image_name": "cyberdojofoundation/java_junit", "red_amber_green" : [ "lambda { |output|", " return :red if /^Tests run: (\\d*),(\\s)+Failures: (\\d*)/.match(output)", " return :green if /^OK \\((\\d*) test/.match(output)", " return :amber", "}" ], "filename_extension": ".java", "tab_size": 4, "progress_regexs" : [ "Tests run\\: (\\d)+,(\\s)+Failures\\: (\\d)+", "OK \\((\\d)+ test(s)?\\)" ] }

Required entries

"display_name": string

The (major, minor) names as they appear in the start-point setup pages where you select your language,test. Also appears in the footer displayed at the bottom of some pages. A single string with the major name first, then a comma, then the minor name. Should not contain any digits.

"visible_filenames": [ string, string, ... ]

Filenames that will be visible in the browser's editor when an animal initially enter's a cyber-dojo. Each of these files must exist in the manifest.json's directory. Must include This is because is the name of the shell file assumed by the ruby code (in the Rails server) to be the start point for running the tests. You can write any actions in the file but clearly any programs it tries to run must be installed in the docker image_name. For example, if runs gcc to compile C files then gcc has to be installed. If runs javac to compile java files then javac has to be installed.

"image_name": string

The name of the docker image used to run a container in which is run. Do not include any version numbers (eg of the compiler or test-framework).

"red_amber_green": [ string, string, ... ]

A Ruby lambda, one line per string, which will be passed the output of when run inside docker_image. Must return :red, :amber, or :green as described below. Note that backslashes have to be escaped.
  • :red - the tests ran but at least one failed
  • :amber - the tests could not be run (eg syntax error)
  • :green - the tests ran and all passed

Optional entries

"filename_extension": string

The filename extension used when creating a new filename. For example, if set to ".java" the new filename will be
Defaults to the empty string (and the new filename will be filename).

"tab_size": int

The number of spaces a tab character expands to in the browser's textarea editor.
Defaults to 4.

"progress_regexs": [ string, string ]

Two regexs, the first one to match a red traffic light's test output, and the second one to match a green traffic light's test output. Used on the dashboard to show the test output line (which often contains the number of passing and failing tests) of each animal's most recent red/green traffic light. Useful when your practice session starts from a large number of pre-written tests and you wish to monitor the progress of each animal.
Defaults to an empty array.

"highlight_filenames": [ string, string, ... ]

Filenames whose appearance is highlighted in the browser. This can be useful if you have many "visible_filenames" and want to mark which files form the focus of the practice.
A strict subset of "visible_filenames".
For example
"highlight_filenames": [ "buffer.cpp", "buffer.hpp" ]
The appearance of "highlight_filenames" is controlled by the CSS in kata.css.scss
div[class~='filename'][class~='highlight'] { ... }
The highlight_filenames entry also interacts with lowlights_filenames, see StartPoint.lowlight_filenames() in start_point.rb and cd.notLowlightFilenames() in cyber-dojo_file_load.js
Again, its appearance in controlled from the same CSS file...
div[class~='filename'][class~='lowlight'] { ... }
If there is a "highlight_filenames" entry, then lowlight-filenames will be
[visible_filenames] - [highlight_filenames]
If there is no "highlight_filenames" entry, then lowlight-filenames will default to something like
[ 'cyber-dojo', 'makefile', 'Makefile' ]
Defaults to an empty array.

running your own cyber-dojo web server

Please note:
  • These instructions relate to the cyber-dojo web server image named cyberdojo/web built from the cyber-dojo github repo.
  • All development work on Jon Jagger's github repo which built a web server image named cyberdojofoundation/web has ceased.
  • If you have any questions or problems please email me

install docker engine+machine+compose

  • Linux users: install docker-engine, docker-machine, and docker-compose.
    To do all three in one go:
    $ curl -O $ chmod +x $ sudo ./
  • Mac and Windows users: install Docker Toolbox and open a Docker-Quickstart-Terminal

Please note:
  • When you bring your cyber-dojo server up for the first time, the docker daemon will automatically pull the web server image.
  • The cyber-dojo web server image is docker version sensitive.
  • Each image is tagged with the version number corresponding to its docker version number.
  • Here's a list of all the tagged cyber-dojo web server images.
  • If the version of docker on your host server is not in this list please email me telling me what version you need and I will build it and push it to the list.
  • To determine the version of docker running on your host server type:
    $ sudo docker --version

download the cyber-dojo shell script

$ curl -O $ chmod +x cyber-dojo
The cyber-dojo script must be run as root.

bring up your cyber-dojo web server

$ sudo ./cyber-dojo up
That's it!
This will download the docker images for the server (once only) and bring up your server.
Put your server's IP address into your browser.
Mac and Windows users can get their server's IP address as follows:
$ docker-machine ip default

bring down your cyber-dojo web server


$ sudo ./cyber-dojo down

pre-pulling cyber-dojo images

When you setup a practice session (eg C# and Moq) the server checks if its associated docker-image (eg cyberdojofoundation/csharp_moq) has been pulled. If it hasn't the server will pull it. If you want to pre-pull all docker-images named in a start-point onto the web server use the [start-point pull] command.

For example:
$ sudo ./cyber-dojo start-point pull languages PULLING cyberdojofoundation/nasm_assert (Asm, assert) ... PULLING cyberdojofoundation/bcpl_all_tests_passed (BCPL, all_tests_passed) ... PULLING cyberdojofoundation/bash_unit (Bash, bash_unit) ... PULLING cyberdojofoundation/clang_cgreen (C (clang), Cgreen) ...

cyber-dojo traffic-lights!

My friend Byran who works at the awesome Bluefruit Software in Redruth has hooked up his cyber-dojo web server to an actual traffic-light! Fantastic. Check out the video below :-)

Byran writes
It started out as a joke between myself and Josh (one of the testers at Bluefruit). I had the traffic lights in my office as I was preparing a stand to promote the outreach events (Summer Huddle, Mission to Mars, etc...) Software Cornwall runs. The conversation went on to alternative uses for the traffic lights, I was planning to see if people would pay attention to the traffic lights if I put them in a corridor at the event; we then came up with the idea that we could use them to indicate TDD test status.
Although it started out as a joke I am going to use it at the Summer Huddle, the lights change every time anyone runs a test so it should give an idea of how the entire group are doing without highlighting an individual pair.
The software setup is very simple, there is a Python web server (using the Flask library) running on a Raspberry Pi that controls the traffic lights using GPIO Zero. When the appendTestTrafficLight() function (in run_tests.js.erb) appends the traffic light image to the webpage I made it send an http 'get' request to the Raspberry Pi web server to set the physical traffic lights at the same time. At the moment the IP address of the Raspberry Pi is hard coded in the 'run_tests.js.erb' file so I have to rebuild the web image if anything changes but it was only meant to be a joke/proof of concept. The code is on a branch called traffic_lights on my fork of the cyber-dojo web repository.
The hardware is also relatively simple, there is a converter board on the Pi; this only converts the IO pin output connector of the Raspberry Pi to the cable that attaches to the traffic lights.
The other end of the cable from the converter board attaches to the board in the top left of the inside the traffic lights; this has some optoisolators that drive the relays in the top right which in turn switch on and off the transformers (the red thing in the bottom left) that drive the lights.
I have to give credit to Steve Amor for building the hardware for the traffic lights. They are usually used during events we run to teach coding to children (and sometimes adults). The converter board has LEDs, switches and buzzers on it to show that there isn't a difference between writing software to toggle LEDs vs driving actual real world systems, it's just what's attached to the pin. Having something where they can run the same code to drive LEDs and drive real traffic lights helps to emphasise this point.