# Testing project Goal of this project is to automate various testing of GCC Rust. This includes running the offical Rustc testsuite but also projects that we are using as goal-testcases ## Work Items 1. Maintain the testsuites 2. Automation 3. Create summary outputs 4. Dashboard ### Maintain the testsuites We have various unique test-suites within this testing project: - `gccrs` parsing only. - `rustc` on dejagnu testsuite - `gccrs` on valid test cases only - `gccrs` on valid `#[no_std]` test cases only - `gccrs` on valid `#[no_core]` test cases only - libcore 1.49.0 - Blake3 ### Automation Nightly runs using out dockerfile of the latest GCC Rust master build - Each testsuite should be its own job - see https://github.com/marketplace/actions/deploy-nightly for an example cron line - Each run should archive its test-results - See https://github.com/Rust-GCC/gccrs/blob/e9d41c4ef9da8ba71570ecf83691c813c12d9149/.github/workflows/ccpp.yml#L71-L76 ### Summary outputs We need the testsuite to generate a json file of the results. Using junit-xml formats is overkill here so all we need is a json object such as: ```javascript= { 'test-suite-name': "gccrs-fsyntax-only", 'testing-commit': commit-sha of testing-project, 'date': 'date of result', 'gccrs-commit': commit-sha-of-gccrs // maybe we can add in a commit-sha fILE into the dockerfile that we can pull out 'passes:' 1234, 'failures': 44567, } ``` ### Dashboard Since we are writing a rust compiler it would be nice to reuse rust. My personal preference would be just hack up some python but lets give rust a chance. Web frameworks in rust: - rocket - actix - List others! Front-end frameworks in rust: - [Yew](https://github.com/yewstack/yew) - [Seed](https://github.com/seed-rs/seed) #### Design In order to avoid requiring the web-app to need a persistence layer lets use github as the persistence layer. The webapp will have a cron job to nightly poll for new testruns and store the results in memory. Using the github API to fetch all test-results. It will prove a rest api to lookup the testsuite results over time with their associated commits. Web ui frameworks could be simple templates for now using vis.js for data visualisations. ##### Phase 1 - startup fetch results Rust app on startup uses GITHUB_TOKEN to access the archived results of all nightly runs on github.com/Rust-GCC/testing. We have data structures of: ```map ['test-suite-name'] = [{'result'}, {'result'}, ...]``` The list does not have to be ordered we can fix this in the UI or by adding queries to our rest API. Octorust looks like a nice API to use. - https://docs.rs/octorust/latest/octorust/actions/struct.Actions.html#method.list_artifacts_for_repo - https://docs.rs/octorust/latest/octorust/types/struct.Artifact.html ##### Phase 2 - create rest end points - GET /api/testsuites returns a JSON list of all keys in our datastructure in PHASE 1 - GET /api/testsuites/{key: testsuite-name} returns the results of that testrun in any order they key will map to the keys in the map of results Upon failure we should return a 404 not found when the test-suite does not exist ##### Phase 3 - Begin UI Dev Choose a UI web framework, probably just use bootstrap and vis.js we only need a simple single page app. With really basic rest calls ##### Phase 4 - Scheduled task The webapp on startup loads all test runs by requesting them from github and stores them in memory. This then needs a scheduled task each day to refetch all of the data. Depending on how long this takes, we should support a mechanism to fetch async and upon susessful completion override the existing data in memory. https://crates.io/crates/tokio-cron-scheduler ### Update idea and flowgraph ```mermaid flowchart LR; Dashboard --> API; curl --> API; API --> check_cache[Check cache]; check_cache --> is_outdated[Is it too old?]; is_outdated --Yes-->update[Update cache]; update-->cached; is_outdated --No-->cached[Return cached json]; cached --> API; ``` - [ ] How do we store files appropriately? - [ ] Can we just keep a hashmap as database and return this? No writing to disk? - [ ] Yes? Since we only care about the last 90 days anyway? - [ ] Do we have to purge the cache every once in a while to only keep 90 days? - [ ] How do we return them to the user? - [ ] What return type? Is there a `rocket::Json`? - [x] What does it mean to "check if a file is too old" when we're keeping track of each file's run date? - [ ] Is that even what we want to do? We just care about the `.last_date` and keeping the hashmap updated - [ ] Just entering the cache directory and looking for the most recent file? - [x] We can keep a field `.last_date` in our `Cache` structure for an easy check! - [ ] We still need to check for the most recent file if we already have a cache directory? Later? Later!