Skip to content

Environment Configuration

João Pedro Finoto edited this page Jun 11, 2017 · 2 revisions

What is an environment?

An environment is a set of tools (usually a docker image and a grader program) and instructions on how to run and process the student's code.

Each environment is represented by a folder on disk, containing a env.json file.

Setting up and environment

To create an environment, create a folder on /var/moodlecode/env. The name of this folder will be the ID for this env. You should try to make the folder name as descriptive as possible, preferably containing the language this is designed for.

Next up, create a file named env.json inside of this folder.

env.json structure

Take a look at this example file:

{
	"name": "C Output",
	"action": {
		"grade": {
			"type": "docker",
			"image": "mcl-c",
			"copy": "*",
			"copyTo": "/tmp/mclrun",
			"outputProcess": {
				"function": "resultCompare",
				"params": {
					"model": "expected.output.value",
					"response": "_output.output",
					"feedback": "feedback.output.value"
				}
			},
			"testCases": {
				"method": false
			},
			"commands": [{
					"cmd": "echo Input source code: && cat %answer.output.name && echo",
					"output": [
						"log"
					]
				}, {
					"cmd": "gcc -Wall -o program %answer.output.name 2>&1",
					"output": [
						"log",
						"feedback"
					]
				},
				"chmod 777 *", {
					"cmd": "cat %input.output.name | timeout 3 ./program > _output.txt",
					"if:and": [{
						"a": "%expected.output.type",
						"operation": "=",
						"b": "std"
					}, {
						"a": "%input.output.type",
						"operation": "=",
						"b": "std"
					}],
					"output": [
						"log"
					]
				}, {
					"cmd": "cat %input.output.name | timeout 3 ./program && cat %expected.output.name > _output.txt",
					"if:and": [{
						"a": "%expected.output.type",
						"operation": "=",
						"b": "file"
					}, {
						"a": "%input.output.type",
						"operation": "=",
						"b": "std"
					}],
					"output": [
						"log"
					]
				}, {
					"cmd": "timeout 3 ./program > _output.txt",
					"if:and": [{
						"a": "%expected.output.type",
						"operation": "=",
						"b": "std"
					}, {
						"a": "%input.output.type",
						"operation": "=",
						"b": "file"
					}],
					"output": [
						"log"
					]
				}, {
					"cmd": "timeout 3 ./program && cat %expected.output.name > _output.txt",
					"if:and": [{
						"a": "%expected.output.type",
						"operation": "=",
						"b": "file"
					}, {
						"a": "%input.output.type",
						"operation": "=",
						"b": "file"
					}],
					"output": [
						"log"
					]
				}, {
					"cmd": "cat _output.txt",
					"output": [
						"log",
						"output"
					]
				}
			]
		},
		"test": {
			"type": "docker",
			"image": "mcl-c",
			"copy": "*",
			"copyTo": "/tmp/mclrun",
			"commands": [{
					"cmd": "gcc -Wall -o program %answer.output.name 2>&1",
					"output": [
						"feedback"
					]
				},
				"touch %testoutput.value",
				"chmod 777 *",
				"rm -rf %expected.output.name env.json grader",
				{
					"cmd": "cat %testinput.output.name | timeout 3 ./program > _output.txt",
					"if:and": [{
						"a": "%testoutput.selected",
						"operation": "=",
						"b": "std"
					}, {
						"a": "%testinput.output.type",
						"operation": "=",
						"b": "std"
					}],
					"output": [
						"feedback"
					]
				}, {
					"cmd": "cat %testinput.output.name | timeout 3 ./program && cat %testoutput.value > _output.txt",
					"if:and": [{
						"a": "%testoutput.selected",
						"operation": "=",
						"b": "file"
					}, {
						"a": "%testinput.output.type",
						"operation": "=",
						"b": "std"
					}],
					"output": [
						"feedback"
					]
				}, {
					"cmd": "timeout 3 ./program > _output.txt",
					"if:and": [{
						"a": "%testoutput.selected",
						"operation": "=",
						"b": "std"
					}, {
						"a": "%testinput.output.type",
						"operation": "=",
						"b": "file"
					}],
					"output": [
						"feedback"
					]
				}, {
					"cmd": "timeout 3 ./program && cat %testoutput.value > _output.txt",
					"if:and": [{
						"a": "%testoutput.selected",
						"operation": "=",
						"b": "file"
					}, {
						"a": "%testinput.output.type",
						"operation": "=",
						"b": "file"
					}],
					"output": [
						"feedback"
					]
				}, {
					"cmd": "cat _output.txt",
					"output": [
						"feedback"
					]
				}
			]
		}
	},
	"options": [{
		"type": "textarea",
		"id": "input",
		"name": "Program input",
		"encode": "base64",
		"output": {
			"type": "file",
			"name": "input.txt"
		}
	}, {
		"type": "textarea",
		"id": "expected",
		"name": "Expected output",
		"encode": "base64",
		"output": {
			"type": "file",
			"nofile": true,
			"name": "expected.txt"
		}
	}, {
		"type": "textarea",
		"id": "feedback",
		"name": "Test case feedback",
		"default": "",
		"desc": "Feedback given if this testcase isn't 100% correct",
		"encode": "plain",
		"lang": "plain",
		"nofile": true,
		"output": {
			"value": ""
		}
	}],
	"inputs": [{
		"type": "editor",
		"id": "answer",
		"name": "Answer",
		"default": "I2luY2x1ZGUgPHN0ZGlvLmg+DQoNCmludCBtYWluKCkgew0KICAgIHJldHVybiAwOw0KfQ==",
		"encode": "base64",
		"lang": "c_cpp",
		"nofile": true,
		"output": {
			"type": "file",
			"name": "main.c",
			"defaultName": "main.c"
		}
	}, {
		"type": "editor",
		"id": "testinput",
		"name": "Test input",
		"desc": "Shown to the student when answering the question. Used for testing the program.",
		"default": "",
		"encode": "base64",
		"lang": "plain",
		"output": {
			"type": "std",
			"name": "Input"
		}
	}, {
		"type": "textselect",
		"id": "testoutput",
		"name": "Test output",
		"desc": "How the output from the program is read. File will read the file and cat to the student. Stdout will show the output from the program.",
		"encode": "plain",
		"value": "output.txt",
		"selected": "std",
		"hidden": true,
		"list": [
			{
				"label": "File",
				"value": "file"
			},
			{
				"label": "stdout",
				"value": "std"
			}
		]
	}],
	"validation": [{
		"id": "answer.output.name",
		"type": "replace",
		"exp": "/[^A-Za-z0-9.]/",
		"replace": ""
	}]
}

