Repository navigation
test: keep every GraphQL operation within the request limits of Unraid 7.4 - #337
Merged
1 commit merged intoNov 13, 2026
Merged
1 commit merged into
1 commit merged into
Conversation
…d 7.4 Unraid 7.4.0 refuses requests above a cost of 1,000, depth 20, 100 aliases and 5,000 GraphQL tokens (unraid/api request-protection.ts, graphql-armor 3.2.0). A query that grows past them would only show up as a failed screen. GraphqlRequestLimitsTest re-implements the server's formulas (documented with their source in GraphqlDocumentMetrics), measures every operation in app/src/main/graphql as Apollo sends it and fails, naming the operation and the measure, when one passes 70 percent of a limit. Its other tests pin the formulas to the server's own boundaries. HANDOFF.md records the limits, the margin and the result measured on a real Unraid 7.4.0. No app code changes: the largest operation (GetArray) costs 59 of 1,000. Closes #320 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3 tasks
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.
Closes #320
What changed and why
Unraid 7.4.0 refuses GraphQL requests above fixed limits. Nothing in NOVA noticed when a query grew; the first sign would have been a failed screen. This adds a CI guard and records the real numbers.
GraphqlRequestLimitsTest(unit test, runs in CI): measures every operation inapp/src/main/graphqlas Apollo sends it (the generated document, fragments and__typenameincluded) by the server's formulas and fails, naming the operation and the measure, when one passes 70 % of a limit. It prints a table of all 45 operations. Nine more tests in the same class pin the re-implemented formulas to the server's own boundaries (1,000 fields pass and 1,001 fail, 100 aliases pass and 101 fail, depth 20 versus 21, fragments add no depth,first/lastmultiply butlimitdoes not) and prove the gate can fail (an 800-field query is reported).GraphqlDocumentMetrics.kt(test source set): a small hand-written lexer and parser plus the formulas. The Apollo compiler is a Gradle-plugin dependency and not on the test classpath, and graphql-java would be a new dependency, so neither is used. No dependency added.HANDOFF.md: section "Unraid 7.4 request limits (Verify NOVA against the Unraid 7.4.0 request limits #320)" with limits, sources, margin and the live result, and a pointer in the gotchas list.The limits and where they come from
Read from the source, not from memory: unraid/api commit
8e587fe(2026-11-04),api/src/unraid-api/graph/request-protection.tsandgraph.module.ts, configuring@escape.tech/graphql-armor3.2.0 (cost-limit 2.4.3, max-depth 2.4.2, max-aliases 2.6.2) andgraphql16.11.0. The formulas were taken from the published plugin code.first/lastmultiplyparseOptions, WebSocket inonSubscribe);connection_initis not parsed as GraphQLbodyLimitanywhere, so Fastify 5's defaultThe test server reports Unraid 7.4.0 with API
4.37.11+8e587fe2, i.e. built from that very commit.Live check on a real Unraid 7.4.0 (read-only, run once, not part of CI)
Each shipped query was sent once with the read-only API key (no mutation, no subscription). Every query validates against the limits and answers HTTP 200 with data.
FetchContainerLogswas sent with a non-existent container id: it passes validation and the resolver answers "Failed to fetch logs" (error expected, no private data involved).Limits for comparison: cost 1,000 (margin 700), depth 20 (14), aliases 100 (70), tokens 5,000 (3,500). The largest request body is 477 bytes. The 25 mutations and 5 subscriptions are measured by the test but were not sent; the largest of them costs 10 (
SystemMetricsTemperature), the subscriptions use 8 to 20 tokens.Control requests (harmless
__typenamequeries and aliased copies of shipped queries) confirm the formulas on the live server: cost 1,000 accepted and 1,001 refused ("Query Cost limit of 1000 exceeded, found 1001"); 100 aliases accepted and 101 refused; 5,001 tokens refused ("more that 5000 tokens"); 17 aliased copies ofGetArrayrefused with "found 1003" (17 x 59) and 31 copies ofGetNotificationListwith "found 1023" (31 x 33, fragments included). The server's numbers equal the test's.Answers to the open questions of #320: the server does not report the cost of an accepted query, but the refusals above show it equals the test's value, so
GetArraycosts 59 of 1,000 (6 %). The subscriptionconnection_initmessage is not tokenised; only the subscribe query is, and the largest subscription uses 20 of 5,000 tokens.Deliberately left out
.github/.Checks
./scripts/local-ci.sh: passed (generateApolloSources, lintDirectDebug, assembleDirectDebug, assembleRelease, testDirectDebugUnitTest; 288 unit tests, 0 failed, 0 skipped).🤖 Generated with Claude Code