diff --git a/tests/tests.yaml b/tests/tests.yaml index d2b45ea..4898ef0 100644 --- a/tests/tests.yaml +++ b/tests/tests.yaml @@ -35,10 +35,10 @@ # args State cases: the command plus Config fields (`command` # plus snake_case field names; true = bare flag, lists = # comma-joined values). ONE mapping drives BOTH -# entrypoints: locally the case runs twice — the +# entrypoints: locally the case runs twice -- the # generated command line through the real argument # parser, and the same mapping through the Python import -# API (cli.Config + resolve_command + run_command) — +# API (cli.Config + resolve_command + run_command) -- # and both must produce the identical expected state. # Flags come from the Config field metadata, never # guessed. maps_path defaults to the case directory's @@ -66,11 +66,45 @@ # # `{user}` in a cliCommand resolves to the configured --user on the test # instance (live/performance modes only). +# +# Each case carries two comment maps sizing its work: +# +# scope: -- net state change between before.json and after.json: +# users: distinct users whose explicit grants change +# repos: repos whose explicit or pending grant lists change +# perms: grant additions + removals (user-repo pairs, incl. pending +# bindIDs) +# Rejections, expected errors, dry runs, no-ops, and read-only gets affect +# nothing. Overwrite mutations that resend an identical list count in +# expectedMutations but not here. +# +# cost: -- the reads + writes driving runtime: +# bigO: complexity class. U = user count, R = repo count, +# U*scan = per-user explicit-grant scan (the ~400 s tier) +# reads: +# users: user-metadata records fetched (paged, fast) +# repos: repo records fetched (paged, fast) +# userPermScans: per-user explicit-grant reads -- the DOMINANT cost: +# the server materializes every accessible repo per +# probe (~25 users/s; all ~ 400 s live) +# writes: GraphQL permission mutations (= expectedMutations) +# note: what bounds or skips the work +# `all` means a full-instance scan: 10,000 users / 50,000 repos on the +# live instance (tests/setup.yaml); locally it is the fixture's tiny +# counts, so every local run is sub-second regardless of class. +# Live harness seeding/verify/restore overhead is excluded. cases: - # ── Local parse replays: argument validation, in-process, no files (fastest) ── + # -- Local parse replays: argument validation, in-process, no files (fastest) -- reject-bare-invocation: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: A bare invocation without a command prints usage and exits 2. modes: - local @@ -80,6 +114,13 @@ cases: - "the following arguments are required: COMMAND" reject-unknown-command: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: An unknown subcommand is rejected with the valid choices. modes: - local @@ -89,6 +130,13 @@ cases: - "invalid choice: 'bogus'" reject-two-commands: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: Two subcommands in one invocation are rejected. modes: - local @@ -98,6 +146,13 @@ cases: - unrecognized arguments reject-get-apply: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: get is read-only; --apply is rejected. modes: - local @@ -107,6 +162,13 @@ cases: - unrecognized arguments reject-get-full: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: --full requires the set command. modes: - local @@ -116,6 +178,13 @@ cases: - unrecognized arguments reject-malformed-date: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: dates must match YYYY-MM-DD before any network call. modes: - local @@ -125,6 +194,13 @@ cases: - string_pattern_mismatch reject-user-filter-conflict: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: user filters are mutually exclusive. modes: - local @@ -134,6 +210,13 @@ cases: - choose only one of --users reject-user-and-repo-filters: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: user filters and repo filters cannot be combined. modes: - local @@ -143,6 +226,13 @@ cases: - choose either user filters or repo filters reject-repo-filter-conflict: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: repo filters are mutually exclusive. modes: - local @@ -152,6 +242,13 @@ cases: - choose only one of --repos reject-repos-created-after-malformed: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: repo creation dates must match YYYY-MM-DD at parse time. modes: - local @@ -161,6 +258,13 @@ cases: - string_pattern_mismatch reject-get-removed-repositories-created-after: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: >- The removed --repositories-created-after spelling stays removed; the flag is --repos-created-after. @@ -172,6 +276,13 @@ cases: - "unrecognized arguments: --repositories-created-after" reject-verbosity-conflict: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: the --verbose and --quiet log-level aliases are mutually exclusive. modes: - local @@ -181,6 +292,13 @@ cases: - choose only one of --verbose/-v, --quiet/-q, or --silent/-s reject-bare-set: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: set requires an explicit mode flag. modes: - local @@ -190,6 +308,13 @@ cases: - set requires one of --full reject-set-full-and-users: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: set modes are mutually exclusive. modes: - local @@ -199,6 +324,13 @@ cases: - choose at most one reject-set-user-filter-conflict: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: set user filters are mutually exclusive. modes: - local @@ -208,6 +340,13 @@ cases: - choose only one of --users reject-set-full-and-created-after: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: full overwrite cannot be combined with the additive date filter. modes: - local @@ -217,6 +356,13 @@ cases: - "--full cannot be combined with --created-after" reject-set-restore-path: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: "--restore-path belongs to restore; set does not accept it." modes: - local @@ -226,6 +372,13 @@ cases: - "unrecognized arguments: --restore-path" reject-bare-restore: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: restore requires a snapshot path. modes: - local @@ -235,6 +388,13 @@ cases: - restore requires --restore-path reject-restore-with-users: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: restore does not take user filters. modes: - local @@ -244,6 +404,13 @@ cases: - unrecognized arguments reject-restore-repos: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: restore does not take repo filters. modes: - local @@ -253,6 +420,13 @@ cases: - "unrecognized arguments: --repos" reject-restore-sync-saml-orgs: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: "--sync-saml-orgs belongs to set; restore does not accept it." modes: - local @@ -262,6 +436,13 @@ cases: - "unrecognized arguments: --sync-saml-orgs" reject-sync-saml-orgs-created-after: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: sync-saml-orgs does not take user filters. modes: - local @@ -271,6 +452,13 @@ cases: - unrecognized arguments reject-sync-saml-orgs-users: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: sync-saml-orgs does not take a user list. modes: - local @@ -280,6 +468,13 @@ cases: - "unrecognized arguments: --users" reject-sync-saml-orgs-full: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: "--full belongs to set; sync-saml-orgs does not accept it." modes: - local @@ -289,6 +484,13 @@ cases: - "unrecognized arguments: --full" reject-sync-saml-orgs-restore-path: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: parse-only -- no instance reads or writes description: "--restore-path belongs to restore; sync-saml-orgs does not accept it." modes: - local @@ -297,8 +499,19 @@ cases: expectedOutput: - "unrecognized arguments: --restore-path" - # ── Local state cases: full CLI runs against an in-memory instance ── + # -- Local state cases: full CLI runs against an in-memory instance -- and-filters-intersect: + # scope: + # users: 1 + # repos: 1 + # perms: 1 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 1 mutation description: >- Multiple user filters AND together: both users are in the SAML group, but only test_user_09991 matches the email filter. @@ -312,6 +525,17 @@ cases: expectedMutations: 1 regex-filters-scope: + # scope: + # users: 2 + # repos: 2 + # perms: 4 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 2 mutations description: >- Email and repo-name regex filters scope grants to matching users and repos only. Live, the declared involvedRepos cover the full closed @@ -341,6 +565,17 @@ cases: expectedMutations: 2 saml-group-filter: + # scope: + # users: 1 + # repos: 2 + # perms: 2 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 2 mutations description: >- authProvider samlGroup filter grants Bitbucket repos only to users whose SAML assertion includes the group. @@ -354,6 +589,17 @@ cases: expectedMutations: 2 saml-group-live: + # scope: + # users: 2 + # repos: 2 + # perms: 4 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 2 mutations description: >- authProvider samlGroup filter against the FABRICATED SAML accounts that tests/setup.py provisions (setup.yaml samlAccounts): eng-group @@ -384,6 +630,18 @@ cases: expectedMutations: 2 set-created-after-temp-user: + # scope: + # users: 1 + # repos: 1 + # perms: 1 + # cost: + # bigO: O(R) + # reads: + # users: 1 + # repos: all + # userPermScans: 1 + # writes: 1 mutation + # note: server-side date filter selects only the temp user description: >- POSITIVE created-after selection on the real instance: the harness creates a fresh temporary user (created today), so @@ -405,6 +663,18 @@ cases: expectedMutations: 1 set-users-created-after: + # scope: + # users: 2 + # repos: 2 + # perms: 4 + # cost: + # bigO: O(R) + # reads: + # users: selected + # repos: all + # userPermScans: selected + # writes: 4 mutations + # note: server-side date filter description: >- createdAfter mode additively grants mapped repos to users created on/after the date, preserving existing grants. @@ -419,6 +689,18 @@ cases: expectedMutations: 4 set-users-without-explicit-perms: + # scope: + # users: 1 + # repos: 2 + # perms: 2 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: rule-matched + # writes: 2 mutations + # note: candidates + hydration for all users; perm probes only for rule-matched description: >- --users-without-explicit-perms additively grants mapped repos only to users who currently hold no explicit grants anywhere. The local @@ -439,6 +721,18 @@ cases: expectedMutations: 2 set-users-without-explicit-perms-default-batch: + # scope: + # users: 1 + # repos: 2 + # perms: 2 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: rule-matched + # writes: 2 mutations + # note: candidates + hydration for all users; perm probes only for rule-matched description: >- Performance-tier twin of set-users-without-explicit-perms at default --parallelism and --explicit-permissions-batch-size, so the measured @@ -459,6 +753,18 @@ cases: expectedMutations: 2 set-repos-without-explicit-perms: + # scope: + # users: 2 + # repos: 1 + # perms: 2 + # cost: + # bigO: O(U*scan + R) + # reads: + # users: all + # repos: all + # userPermScans: all + # writes: 1 mutation + # note: mode forces the full before-snapshot description: >- --repos-without-explicit-perms overwrites only repos that currently have no explicit grants. Runs in the performance tier on the instance @@ -474,6 +780,18 @@ cases: expectedMutations: 1 set-repos-created-after: + # scope: + # users: 2 + # repos: 1 + # perms: 2 + # cost: + # bigO: O(U) + # reads: + # users: all + # repos: date-matched + # userPermScans: 0 + # writes: 1 mutation + # note: createdAt-ordered repo scan stops at the threshold description: >- --repos-created-after scopes the overwrite to repos created on/after the date. @@ -487,9 +805,21 @@ cases: expectedMutations: 1 full-overwrite-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan + R) + # reads: + # users: all + # repos: all + # userPermScans: all + # writes: none + # note: dry run forces the before-capture description: >- set without --apply plans the full overwrite but makes zero mutations - and leaves state untouched — the dry-run default never mutates. + and leaves state untouched -- the dry-run default never mutates. modes: - local args: @@ -499,6 +829,13 @@ cases: expectedMutations: 0 empty-maps-noop: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: no rules -> exits before any instance scan description: >- An empty maps list is a no-op, not an error: zero mutations, existing grants untouched. @@ -512,6 +849,17 @@ cases: expectedMutations: 0 match-provider-and-host-fields: + # scope: + # users: 2 + # repos: 2 + # perms: 4 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 2 mutations description: >- Users matched by authProvider type/serviceID/clientID/displayName (without configID or samlGroup) and repos matched by codeHostConnection @@ -526,6 +874,17 @@ cases: expectedMutations: 2 add-users-by-email-and-list: + # scope: + # users: 2 + # repos: 2 + # perms: 4 + # cost: + # bigO: O(R) + # reads: + # users: 2 + # repos: all + # userPermScans: 2 + # writes: 4 mutations description: >- --users accepts a comma-delimited mix of an email address and a username; only the two selected users gain grants, additively. @@ -541,6 +900,17 @@ cases: expectedMutations: 4 restore-dry-run-noop: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan) + # reads: + # users: all + # userPermScans: all + # writes: none + # note: current-state capture scans every user description: >- restore without --apply plans against a snapshot that differs from current state but makes zero mutations. @@ -553,6 +923,17 @@ cases: expectedMutations: 0 restore-applies-snapshot: + # scope: + # users: 2 + # repos: 1 + # perms: 2 + # cost: + # bigO: O(U*scan) + # reads: + # users: all + # userPermScans: all + # writes: 1 mutation + # note: current-state capture scans every user description: >- restore --apply overwrites the repo that differs from the snapshot and skips the repo that already matches. @@ -566,6 +947,16 @@ cases: expectedMutations: 1 restore-restores-pending: + # scope: + # users: 0 + # repos: 2 + # perms: 2 (both perms are pending bindID grants) + # cost: + # bigO: O(U*scan) + # reads: + # users: all + # userPermScans: all + pending listing + # writes: 2 mutations description: >- restore --apply recreates the snapshot's pending grants (bindIDs that never resolved to a user) and wipes pending grants the snapshot does @@ -580,10 +971,22 @@ cases: expectedMutations: 2 full-overwrite-preserves-pending: + # scope: + # users: 2 + # repos: 1 + # perms: 2 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 1 mutation + # note: pending listing only description: >- A full-overwrite apply (without backup, so the pending state is fetched live) resends each mapped repo's pending bindIDs and leaves - unmapped repos' pending grants alone — the script neither creates + unmapped repos' pending grants alone -- the script neither creates nor loses pending permissions. modes: - local @@ -595,6 +998,18 @@ cases: expectedMutations: 1 full-overwrite-with-backup: + # scope: + # users: 2 + # repos: 1 + # perms: 2 + # cost: + # bigO: O(U*scan + R) + # reads: + # users: all + # repos: all + # userPermScans: 2x all + # writes: 1 mutation + # note: before + after snapshots description: >- The default backup path (no --no-backup) captures before/after snapshots (including a pending grant on the mutated repo, which must @@ -608,6 +1023,15 @@ cases: expectedMutations: 1 get-user-grants: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: 1 + # userPermScans: 1 description: >- get scoped to one user captures that user's explicit grants and never mutates the instance. @@ -619,8 +1043,15 @@ cases: - test_user_09991 expectedMutations: 0 - # ── Local + live: expected-error cases, replayed read-only on the instance ── + # -- Local + live: expected-error cases, replayed read-only on the instance -- invalid-bad-regex: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: maps validation fails before any instance read description: >- An invalid Python regex in a filter is rejected by structural validation before any mutation. @@ -635,6 +1066,13 @@ cases: - is not a valid Python regex invalid-missing-repos-section: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: maps validation fails before any instance read description: >- A rule without a repos section is rejected by structural validation before any mutation. @@ -649,6 +1087,13 @@ cases: - "`repos:` section is missing" invalid-unknown-selector-field: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: maps validation fails before any instance read description: >- A typo'd selector field is rejected by structural validation before any mutation. @@ -663,6 +1108,13 @@ cases: - unknown users field 'userNames' invalid-set-created-after-date: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: date validation fails before any instance read description: >- An impossible calendar date passes the YYYY-MM-DD shape check but set rejects it post-parse, before any mutation. @@ -677,6 +1129,13 @@ cases: - "--created-after must use YYYY-MM-DD" invalid-set-repos-created-after-date: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: date validation fails before any instance read description: >- An impossible calendar date passes the YYYY-MM-DD shape check but the repo-scoped set rejects it post-parse, before any mutation. @@ -691,6 +1150,15 @@ cases: - "--repos-created-after must use YYYY-MM-DD" invalid-set-unknown-user: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: <=2 lookups + # note: fails before any scan description: >- A --users value naming no Sourcegraph user fails before any mutation. modes: @@ -705,6 +1173,15 @@ cases: - "No Sourcegraph user found for 'username_doesnt_exist_01'" invalid-set-unknown-repo: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # repos: 1 name lookup + # note: fails before the user scan description: >- A --repos value naming no Sourcegraph repo fails before any mutation. modes: @@ -719,6 +1196,13 @@ cases: - "No Sourcegraph repo found for: repo-doesnt-exist-49999" invalid-restore-wrong-schema-version: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: reads the snapshot file only -- no instance reads description: >- A snapshot with an unsupported schema_version is refused without changing any state. @@ -732,6 +1216,13 @@ cases: - "snapshot schema_version is 1, expected" restore-missing-file: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: file-existence check only -- no instance reads description: >- restore with a snapshot path that does not exist fails without changing any state. @@ -745,8 +1236,19 @@ cases: expectedErrors: - "restore snapshot file does not exist" - # ── Local + live: mutating cases, seeded and restored on the instance ── + # -- Local + live: mutating cases, seeded and restored on the instance -- no-match-noop: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: none description: >- A rule matching no users produces zero mutations and leaves existing grants untouched. @@ -761,6 +1263,17 @@ cases: expectedMutations: 0 set-repos-filter: + # scope: + # users: 3 + # repos: 1 + # perms: 3 + # cost: + # bigO: O(U) + # reads: + # users: all + # repos: 1 + # userPermScans: 0 + # writes: 1 mutation description: >- --repos scopes the full overwrite to the listed repos; other mapped repos keep their existing grants. Also pins --src-log-level DEBUG: @@ -779,6 +1292,17 @@ cases: expectedMutations: 1 add-users-preserves-existing: + # scope: + # users: 1 + # repos: 2 + # perms: 2 + # cost: + # bigO: O(R) + # reads: + # users: 1 + # repos: all + # userPermScans: 1 + # writes: 2 mutations description: >- Additive --users mode grants mapped repos to one user without dropping existing repo users. @@ -794,6 +1318,17 @@ cases: expectedMutations: 2 full-overwrite-removes-stale-grant: + # scope: + # users: 2 + # repos: 1 + # perms: 2 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 1 mutation description: >- Full set mode overwrites a mapped repo's explicit users, removing grants that no rule justifies. @@ -807,8 +1342,15 @@ cases: no_backup: true expectedMutations: 1 - # ── Live only: real-instance validation and organization sync ── + # -- Live only: real-instance validation and organization sync -- invalid-created-after-date: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: date validation fails before any instance read description: >- An impossible calendar date passes the YYYY-MM-DD shape check but is rejected by date validation. @@ -821,6 +1363,13 @@ cases: - "--created-after must use YYYY-MM-DD" invalid-missing-maps-file: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # note: maps-file existence check only -- no instance reads description: >- A maps path that does not exist is rejected with a pointer to the command that creates the default maps file. Also pins the --quiet @@ -836,6 +1385,16 @@ cases: - set input file does not exist get-created-after-future: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: 0 + # userPermScans: 0 + # note: server-side date filter selects nobody description: >- A far-future --created-after selects no users on the real instance. modes: @@ -846,6 +1405,16 @@ cases: - Selected 0 user(s) for get output. get-user-created-after-future: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: 1 lookup + # userPermScans: 0 + # note: the user is filtered out by date description: >- --users combined with a far-future --created-after filters the named user out of the selection. @@ -857,6 +1426,16 @@ cases: - no user metadata selected get-users-without-perms-created-after-future: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: 0 + # userPermScans: 0 + # note: filtered candidate query selects nobody description: >- --users-without-explicit-perms combined with a far-future --created-after selects no users. @@ -868,6 +1447,18 @@ cases: - Selected 0 user(s) for get output. get-repos-filter: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan) + # reads: + # users: all + # repos: 1 + # userPermScans: all + # writes: none + # note: ~400 s at 10k users description: >- get scoped to one repo by exact name. The snapshot still scans every user's explicit grants to find the repo's holders (measured ~400 s at @@ -880,6 +1471,18 @@ cases: - Selected 1 repo(s) by exact name. get-repos-created-after-future: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U) + # reads: + # users: all + # repos: ~1 page + # userPermScans: 0 + # writes: none + # note: empty repo selection skips the perm probes description: >- A far-future --repos-created-after selects no repos. Also pins the --verbose alias: DEBUG verbosity must not hide the INFO summary. @@ -891,6 +1494,15 @@ cases: - Selected 0 Sourcegraph repo(s) created on or after 2099-01-01. set-users-created-after-noop: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: 0 + # note: server-side date filter selects nobody -- exits before the repo scan description: >- A far-future --created-after selects no users on the real instance: zero mutations, seeded state untouched. @@ -905,6 +1517,17 @@ cases: expectedMutations: 0 set-repos-created-after-noop: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U) + # reads: + # users: all + # repos: ~1 page + # userPermScans: 0 + # writes: none description: >- A far-future --repos-created-after selects no repos on the real instance: zero mutations, seeded state untouched. @@ -919,6 +1542,17 @@ cases: expectedMutations: 0 sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U) + # reads: + # users: all + # orgMembers: all + # writes: none + # note: streams every user's SAML account data description: >- Standalone organization sync dry run. Also pins the explicit --env-file flag against its default value. @@ -930,6 +1564,17 @@ cases: - Dry run complete set-users-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U) + # reads: + # users: 1 + all + # userPermScans: 1 + # writes: none + # note: org phase streams all users description: >- Combined permission + organization sync dispatch, user-scoped, dry run only. @@ -941,6 +1586,18 @@ cases: - Dry run complete set-full-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan + R) + # reads: + # users: all + # repos: all + # userPermScans: all + # writes: none + # note: ~395 s; org phase reuses the streamed users description: >- Combined permission + organization sync dispatch, full mode, dry run only. The dry-run before-capture scans every user (measured ~395 s), @@ -953,6 +1610,16 @@ cases: - Dry run complete set-created-after-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U) + # reads: + # users: 0 + all + # writes: none + # note: perm phase selects nobody; org phase streams all users description: >- Combined permission + organization sync dispatch, created-after mode (far-future date selects no users), dry run only. @@ -964,6 +1631,18 @@ cases: - Dry run complete set-repos-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan) + # reads: + # users: 2x all + # repos: 1 + # userPermScans: all + # writes: none + # note: ~400 s; perm and org phases each stream all users description: >- Combined permission + organization sync dispatch, repo-scoped, dry run only. The dry-run before-capture scans every user even for one repo @@ -976,6 +1655,18 @@ cases: - Dry run complete set-users-without-perms-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U+R) + # reads: + # users: 2x all + # repos: all + # userPermScans: rule-matched + # writes: none + # note: hydration + org stream each cover all users description: >- Combined permission + organization sync dispatch, users-without-explicit-perms mode, dry run only. The unfiltered @@ -989,6 +1680,17 @@ cases: - Dry run complete set-repos-created-after-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U) + # reads: + # users: 0 + all + # repos: ~1 page + # writes: none + # note: perm phase selects nobody; org phase streams all users description: >- Combined permission + organization sync dispatch, repos-created-after mode (far-future date selects no repos), dry run only. @@ -1000,6 +1702,16 @@ cases: - Dry run complete sync-saml-orgs-apply: + # scope: + # users: 0 + # repos: 0 + # perms: 0 (converges org memberships only; no repo perms) + # cost: + # bigO: O(U) + # reads: + # users: all + # orgMembers: all + # writes: org-membership mutations (convergent -- usually few) description: >- Org membership sync converges to SAML group data and validates its own outcome; it is safe to re-run. @@ -1010,13 +1722,24 @@ cases: expectedOutput: - "VALIDATION OK: all target org memberships match" - # ── Live + performance: timed, measured runs (slowest) ── + # -- Live + performance: timed, measured runs (slowest) -- full-overwrite-unions: + # scope: + # users: 3 + # repos: 2 + # perms: 5 + # cost: + # bigO: O(U+R) + # reads: + # users: all + # repos: all + # userPermScans: 0 + # writes: 2 mutations description: >- Full set mode unions users across rules, overwrites mapped repos, and leaves unmapped repos alone. Pending bindIDs ride along: one on a mapped repo must survive its overwrite, one on an unmapped canary - must stay untouched — live runs seed, verify, and restore them + must stay untouched -- live runs seed, verify, and restore them against the real instance. modes: - local @@ -1030,6 +1753,15 @@ cases: expectedMutations: 2 get-user-baseline: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(1) + # reads: + # users: 1 + # userPermScans: 1 description: Timed read-only baseline of one user's explicit grants. modes: - performance @@ -1037,6 +1769,17 @@ cases: expectedExitCode: 0 get-full-snapshot: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan) + # reads: + # users: all + # userPermScans: all + # writes: none + # note: ~400 s at 10k users description: >- Bare get captures the full instance snapshot. Locally it proves get never mutates; on the instance it is the timed full 10k-user capture, @@ -1049,6 +1792,17 @@ cases: expectedMutations: 0 get-repos-without-explicit-perms: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan + R) + # reads: + # users: all + # repos: all + # userPermScans: all + # writes: none description: >- get --repos-without-explicit-perms scopes the snapshot to repos with no explicit grants. Requires the full before-snapshot, so on the @@ -1062,6 +1816,18 @@ cases: expectedMutations: 0 set-repos-without-perms-sync-saml-orgs-dry-run: + # scope: + # users: 0 + # repos: 0 + # perms: 0 + # cost: + # bigO: O(U*scan + R) + # reads: + # users: 2x all + # repos: all + # userPermScans: all + # writes: none + # note: perm and org phases each stream all users description: >- Combined permission + organization sync dispatch, repos-without-explicit-perms mode, dry run only. Needs the full