This environment configuration copies and runs a source file written in c, and compares it's output to a desired one.

The fields in this file are:

  • name - string containing a descriptive name for this environment. This will be displayed on the environment selection box on the question page.
  • action - Object. Must contain two properties: "grade" and "test". The first is run when the student submits the question for grading, processes it and returns a score. The second one is run when the "Run" button is pressed in the interface, providing the output to the student.
  • action.(grade|test) - Object or string. If a string is given, this command will be run on the host (not recommended). If an object is given:
    • type - string. The only supported value is "docker"

    • image - string. The docker image that will be run.

    • copy - "*" or array. List of files to be copied, relative to the environment root, or "*" to copy all.

    • copyTo - string. The directory on the docker machine where these files will be copied to. It gets created if it doesn't exist.

    • commands - array. List of commands that get executed, in order. Note that all commands are independent, meaning they don't share the same session. Commands can be string or objects. If a string is given, this command gets executed, and its results are added to the output, which is later processed for tags. Alternatively, a object can be given.

      • cmd - string. The command to execute. Escape any double quotes, as this gets executed as bash -c "command"
      • output optional - array. List of outputs of this command. The result is added to the end of previous outputs of the same type. Currently available outputs are:
        • output - passed to the tag parser.
        • log - added to the log
        • feedback - added to the student's feedback and displayed after the question is corrected.
      • if:and optional - array. Condition for this command to execute. Operands can use % values to get dynamic values.
        • a - first operand
        • operation - comparator function. Can be "=" or "!="
        • b - second operand
    • options - array. List of configuration fields. These are used to setup inputs and outputs for question instances.

      • type - string. Currently, only "textarea"
      • id - string. A unique id that represents this field.
      • name - string. Name displayed on the question editor.
      • encode- string. How the contents are stored on the file. Can be base64 or plain.
      • output - object
        • type - string. How this output is treated. Can only be file. Anything else will cause no output.
        • name - string. Used for file output. The file will receive this name and added to the temporary directory.
        • value - string. Value for this option. Usually set on the question editor. Has the same encoding as it's parent.
    • inputs - array. Inputs the student is presented with. Has the same fields as options, and some adicional ones:

      • type - string. Can only be "editor"
      • lang - string. ACE-editor name of the language. Used on the editor for syntax highlighting.
      • default - string. Default value for this field. Has the same encoding as it's input.
      • output
        • name - string. If left blank, will case an input box for the student to fill.
        • defaultName optional - string. Default name for the input box.
    • validation optional - array. Used for field validation.

      • id - string. Field ID this is applied on.
      • type - string. At the moment, only replace
      • exp - string (regex). Search regex.
      • replace - string. What to replace regex matches with.

Clone this wiki locally