{"id":19320517,"url":"https://github.com/aluriak/weldon","last_synced_at":"2026-05-14T18:32:25.789Z","repository":{"id":143141054,"uuid":"95584624","full_name":"Aluriak/weldon","owner":"Aluriak","description":"Learning system targetting practical programming courses","archived":false,"fork":false,"pushed_at":"2018-02-04T14:53:51.000Z","size":105,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-24T05:23:20.551Z","etag":null,"topics":["learning","linting","system","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aluriak.png","metadata":{"files":{"readme":"README.mkd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-27T17:39:12.000Z","updated_at":"2017-06-29T17:17:59.000Z","dependencies_parsed_at":"2023-04-27T05:31:08.153Z","dependency_job_id":null,"html_url":"https://github.com/Aluriak/weldon","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Aluriak/weldon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aluriak%2Fweldon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aluriak%2Fweldon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aluriak%2Fweldon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aluriak%2Fweldon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aluriak","download_url":"https://codeload.github.com/Aluriak/weldon/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aluriak%2Fweldon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33037819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["learning","linting","system","unit-testing"],"created_at":"2024-11-10T01:29:19.131Z","updated_at":"2026-05-14T18:32:25.771Z","avatar_url":"https://github.com/Aluriak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Weldon\nWeldon is mainly a system built on top of any OS and editor allowing students to practice TDD,\naggressive testing and more generally Python.\n\nWeldon also allow a battle mode, where teams of coders confront against teams of testers.\n\n\n## Principles\nPlayers are the main user of Weldon, and generally named *students* or *coders* (rooters are the admin/teachers).\nRooter starts a server, to which he can add *problems*.\nProblems are retrieved by coders that can then work as they wish on it,\nand when wanted submit their source code, that constitute their *solution* to the problem.\n\nCoders answers are collected by the server, and tested against the *unit tests* defined in the problem.\nUnit tests comes in 3 flavors : public, hidden and community.\nPublic tests are accessible by coders, so they can see what to expect from tests.\nHidden tests are not accessible by coders. This ensure that they do not code a 1-to-1 mapping of I/O.\nCommunity tests are uploaded by coders. These allow the students to perform aggressive testing against each others.\n\nTesters are a special flavor of players that have for only job to upload tests that fail in other players submissions.\n\n\n\n## Current state\nWeldon is currently in POC stage : all codes here are mainly\nhere to show that the goals are realistic and reachable.\nThese codes should not be used in production.\n\n\n\n## Examples\nRun or read module *problem01.py*, that contains a linear use case where a teacher create a problem\nand a student send solutions and tests then retrieve the results.\n\nModule *webclient.py* is exactly the same story, but using the over-the-network API of weldon.\nTherefore, an instance of the *webserver.py* must run during *webclient* execution.\n\n\n\n## Installation\nCreate your virtualenv with pytest inside. Run the modules you want to. Hack around.\n\nCurrently weldon is not packaged, but that's something\nthat will naturally arise when Weldon will quit the POC stage.\n\n\n## Features\n- [x] two user level: player and rooter. A rooter is a player.\n- [x] a user is identified by a unique secret token sent by server after registration.\n- [x] problem definition: have description, title, and tests.\n- [x] tests are divided into 3 category: public, hidden and community. The second contains tests that are known only by teachers.\n- [x] users can register using a password defined by Server's admin.\n- [x] submissions (source code for a given problem) is tested using pytest.\n- [x] submission result (output of pytest + parsed information) is returned to user.\n- [x] submission result are kept in a local database. Further exploitation of these data is possible.\n- [x] users with last submitted source code meeting all the tests can upload community tests for everyone.\n- [x] basic permission management: only teachers can access hidden tests of a problem.\n- [ ] new role: tester, a player that do not have to submit a solution to upload new tests. Testers gain points by uploading tests that are failed by players.\n- [ ] in pytest return result, filter out lines that expose the content of hidden tests.\n- [ ] allow teacher to provide at problem definition a reference implementation. Any community test that fails against reference implementation is rejected.\n- [ ] allow arbitrary number/hierarchy of file for user submissions\n- [ ] allow arbitrary number/hierarchy of file for test submissions and definition\n- [ ] allow arbitrary number/hierarchy of file for test problem definition (that could include public \u0026 community tests, readme, instructions, code template,…)\n- [x] basic gui allowing student to interact with the server without knowledge of the protocol\n- [ ] gui: better printing of the submission results\n- [ ] gui: printing of the report (will need works on server code to get a formal representation of reports, or a very direct printing of the report as a multiline label)\n- [ ] gui: make a distributable, dinopython compatible, single-file, version of the gui, so it can be used on any machine having python.\n  - [x] no third-party module\n  - [ ] cross python compliancy OR two living versions at the same time (using [3to2]()https://pypi.python.org/pypi/3to2)\n  - [ ] single file packaging (students just have to run the file, that can easily be sent by mail or retrieved from the forge) ()\n  - [ ] ALTERNATIVE: compilation for main OSs to a unique executable file.\n- [ ] automatic generation of a single file module for client side of the webinterface so they can use the functions by just pluging it into their project.\n- [x] management of tests as a list of complex objects having implementation and author\n- [x] provides more insight into tests using [static analysis](ast_analyser.py) (function name, fixtures,…)\n- [ ] human readable serialization of server, so it can be edited and reloaded easily\n- [ ] server configuration by command line or from any rooter account\n- [x] provides way to control student names (could force them to use their official mail)\n- [ ] configuration of testers by problem (how many ? randomly choosen ?).\n- [x] system to avoid naming collisions leading one player to hide a community test by providing a new test with the same name (thank you, ast analysis !).\n- [x] perform report for each player, providing him results about number of passed tests (using [bashplotlib](https://github.com/glamp/bashplotlib)) and [pylint](https://pylint.org) rate and messages.\n- [ ] perform post-session report for each player, providing him insight of the data (graphic of number of passing (hidden) test and regression according to time, for instance), and the hidden tests.\n- [ ] perform during-session report for all players, providing insight about best players/testers.\n- [x] allow teachers to know which players are working on a particular problem.\n- [x] allow teachers to access players report.\n- [x] allow teachers to close submissions to a particular problem.\n- [x] allow teachers to add new public and hidden tests.\n- [x] cut this implementation into dedicated files.\n- [ ] perform a real sandboxing to avoid attacks by players on the server (firejail ? apparmor ?).\n- [ ] provides one supplementary problem example, with different use-case and more complex story (involving multiple problems and students).\n- [x] over the network discussion between server and players, allowing the program to be used by multiple players without access to the server machine, and also ensure that players do not access internal data of the server (that includes hidden tests and everyone's users).\n- [ ] verify multi-user handling of the WebInterface\n- [x] network discussion needs encryption: using wireshark its easy to intercept token, source and submissions of others players.\n  - [x] found how to perform asymmetric encryption using python\n  - [x] integrate it into code\n  - [x] allow clients to perform encryption if the python module is available.\n- [ ] extend weldon to work with arbitrary command for testing result generation (this leads to arbitrary language support).\n- [ ] arbitrary language and unit test framework support.\n\n\n\n## Sandboxing\nA sandboxing solution for testing is a necessity before employing Weldon in production.\n\n\n[wiki about sandboxing](https://wiki.python.org/moin/SandboxedPython)\n\n### pypy sandboxing\n[pypy](http://pypy.org/features.html) and [doc](http://pypy.readthedocs.io/en/latest/sandbox.html)\nCons: sandboxing is currently incomplete. Stdlib don't fully exists !\n\n### chrootbuilder\n[chrootbuilder](http://www.wiredyne.com/software/chrootbuilder.html)\nUse OS related data for fake a root hierarchy and sandbox a script.\n\nCons: needs to be read because of many linux distribution-dependant paths\nIt's an automatic chroot jail generator.\n\n### chroot, manually\nCons: not fully secure\n\n### firejail\n[firejail](https://firejail.wordpress.com/) have simplicity in mind.\n\n### apparmor\n[archlinux doc](https://wiki.archlinux.org/index.php/AppArmor)\n\n\n## AST introspection\nUsed to quickly discard some codes for community tests.\n\nOver the long-term, could be used to detect missing functions into the\nsubmitted code, or unexpected behavior of the code itself\n(access to some libraries like `importlib`, usage of particular builtins like `globals`).\n\nCurrently, the community tests, at submission, are tested in the following way:\n- it must have a correct syntax.\n- it must have only one function, eventually decorated.\n- function name must starts with `test_`.\n- it must hold at least one assert or one call to pytest.\n- it must not take any parameter.\n- it must not import some modules (shutil and importlib for instance)\n- it must not use some builtins (locals and globals for instance)\n\nThese restrictions are somehow violent, because they prevent users to use\npytest fixtures system, and not enough against a really motivated attacker.\nAll these verifications are deactivable if necessary.\n\n\n## Data exchange protocol\nServer and client exchange data using the following protocol.\n\nBoth client and server send a JSON-formatted dictionary with two keys:\n- `encryption_key`: contains the encryption key (null when no encryption)\n- `payload`: contains the (possibly encrypted) data\n\nServer also provides `status`, which is either `succeed` or `failed`.\nIn fail case, the payload is not encrypted and contains the error\nmessage describing the origin of the failure (for instance: bad parameters for a command).\n\n\n### Encryption\nEncryption is performed with [PyCrypto](https://www.dlitz.net/software/pycrypto/), and wrapped in an [hybrid encryption system](hybrid_encryption.py).\n\nThe first step of communication between a client and a server, if the client wants its communications to be encrypted,\nis the retrieval of server's public key. This method is integrated in the API itself.\nThe second step is made during registration, where the client may communicate its public key.\n\nServer and client expect payloads to be encrypted with the public key they communicate.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faluriak%2Fweldon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faluriak%2Fweldon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faluriak%2Fweldon/lists"}