Repository navigation
fix: Python codebase review: bugs (B1-B9), security (S1, S3, S4), performance (P1-P4), cleanups (C5, C7, C9) - #383
Merged
Merged
Conversation
- update_output_path matches the whole file name and prefers the newest run, so a log.html upload no longer always relinks the oldest run - insert_output_data runs in one transaction and re-raises, a failed insert no longer leaves a run that is rejected as duplicate forever (also 5x fewer commits per output) - age= uses fullmatch: "6mo" was read as 6 minutes - dashboard title is escaped for the JS string and the <title> tag, a quote in -t no longer breaks the whole script - -o/-f/-r use every value after the flag instead of only the first - error exits use code 1 instead of 0 - run_start_exists compares without the offset instead of a prefix match, which skipped runs at exactly .000000 seconds - non-ASCII server credentials: compare bytes (401, not 500) and reject them at startup, FastAPI decodes Basic auth as ASCII - tag=/limit=;tag= match whole run tags, test tags keep inner spaces, age= reads offset-less run_starts as local time, NULL ids become "", --quantity is an int >= 1, --timezone must be +HH:MM, run alias only strips the output_ prefix and .xml suffix, config files and the RF 6 header are read as UTF-8 - Python 3.9 is the minimum (removeprefix was already used) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Security/robustness (S3, S4): - --jsonconfig must be valid JSON; "</" is escaped in the JSON and message config so a value cannot end the inline script - /add-log writes a .part file, updates the database, then renames, so a failed update leaves an existing log untouched - upload success is decided by the update_output_path result only, not by "ERROR" anywhere in the console - gzip uploads are decompressed with a 1 GiB cap - /remove-log all skips folders - --server keeps everything after the user as password (may contain ':'), accepts [ipv6]:port, and reads ROBOTDASHBOARD_SERVER_USER / ROBOTDASHBOARD_SERVER_PASSWORD when it has no credentials Performance (P1-P4): - 504 inserts 11.0 -> 2.6 s (one commit per output, previous commit) - an output already in the database is skipped after reading only the <robot generated="..."> header instead of a full XML parse - suite/test processors skip what they do not use and one walk feeds the keyword and exception processors (identical output on fixtures) - run_start_exists is a single query, label sets in get_data, and the JS/CSS/offline blocks are cached keyed on source file mtime and size Structure (C5, C7, C9): - database messages go through one _print_console helper - RobotDashboard opens the database in a context manager that always closes it - per-run selects moved to queries.py; CLAUDE.md and the js-bundling skill now say every js/ file is bundled and imports only set order Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes from a line-by-line review of
robotframework_dashboard/*.py. Independent of #382 (no shared files except one line induration_deviation.js).Bugs
log.htmlwas always linked to the oldest run whose path containedoutput.xml, so with the listener's default names newer runs never got their log. Now: exact file name, newest run first. Known limit, not changed here: default names still overwriterobot_logs/log.htmlon every upload.age=6momeant 6 minutes (B3): the pattern now has to match the whole value;6moand10daysare rejected.-t "Tim's board"broke the whole dashboard (B4): the title is now escaped separately for the JS string and for<title>.-o a.xml b.xmldroppedb.xml(B5), same for-fand-r(the docs example-f ./results:version_1.1 ./results2:...was affected)..000000seconds was skipped as a duplicate of any run in that second.tag=prodno longer removespreprod/production.age=reads offset-lessrun_startvalues as local time."".--quantitymust be ≥ 1.--timezonemust be+HH:MM.output_prefix and.xml.removeprefixwas already used. Set inpython_requires, the docs and thecoding-standardsskill.Security / robustness
--jsonconfigmust be valid JSON.</is escaped in the JSON and message config, so a value cannot end the inline<script>./add-logwrites<name>.part, updates the database, then renames. A failed update leaves an existing log untouched.update_output_pathresult only, not byERRORanywhere in the console text (a folder namedERRORSfailed good uploads)./remove-log allskips folders.--server: the password may contain:, IPv6 hosts work as[::1]:port, and the credentials can come fromROBOTDASHBOARD_SERVER_USER/ROBOTDASHBOARD_SERVER_PASSWORDto keep them out of the process list.Performance (measured on 504 runs / 41.7k tests)
<robot generated="...">header. Before, the whole XML was parsed first. For 18 files the check takes 3 ms; a full parse was about 50 ms per file.run_start_existsis one SQL query, and the JS/CSS/offline blocks are cached keyed on every source file's mtime and size, so edits are still picked up while the server runs.Cleanups
_print_consolehelper instead ofprint+console +=copies.RobotDashboardopens the database in a context manager that always closes it.queries.py. CLAUDE.md and thejs-bundlingskill now say everyjs/file is bundled and imports only set the order.Behaviour changes for the changelog
tag=matches the whole tag.age=,--timezone,--quantityand--jsonconfigare validated.Tests
00_cli.robotnow uses-q 25instead of-q -25.ERRORstring fromcreate_dashboardto fail the upload now make it raise, since the real one raises on failure.🤖 Generated with Claude Code