{"id":29702429,"url":"https://github.com/liam-colle/grindme","last_synced_at":"2026-05-15T12:32:42.800Z","repository":{"id":283476313,"uuid":"951470292","full_name":"liam-colle/GrindMe","owner":"liam-colle","description":"An automatic valgrind tester for your DevOps or laziness needs.","archived":false,"fork":false,"pushed_at":"2026-02-09T12:40:04.000Z","size":79,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-09T17:42:21.577Z","etag":null,"topics":["cd-ci","github-actions","python3","valgrind"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liam-colle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-19T18:19:34.000Z","updated_at":"2026-02-09T12:40:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"553b72ee-7845-4849-a497-0087d6ec6723","html_url":"https://github.com/liam-colle/GrindMe","commit_stats":null,"previous_names":["liam-colle-archivist/grindme","liam-colle/grindme"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/liam-colle/GrindMe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liam-colle%2FGrindMe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liam-colle%2FGrindMe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liam-colle%2FGrindMe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liam-colle%2FGrindMe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liam-colle","download_url":"https://codeload.github.com/liam-colle/GrindMe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liam-colle%2FGrindMe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33067232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cd-ci","github-actions","python3","valgrind"],"created_at":"2025-07-23T12:14:03.602Z","updated_at":"2026-05-15T12:32:42.795Z","avatar_url":"https://github.com/liam-colle.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GrindMe\n\n**An automatic valgrind tester for your DevOps or laziness needs.**\n\n![Python](https://img.shields.io/badge/python-3670A0?style=flat\u0026logo=python\u0026logoColor=ffdd54\u0026label=3.11.2)\n[![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=flat\u0026logo=githubactions\u0026logoColor=white)](https://github.com/liam-colle/GrindMe/actions)\n[![GrindMe CD/CI](https://github.com/liam-colle/GrindMe/actions/workflows/actions.yml/badge.svg)](https://github.com/liam-colle/GrindMe/actions/workflows/actions.yml)\n![GPL v3](https://img.shields.io/badge/license-GPLv3-blue?style=flat)\n\n## Description\n\nGrindMe allows you to setup a custom json script that will launch automated valgrind tests\nand report them in the way you'd like (Plaintext, JSON Output, etc...).\nBy default, GrindMe doesn't test anything unless specified.\n\n## Installation\n\n### Requirements\n\n* valgrind\n* git\n* python3\n  * ``py3`` for alpine users\n* python3-venv\n  * ``py3-venv`` for alpine users\n\n### How to install?\n\n```shell\ncurl -B https://raw.githubusercontent.com/liam-colle/GrindMe/refs/heads/main/install.sh | bash\n```\n\n## Features\n\n* Highly Customizable JSON script\n* Multiple ways to print out or export test results\n\n## Usage\n\n### Program\n\n```plaintext\nusage: GrindMe [-h] [--dump-report [DUMP_REPORT]] [--dump-report-type [DUMP_REPORT_TYPE]] [--github-action] [-s] [-g] [-v] [filename]\n\nAn automatic valgrind tester for your DevOps or laziness needs.\n\npositional arguments:\n  filename\n\noptions:\n  -h, --help            show this help message and exit\n  --dump-report [DUMP_REPORT]\n  --dump-report-type [DUMP_REPORT_TYPE]\n  --github-action\n  -s, --strict\n  -g, --generate-file\n  -v, --verbose\n```\n\n### Configuration\n\nConfiguration should be stored in a ``.grindme`` directory and the configuration file should be named ``config.json``\nif you want to run GrindMe in \"automatic mode\" / without any arguments.\n\n\nThe JSON scripts now support additional per-test options under an `options` object. Example structure:\n\n```json\n{\n  \"suites\": [\n    {\n      \"name\": \"Test mytest\",\n      \"tests\": [\n        {\n          \"name\": \"Test 1\",\n          \"description\": \"Check if program works\",\n          \"executable\": \"./mytest\",\n          \"args\": [],\n          \"input_file\": null,\n          \"options\": {\n            \"timeout\": 10.0,                // [optional] Timeout in seconds for this test (float, default: 10.0)\n            \"trace_children\": true,         // [optional] Trace child processes (bool, default: false)\n            \"lenient_memory_check\": false   // [optional] If true, disables full leak check (bool, default: false)\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\n* ``suites``: The suites used by grindme ``(list: (object))``\n  * ``name``: The name of the suite ``(string)``\n  * ``tests``: The tests in the suite ``(list: (object))``\n    * ``name``: The name of the test ``(string)``\n    * ``description``: The description of the test ``(string)``\n    * ``executable``: The executable used by the test ``(string)``\n    * ``args``: The arguments used by the test ``(list: (string))``\n    * ``input_file``: A file to pipe into the stdin buffer of the program ``(string | null)`` ``[optional]``\n    * ``options``: Additional test options ``(object)`` ``[optional]``\n      * ``timeout``: Timeout in seconds for this test ``(float, default: 10.0)``\n      * ``trace_children``: Trace child processes ``(bool, default: false)``\n      * ``lenient_memory_check``: If true, disables full leak check ``(bool, default: false)``\n\n### Script Examples\n\n*Note: The program does not support JSON with comments. Parts of it are commented for demonstration purposes only.*\n\n#### Test : ``Single Program`` - ``mytest``\n\n##### JSON\n\n```json\n{\n  \"suites\": [\n    {\n      \"name\": \"Test mytest\",\n      \"tests\": [\n        {\n          \"name\": \"Test 1\",\n          \"description\": \"Check if program works\",\n          \"executable\": \"./mytest\",\n          \"args\": [],\n          \"input_file\": null\n        }\n      ]\n    }\n  ]\n}\n```\n\n##### Example Console Output\n\n```plaintext\n=== SUITE RESULTS : 'Test mytest' ===\n\n== TEST RESULTS : 'Test 1' ==\nStatus: OK\n==\n\nPercentages of suite 'Test mytest':\n[=====================================] - 100.0%\n===\n```\n\n#### Test : ``Single Program`` - ``mytest`` with many errors\n\n##### JSON\n\n```json\n{\n  \"suites\": [\n    {\n      \"name\": \"Test mytest\",\n      \"tests\": [\n        {\n          \"name\": \"Test 1\",\n          \"description\": \"Check if program works\",\n          \"executable\": \"./mytest\",\n          \"args\": [],\n          \"input_file\": null\n        }\n      ]\n    },\n    {\n      \"name\": \"Test mytest (CRASH)\",\n      \"tests\": [\n        {\n          \"name\": \"Test 1\",\n          \"description\": \"Check if program works\",\n          \"executable\": \"./mytest\",\n          \"args\": [\"-f\", \"./tests/test.txt\"],\n          \"input_file\": null\n        },\n        {\n          \"name\": \"Test 2\",\n          \"description\": \"Check if program works\",\n          \"executable\": \"./mytest\",\n          \"args\": [\"-f\", \"./tests/test.txt\", \"-e\"],\n          \"input_file\": \"./tests/nothing.txt\"\n        }\n      ]\n    }\n  ]\n}\n```\n\n##### Example Console Output\n\n```plaintext\n=== SUITE RESULTS : 'Test mytest' ===\n\n== TEST RESULTS : 'Test 1' ==\nStatus: OK\n==\n\nPercentages of suite 'Test mytest':\n[=====================================] - 100.0%\n===\n\n=== SUITE RESULTS : 'Test mytest (CRASH)' ===\n\n== TEST RESULTS : 'Test 1' ==\nStatus: KO\nDetailed data:\n - ⚠️  ➜  Conditional jump on uninitialized values\n - ⚠️  ➜  Memory Leak\n==\n\n== TEST RESULTS : 'Test 2' ==\nStatus: CRASH\nDetailed data:\n - ⚠️  ➜  Conditional jump on uninitialized values\n - ⚠️  ➜  Abnormal termination\n - ⚠️  ➜  Memory Leak\n==\n\nPercentages of suite 'Test mytest (CRASH)':\n[                                     ] - 0.0%\n===\n```\n\n### Docker\n\nGrindMe comes shipped with a Docker image on Docker Hub.\n\n``liamcollearchivist/grindme`` - [DockerIO Repository](https://hub.docker.com/repository/docker/liamcollearchivist/grindme)\n\nGrindMe offers 3 types of images\n\n* ``latest``\n\n  An image running on Ubuntu (``ubuntu:latest``) which only comes supplied with the bare minimum for GrindMe to function.\n\n  * Compressed Size: ~170 MB\n  * Local run script: ``docker run -v ./:/grindme -it --rm liamcollearchivist/grindme /bin/bash``\n  \u003e ⚠️ - Additional build packages must be installed manually by creating another Docker image based on this one,\n    or using your CD/CI workflow tool.\n\n* ``alpine-latest``\n  An image running on Alpine (``alpine:latest``) which only comes supplied with the bare minimum for GrindMe to function.\n\n  * Compressed Size: ~70 MB\n  * Local run script: ``docker run -v ./:/grindme -it --rm liamcollearchivist/grindme:alpine-latest /bin/bash``\n  \u003e ⚠️ - Additional build packages must be installed manually by creating another Docker image based on this one,\n    or using your CD/CI workflow tool.\n\n* ``epitech-latest``\n  An image running on Ubuntu using the official Epitech 'Epitest' docker (``epitechcontent/epitest-docker``)\n  which comes with the bare minimum for GrindMe to function alongside everything that Epitech needs to use their 'moulinette'.\n\n  * Compressed Size: ~1.85 GB\n  * Local run script: ``docker run -v ./:/grindme -it --rm liamcollearchivist/grindme:epitech-latest /bin/bash``\n\n### CD/CI - ``GitHub Actions``\n\nThe GrindMe docker can be invoked in a job within a GitHub Actions workflow.\n\n\u003e ⚠️ - This however requires a customized setup due to limitations of valgrind applying to Docker containers.\n  This is due to the fact that valgrind requires the file descriptors to be limited to a low amount, or else it will refuse to execute.\n  As of now we haven't found a way to statically set the ulimit in the image directly.\n  Therefore, a 'ulimit' option has been added in the container invokation options in the job to ensure that the docker\n  executes with the right permissions.\n  We do not know what going above 1024 does, as we've never tried it yet. At your own risk! ``¯\\_(ツ)_/¯``\n\n```yaml\nname: GrindMe Test\n\non: [push, pull_request]\n\njobs:\n  run_grind_me:\n    runs-on: ubuntu-latest\n    container:\n      image: liamcollearchivist/grindme:epitech-latest\n      options: --ulimit nofile=1024:1024\n\n    steps:\n    - name: \"[GITHUB] Checkout code from GitHub\"\n      uses: actions/checkout@v4\n\n    # \u003c Compile or get your program here\n\n    - name: \"[TESTS] Execute tests\"\n      run: grindme --github-action\n\n    # \u003c Do your teardown here\n```\n\n[GrindMe](https://github.com/liam-colle/GrindMe) by [Liam Colle](https://github.com/liam-colle) is licensed under GPL v3.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliam-colle%2Fgrindme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliam-colle%2Fgrindme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliam-colle%2Fgrindme/lists"}