Skip to main content

Computer Science programming submission testing tool

Project description

CSTester is a Python curses package to automate Computer Science programming assignment evaluation.

Configuration options

  • phasedir

    The directory containing groups’ submissions

  • phasezip

    A zip containing groups’ zipfiles

  • keyfile

    Keys to associate with group numbers to aid extraction

  • groupre_str

    A regex to extract group numbers from group zip filenames

  • zipexclude_strs

    A list of regex patterns to exclude files if any portion of the filename matches a pattern

  • zipinclude_strs

    A map of files to explicitly place at a location relative to the group’s root directory

  • allgroups

    A calculated number/range list and includes all group numbers

  • include

    A number/range list of groups to only include

  • exclude

    A number/range list of groups to exclude

  • freezefiles

    A pattern for files to “freeze”

  • cleanfiles

    A pattern for files to remove with the clean command

  • casedir

    The directory containing input test cases

  • caseext

    The file extension of input test cases

  • cases

    A calculated list of input test cases

  • expdir

    The directory containing expected output files

  • expext

    The file extension of expected output files

  • exps

    A calculated list of expected output files

  • testcmd

    The testing command to run from each group’s directory

  • prepcmds

    A list of commands to run from selected group directories

  • readmename

    The name of a text file that should be included in submissions

  • searchstrs

    A list of regex patterns to search for within searchfiles

  • searchfiles

    A pattern for files to include within the strings search


Phase directory

One of the first things wich must be done is setting up the phase directory.

The phase directory contains each group’s submission in a subdirectory in the form group_n, where n is a non-negative integer.

Extraction

The extractor was made to extract submissions.zip, where each group submits a zip.

submissions.zip is a zip containing other zips.

Group numbers are obtained through a group regex, or, optionally, using a keyfile.

The group regex extracts a number from a filename, using re.match, e.g.,

^group_(0|[1-9][0-9]*).*\.zip$

The key-value pairs taken from the keyfile are of the form

^(0|[1-9][0-9]*)(?:,.*):([^:]+)$

That is, lines start with a valid group number, optionally followed by a comma and some series of text before a trailing colon, finally, the key to search for in the filename is after the final colon.

For example, with

42,Group leader: A name, Members: Another name:groupname

if groupname exists within the filename then the group number will be inferred to be 42.

All regex matches performed during extraction are all case-insensitive. Regexes in a keyfile must be unique, group numbers need not be.

Group directories are of the form group_n, where n is the group number

Within the phase directory, an extraction log is created: phasedir/x.log

The extraction log records general information about extraction
  • If a keyfile was used and how many keys were obtained from the keyfile

  • If files were skipped/ignored

  • If a group number was inferred from keyfile and why

  • If a group number was manually entered (decisions in subsequent extractions of the same zipfile can be repeated)

  • Which file was chosen among multiple submissions

  • How many group->file pairs were found

  • If duplicate files were ignored

  • If a submission zip had symlink files

  • If extraction of a submission zip had an exception

  • If a submission wasn’t extracted due to a suspicious compression ratio

  • If duplicate files were ignored

  • If extracted files needed to be renamed

Within group directories, e.g., phasedir/group_1/
  • group1.zip–contains the original zipfile

  • sub.nfo–contains details of the original zipfile The original zip filename The compressed size, extracted size, and compression ratio Whether symlink files existed (and were skipped) List of extracted files List of files excluded

Extracting individual zip files

The submissions zip is extracted to a temporary directory.

We examine the zip memberlist against exclude patterns, and do not extract files which match (case-insensitive) an exclude pattern.

For files we want at a specific location, these can be specified in the include pattern map:

  • The key is a regex to match the file

  • The val is a relative location from the group directory

We exclude (and print a warning) any symlinks within the archive. We extract the contents of the zip to a new temporary directory. We ensure all files are chmod 600 (owner rw), and all directories are chmod 700 (owner rwx).

We move all files to the final extraction directory, we remove any special characters from file/directory names, and spaces are converted to underscores. We put the original zip in the group’s directory. A text file, ./sub.nfo, will contain the zip filename, original content list with sizes (compressed/decompressed), and compression ratio of extracted files.


Making patches

Patches can be made which can be shared
  • So that they can be applied with the patch command

  • To show changes made

To make patches, relevant files must be first frozen in their initial state.

Freezing files requires a regex to match files of interest.

All files within group directories which match the regex
  • Are duplicated in a zip archive

  • Their hash is calculated and stored in a text file

The frozen zip and hashes are stored in the root of the phase directory.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cstester-2.0.0.tar.gz (52.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cstester-2.0.0-py3-none-any.whl (56.8 kB view details)

Uploaded Python 3

File details

Details for the file cstester-2.0.0.tar.gz.

File metadata

  • Download URL: cstester-2.0.0.tar.gz
  • Upload date:
  • Size: 52.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for cstester-2.0.0.tar.gz
Algorithm Hash digest
SHA256 b81079a7a7ea239ef3ef1fbebca1c6aa9c22bfe4b6a0c97794143e369939a4a8
MD5 e159642cde5931a1197311917f10c1bc
BLAKE2b-256 c336d0d67f4e772a0db83e3f0a624ded3f9f9ce39496af2360d1c7637053bbea

See more details on using hashes here.

File details

Details for the file cstester-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: cstester-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 56.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for cstester-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a630196cd38b3daaf94c4213dba5e32349998fa8a1717d46952d406b273c3bb
MD5 4157f45bed5f14d157521a639fec2b1c
BLAKE2b-256 35a1764a503539d25ddc80c41292e29e6173fcc6d00da6593a97f0d26f6bb4ae

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page