Running with gitlab-runner 16.3.0~beta.108.g2b6048b4 (2b6048b4)
  on blue-2.private.runners-manager.gitlab.com/gitlab.com/gitlab-org QvBVRoXM, system ID: s_49b872f8ccf6
  feature flags: FF_NETWORK_PER_BUILD:true, FF_USE_FASTZIP:true, FF_USE_IMPROVED_URL_MASKING:true, FF_RESOLVE_FULL_TLS_CHAIN:false
section_start:1697709981:resolve_secrets
Resolving secrets
section_end:1697709981:resolve_secrets
section_start:1697709981:prepare_executor
Preparing the "docker+machine" executor
Using Docker executor with image registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-3.0.patched-golang-1.20-rust-1.65-node-18.17-postgresql-14:rubygems-3.4-git-2.36-lfs-2.9-chrome-113-yarn-1.22-graphicsmagick-1.3.36 ...
Starting service registry.gitlab.com/gitlab-org/gitlab-build-images:postgres-14-pgvector-0.4.1 ...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image registry.gitlab.com/gitlab-org/gitlab-build-images:postgres-14-pgvector-0.4.1 ...
Using docker image sha256:6c7370fd46a94d5beaed2a0304c7518e74a5759d4da3322ea9f7052507f51d80 for registry.gitlab.com/gitlab-org/gitlab-build-images:postgres-14-pgvector-0.4.1 with digest registry.gitlab.com/gitlab-org/gitlab-build-images@sha256:1b39aac95406782d786043ec3f1772c0a3a5ce1b9ce28cf001cac9a290f366c8 ...
WARNING: Service registry.gitlab.com/gitlab-org/gitlab-build-images:redis-cluster-6.2.12 is already created. Ignoring.
WARNING: Service registry.gitlab.com/gitlab-org/gitlab-build-images:redis-cluster-6.2.12 is already created. Ignoring.
Starting service registry.gitlab.com/gitlab-org/gitlab-build-images:redis-cluster-6.2.12 ...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image registry.gitlab.com/gitlab-org/gitlab-build-images:redis-cluster-6.2.12 ...
Using docker image sha256:f4c047edb00d9bbfcc2b002a01548fab14592940f5b3e6b3f227f690e3fa272d for registry.gitlab.com/gitlab-org/gitlab-build-images:redis-cluster-6.2.12 with digest registry.gitlab.com/gitlab-org/gitlab-build-images@sha256:9a1b6b68dc464f0baae914703d5b059e7773bf23c9579c44e2a1b1154a83656f ...
Starting service redis:6.2-alpine ...
Pulling docker image redis:6.2-alpine ...
Using docker image sha256:9b4dc93acb797b99419bb31d8a452680508f1bf10a8604d721c0474072417a2b for redis:6.2-alpine with digest redis@sha256:452b7655bda0e270a6376b71d22fcb30662e745dcb4728f99fa87f01287b465d ...
Waiting for services to be up and running (timeout 30 seconds)...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-3.0.patched-golang-1.20-rust-1.65-node-18.17-postgresql-14:rubygems-3.4-git-2.36-lfs-2.9-chrome-113-yarn-1.22-graphicsmagick-1.3.36 ...
Using docker image sha256:d68252162deca904d1a0066983188b98dfe3f6fe8181458b0a55905e79ed85a1 for registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-3.0.patched-golang-1.20-rust-1.65-node-18.17-postgresql-14:rubygems-3.4-git-2.36-lfs-2.9-chrome-113-yarn-1.22-graphicsmagick-1.3.36 with digest registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-3.0.patched-golang-1.20-rust-1.65-node-18.17-postgresql-14@sha256:2113f34affc7e2ee40bac87419dcd7c65a94d4abfa9edb86192e1aa6a1e46590 ...
section_end:1697709989:prepare_executor
section_start:1697709989:prepare_script
Preparing environment
Running on runner-qvbvroxm-project-278964-concurrent-0 via runner-qvbvroxm-private-1697702256-173bd1ab...
section_end:1697709989:prepare_script
section_start:1697709989:get_sources
Getting source from Git repository
Fetching changes with git depth set to 20...
Initialized empty Git repository in /builds/gitlab-org/gitlab/.git/
Created fresh repository.
remote: Enumerating objects: 114872        
remote: Enumerating objects: 175495, done.        
remote: Counting objects:   0% (1/175495)        
remote: Counting objects:   1% (1755/175495)        
remote: Counting objects:   2% (3510/175495)        
remote: Counting objects:   3% (5265/175495)        
remote: Counting objects:   4% (7020/175495)        
remote: Counting objects:   5% (8775/175495)        
remote: Counting objects:   6% (10530/175495)        
remote: Counting objects:   7% (12285/175495)        
remote: Counting objects:   8% (14040/175495)        
remote: Counting objects:   9% (15795/175495)        
remote: Counting objects:  10% (17550/175495)        
remote: Counting objects:  11% (19305/175495)        
remote: Counting objects:  12% (21060/175495)        
remote: Counting objects:  13% (22815/175495)        
remote: Counting objects:  14% (24570/175495)        
remote: Counting objects:  15% (26325/175495)        
remote: Counting objects:  16% (28080/175495)        
remote: Counting objects:  17% (29835/175495)        
remote: Counting objects:  18% (31590/175495)        
remote: Counting objects:  19% (33345/175495)        
remote: Counting objects:  20% (35099/175495)        
remote: Counting objects:  21% (36854/175495)        
remote: Counting objects:  22% (38609/175495)        
remote: Counting objects:  23% (40364/175495)        
remote: Counting objects:  24% (42119/175495)        
remote: Counting objects:  25% (43874/175495)        
remote: Counting objects:  26% (45629/175495)        
remote: Counting objects:  27% (47384/175495)        
remote: Counting objects:  28% (49139/175495)        
remote: Counting objects:  29% (50894/175495)        
remote: Counting objects:  30% (52649/175495)        
remote: Counting objects:  31% (54404/175495)        
remote: Counting objects:  32% (56159/175495)        
remote: Counting objects:  33% (57914/175495)        
remote: Counting objects:  34% (59669/175495)        
remote: Counting objects:  35% (61424/175495)        
remote: Counting objects:  36% (63179/175495)        
remote: Counting objects:  37% (64934/175495)        
remote: Counting objects:  38% (66689/175495)        
remote: Counting objects:  39% (68444/175495)        
remote: Counting objects:  40% (70198/175495)        
remote: Counting objects:  41% (71953/175495)        
remote: Counting objects:  42% (73708/175495)        
remote: Counting objects:  43% (75463/175495)        
remote: Counting objects:  44% (77218/175495)        
remote: Counting objects:  45% (78973/175495)        
remote: Counting objects:  46% (80728/175495)        
remote: Counting objects:  47% (82483/175495)        
remote: Counting objects:  48% (84238/175495)        
remote: Counting objects:  49% (85993/175495)        
remote: Counting objects:  50% (87748/175495)        
remote: Counting objects:  51% (89503/175495)        
remote: Counting objects:  52% (91258/175495)        
remote: Counting objects:  53% (93013/175495)        
remote: Counting objects:  54% (94768/175495)        
remote: Counting objects:  55% (96523/175495)        
remote: Counting objects:  56% (98278/175495)        
remote: Counting objects:  57% (100033/175495)        
remote: Counting objects:  58% (101788/175495)        
remote: Counting objects:  59% (103543/175495)        
remote: Counting objects:  60% (105297/175495)        
remote: Counting objects:  61% (107052/175495)        
remote: Counting objects:  62% (108807/175495)        
remote: Counting objects:  63% (110562/175495)        
remote: Counting objects:  64% (112317/175495)        
remote: Counting objects:  65% (114072/175495)        
remote: Counting objects:  66% (115827/175495)        
remote: Counting objects:  67% (117582/175495)        
remote: Counting objects:  68% (119337/175495)        
remote: Counting objects:  69% (121092/175495)        
remote: Counting objects:  70% (122847/175495)        
remote: Counting objects:  71% (124602/175495)        
remote: Counting objects:  72% (126357/175495)        
remote: Counting objects:  73% (128112/175495)        
remote: Counting objects:  74% (129867/175495)        
remote: Counting objects:  75% (131622/175495)        
remote: Counting objects:  76% (133377/175495)        
remote: Counting objects:  77% (135132/175495)        
remote: Counting objects:  78% (136887/175495)        
remote: Counting objects:  79% (138642/175495)        
remote: Counting objects:  80% (140396/175495)        
remote: Counting objects:  81% (142151/175495)        
remote: Counting objects:  82% (143906/175495)        
remote: Counting objects:  83% (145661/175495)        
remote: Counting objects:  84% (147416/175495)        
remote: Counting objects:  85% (149171/175495)        
remote: Counting objects:  86% (150926/175495)        
remote: Counting objects:  87% (152681/175495)        
remote: Counting objects:  88% (154436/175495)        
remote: Counting objects:  89% (156191/175495)        
remote: Counting objects:  90% (157946/175495)        
remote: Counting objects:  91% (159701/175495)        
remote: Counting objects:  92% (161456/175495)        
remote: Counting objects:  93% (163211/175495)        
remote: Counting objects:  94% (164966/175495)        
remote: Counting objects:  95% (166721/175495)        
remote: Counting objects:  96% (168476/175495)        
remote: Counting objects:  97% (170231/175495)        
remote: Counting objects:  98% (171986/175495)        
remote: Counting objects:  99% (173741/175495)        
remote: Counting objects: 100% (175495/175495)        
remote: Counting objects: 100% (175495/175495), done.        
remote: Compressing objects:   0% (1/119238)        
remote: Compressing objects:   1% (1193/119238)        
remote: Compressing objects:   2% (2385/119238)        
remote: Compressing objects:   3% (3578/119238)        
remote: Compressing objects:   4% (4770/119238)        
remote: Compressing objects:   5% (5962/119238)        
remote: Compressing objects:   6% (7155/119238)        
remote: Compressing objects:   7% (8347/119238)        
remote: Compressing objects:   8% (9540/119238)        
remote: Compressing objects:   9% (10732/119238)        
remote: Compressing objects:  10% (11924/119238)        
remote: Compressing objects:  11% (13117/119238)        
remote: Compressing objects:  12% (14309/119238)        
remote: Compressing objects:  13% (15501/119238)        
remote: Compressing objects:  14% (16694/119238)        
remote: Compressing objects:  15% (17886/119238)        
remote: Compressing objects:  16% (19079/119238)        
remote: Compressing objects:  17% (20271/119238)        
remote: Compressing objects:  18% (21463/119238)        
remote: Compressing objects:  19% (22656/119238)        
remote: Compressing objects:  20% (23848/119238)        
remote: Compressing objects:  21% (25040/119238)        
remote: Compressing objects:  22% (26233/119238)        
remote: Compressing objects:  23% (27425/119238)        
remote: Compressing objects:  24% (28618/119238)        
remote: Compressing objects:  25% (29810/119238)        
remote: Compressing objects:  26% (31002/119238)        
remote: Compressing objects:  27% (32195/119238)        
remote: Compressing objects:  28% (33387/119238)        
remote: Compressing objects:  29% (34580/119238)        
remote: Compressing objects:  30% (35772/119238)        
remote: Compressing objects:  31% (36964/119238)        
remote: Compressing objects:  32% (38157/119238)        
remote: Compressing objects:  32% (38161/119238)        
remote: Compressing objects:  33% (39349/119238)        
remote: Compressing objects:  34% (40541/119238)        
remote: Compressing objects:  35% (41734/119238)        
remote: Compressing objects:  36% (42926/119238)        
remote: Compressing objects:  37% (44119/119238)        
remote: Compressing objects:  38% (45311/119238)        
remote: Compressing objects:  39% (46503/119238)        
remote: Compressing objects:  40% (47696/119238)        
remote: Compressing objects:  41% (48888/119238)        
remote: Compressing objects:  42% (50080/119238)        
remote: Compressing objects:  43% (51273/119238)        
remote: Compressing objects:  44% (52465/119238)        
remote: Compressing objects:  45% (53658/119238)        
remote: Compressing objects:  46% (54850/119238)        
remote: Compressing objects:  47% (56042/119238)        
remote: Compressing objects:  48% (57235/119238)        
remote: Compressing objects:  49% (58427/119238)        
remote: Compressing objects:  50% (59619/119238)        
remote: Compressing objects:  51% (60812/119238)        
remote: Compressing objects:  52% (62004/119238)        
remote: Compressing objects:  53% (63197/119238)        
remote: Compressing objects:  54% (64389/119238)        
remote: Compressing objects:  55% (65581/119238)        
remote: Compressing objects:  56% (66774/119238)        
remote: Compressing objects:  57% (67966/119238)        
remote: Compressing objects:  58% (69159/119238)        
remote: Compressing objects:  59% (70351/119238)        
remote: Compressing objects:  60% (71543/119238)        
remote: Compressing objects:  61% (72736/119238)        
remote: Compressing objects:  62% (73928/119238)        
remote: Compressing objects:  63% (75120/119238)        
remote: Compressing objects:  64% (76313/119238)        
remote: Compressing objects:  65% (77505/119238)        
remote: Compressing objects:  66% (78698/119238)        
remote: Compressing objects:  67% (79890/119238)        
remote: Compressing objects:  68% (81082/119238)        
remote: Compressing objects:  68% (82099/119238)        
remote: Compressing objects:  69% (82275/119238)        
remote: Compressing objects:  70% (83467/119238)        
remote: Compressing objects:  71% (84659/119238)        
remote: Compressing objects:  72% (85852/119238)        
remote: Compressing objects:  73% (87044/119238)        
remote: Compressing objects:  74% (88237/119238)        
remote: Compressing objects:  75% (89429/119238)        
remote: Compressing objects:  76% (90621/119238)        
remote: Compressing objects:  77% (91814/119238)        
remote: Compressing objects:  78% (93006/119238)        
remote: Compressing objects:  79% (94199/119238)        
remote: Compressing objects:  80% (95391/119238)        
remote: Compressing objects:  81% (96583/119238)        
remote: Compressing objects:  82% (97776/119238)        
remote: Compressing objects:  83% (98968/119238)        
remote: Compressing objects:  84% (100160/119238)        
remote: Compressing objects:  85% (101353/119238)        
remote: Compressing objects:  86% (102545/119238)        
remote: Compressing objects:  87% (103738/119238)        
remote: Compressing objects:  88% (104930/119238)        
remote: Compressing objects:  89% (106122/119238)        
remote: Compressing objects:  90% (107315/119238)        
remote: Compressing objects:  91% (108507/119238)        
remote: Compressing objects:  92% (109699/119238)        
remote: Compressing objects:  92% (110366/119238)        
remote: Compressing objects:  93% (110892/119238)        
remote: Compressing objects:  94% (112084/119238)        
remote: Compressing objects:  95% (113277/119238)        
remote: Compressing objects:  96% (114469/119238)        
remote: Compressing objects:  97% (115661/119238)        
remote: Compressing objects:  98% (116854/119238)        
remote: Compressing objects:  99% (118046/119238)        
remote: Compressing objects: 100% (119238/119238)        
remote: Compressing objects: 100% (119238/119238), done.        
Receiving objects:   0% (1/175495)
Receiving objects:   1% (1755/175495)
Receiving objects:   2% (3510/175495)
Receiving objects:   3% (5265/175495)
Receiving objects:   4% (7020/175495)
Receiving objects:   5% (8775/175495)
Receiving objects:   6% (10530/175495)
Receiving objects:   7% (12285/175495)
Receiving objects:   8% (14040/175495)
Receiving objects:   9% (15795/175495)
Receiving objects:  10% (17550/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  11% (19305/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  12% (21060/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  13% (22815/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  14% (24570/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  15% (26325/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  16% (28080/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  17% (29835/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  18% (31590/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  19% (33345/175495), 14.23 MiB | 28.44 MiB/s
Receiving objects:  19% (33935/175495), 28.87 MiB | 28.87 MiB/s
Receiving objects:  20% (35099/175495), 28.87 MiB | 28.87 MiB/s
Receiving objects:  21% (36854/175495), 28.87 MiB | 28.87 MiB/s
Receiving objects:  22% (38609/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  23% (40364/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  24% (42119/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  25% (43874/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  26% (45629/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  27% (47384/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  28% (49139/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  29% (50894/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  30% (52649/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  31% (54404/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  32% (56159/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  33% (57914/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  34% (59669/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  34% (60577/175495), 48.08 MiB | 32.05 MiB/s
Receiving objects:  35% (61424/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  36% (63179/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  37% (64934/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  38% (66689/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  39% (68444/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  40% (70198/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  41% (71953/175495), 59.17 MiB | 29.58 MiB/s
Receiving objects:  42% (73708/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  43% (75463/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  44% (77218/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  45% (78973/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  46% (80728/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  47% (82483/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  48% (84238/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  48% (85123/175495), 72.18 MiB | 28.87 MiB/s
Receiving objects:  49% (85993/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  50% (87748/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  51% (89503/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  52% (91258/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  53% (93013/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  54% (94768/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  55% (96523/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  56% (98278/175495), 87.16 MiB | 29.05 MiB/s
Receiving objects:  57% (100033/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  58% (101788/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  59% (103543/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  60% (105297/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  61% (107052/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  62% (108807/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  63% (110562/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  64% (112317/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  65% (114072/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  66% (115827/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  66% (115994/175495), 99.58 MiB | 28.45 MiB/s
Receiving objects:  67% (117582/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  68% (119337/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  69% (121092/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  70% (122847/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  71% (124602/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  72% (126357/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  73% (128112/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  74% (129867/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  75% (131622/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  76% (133377/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  77% (135132/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  78% (136887/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  79% (138642/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  80% (140396/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  81% (142151/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  82% (143906/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  83% (145661/175495), 120.18 MiB | 30.04 MiB/s
Receiving objects:  84% (147416/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  85% (149171/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  86% (150926/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  87% (152681/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  88% (154436/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  89% (156191/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  90% (157946/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  91% (159701/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  92% (161456/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  93% (163211/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  94% (164966/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  95% (166721/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  96% (168476/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  97% (170231/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  98% (171986/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects:  99% (173741/175495), 136.37 MiB | 30.30 MiB/s
remote: Total 175495 (delta 83016), reused 113694 (delta 49335), pack-reused 0        
Receiving objects: 100% (175495/175495), 136.37 MiB | 30.30 MiB/s
Receiving objects: 100% (175495/175495), 148.32 MiB | 30.21 MiB/s, done.
Resolving deltas:   0% (0/83016)
Resolving deltas:   1% (831/83016)
Resolving deltas:   2% (1661/83016)
Resolving deltas:   3% (2491/83016)
Resolving deltas:   4% (3321/83016)
Resolving deltas:   5% (4151/83016)
Resolving deltas:   6% (4981/83016)
Resolving deltas:   7% (5812/83016)
Resolving deltas:   8% (6642/83016)
Resolving deltas:   9% (7472/83016)
Resolving deltas:  10% (8302/83016)
Resolving deltas:  11% (9132/83016)
Resolving deltas:  12% (9962/83016)
Resolving deltas:  13% (10794/83016)
Resolving deltas:  14% (11623/83016)
Resolving deltas:  15% (12453/83016)
Resolving deltas:  16% (13283/83016)
Resolving deltas:  17% (14113/83016)
Resolving deltas:  18% (14943/83016)
Resolving deltas:  19% (15774/83016)
Resolving deltas:  20% (16604/83016)
Resolving deltas:  21% (17434/83016)
Resolving deltas:  22% (18264/83016)
Resolving deltas:  23% (19095/83016)
Resolving deltas:  24% (19924/83016)
Resolving deltas:  24% (19933/83016)
Resolving deltas:  25% (20754/83016)
Resolving deltas:  26% (21585/83016)
Resolving deltas:  27% (22415/83016)
Resolving deltas:  27% (22876/83016)
Resolving deltas:  28% (23245/83016)
Resolving deltas:  29% (24075/83016)
Resolving deltas:  30% (24905/83016)
Resolving deltas:  31% (25735/83016)
Resolving deltas:  32% (26566/83016)
Resolving deltas:  33% (27396/83016)
Resolving deltas:  34% (28226/83016)
Resolving deltas:  35% (29056/83016)
Resolving deltas:  36% (29886/83016)
Resolving deltas:  37% (30716/83016)
Resolving deltas:  38% (31547/83016)
Resolving deltas:  39% (32377/83016)
Resolving deltas:  40% (33207/83016)
Resolving deltas:  41% (34037/83016)
Resolving deltas:  42% (34867/83016)
Resolving deltas:  43% (35697/83016)
Resolving deltas:  44% (36528/83016)
Resolving deltas:  45% (37358/83016)
Resolving deltas:  46% (38188/83016)
Resolving deltas:  47% (39018/83016)
Resolving deltas:  48% (39848/83016)
Resolving deltas:  49% (40678/83016)
Resolving deltas:  50% (41508/83016)
Resolving deltas:  50% (42095/83016)
Resolving deltas:  51% (42340/83016)
Resolving deltas:  52% (43169/83016)
Resolving deltas:  53% (43999/83016)
Resolving deltas:  54% (44829/83016)
Resolving deltas:  55% (45659/83016)
Resolving deltas:  56% (46489/83016)
Resolving deltas:  57% (47321/83016)
Resolving deltas:  58% (48150/83016)
Resolving deltas:  59% (48980/83016)
Resolving deltas:  60% (49810/83016)
Resolving deltas:  61% (50640/83016)
Resolving deltas:  62% (51470/83016)
Resolving deltas:  63% (52301/83016)
Resolving deltas:  64% (53131/83016)
Resolving deltas:  64% (53729/83016)
Resolving deltas:  65% (53961/83016)
Resolving deltas:  65% (54182/83016)
Resolving deltas:  66% (54791/83016)
Resolving deltas:  67% (55621/83016)
Resolving deltas:  68% (56451/83016)
Resolving deltas:  69% (57282/83016)
Resolving deltas:  70% (58112/83016)
Resolving deltas:  71% (58942/83016)
Resolving deltas:  72% (59772/83016)
Resolving deltas:  73% (60602/83016)
Resolving deltas:  74% (61432/83016)
Resolving deltas:  75% (62263/83016)
Resolving deltas:  76% (63093/83016)
Resolving deltas:  77% (63923/83016)
Resolving deltas:  78% (64753/83016)
Resolving deltas:  79% (65583/83016)
Resolving deltas:  80% (66414/83016)
Resolving deltas:  81% (67243/83016)
Resolving deltas:  82% (68074/83016)
Resolving deltas:  83% (68904/83016)
Resolving deltas:  84% (69734/83016)
Resolving deltas:  84% (70377/83016)
Resolving deltas:  85% (70564/83016)
Resolving deltas:  86% (71394/83016)
Resolving deltas:  87% (72224/83016)
Resolving deltas:  88% (73056/83016)
Resolving deltas:  89% (73885/83016)
Resolving deltas:  90% (74715/83016)
Resolving deltas:  91% (75545/83016)
Resolving deltas:  92% (76376/83016)
Resolving deltas:  93% (77205/83016)
Resolving deltas:  94% (78036/83016)
Resolving deltas:  95% (78866/83016)
Resolving deltas:  96% (79696/83016)
Resolving deltas:  97% (80526/83016)
Resolving deltas:  98% (81356/83016)
Resolving deltas:  99% (82186/83016)
Resolving deltas: 100% (83016/83016)
Resolving deltas: 100% (83016/83016), done.
From https://us-east1-d.ci-gateway.int.gprd.gitlab.net:8989/gitlab-org/gitlab
 * [new ref]             refs/pipelines/1042272888 -> refs/pipelines/1042272888
Checking out 3af7b5df as detached HEAD (ref is refs/merge-requests/134621/merge)...

Skipping Git submodules setup
$ git remote set-url origin "${CI_REPOSITORY_URL}"
section_end:1697710019:get_sources
section_start:1697710019:restore_cache
Restoring cache
Checking cache for ruby-gems-debian-bullseye-ruby-3.0-16...
cache.zip is up to date                            
Successfully extracted cache
section_end:1697710033:restore_cache
section_start:1697710033:download_artifacts
Downloading artifacts
Downloading artifacts for compile-test-assets (5328358048)...
Downloading artifacts from coordinator... ok        host=storage.googleapis.com id=5328358048 responseStatus=200 OK token=64_Fm3NK
Downloading artifacts for detect-tests (5328358058)...
Downloading artifacts from coordinator... ok        host=storage.googleapis.com id=5328358058 responseStatus=200 OK token=64_Fm3NK
Downloading artifacts for retrieve-tests-metadata (5328358066)...
Downloading artifacts from coordinator... ok        host=storage.googleapis.com id=5328358066 responseStatus=200 OK token=64_Fm3NK
Downloading artifacts for setup-test-env (5328358054)...
Downloading artifacts from coordinator... ok        host=storage.googleapis.com id=5328358054 responseStatus=200 OK token=64_Fm3NK
section_end:1697710055:download_artifacts
section_start:1697710055:step_script
Executing "step_script" stage of the job script
Using docker image sha256:d68252162deca904d1a0066983188b98dfe3f6fe8181458b0a55905e79ed85a1 for registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-3.0.patched-golang-1.20-rust-1.65-node-18.17-postgresql-14:rubygems-3.4-git-2.36-lfs-2.9-chrome-113-yarn-1.22-graphicsmagick-1.3.36 with digest registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-3.0.patched-golang-1.20-rust-1.65-node-18.17-postgresql-14@sha256:2113f34affc7e2ee40bac87419dcd7c65a94d4abfa9edb86192e1aa6a1e46590 ...
$ echo $FOSS_ONLY

$ [ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb
$ export GOPATH=$CI_PROJECT_DIR/.go
$ mkdir -p $GOPATH
$ source scripts/utils.sh
$ source scripts/prepare_build.sh
section_start:1697710056:bundle-install[collapsed=true]
Installing gems
3.4.4
Bundler version 2.4.4
Successfully installed bundler-2.4.11
1 gem installed
production:development
Settings are listed in order of priority. The top value will be used.
clean
Set for your local app (/builds/gitlab-org/gitlab/.bundle/config): true

frozen
Set via BUNDLE_FROZEN: true

install_flags
Set via BUNDLE_INSTALL_FLAGS: "--jobs=$(nproc) --retry=3"

path
Set for your local app (/builds/gitlab-org/gitlab/.bundle/config): "/builds/gitlab-org/gitlab/vendor"

without
Set via BUNDLE_WITHOUT: [:production, :development]

$ bundle install --jobs=$(nproc) --retry=3 
Don't run Bundler as root. Installing your bundle as root will break this
application for all non-root users on this machine.
Patching bundler with bundler-checksum...
Bundle complete! 318 Gemfile dependencies, 629 gems now installed.
Gems in the groups 'production' and 'development' were not installed.
Bundled gems are installed into `./vendor`
2 installed gems you directly depend on are looking for funding.
  Run `bundle fund` for details
==> 'bundle install --jobs=$(nproc) --retry=3 ' succeeded in 1 seconds.
$ bundle pristine pg
Patching bundler with bundler-checksum...
Installing pg 1.5.4 with native extensions
==> 'bundle pristine pg' succeeded in 10 seconds.
section_end:1697710070:bundle-install

Using decomposed database config (config/database.yml.decomposed-postgresql)
Geo DB won't be set up.
Embedding DB won't be set up.
section_start:1697710070:setup-db[collapsed=true]
Setting up DBs
CREATE ROLE
GRANT
$ bundle exec rake db:drop db:create db:schema:load db:migrate gitlab:db:lock_writes
Dropped database 'gitlabhq_test'
Dropped database 'gitlabhq_test_ci'
Created database 'gitlabhq_test'
Created database 'gitlabhq_test_ci'
INFO:  analyzing "public.p_ci_runner_machine_builds" inheritance tree
INFO:  analyzing "gitlab_partitions_dynamic.ci_runner_machine_builds_100"
INFO:  "ci_runner_machine_builds_100": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
INFO:  analyzing "public.p_ci_job_annotations" inheritance tree
INFO:  analyzing "gitlab_partitions_dynamic.ci_job_annotations_100"
INFO:  "ci_job_annotations_100": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
INFO:  analyzing "public.p_ci_builds_metadata" inheritance tree
INFO:  analyzing "public.ci_builds_metadata"
INFO:  "ci_builds_metadata": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
INFO:  analyzing "public.p_ci_runner_machine_builds" inheritance tree
INFO:  analyzing "gitlab_partitions_dynamic.ci_runner_machine_builds_100"
INFO:  "ci_runner_machine_builds_100": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
INFO:  analyzing "public.p_ci_job_annotations" inheritance tree
INFO:  analyzing "gitlab_partitions_dynamic.ci_job_annotations_100"
INFO:  "ci_job_annotations_100": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
INFO:  analyzing "public.p_ci_builds_metadata" inheritance tree
INFO:  analyzing "public.ci_builds_metadata"
INFO:  "ci_builds_metadata": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in sample, 0 estimated total rows
==> 'bundle exec rake db:drop db:create db:schema:load db:migrate gitlab:db:lock_writes' succeeded in 51 seconds.
SELECT pg_catalog.set_config('search_path', '', false);
CREATE DATABASE praefect_test ENCODING 'UTF8';
section_end:1697710121:setup-db

$ source ./scripts/rspec_helpers.sh
$ run_timed_command "gem install knapsack --no-document"
$ gem install knapsack --no-document
Successfully installed knapsack-4.0.0
1 gem installed
==> 'gem install knapsack --no-document' succeeded in 1 seconds.
$ section_start "gitaly-test-spawn" "Spawning Gitaly"; scripts/gitaly-test-spawn; section_end "gitaly-test-spawn"
section_start:1697710122:gitaly-test-spawn[collapsed=true]
Spawning Gitaly
Trying to connect to gitaly: .... OK
Trying to connect to gitaly2: ...... OK
Starting Praefect with in-memory election strategyTrying to connect to praefect: ...... OK
section_end:1697710125:gitaly-test-spawn

$ export RSPEC_SKIPPED_TESTS_REPORT_PATH="rspec/skipped_tests-${CI_JOB_ID}.txt"
$ export RSPEC_RETRIED_TESTS_REPORT_PATH="rspec/retried_tests-${CI_JOB_ID}.txt"
$ tooling/bin/create_job_metrics_file || true
[job-metrics] Creating the job metrics file for the CI/CD job.
$ rspec_paralellized_job "--fail-fast=${RSPEC_FAIL_FAST_THRESHOLD} --tag ~quarantine --tag ~level:background_migration --tag ~click_house --tag ~real_ai_request"
RETRY_FAILED_TESTS_IN_NEW_PROCESS: true
KNAPSACK_GENERATE_REPORT: true
FLAKY_RSPEC_GENERATE_REPORT: true
KNAPSACK_TEST_FILE_PATTERN: spec/{commands,controllers,mailers,requests}{,/**/}*_spec.rb
KNAPSACK_LOG_LEVEL: debug
KNAPSACK_REPORT_PATH: knapsack/rspec_integration_pg14_8_13_report.json
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec/flaky/report-suite.json
FLAKY_RSPEC_REPORT_PATH: rspec/flaky/all_rspec_integration_pg14_8_13_report.json
NEW_FLAKY_RSPEC_REPORT_PATH: rspec/flaky/new_rspec_integration_pg14_8_13_report.json
RSPEC_SKIPPED_TESTS_REPORT_PATH: rspec/skipped_tests-5328358281.txt
CRYSTALBALL: 
RSPEC_TESTS_MAPPING_ENABLED: 
RSPEC_TESTS_FILTER_FILE: 
Shell set options (set -o) enabled:
braceexpand    	on
hashall        	on
interactive-comments	on
pipefail       	on
Knapsack report generator started!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/service_response_factory.rb:41: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/workspaces/create_service.rb:28: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/workspaces/reconcile_service.rb:38: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/workspaces/update_service.rb:28: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/agent_config/main.rb:32: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/agent_config/updater.rb:11: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/authorizer.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/authorizer.rb:13: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/creator.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/creator.rb:19: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/devfile_fetcher.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/devfile_fetcher.rb:16: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/devfile_flattener.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:17: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:18: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/personal_access_token_creator.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/personal_access_token_creator.rb:17: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:43: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:54: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:102: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:126: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:159: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:202: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:235: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/pre_flatten_devfile_validator.rb:24: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/pre_flatten_devfile_validator.rb:52: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:17: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:18: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:23: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/volume_component_injector.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/volume_component_injector.rb:13: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/volume_component_injector.rb:14: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:24: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:25: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:28: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_variables_creator.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/main.rb:43: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/update/authorizer.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/update/updater.rb:13: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/agent_infos_observer.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_extractor.rb:14: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_extractor.rb:16: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_to_infos_converter.rb:14: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_validator.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/output/rails_infos_observer.rb:11: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/output/workspaces_to_rails_infos_converter.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/orphaned_workspaces_observer.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_from_agent_infos_updater.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_to_be_returned_finder.rb:16: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_to_be_returned_updater.rb:11: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
Run options: exclude {:quarantine=>true, :level=>"background_migration", :click_house=>true, :real_ai_request=>true}

Test environment set up in 0.528033871 seconds

API::Projects
  GET /projects
    when unauthenticated
      behaves like projects response
        returns an array of projects
        returns the proper security headers
      behaves like projects response without N + 1 queries
        avoids N + 1 queries
    when authenticated as regular user
      is expected to eq false
      includes various project feature fields
      includes correct value of container_registry_enabled
      includes project topics
      includes open_issues_count
      does not include projects marked for deletion
      does not include open_issues_count if issues are disabled
      does not include statistics by default
      includes statistics if requested
      does not include license by default
      does not include license if requested
      behaves like projects response
        returns an array of projects
        returns the proper security headers
      behaves like projects response without N + 1 queries
        avoids N + 1 queries
      when some projects are in a group
        behaves like projects response without N + 1 queries
          avoids N + 1 queries
      filter by topic (column topic_list)
        returns no projects
        returns matching project for a single topic
        returns matching project for multiple topics
        returns no projects if project match only some topic
        ignores topic if it is empty
      filter by topic_id
        with id of assigned topic
          behaves like projects response
            returns an array of projects
            returns the proper security headers
        with id of unassigned topic
          behaves like projects response
            returns an array of projects
            returns the proper security headers
        with non-existing topic id
          behaves like projects response
            returns an array of projects
            returns the proper security headers
        with empty topic id
          behaves like projects response
            returns an array of projects
            returns the proper security headers
      and with_issues_enabled=true
        only returns projects with issues enabled
      when external issue tracker is enabled
        includes open_issues_count
        does not include open_issues_count if issues are disabled
      and with simple=true
        returns a simplified version of all the projects
      and using archived
        returns archived projects
        returns non-archived projects
        returns every project
      filter by updated_at
        returns projects sorted by updated_at
        behaves like projects response
          returns an array of projects
          returns the proper security headers
        when filtering by updated_at and sorting by a different column
          returns an error
      and using search
        behaves like projects response
          returns an array of projects
          returns the proper security headers
      and using search and search_namespaces is true
        behaves like projects response
          returns an array of projects
          returns the proper security headers
      and using id_after
        behaves like projects response
          returns an array of projects
          returns the proper security headers
        regression: empty string is ignored
          behaves like projects response
            returns an array of projects
            returns the proper security headers
      and using id_before
        behaves like projects response
          returns an array of projects
          returns the proper security headers
        regression: empty string is ignored
          behaves like projects response
            returns an array of projects
            returns the proper security headers
      and using both id_after and id_before
        behaves like projects response
          returns an array of projects
          returns the proper security headers
      and membership=true
        behaves like projects response
          returns an array of projects
          returns the proper security headers
      and using the visibility filter
        filters based on private visibility param
        filters based on internal visibility param
        filters based on public visibility param
      and using the programming language filter
        filters case-insensitively by programming language
      and using sorting
        returns the correct order when sorted by id
      and with owned=true
        returns an array of projects the user owns
        when admin creates a project
          does not list as owned project for admin
      and with starred=true
        returns the starred projects viewable by the user
      and with all query parameters
        including owned filter
          returns only projects that satisfy all query parameters
        including membership filter
          returns only projects that satisfy all query parameters
      and with min_access_level
        returns an array of projects the user has at least developer access
    and imported=true
      returns only imported projects owned by current user
      does not expose import credentials
    when authenticated as a different user
      behaves like projects response
        returns an array of projects
        returns the proper security headers
      and with_issues_enabled=true
        does not return private issue projects
    when authenticated as admin
      returns a project with user namespace that has a missing owner
      behaves like projects response
        returns an array of projects
        returns the proper security headers
    with default created_at desc order
      orders by id desc instead
    sorting
      by project statistics
        sorting by repository_size
          admin user
            when sorting by repository_size ascendingly
              returns a properly sorted list of projects
            when sorting by repository_size descendingly
              returns a properly sorted list of projects
          non-admin user
            returns projects ordered normally
        sorting by storage_size
          admin user
            when sorting by storage_size ascendingly
              returns a properly sorted list of projects
            when sorting by storage_size descendingly
              returns a properly sorted list of projects
          non-admin user
            returns projects ordered normally
        sorting by wiki_size
          admin user
            when sorting by wiki_size ascendingly
              returns a properly sorted list of projects
            when sorting by wiki_size descendingly
              returns a properly sorted list of projects
          non-admin user
            returns projects ordered normally
        sorting by packages_size
          admin user
            when sorting by packages_size ascendingly
              returns a properly sorted list of projects
            when sorting by packages_size descendingly
              returns a properly sorted list of projects
          non-admin user
            returns projects ordered normally
      by similarity
        returns non-public items based ordered by similarity
        when `search` parameter is not given
          returns items ordered by created_at descending
        when called anonymously
          returns items ordered by created_at descending
    filtering by repository_storage
      admin user
        behaves like projects response
          returns an array of projects
          returns the proper security headers
      non-admin user
        behaves like projects response
          returns an array of projects
          returns the proper security headers
    with keyset pagination
      headers and records
        includes a pagination header with link to the next page
        contains only the first project with per_page = 1
        still includes a link if the end has reached and there is no more data after this page
        does not include a next link when the page does not have any records
        returns an empty array when the page does not have any records
        responds with 501 if order_by is different from id
      with descending sorting
        includes a pagination header with link to the next page
        contains only the last project with per_page = 1
      retrieving the full relation
        returns all projects
    with forked projects
      avoids N+1 queries
    when service desk is enabled
      avoids N+1 queries
    rate limiting
      when the user is signed in
        behaves like does not log request and does not block the request
          is expected not to receive error(*(any args)) 0 times
      when the user is not signed in
        behaves like rate limited endpoint
          when rate limiter enabled
            logs request and declines it when endpoint called more than the threshold
          when rate limiter is disabled
            does not log request and does not block the request
  POST /projects
    creates new project without path but with name and returns 201
    creates new project without name but with path and returns 201
    creates new project with name and path and returns 201
    creates last project before reaching project limit
    does not create new project without name or path and returns 400
    assigns attributes to project
    assigns container_registry_enabled to project
    assigns container_registry_enabled to project
    creates a project using a template
    returns 400 for an invalid template
    disallows creating a project with an import_url and template
    disallows creating a project with an import_url when git import source is disabled
    allows creating a project without an import_url when git import source is disabled
    disallows creating a project with an import_url that is not reachable
    creates a project with an import_url that is valid
    sets a project as public
    sets a project as internal
    sets a project as private
    creates a new project initialized with a README.md
    sets tag list to a project (deprecated)
    sets topics to a project
    uploads avatar for project a project
    sets a project as not allowing outdated diff discussions to automatically resolve
    sets a project as allowing outdated diff discussions to automatically resolve
    sets a project as not removing source branches
    sets a project as removing source branches
    sets a project as allowing merge even if build fails
    sets a project as allowing merge only if merge_when_pipeline_succeeds
    sets a project as not allowing merge when pipeline is skipped
    sets a project as allowing merge when pipeline is skipped
    sets a project as allowing merge even if discussions are unresolved
    sets a project as allowing merge if only_allow_merge_if_all_discussions_are_resolved is nil
    sets a project as allowing merge only if all discussions are resolved
    sets a project as enabling auto close referenced issues
    sets a project as disabling auto close referenced issues
    sets the merge method of a project to rebase merge
    rejects invalid values for merge_method
    ignores import_url when it is nil
    maximum number of projects reached
      does not create new project and respond with 403
    behaves like create project with default branch parameter
      creates project with provided default branch name
      when branch name is empty
        creates project with a default project branch name
      when initialize with readme is not set
        creates project with a default project branch name
    when a visibility level is restricted
      does not allow a non-admin to use a restricted visibility level
      allows an admin to override restricted visibility settings
  GET /users/:user_id/projects/
    returns error when user not found
    returns projects filtered by user id
    includes container_registry_access_level
    returns projects filtered by username
    returns projects filtered by minimal access level
    filter by updated_at
      returns only projects updated on the given timeframe
    and using id_after
      only returns projects with id_after filter given
      returns both projects without a id_after filter
    and using id_before
      only returns projects with id_before filter given
      returns both projects without a id_before filter
    and using both id_before and id_after
      only returns projects with id matching the range
    and using an admin to search
      returns users projects when authenticated as admin
    and using the programming language filter
      filters case-insensitively by programming language
  GET /users/:user_id/starred_projects/
    returns error when user not found
    with a public profile
      returns projects filtered by user
      filter by updated_at
        returns only projects updated on the given timeframe
    with a private profile
      user does not have access to view the private profile
        returns no projects
      user has access to view the private profile
        returns projects filtered by user
  GET /users/:user_id/contributed_projects/
    returns error when user not found
    with a public profile
      returns projects filtered by user
    with a private profile
      user does not have access to view the private profile
        returns no projects (FAILED - 1)
      user has access to view the private profile as an admin
        returns projects filtered by user
  POST /projects/user/:id
    creates new project without path but with name and return 201
    creates new project with name and path and returns 201
    responds with 400 on failure and not project
    sets container_registry_enabled
    assigns attributes to project
    sets a project as public
    sets a project as internal
    sets a project as private
    sets a project as not allowing outdated diff discussions to automatically resolve
    sets a project as allowing outdated diff discussions to automatically resolve
    sets a project as not removing source branches
    sets a project as removing source branches
    sets a project as allowing merge even if build fails
    sets a project as allowing merge only if pipeline succeeds
    sets a project as not allowing merge when pipeline is skipped
    sets a project as allowing merge when pipeline is skipped
    sets a project as allowing merge even if discussions are unresolved
    sets a project as allowing merge only if all discussions are resolved
    behaves like POST request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    behaves like create project with default branch parameter
      creates project with provided default branch name
      when branch name is empty
        creates project with a default project branch name
      when initialize with readme is not set
        creates project with a default project branch name
    container_registry_enabled
      container_registry_enabled: true, container_registry_access_level: 20
        setting container_registry_enabled also sets container_registry_access_level
      container_registry_enabled: false, container_registry_access_level: 0
        setting container_registry_enabled also sets container_registry_access_level
    container_registry_access_level
      container_registry_access_level: "enabled", container_registry_enabled: true
        setting container_registry_access_level also sets container_registry_enabled
      container_registry_access_level: "private", container_registry_enabled: true
        setting container_registry_access_level also sets container_registry_enabled
      container_registry_access_level: "disabled", container_registry_enabled: false
        setting container_registry_access_level also sets container_registry_enabled
  POST /projects/:id/uploads/authorize
    with authorized user
      returns 200
    with unauthorized user
      returns 404
    with exempted project
      returns 200
    with no Workhorse headers
      returns 403
  POST /projects/:id/uploads
    uploads the file and returns its info
    does not leave the temporary file in place after uploading, even when the tempfile reaper does not run
    with exempted project
      behaves like capped upload attachments
        limits the upload to 1 GiB
        logs a warning if file exceeds attachment size
  GET /projects/:id/groups
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when unauthenticated
      does not return groups for private projects
      for public projects
        behaves like successful groups response
          returns an array of groups
    when authenticated as user
      when user does not have access to the project
        does not return groups
      when user has access to the project
        behaves like successful groups response
          returns an array of groups
        when search by root group name
          behaves like successful groups response
            returns an array of groups
        with_shared option is on
          behaves like successful groups response
            returns an array of groups
          when shared_min_access_level is set
            behaves like successful groups response
              returns an array of groups
          when shared_visible_only is on
            behaves like successful groups response
              returns an array of groups
          when search by shared group name
            behaves like successful groups response
              returns an array of groups
          when skip_groups is set
            behaves like successful groups response
              returns an array of groups
    when authenticated as admin
      behaves like successful groups response
        returns an array of groups
  GET /project/:id/share_locations
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when unauthenticated
      does not return the groups for the given project
    when authenticated
      when user is not the owner of the project
        does not return the groups
      when user is the owner of the project
        with default search
          behaves like successful groups response
            returns an array of groups
        when searching by group name
          searching by group name
            behaves like successful groups response
              returns an array of groups
          searching by full group path
            behaves like successful groups response
              returns an array of groups
    when authenticated as admin
      without share_with_group_lock
        behaves like successful groups response
          returns an array of groups
      with share_with_group_lock
        behaves like successful groups response
          returns an array of groups
  GET /projects/:id
    exposes service desk attributes
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when unauthenticated
      does not return private projects
      returns public projects
      the project is a public fork
        hides details of a public fork parent
      and the project has a private repository
        hides protected attributes of private repositories if user is not a member
        exposes protected attributes of private repositories if user is a member
    when authenticated as an admin
      returns a project by id
      exposes all necessary attributes
    when authenticated as a regular user
      returns a project by id
      returns a group link with expiration date
      returns a project by path name
      returns a 404 error if not found
      returns a 404 error if user is not a member
      handles users with dots
      exposes namespace fields
      does not include license fields by default
      includes license fields when requested
      does not include statistics by default
      includes statistics if requested
      includes import_error if user can admin project
      does not include import_error if user cannot admin project
      returns 404 when project is marked for deletion
      when a project is moved
        redirects to the new project location
        when a user do not have access
          returns a 404 error
        when api_redirect_moved_projects is disabled
          returns a 404 error
      and the project has a private repository
        does not include statistics if user is not a member
        includes statistics if user is a member
        includes statistics also when repository is disabled
      links exposure
        exposes related resources full URIs
        filters related URIs when their feature is not enabled
      the project is a fork
        shows details of a visible fork parent
        hides details of a hidden fork parent
      permissions
        all projects
          contains permission information
        personal project
          sets project access and returns 200
        group project
          sets the owner and return 200
        nested group project
          sets group access and return 200
          with various access levels across nested groups
            sets the maximum group access and return 200
      when project belongs to a group namespace
        returns group web_url and avatar_url
      when project belongs to a user namespace
        returns user web_url and avatar_url
    when authenticated as a developer
      hides sensitive admin attributes
    behaves like storing arguments in the application context for the API
      places the expected params in the application context
    repository_storage attribute
      when authenticated as an admin
        returns repository_storage attribute
      when authenticated as a regular user
        does not return repository_storage attribute
    when project is shared to multiple groups
      avoids N+1 queries
  GET /projects/:id/users
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when unauthenticated
      behaves like project users response
        returns the project users
    when authenticated
      returns a 404 error if not found
      returns a 404 error if user is not a member
      filters out users listed in skip_users
      valid request
        behaves like project users response
          returns the project users
  fork management
    POST /projects/:id/fork/:forked_from_id
      refreshes the forks count cache
      behaves like POST request permissions for admin mode
        behaves like when admin
          behaves like makes request
            returns
          behaves like makes request
            returns
        behaves like when user
          returns
          behaves like makes request
            returns
      user is a developer
        denies project to be forked from an existing project
      user is maintainer
        denies project to be forked from an existing project
      user is owner
        fails without permission from forked_from project
        denies project to be forked from a private project
        and user is a reporter of target group
          fails as target namespace is unauthorized
        and user is a developer of target group
          allows project to be forked from an existing project
      user is admin
        allows project to be forked from an existing project
        allows project to be forked from a private project
        refreshes the forks count cachce
        fails if forked_from project which does not exist
        fails with 409 if already forked
    DELETE /projects/:id/fork
      is not visible to users outside group
      when users belong to project group
        is forbidden to non-owner users
        is idempotent if not forked
        for a forked project
          makes forked project unforked
          behaves like DELETE request permissions for admin mode
            behaves like when admin
              behaves like makes request
                returns
              behaves like makes request
                returns
            behaves like when user
              returns
              behaves like makes request
                returns
          behaves like 412 response
            for a modified resource
              returns 412 with a JSON error
            for an unmodified resource
              returns 204 with an empty body
    GET /projects/:id/forks
      for a forked project
        for a user that can access the forks
          returns the forks
          filter by updated_at
            returns only forks updated on the given timeframe
        for a user that cannot access the forks
          returns an empty array
      for a non-forked project
        returns an empty array
  POST /projects/:id/share
    shares project with group
    updates project authorization
    returns a 400 error when group id is not given
    returns a 400 error when access level is not given
    returns a 400 error when sharing is disabled
    returns a 404 error when user cannot read group
    returns a 404 error when group does not exist
    returns a 400 error when wrong params passed
    returns a 400 error when the project-group share is created with an OWNER access level
    returns a 409 error when link is not saved
    when project is forked
      returns a 404 error when group does not exist
  DELETE /projects/:id/share/:group_id
    returns a 400 when group id is not an integer
    returns a 404 error when group link does not exist
    returns a 404 error when project does not exist
    for a valid group
      returns 204 when deleting a group share
      updates project authorization
      behaves like 412 response
        for a modified resource
          returns 412 with a JSON error
        for an unmodified resource
          returns 204 with an empty body
  POST /projects/:id/import_project_members/:project_id
    records the query
    returns 200 when it successfully imports members from another project
    returns 404 if the source project does not exist
    returns 404 if the target project members cannot be administered by the requester
    returns 404 if the source project members cannot be viewed by the requester
    returns 403 if the source project members cannot be administered by the requester
    returns 422 if the import failed for valid projects
    when importing of members did not work for some or all members
      fails to import some members
  PUT /projects/:id
    sets container_registry_access_level
    sets container_registry_enabled
    sets security_and_compliance_access_level
    sets analytics_access_level
    sets releases_access_level
    sets environments_access_level
    sets feature_flags_access_level
    sets infrastructure_access_level
    sets monitor_access_level
    sets model_experiments_access_level
    returns 400 when nothing sent
    behaves like PUT request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    updating packages_enabled attribute
      is enabled by default
      disables project packages feature
    when unauthenticated
      returns authentication error
    when authenticated as project owner
      updates visibility_level
      updates visibility_level from public to private
      does not update visibility_level if it is restricted
      does not update name to existing name
      updates request_access_enabled
      updates path & name to existing path & name in different namespace
      updates default_branch
      updates jobs_enabled
      updates builds_access_level
      updates pages_access_level
      updates emails_disabled
      updates emails_enabled?
      updates build_git_strategy
      rejects to update build_git_strategy when build_git_strategy is invalid
      updates merge_method
      rejects to update merge_method when merge_method is invalid
      updates restrict_user_defined_variables
      updates auto_devops_deploy_strategy
      updates auto_devops_enabled
      updates topics using tag_list (deprecated)
      updates topics
      updates enforce_auth_checks_on_uploads
      updates squash_option
      does not update an invalid squash_option
      with changes to the avatar
        uploads avatar to project without an avatar
        uploads and changes avatar to project with an avatar
        uploads and changes avatar to project among other changes
        removes avatar from project with an avatar
    when authenticated as project maintainer
      updates path
      updates other attributes
      does not update path to existing path
      updates name
      does not update visibility_level
      updates container_expiration_policy
      doesn't update container_expiration_policy with invalid regex
      doesn't update container_expiration_policy with invalid keep_n
    when authenticated as project developer
      does not update other attributes
    when authenticated as the admin
      ignores visibility level restrictions
    when updating repository storage
      as a user
        returns 200 but does not change repository_storage
      as an admin
        returns 400 when repository storage is unknown
        returns 200 when repository storage has changed
    when updating service desk
      returns 200
      enables the service_desk
    when updating keep latest artifact
      returns 200
      enables keep_latest_artifact
    attribute mr_default_target_self
      is by default set to false
      for a non-forked project
        is not exposed
        is not possible to update
      for a forked project
        updates to true
  POST /projects/:id/archive
    on an unarchived project
      archives the project
    on an archived project
      remains archived
    user without archiving rights to the project
      rejects the action
    when a project is moved
      returns 405 error
      when user do not have access to the project
        returns 404 error
  POST /projects/:id/unarchive
    on an unarchived project
      remains unarchived
    on an archived project
      unarchives the project
    user without archiving rights to the project
      rejects the action
  POST /projects/:id/star
    on an unstarred project
      stars the project
    on a starred project
      does not modify the star count
  POST /projects/:id/unstar
    on a starred project
      unstars the project
    on an unstarred project
      does not modify the star count
  GET /projects/:id/starrers
    returns not_found(404) for not existing project
    public project without user
      returns only starrers with a public profile
      behaves like project starrers response
        returns an array of starrers
        returns the proper security headers
    public project with user with private profile
      returns current user with a private profile
      behaves like project starrers response
        returns an array of starrers
        returns the proper security headers
    private project
      with unauthorized user
        returns not_found for existing but unauthorized project
      without user
        returns not_found for existing but unauthorized project
  GET /projects/:id/languages
    with an authorized user
      returns not_found(404) for not existing project
      behaves like languages and percentages JSON response
        when the languages haven't been detected yet
          returns expected language values
        when the languages were detected before
          returns the detection from the database
    with not authorized user
      returns not_found for existing but unauthorized project
    without user
      returns not_found for existing but unauthorized project
      behaves like languages and percentages JSON response
        when the languages haven't been detected yet
          returns expected language values
        when the languages were detected before
          returns the detection from the database
  DELETE /projects/:id
    behaves like DELETE request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when authenticated as user
      removes project
      does not remove a project if not an owner
      does not remove a non existing project
      does not remove a project not attached to user
      behaves like 412 response
        for a modified resource
          returns 412 with a JSON error
        for an unmodified resource
          returns 204 with an empty body
    when authenticated as admin
      removes any existing project
      does not remove a non existing project
      behaves like 412 response
        for a modified resource
          returns 412 with a JSON error
        for an unmodified resource
          returns 204 with an empty body
  POST /projects/:id/fork
    behaves like POST request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when authenticated
      forks if user has sufficient access to project
      forks if user is admin
      fails on missing project access for the project to fork
      fails if forked project exists in the user namespace
      fails if project to fork from does not exist
      forks with explicit own user namespace id
      forks with explicit own user name as namespace
      forks to another user when admin
      fails if trying to fork to another user when not admin
      fails if trying to fork to non-existent namespace
      forks to owned group
      forks to owned subgroup
      fails to fork to not owned group
      forks to not owned group when admin
      accepts a path for the target project
      fails to fork if path is already taken
      accepts custom parameters for the target project
      fails to fork if name is already taken
      forks to the same namespace with alternative path and name
      fails to fork to the same namespace without alternative path and name
      fails to fork with an unknown visibility level
      when namespace_id is specified
        and namespace_id is specified alone
          behaves like forking to specified namespace_id
            forks to specified namespace_id
        and namespace_id and namespace are both specified
          behaves like forking to specified namespace_id
            forks to specified namespace_id
        and namespace_id and namespace_path are both specified
          behaves like forking to specified namespace_id
            forks to specified namespace_id
      when namespace_path is specified
        and namespace_path is specified alone
          behaves like forking to specified namespace_path
            forks to specified namespace_path
        and namespace_path and namespace are both specified
          behaves like forking to specified namespace_path
            forks to specified namespace_path
    when unauthenticated
      returns authentication error
    forking disabled
      denies project to be forked
  POST /projects/:id/housekeeping
    when authenticated as owner
      starts the housekeeping process
      logs an audit event
      when requesting prune
        triggers a prune
      when requesting an unsupported task
        responds with bad_request
      when housekeeping lease is taken
        returns conflict
    when authenticated as developer
      returns forbidden error
    when unauthenticated
      returns authentication error
  POST /projects/:id/repository_size
    when authenticated as owner
      starts the housekeeping process
    when authenticated as developer
      returns forbidden error
    when unauthenticated
      returns authentication error
  PUT /projects/:id/transfer
    when authenticated as owner
      transfers the project to the new namespace
      fails when transferring to a non owned namespace
      fails when transferring to an unknown namespace
      fails on missing namespace
    when authenticated as developer
      target namespace allows developers to create projects
        fails transferring the project to the target namespace
  GET /projects/:id/transfer_locations
    when the user has rights to transfer the project
      returns 200
      includes groups where the user has permissions to transfer a project to
      does not include groups where the user doesn not have permissions to transfer a project
      does not include the group id of the current project
      with search
        includes groups where the user has permissions to transfer a project to
      group shares
        only includes groups arising from group shares where the user has permission to transfer a project to
    when the user does not have permissions to transfer the project
      returns 403
  GET /projects/:id/storage
    returns project storage data when user is admin
    does not return project storage data when user is not admin
    responds with a 401 for unauthenticated users trying to access a non-existent project id
    responds with a 403 for non-admin users trying to access a non-existent project id
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when unauthenticated
      does not return project storage data
  behaves like custom attributes endpoints
    GET /projects with custom attributes filter
      with an unauthorized user
        does not filter by custom attributes
      with an authorized user
        filters by custom attributes
    GET /projects with custom attributes
      with an unauthorized user
        does not include custom attributes
      with an authorized user
        does not include custom attributes by default
        includes custom attributes if requested
    GET /projects/:id with custom attributes
      with an unauthorized user
        does not include custom attributes
      with an authorized user
        does not include custom attributes by default
        includes custom attributes if requested
    GET /projects/:id/custom_attributes
      with an unauthorized user
        behaves like an unauthorized API user
          is expected to eq 403
      with an authorized user
        returns all custom attributes
    GET /projects/:id/custom_attributes/:key
      with an unauthorized user
        behaves like an unauthorized API user
          is expected to eq 403
      with an authorized user
        returns a single custom attribute
    PUT /projects/:id/custom_attributes/:key
      with an unauthorized user
        behaves like an unauthorized API user
          is expected to eq 403
      with an authorized user
        creates a new custom attribute
        updates an existing custom attribute
    DELETE /projects/:id/custom_attributes/:key
      with an unauthorized user
        behaves like an unauthorized API user
          is expected to eq 403
      with an authorized user
        deletes an existing custom attribute

API::Branches
  GET /projects/:id/repository/branches
    when search parameter is passed
      and branch exists
        returns correct branches
      and branch does not exist
        returns an empty array
    when sort parameter is passed
      sorts branches
      when sort value is not supported
        behaves like 400 response
          returns 400
    when unauthenticated and project is public
      behaves like repository branches
        with branch_list_keyset_pagination feature off
          with offset pagination params
            returns the repository branches
            determines only a limited number of merged branch names
            merge status matches reality on paginated input
            recovers pagination headers from cache between consecutive requests
          with gitaly pagination params
            merge status matches reality on paginated input
        with branch_list_keyset_pagination feature on
          with keyset pagination option
            with gitaly pagination params
              returns the repository branches
              determines only a limited number of merged branch names
              merge status matches reality on paginated input
            with offset pagination params
              ignores legacy pagination params
        when repository is disabled
          behaves like 404 response
            returns 404
      caching
        caches the query
        uses the cache up to 60 minutes
        requests for new value after 60 minutes
    when unauthenticated and project is private
      behaves like 404 response
        returns 404
    when authenticated as a maintainer
      does not submit N+1 DB queries
      behaves like repository branches
        with branch_list_keyset_pagination feature off
          with offset pagination params
            returns the repository branches
            determines only a limited number of merged branch names
            merge status matches reality on paginated input
            recovers pagination headers from cache between consecutive requests
          with gitaly pagination params
            merge status matches reality on paginated input
        with branch_list_keyset_pagination feature on
          with keyset pagination option
            with gitaly pagination params
              returns the repository branches
              determines only a limited number of merged branch names
              merge status matches reality on paginated input
            with offset pagination params
              ignores legacy pagination params
        when repository is disabled
          behaves like 404 response
            returns 404
      requesting with the escaped project full path
        behaves like repository branches
          with branch_list_keyset_pagination feature off
            with offset pagination params
              returns the repository branches
              determines only a limited number of merged branch names
              merge status matches reality on paginated input
              recovers pagination headers from cache between consecutive requests
            with gitaly pagination params
              merge status matches reality on paginated input
          with branch_list_keyset_pagination feature on
            with keyset pagination option
              with gitaly pagination params
                returns the repository branches
                determines only a limited number of merged branch names
                merge status matches reality on paginated input
              with offset pagination params
                ignores legacy pagination params
          when repository is disabled
            behaves like 404 response
              returns 404
    when authenticated as a guest
      behaves like 403 response
        returns 403
  GET /projects/:id/repository/branches/:branch
    when unauthenticated and project is public
      returns that the current user cannot push
      behaves like repository branch
        returns the repository branch
        HEAD request
          returns 204 No Content
          returns 404 Not Found
        when branch does not exist
          behaves like 404 response
            returns 404
        when the branch refname is invalid
          behaves like 400 response
            returns 400
        when repository is disabled
          behaves like 404 response
            returns 404
        when branch is ambiguous
          behaves like 404 response
            returns 404
        when repository does not exist
          behaves like 404 response
            returns 404
    when unauthenticated and project is private
      behaves like 404 response
        returns 404
    when authenticated as a maintainer
      returns that the current user can push
      behaves like repository branch
        returns the repository branch
        HEAD request
          returns 204 No Content
          returns 404 Not Found
        when branch does not exist
          behaves like 404 response
            returns 404
        when the branch refname is invalid
          behaves like 400 response
            returns 400
        when repository is disabled
          behaves like 404 response
            returns 404
        when branch is ambiguous
          behaves like 404 response
            returns 404
        when repository does not exist
          behaves like 404 response
            returns 404
      when branch contains a dot
        behaves like repository branch
          returns the repository branch
          HEAD request
            returns 204 No Content
            returns 404 Not Found
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
          when branch is ambiguous
            behaves like 404 response
              returns 404
          when repository does not exist
            behaves like 404 response
              returns 404
      when branch contains dot txt
        behaves like repository branch
          returns the repository branch
          HEAD request
            returns 204 No Content
            returns 404 Not Found
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
          when branch is ambiguous
            behaves like 404 response
              returns 404
          when repository does not exist
            behaves like 404 response
              returns 404
      when branch contains a slash
        behaves like 404 response
          returns 404
      when branch contains an escaped slash
        behaves like repository branch
          returns the repository branch
          HEAD request
            returns 204 No Content
            returns 404 Not Found
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
          when branch is ambiguous
            behaves like 404 response
              returns 404
          when repository does not exist
            behaves like 404 response
              returns 404
      requesting with the escaped project full path
        behaves like repository branch
          returns the repository branch
          HEAD request
            returns 204 No Content
            returns 404 Not Found
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
          when branch is ambiguous
            behaves like 404 response
              returns 404
          when repository does not exist
            behaves like 404 response
              returns 404
        when branch contains a dot
          behaves like repository branch
            returns the repository branch
            HEAD request
              returns 204 No Content
              returns 404 Not Found
            when branch does not exist
              behaves like 404 response
                returns 404
            when the branch refname is invalid
              behaves like 400 response
                returns 400
            when repository is disabled
              behaves like 404 response
                returns 404
            when branch is ambiguous
              behaves like 404 response
                returns 404
            when repository does not exist
              behaves like 404 response
                returns 404
    when authenticated as a developer and branch is protected
      returns that the current user cannot push
      behaves like repository branch
        returns the repository branch
        HEAD request
          returns 204 No Content
          returns 404 Not Found
        when branch does not exist
          behaves like 404 response
            returns 404
        when the branch refname is invalid
          behaves like 400 response
            returns 400
        when repository is disabled
          behaves like 404 response
            returns 404
        when branch is ambiguous
          behaves like 404 response
            returns 404
        when repository does not exist
          behaves like 404 response
            returns 404
    when authenticated as a guest
      behaves like 403 response
        returns 403
  PUT /projects/:id/repository/branches/:branch/protect
    when unauthenticated and project is private
      behaves like 404 response
        returns 404
    when authenticated as a guest
      behaves like 403 response
        returns 403
    when authenticated as a maintainer
      when a protected branch doesn't already exist
        behaves like repository new protected branch
          protects a single branch
          protects a single branch and developers can push
          protects a single branch and developers can merge
          protects a single branch and developers can push and merge
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
        when branch contains a dot
          behaves like repository new protected branch
            protects a single branch
            protects a single branch and developers can push
            protects a single branch and developers can merge
            protects a single branch and developers can push and merge
            when branch does not exist
              behaves like 404 response
                returns 404
            when the branch refname is invalid
              behaves like 400 response
                returns 400
            when repository is disabled
              behaves like 404 response
                returns 404
        when branch contains a slash
          behaves like 404 response
            returns 404
        when branch contains an escaped slash
          behaves like repository new protected branch
            protects a single branch
            protects a single branch and developers can push
            protects a single branch and developers can merge
            protects a single branch and developers can push and merge
            when branch does not exist
              behaves like 404 response
                returns 404
            when the branch refname is invalid
              behaves like 400 response
                returns 400
            when repository is disabled
              behaves like 404 response
                returns 404
        requesting with the escaped project full path
          behaves like repository new protected branch
            protects a single branch
            protects a single branch and developers can push
            protects a single branch and developers can merge
            protects a single branch and developers can push and merge
            when branch does not exist
              behaves like 404 response
                returns 404
            when the branch refname is invalid
              behaves like 400 response
                returns 400
            when repository is disabled
              behaves like 404 response
                returns 404
          when branch contains a dot
            behaves like repository new protected branch
              protects a single branch
              protects a single branch and developers can push
              protects a single branch and developers can merge
              protects a single branch and developers can push and merge
              when branch does not exist
                behaves like 404 response
                  returns 404
              when the branch refname is invalid
                behaves like 400 response
                  returns 400
              when repository is disabled
                behaves like 404 response
                  returns 404
      when protected branch already exists
        when developers can push and merge
          updates that a developer cannot push or merge
        when developers cannot push or merge
          updates that a developer can push and merge
  PUT /projects/:id/repository/branches/:branch/unprotect
    when unauthenticated and project is private
      behaves like 404 response
        returns 404
    when authenticated as a guest
      behaves like 403 response
        returns 403
    when authenticated as a maintainer
      behaves like repository unprotected branch
        when branch is protected
          unprotects a single branch
        when branch is not protected
          returns a single branch response
        when branch does not exist
          behaves like 404 response
            returns 404
        when the branch refname is invalid
          behaves like 400 response
            returns 400
        when repository is disabled
          behaves like 404 response
            returns 404
      when branch contains a dot
        behaves like repository unprotected branch
          when branch is protected
            unprotects a single branch
          when branch is not protected
            returns a single branch response
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
      when branch contains a slash
        behaves like 404 response
          returns 404
      when branch contains an escaped slash
        behaves like repository unprotected branch
          when branch is protected
            unprotects a single branch
          when branch is not protected
            returns a single branch response
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
      requesting with the escaped project full path
        behaves like repository unprotected branch
          when branch is protected
            unprotects a single branch
          when branch is not protected
            returns a single branch response
          when branch does not exist
            behaves like 404 response
              returns 404
          when the branch refname is invalid
            behaves like 400 response
              returns 400
          when repository is disabled
            behaves like 404 response
              returns 404
        when branch contains a dot
          behaves like repository unprotected branch
            when branch is protected
              unprotects a single branch
            when branch is not protected
              returns a single branch response
            when branch does not exist
              behaves like 404 response
                returns 404
            when the branch refname is invalid
              behaves like 400 response
                returns 400
            when repository is disabled
              behaves like 404 response
                returns 404
  POST /projects/:id/repository/branches
    returns 400 if branch name is invalid
    returns 400 if branch already exists
    returns 400 if ref name is invalid
    when unauthenticated and project is private
      behaves like 404 response
        returns 404
    when authenticated as a guest
      behaves like 403 response
        returns 403
    when authenticated as a maintainer
      when a protected branch doesn't already exist
        behaves like repository new branch
          creates a new branch
          when repository is disabled
            behaves like 404 response
              returns 404
        requesting with the escaped project full path
          behaves like repository new branch
            creates a new branch
            when repository is disabled
              behaves like 404 response
                returns 404
  DELETE /projects/:id/repository/branches/:branch
    removes branch
    removes a branch with dots in the branch name
    returns 404 if branch not exists
    when the branch refname is invalid
      behaves like 400 response
        returns 400
    behaves like 412 response
      for a modified resource
        returns 412 with a JSON error
      for an unmodified resource
        returns 204 with an empty body
  DELETE /projects/:id/repository/merged_branches
    returns 202 with json body
    returns a 403 error if guest

Rack Attack global throttles
  unauthenticated API requests
    behaves like rate-limited unauthenticated requests
      when the throttle is enabled
        rejects requests over the rate limit
        allows requests after throttling and then waiting for the next period
        counts requests from different IPs separately
        logs RackAttack info into structured logs
        with custom response text
          rejects requests over the rate limit
        when the request is not matched by the throttle
          does not throttle the requests
        when the request is to the api internal endpoints
          allows requests over the rate limit
        when the request is authenticated by a runner token
          does not count as unauthenticated
        when the request is to a health endpoint
          does not throttle the requests
        when the request is to a container registry notification endpoint
          does not throttle the requests
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
      when the throttle is disabled
        allows requests over the rate limit
  unauthenticated web requests
    behaves like rate-limited unauthenticated requests
      when the throttle is enabled
        rejects requests over the rate limit
        allows requests after throttling and then waiting for the next period
        counts requests from different IPs separately
        logs RackAttack info into structured logs
        with custom response text
          rejects requests over the rate limit
        when the request is not matched by the throttle
          does not throttle the requests
        when the request is to the api internal endpoints
          allows requests over the rate limit
        when the request is authenticated by a runner token
          does not count as unauthenticated
        when the request is to a health endpoint
          does not throttle the requests
        when the request is to a container registry notification endpoint
          does not throttle the requests
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
      when the throttle is disabled
        allows requests over the rate limit
  API requests from the frontend
    when unauthenticated
      behaves like rate-limited frontend API requests
        with a CSRF token
          uses the rate limit for web requests
          without a CSRF session
            always uses the rate limit for API requests
        without a CSRF token
          uses the rate limit for API requests
    when authenticated
      behaves like rate-limited frontend API requests
        with a CSRF token
          uses the rate limit for web requests
          without a CSRF session
            always uses the rate limit for API requests
        without a CSRF token
          uses the rate limit for API requests
  API requests authenticated with personal access token
    with the token in the query string
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with the token in the headers
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with the token in the OAuth headers
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with the token in basic auth
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with a read_api scope
      with the token in the headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      with the token in the OAuth headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
  API requests authenticated with OAuth token
    with the token in the query string
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with the token in the headers
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with a read_api scope
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
  "web" (non-API) requests authenticated with RSS token
    with the token in the query string
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
  web requests authenticated with regular login
    behaves like rate-limited web authenticated requests
      when the throttle is enabled
        rejects requests over the rate limit
        does not reject requests if the user is in the allowlist
        allows requests after throttling and then waiting for the next period
        counts requests from different users separately, even from the same IP
        counts all requests from the same user, even via different IPs
        logs RackAttack info into structured logs
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
      when the throttle is disabled
        allows requests over the rate limit
  protected paths
    unauthenticated requests
      when protected paths throttle is disabled
        allows requests over the rate limit
      when protected paths throttle is enabled
        rejects requests over the rate limit
        allows non-POST requests to protected paths over the rate limit
        allows POST requests to unprotected paths over the rate limit
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
    API requests authenticated with personal access token
      with the token in the query string
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      with the token in the headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
    web requests authenticated with regular login
      behaves like rate-limited web authenticated requests
        when the throttle is enabled
          rejects requests over the rate limit
          does not reject requests if the user is in the allowlist
          allows requests after throttling and then waiting for the next period
          counts requests from different users separately, even from the same IP
          counts all requests from the same user, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
  protected paths for get
    unauthenticated requests
      when protected paths throttle is disabled
        allows requests over the rate limit
      when protected paths throttle is enabled
        rejects requests over the rate limit
        allows GET requests to unprotected paths over the rate limit
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
    API requests authenticated with personal access token
      with the token in the query string
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      with the token in the headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
    web requests authenticated with regular login
      behaves like rate-limited web authenticated requests
        when the throttle is enabled
          rejects requests over the rate limit
          does not reject requests if the user is in the allowlist
          allows requests after throttling and then waiting for the next period
          counts requests from different users separately, even from the same IP
          counts all requests from the same user, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
  Packages API
    unauthenticated
      when unauthenticated packages api throttle is disabled
        allows requests over the rate limit
        when unauthenticated api throttle is enabled
          rejects requests over the unauthenticated api rate limit
        when unauthenticated web throttle is enabled
          ignores unauthenticated web throttle
      when unauthenticated packages api throttle is enabled
        rejects requests over the rate limit
        when unauthenticated api throttle is lower
          ignores unauthenticated api throttle
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
    authenticated
      with the token in the query string
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      with the token in the headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      precedence over authenticated api throttle
        when authenticated packages api throttle is enabled
          when authenticated api throttle is lower
            ignores authenticated api throttle
        when authenticated packages api throttle is disabled
          when authenticated api throttle is enabled
            rejects requests over the authenticated api rate limit
      authenticated via deploy token headers
        behaves like rate-limited deploy-token-authenticated requests
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
  dependency proxy
    getting a manifest
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    getting a blob
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
  authenticated git lfs requests
    with regular login
      behaves like rate-limited web authenticated requests
        when the throttle is enabled
          rejects requests over the rate limit
          does not reject requests if the user is in the allowlist
          allows requests after throttling and then waiting for the next period
          counts requests from different users separately, even from the same IP
          counts all requests from the same user, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    with the token in the headers
      behaves like rate-limited user based token-authenticated requests
        when the throttle is enabled
          does not reject requests if the user is in the allowlist
        when the throttle is enabled
          rejects requests over the rate limit
          allows requests after throttling and then waiting for the next period
          counts requests from different requesters separately, even from the same IP
          counts all requests from the same requesters, even via different IPs
          logs RackAttack info into structured logs
          behaves like tracking when dry-run mode is set
            does not throttle the requests when `*` is configured
            logs RackAttack info into structured logs
            when configured with the the throttled name in a list
              does not throttle
        when the throttle is disabled
          allows requests over the rate limit
    precedence over authenticated web throttle
      when authenticated git lfs throttle is enabled
        when authenticated web throttle is lower
          ignores authenticated web throttle
      when authenticated git lfs throttle is disabled
        when authenticated web throttle is enabled
          rejects requests over the authenticated web rate limit
  Files API
    unauthenticated
      when unauthenticated files api throttle is disabled
        allows requests over the rate limit
        when unauthenticated api throttle is enabled
          rejects requests over the unauthenticated api rate limit
        when unauthenticated web throttle is enabled
          ignores unauthenticated web throttle
      when unauthenticated files api throttle is enabled
        rejects requests over the rate limit
        when unauthenticated api throttle is lower
          ignores unauthenticated api throttle
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
    authenticated
      with the token in the query string
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      with the token in the headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      precedence over authenticated api throttle
        when authenticated files api throttle is enabled
          when authenticated api throttle is lower
            ignores authenticated api throttle
        when authenticated files api throttle is disabled
          when authenticated api throttle is enabled
            rejects requests over the authenticated api rate limit
  Deprecated API
    unauthenticated
      when unauthenticated deprecated api throttle is disabled
        allows requests over the rate limit
        when unauthenticated api throttle is enabled
          rejects requests over the unauthenticated api rate limit
        when unauthenticated web throttle is enabled
          ignores unauthenticated web throttle
      when unauthenticated deprecated api throttle is enabled
        rejects requests over the rate limit
        when group endpoint is given with_project=false
          permits requests over the rate limit
        when unauthenticated api throttle is lower
          ignores unauthenticated api throttle
        behaves like tracking when dry-run mode is set
          does not throttle the requests when `*` is configured
          logs RackAttack info into structured logs
          when configured with the the throttled name in a list
            does not throttle
    authenticated
      with the token in the query string
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      with the token in the headers
        behaves like rate-limited user based token-authenticated requests
          when the throttle is enabled
            does not reject requests if the user is in the allowlist
          when the throttle is enabled
            rejects requests over the rate limit
            allows requests after throttling and then waiting for the next period
            counts requests from different requesters separately, even from the same IP
            counts all requests from the same requesters, even via different IPs
            logs RackAttack info into structured logs
            behaves like tracking when dry-run mode is set
              does not throttle the requests when `*` is configured
              logs RackAttack info into structured logs
              when configured with the the throttled name in a list
                does not throttle
          when the throttle is disabled
            allows requests over the rate limit
      precedence over authenticated api throttle
        when authenticated deprecated api throttle is enabled
          when authenticated api throttle is lower
            ignores authenticated api throttle
        when authenticated deprecated api throttle is disabled
          when authenticated api throttle is enabled
            rejects requests over the authenticated api rate limit
  throttle bypass header
    without the bypass header set
      behaves like reject requests over the rate limit
        rejects requests over the rate limit
    with bypass header set to 1
      does not throttle
    with bypass header set to some other value
      behaves like reject requests over the rate limit
        rejects requests over the rate limit
  Gitlab::RackAttack::Request#unauthenticated?
    without authentication
      request is unauthenticated
    authenticated by a runner token
      request is authenticated
    authenticated with personal access token
      request is authenticated by token in query string
      request is authenticated by token in the headers
      request is authenticated by token in the OAuth headers
      request is authenticated by token in basic auth
    authenticated with OAuth token
      request is authenticated by token in query string
      request is authenticated by token in the headers
    authenticated with lfs token
      request is authenticated by token in basic auth
      request is not authenticated with API URL
    authenticated with regular login
      request is authenticated after login
      request is not authenticated by credentials in basic auth
      with POST git-upload-pack
        request is authenticated by credentials in basic auth
      with GET info/refs
        request is authenticated by credentials in basic auth

Projects::NotesController
  GET index
    is expected to have request urgency :low
    sets the correct feature category
    passes last_fetched_at from headers to NotesFinder and MergeIntoNotesService
    returns status 400 when last_fetched_at is not present
    when user notes_filter is present
      filters system notes by comments
      returns all notes
      does not merge label event notes
    for a discussion note
      responds with the expected attributes
    for a diff discussion note
      responds with the expected attributes
    for a commit note
      when displayed on a merge request
        responds with the expected attributes
      when displayed on the commit
        responds with the expected attributes
        sets the correct feature category
        when user cannot read commit
          renders 404
    for a snippet note
      responds with the expected attributes
      sets the correct feature category
    for a merge request note
      responds with the expected attributes
      sets the correct feature category
    with cross-reference system note
      filters notes that the user should not see
      does not result in N+1 queries
  POST create
    is expected to have request urgency :low
    making the creation request
      sets the correct feature category
      on an issue
        sets the correct feature category
      on a commit
        sets the correct feature category
      on a project snippet
        sets the correct feature category
      the project is publically available
        for HTML
          returns status 302
        for JSON
          returns status 200 for json
      the note does not have commands_only errors
        for empty note
          returns status 422 for json
      the project is a private project
        format is
          returns status 404
        format is json
          returns status 404
    the user is a developer on a private project
      HTML requests
        returns status 302 (redirect)
      JSON requests
        returns status 200
      the return_discussion param is set
        returns discussion JSON when the return_discussion param is set
      when creating a confidential note
        when parameter is not provided
          sets `confidential` and `internal` to `false` in JSON response
        when is not a confidential note
          when using the `internal` parameter
            sets `confidential` and `internal` to `false` in JSON response
          when using deprecated `confidential` parameter
            sets `confidential` and `internal` to `false` in JSON response
        when is a confidential note
          when using the `internal` parameter
            sets `confidential` and `internal` to `true` in JSON response
          when using deprecated `confidential` parameter
            sets `confidential` and `internal` to `true` in JSON response
          when `internal` parameter is `true` and `confidential` parameter is `false`
            uses the `internal` param as source of truth
      when creating a note with quick actions
        with commands that return changes
          includes changes in commands_changes
          includes command_names
        with commands that do not return changes
          does not include changes in commands_changes
          includes command_names
        with commands that return an error
          returns status 422 with error message
    when the internal project prohibits non-members from accessing merge requests
      prevents a non-member user from creating a note on one of the project's merge requests
      when the user is a team member
        can add comments
      when the request includes a :in_reply_to_discussion_id designed to fool us
        prevents the request from adding notes to the spoofed discussion
        returns an error to the user
    when the public project prohibits non-members from accessing merge requests
      prevents a non-member user from creating a note on one of the project's merge requests
      when the user is a team member
        can add comments
    when merge_request_diff_head_sha present
      returns status 302 for html
    when creating a comment on a commit with SHA1 starting with a large number
      creates a note successfully
    when creating a commit comment from an MR fork
      when the note_project_id is not correct
        returns a 404
      when the user has no access to the fork
        returns a 404
      when the user has access to the fork
        is successful
        creates the note
    when target_id and noteable_id do not match
      uses target_id and ignores noteable_id
    when the merge request discussion is locked
      when a noteable is not found
        returns 404 status
      when a user is a team member
        returns 302 status for html
        returns 200 status for json
        creates a new note
      when a user is not a team member
        returns 404 status
        does not create a new note
    behaves like create notes request exceeding rate limit
      allows user in allow-list to create notes, even if the case is different
      when rate limiter enabled
        logs request and declines it when endpoint called more than the threshold
      when rate limiter is disabled
        does not log request and does not block the request
  PUT update
    is expected to have request urgency :low
    when the note is valid
      updates the note
      returns status 200
    when the issue is confidential and the user has guest permissions
      disallows edits
      returns status 404
    when there are ActiveRecord validation errors
      does not update the note
      returns status 422
  DELETE destroy
    is expected to have request urgency :low
    user is the author of a note
      returns status 200 for html
      deletes the note
    user is not the author of a note
      returns status 404
  POST toggle_award_emoji
    is expected to have request urgency :low
    toggles the award emoji
    removes the already awarded emoji
    marks Todos on the Noteable as done
  resolving and unresolving
    POST resolve
      is expected to have request urgency :low
      when the user is not authorized to resolve the note
        returns status 404
      when the user is authorized to resolve the note
        when the note is not resolvable
          returns status 404
        when the note is resolvable
          resolves the note
          sends notifications if all discussions are resolved
          returns the name of the resolving user
          returns status 200
    DELETE unresolve
      is expected to have request urgency :low
      when the user is not authorized to resolve the note
        returns status 404
      when the user is authorized to resolve the note
        when the note is not resolvable
          returns status 404
        when the note is resolvable
          unresolves the note
          returns status 200
  GET outdated_line_change
    successfully renders expected JSON response
    is expected to have request urgency :low

API::Wikis
  GET /projects/:id/wikis
    when wiki is disabled
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 403 Forbidden
    when wiki is available only for team members
      when user is guest
        returns 404 Project Not Found
      when user is developer
        return the empty list of wiki pages
        when wiki has pages
          returns the list of wiki pages without content
          returns the list of wiki pages with content
      when user is maintainer
        return the empty list of wiki pages
        when wiki has pages
          returns the list of wiki pages without content
          returns the list of wiki pages with content
    when wiki is available for everyone with access
      when user is guest
        returns 404 Project Not Found
      when user is developer
        return the empty list of wiki pages
        when wiki has pages
          returns the list of wiki pages without content
          returns the list of wiki pages with content
      when user is maintainer
        return the empty list of wiki pages
        when wiki has pages
          returns the list of wiki pages without content
          returns the list of wiki pages with content
  GET /projects/:id/wikis/:slug
    when wiki is disabled
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 403 Forbidden
    when wiki is available only for team members
      when user is guest
        returns 404 Project Not Found
      when user is developer
        behaves like returns wiki page
          is expected to eq "Page 5"
        when render param is false
          behaves like returns wiki page
            is expected to eq "Page 6"
        when render param is true
          behaves like returns wiki page
            is expected to eq "Page 7"
        when wiki page has versions
          when version param is not present
            retrieves the last version
          when version param is set
            retrieves the specific page version
            when version param is not valid or inexistent
              behaves like wiki API 404 Wiki Page Not Found
                returns 404 Wiki Page Not Found
        when page is not existing
          returns 404 Wiki Page Not Found
      when user is maintainer
        behaves like returns wiki page
          is expected to eq "Page 11"
        when render param is false
          behaves like returns wiki page
            is expected to eq "Page 12"
        when render param is true
          behaves like returns wiki page
            is expected to eq "Page 13"
        when wiki page has versions
          when version param is not present
            retrieves the last version
          when version param is set
            retrieves the specific page version
            when version param is not valid or inexistent
              behaves like wiki API 404 Wiki Page Not Found
                returns 404 Wiki Page Not Found
        when page is not existing
          returns 404 Wiki Page Not Found
    when wiki is available for everyone with access
      when user is guest
        returns 404 Project Not Found
      when user is developer
        behaves like returns wiki page
          is expected to eq "Page 18"
        when render param is false
          behaves like returns wiki page
            is expected to eq "Page 19"
        when render param is true
          behaves like returns wiki page
            is expected to eq "Page 20"
        when wiki page has versions
          when version param is not present
            retrieves the last version
          when version param is set
            retrieves the specific page version
            when version param is not valid or inexistent
              behaves like wiki API 404 Wiki Page Not Found
                returns 404 Wiki Page Not Found
        when page is not existing
          returns 404 Wiki Page Not Found
      when user is maintainer
        behaves like returns wiki page
          is expected to eq "Page 24"
        when render param is false
          behaves like returns wiki page
            is expected to eq "Page 25"
        when render param is true
          behaves like returns wiki page
            is expected to eq "Page 26"
        when wiki page has versions
          when version param is not present
            retrieves the last version
          when version param is set
            retrieves the specific page version
            when version param is not valid or inexistent
              behaves like wiki API 404 Wiki Page Not Found
                returns 404 Wiki Page Not Found
        when page is not existing
          returns 404 Wiki Page Not Found
      when content contains a reference
        expands the reference in the content
  POST /projects/:id/wikis
    when wiki is disabled
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 403 Forbidden
    when wiki is available only for team members
      when user is guest
        returns 404 Project Not Found
      when user is developer
        creates the wiki page
        responds with validation error on empty title
        responds with validation error on empty content
      when user is maintainer
        creates the wiki page
        responds with validation error on empty title
        responds with validation error on empty content
    when wiki is available for everyone with access
      when user is guest
        returns 404 Project Not Found
      when user is developer
        creates the wiki page
        responds with validation error on empty title
        responds with validation error on empty content
      when user is maintainer
        creates the wiki page
        responds with validation error on empty title
        responds with validation error on empty content
  PUT /projects/:id/wikis/:slug
    when wiki is disabled
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 403 Forbidden
    when wiki is available only for team members
      when user is guest
        returns 404 Project Not Found
      when user is developer
        updates the wiki page
        updates with wiki with missing title
        updates with wiki with missing content
        updates with wiki with missing format
        when page is not existing
          returns 404 Wiki Page Not Found
      when user is maintainer
        updates the wiki page
        updates with wiki with missing title
        updates with wiki with missing content
        updates with wiki with missing format
        when page is not existing
          returns 404 Wiki Page Not Found
    when wiki is available for everyone with access
      when user is guest
        returns 404 Project Not Found
      when user is developer
        updates the wiki page
        updates with wiki with missing title
        updates with wiki with missing content
        updates with wiki with missing format
        when page is not existing
          returns 404 Wiki Page Not Found
      when user is maintainer
        updates the wiki page
        updates with wiki with missing title
        updates with wiki with missing content
        updates with wiki with missing format
        when page is not existing
          returns 404 Wiki Page Not Found
    when wiki belongs to a group project
      updates the wiki page
      updates with wiki with missing title
      updates with wiki with missing content
      updates with wiki with missing format
  DELETE /projects/:id/wikis/:slug
    when wiki is disabled
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 403 Forbidden
    when wiki is available only for team members
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 204 No Content
    when wiki is available for everyone with access
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 204 No Content
        when page is not existing
          returns 404 Wiki Page Not Found
      when there is an error deleting the page
        returns 422
    when wiki belongs to a group project
      returns 204 No Content
  POST /projects/:id/wikis/attachments
    when wiki is disabled
      when user is guest
        returns 404 Project Not Found
      when user is developer
        returns 403 Forbidden
      when user is maintainer
        returns 403 Forbidden
    when wiki is available only for team members
      when user is guest
        returns 404 Project Not Found
      when user is developer
        pushes attachment to the wiki repository
        responds with validation error on empty file
        responds with validation error on invalid temp file
        is backward compatible with regular multipart uploads
      when user is maintainer
        pushes attachment to the wiki repository
        responds with validation error on empty file
        responds with validation error on invalid temp file
        is backward compatible with regular multipart uploads
    when wiki is available for everyone with access
      when user is guest
        returns 404 Project Not Found
      when user is developer
        pushes attachment to the wiki repository
        responds with validation error on empty file
        responds with validation error on invalid temp file
        is backward compatible with regular multipart uploads
      when user is maintainer
        pushes attachment to the wiki repository
        responds with validation error on empty file
        responds with validation error on invalid temp file
        is backward compatible with regular multipart uploads

API::UsageDataQueries
  GET /usage_data/usage_data_queries
    with authentication
      returns queries if user is admin
      returns forbidden if user is not admin
      behaves like GET request permissions for admin mode
        behaves like when admin
          behaves like makes request
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:25: warning: already initialized constant MACROS_MARKER
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:25: warning: previous definition of MACROS_MARKER was here
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:27: warning: already initialized constant DO_NOT_SPLIT
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:27: warning: previous definition of DO_NOT_SPLIT was here
            returns
          behaves like makes request
            returns
        behaves like when user
          returns
          behaves like makes request
            returns
    without authentication
      returns unauthorized
    when feature_flag is disabled
      returns not_found for admin
      returns forbidden for non-admin
    when querying sql metrics
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:25: warning: already initialized constant MACROS_MARKER
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:25: warning: previous definition of MACROS_MARKER was here
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:27: warning: already initialized constant DO_NOT_SPLIT
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:27: warning: previous definition of DO_NOT_SPLIT was here
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:25: warning: already initialized constant MACROS_MARKER
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:25: warning: previous definition of MACROS_MARKER was here
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:27: warning: already initialized constant DO_NOT_SPLIT
/builds/gitlab-org/gitlab/vendor/ruby/3.0.0/gems/ohai-17.9.0/lib/ohai/plugins/rpm.rb:27: warning: previous definition of DO_NOT_SPLIT was here
      matches the generated query

getting an issue list for a project
  behaves like graphql issue list request spec
    includes a web_url
    includes discussion locked
    behaves like a working graphql query
      returns a successful response
    filters
      when filtering by assignees
        when both assignee_username filters are provided
          returns a mutually exclusive param error
        when both assignee_username and assignee_wildcard_id filters are provided
          returns a mutually exclusive param error
        when filtering by assignee_wildcard_id
          when filtering for all issues with assignees
            returns all issues with assignees
          when filtering for issues without assignees
            returns all issues without assignees
        when filtering by a negated argument
          returns correctly filtered issues
      when filtering by unioned arguments
        when filtering by assignees
          returns correctly filtered issues
        when filtering by labels
          returns correctly filtered issues
        when argument is blank
          does not raise an error
        when feature flag is disabled
          returns an error
      when filtering by a blank negated argument
        does not raise an error
      when filtering by reaction emoji
        value: "thumbsup", issue_list: lazy { voted_issues }
          returns correctly filtered issues
        value: "ANY", issue_list: lazy { voted_issues }
          returns correctly filtered issues
        value: "any", issue_list: lazy { voted_issues }
          returns correctly filtered issues
        value: "AnY", issue_list: lazy { voted_issues }
          returns correctly filtered issues
        value: "NONE", issue_list: lazy { no_award_issues }
          returns correctly filtered issues
        value: "thumbsdown", issue_list: lazy { [] }
          returns correctly filtered issues
      when filtering by search
        behaves like query with a search term
          returns only matching issuables
      when filtering by confidentiality
        when fetching confidential issues
          returns only confidential issues
          when user cannot see confidential issues
            returns an empty list
        when fetching non-confidential issues
          returns only non-confidential issues
          when user cannot see confidential issues
            returns an empty list
    sorting and pagination
      when sorting by severity
        when ascending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
        when descending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
      when sorting by priority
        when ascending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
        when descending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
      when sorting by due date
        when ascending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
        when descending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
      when sorting by relative position
        when ascending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
                when last and sort params are present
                  fetches last elements without error
      when sorting by label priority
        when ascending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
        when descending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
      when sorting by milestone due date
        when ascending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
        when descending
          behaves like sorted paginated query
            behaves like requires variables
              shared example requires variables to be set
            
              when sorting
                sorts correctly
                when paginating
                  paginates correctly
    N+1 query checks
      when requesting `user_notes_count` and `user_discussions_count`
        prevents N+1 queries
      when requesting `merge_requests_count`
        prevents N+1 queries
      when requesting `timelogs`
        prevents N+1 queries
      when requesting `closed_as_duplicate_of`
        prevents N+1 queries
      when award emoji votes
        prevents N+1 queries
      when requesting labels
        prevents N+1 queries
    when confidential issues exist
      when user can see confidential issues
        includes confidential issues
      when user cannot see confidential issues
        does not include confidential issues
    when limiting the number of results
      is expected to check permissions on the first issue only
      behaves like a working graphql query
        returns a successful response
        only returns N issues
      when no limit is provided
        returns all issues
    when the user does not have access to the issue
      returns no issues
    when fetching external participants
      returns the email address
      when user does not have access to view emails
        obfuscates the email address
    when fetching escalation status
      returns the escalation status values
      avoids N+1 queries
    when fetching alert management alert
      avoids N+1 queries
      returns the alert data
      returns the alerts data
    when fetching customer_relations_contacts
      avoids N+1 queries
    when fetching labels
      avoids N+1 queries
    when fetching assignees
      avoids N+1 queries
    when selecting `related_merge_requests`
      limits the field to 1 execution

Projects::MergeRequests::DraftsController
  GET #index
    list merge request draft notes for current user
  POST #create
    creates a draft note
    creates draft note with position
    creates a draft note with quick actions
    without permissions
      does not allow draft note creation
    in a thread
      creates draft note as a reply
      creates a draft note that will resolve a thread
      cannot create more than one draft note per thread
    commit_id is present
      value is a commit sha
        creates the draft note with commit ID
      value is "undefined"
        creates the draft note with nil commit ID
    when the draft note is invalid
      does not allow draft note creation
      returns status 422
  PUT #update
    updates the draft
    without permissions
      does not allow editing draft note belonging to someone else
    when the draft note is invalid
      does not update the draft
      returns status 422
  POST #publish
    publishes draft notes with position
    does nothing if there are no draft notes
    publishes a draft note with quick actions and applies them
    publishes all draft notes for an MR
    can publish just a single draft note
    without permissions
      when note belongs to someone else
        behaves like action that does not allow publishing draft note
          does not allow publishing draft note
      when merge request discussion is locked
        behaves like action that does not allow publishing draft note
          does not allow publishing draft note
    when PublishService errors
      returns message and 500 response
    when publishing drafts in a thread
      resolves a thread if the draft note resolves it
      unresolves a thread if the draft note unresolves it
    publish with note
      creates note
      does not create note when note param is empty
      tracks merge request activity
    approve merge request
      approves merge request
      does not approve merge request
      tracks merge request activity
      when merge request is already approved by user
        does return 200
  DELETE #destroy
    destroys the draft note when ID is given
    without permissions
      does not allow destroying a draft note belonging to someone else
    without permissions
      does not allow editing draft note belonging to someone else
  DELETE #discard
    deletes all DraftNotes belonging to a user in a Merge Request
    without permissions
      does not destroys a draft note belonging to someone else

API::HelmPackages
  GET /api/v4/projects/:id/packages/helm/:channel/index.yaml
    with a project id
      behaves like handling helm chart index requests
        with valid project
          personal token
            visibility: :public, user_role: :guest, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type guest
                  returns a valid YAML response
            visibility: :public, user_role: :not_a_member, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type not_a_member
                  returns a valid YAML response
            visibility: :public, user_role: :anonymous, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type anonymous
                  returns a valid YAML response
            visibility: :private, user_role: :reporter, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type reporter
                  returns a valid YAML response
            visibility: :private, user_role: :guest, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
              behaves like rejects helm packages access
                for user type guest
                  behaves like returning response status
                    returns forbidden
            visibility: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
              behaves like rejects helm packages access
                for user type not_a_member
                  behaves like returning response status
                    returns not_found
            visibility: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
              behaves like rejects helm packages access
                for user type anonymous
                  has the correct response header
                  behaves like returning response status
                    returns unauthorized
          with access to package registry for everyone
            behaves like process helm service index request
              for user type anonymous
                returns a valid YAML response
          when an invalid token is passed
            behaves like returning response status
              returns unauthorized
          with job token
            visibility: :public, user_role: :guest, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type guest
                  returns a valid YAML response
            visibility: :public, user_role: :not_a_member, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type not_a_member
                  returns a valid YAML response
            visibility: :public, user_role: :anonymous, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type anonymous
                  returns a valid YAML response
            visibility: :private, user_role: :reporter, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type reporter
                  returns a valid YAML response
            visibility: :private, user_role: :guest, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
              behaves like rejects helm packages access
                for user type guest
                  behaves like returning response status
                    returns forbidden
            visibility: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
              behaves like rejects helm packages access
                for user type not_a_member
                  behaves like returning response status
                    returns not_found
            visibility: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
              behaves like rejects helm packages access
                for user type anonymous
                  has the correct response header
                  behaves like returning response status
                    returns unauthorized
        behaves like deploy token for package GET requests
          with deploy token headers
            valid token
              behaves like returning response status
                returns success
            invalid token
              behaves like returning response status
                returns unauthorized
        behaves like rejects helm access with unknown project id
          with an unknown project
            as anonymous
              behaves like rejects helm packages access
                for user type anonymous
                  has the correct response header
                  behaves like returning response status
                    returns unauthorized
            as authenticated user
              behaves like rejects helm packages access
                for user type anonymous
                  behaves like returning response status
                    returns not_found
    with an url encoded project id
      behaves like handling helm chart index requests
        with valid project
          personal token
            visibility: :public, user_role: :guest, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type guest
                  returns a valid YAML response
            visibility: :public, user_role: :not_a_member, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type not_a_member
                  returns a valid YAML response
            visibility: :public, user_role: :anonymous, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type anonymous
                  returns a valid YAML response
            visibility: :private, user_role: :reporter, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type reporter
                  returns a valid YAML response
            visibility: :private, user_role: :guest, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
              behaves like rejects helm packages access
                for user type guest
                  behaves like returning response status
                    returns forbidden
            visibility: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
              behaves like rejects helm packages access
                for user type not_a_member
                  behaves like returning response status
                    returns not_found
            visibility: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
              behaves like rejects helm packages access
                for user type anonymous
                  has the correct response header
                  behaves like returning response status
                    returns unauthorized
          with access to package registry for everyone
            behaves like process helm service index request
              for user type anonymous
                returns a valid YAML response
          when an invalid token is passed
            behaves like returning response status
              returns unauthorized
          with job token
            visibility: :public, user_role: :guest, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type guest
                  returns a valid YAML response
            visibility: :public, user_role: :not_a_member, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type not_a_member
                  returns a valid YAML response
            visibility: :public, user_role: :anonymous, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type anonymous
                  returns a valid YAML response
            visibility: :private, user_role: :reporter, shared_examples_name: "process helm service index request", expected_status: :success
              behaves like process helm service index request
                for user type reporter
                  returns a valid YAML response
            visibility: :private, user_role: :guest, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
              behaves like rejects helm packages access
                for user type guest
                  behaves like returning response status
                    returns forbidden
            visibility: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
              behaves like rejects helm packages access
                for user type not_a_member
                  behaves like returning response status
                    returns not_found
            visibility: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
              behaves like rejects helm packages access
                for user type anonymous
                  has the correct response header
                  behaves like returning response status
                    returns unauthorized
        behaves like deploy token for package GET requests
          with deploy token headers
            valid token
              behaves like returning response status
                returns success
            invalid token
              behaves like returning response status
                returns unauthorized
        behaves like rejects helm access with unknown project id
          with an unknown project
            as anonymous
              behaves like rejects helm packages access
                for user type anonymous
                  has the correct response header
                  behaves like returning response status
                    returns unauthorized
            as authenticated user
              behaves like rejects helm packages access
                for user type anonymous
                  behaves like returning response status
                    returns not_found
    with dot in channel
      behaves like returning response status
        returns success
  GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz
    with valid project
      visibility: :public, user_role: :guest, shared_examples_name: "process helm download content request", expected_status: :success
        behaves like process helm download content request
          for user type guest
            returns expected status and a valid package archive
            behaves like a package tracking event
              creates a gitlab tracking event pull_package
            behaves like bumping the package last downloaded at field
              bumps last_downloaded_at
      visibility: :public, user_role: :not_a_member, shared_examples_name: "process helm download content request", expected_status: :success
        behaves like process helm download content request
          for user type not_a_member
            returns expected status and a valid package archive
            behaves like a package tracking event
              creates a gitlab tracking event pull_package
            behaves like bumping the package last downloaded at field
              bumps last_downloaded_at
      visibility: :public, user_role: :anonymous, shared_examples_name: "process helm download content request", expected_status: :success
        behaves like process helm download content request
          for user type anonymous
            returns expected status and a valid package archive
            behaves like a package tracking event
              creates a gitlab tracking event pull_package
            behaves like bumping the package last downloaded at field
              bumps last_downloaded_at
      visibility: :private, user_role: :reporter, shared_examples_name: "process helm download content request", expected_status: :success
        behaves like process helm download content request
          for user type reporter
            returns expected status and a valid package archive
            behaves like a package tracking event
              creates a gitlab tracking event pull_package
            behaves like bumping the package last downloaded at field
              bumps last_downloaded_at
      visibility: :private, user_role: :guest, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type guest
            behaves like returning response status
              returns forbidden
      visibility: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
        behaves like rejects helm packages access
          for user type not_a_member
            behaves like returning response status
              returns not_found
      visibility: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
        behaves like rejects helm packages access
          for user type anonymous
            has the correct response header
            behaves like returning response status
              returns unauthorized
    with access to package registry for everyone
      behaves like process helm download content request
        for user type anonymous
          returns expected status and a valid package archive
          behaves like a package tracking event
            creates a gitlab tracking event pull_package
          behaves like bumping the package last downloaded at field
            bumps last_downloaded_at
    when an invalid token is passed
      behaves like returning response status
        returns unauthorized
    behaves like deploy token for package GET requests
      with deploy token headers
        valid token
          behaves like returning response status
            returns success
        invalid token
          behaves like returning response status
            returns unauthorized
  POST /api/v4/projects/:id/packages/helm/api/:channel/charts/authorize
    with valid project
      visibility_level: :public, user_role: :developer, shared_examples_name: "process helm workhorse authorization", expected_status: :success
        behaves like process helm workhorse authorization
          for user type developer
            has the proper status and content type
            with a request that bypassed gitlab-workhorse
              behaves like returning response status
                returns forbidden
      visibility_level: :public, user_role: :reporter, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type reporter
            behaves like returning response status
              returns forbidden
      visibility_level: :public, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type not_a_member
            behaves like returning response status
              returns forbidden
      visibility_level: :public, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
        behaves like rejects helm packages access
          for user type anonymous
            has the correct response header
            behaves like returning response status
              returns unauthorized
      visibility_level: :private, user_role: :developer, shared_examples_name: "process helm workhorse authorization", expected_status: :success
        behaves like process helm workhorse authorization
          for user type developer
            has the proper status and content type
            with a request that bypassed gitlab-workhorse
              behaves like returning response status
                returns forbidden
      visibility_level: :private, user_role: :reporter, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type reporter
            behaves like returning response status
              returns forbidden
      visibility_level: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
        behaves like rejects helm packages access
          for user type not_a_member
            behaves like returning response status
              returns not_found
      visibility_level: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
        behaves like rejects helm packages access
          for user type anonymous
            has the correct response header
            behaves like returning response status
              returns unauthorized
    when an invalid token is passed
      behaves like returning response status
        returns unauthorized
    behaves like deploy token for package uploads
      with deploy token headers
        valid token
          behaves like returning response status
            returns success
        invalid token
          behaves like returning response status
            returns unauthorized
    behaves like job token for package uploads
      with job token headers
        valid token
          behaves like returning response status
            returns success
        invalid token
          behaves like returning response status
            returns unauthorized
        invalid user
          behaves like returning response status
            returns success
    behaves like rejects helm access with unknown project id
      with an unknown project
        as anonymous
          behaves like rejects helm packages access
            for user type anonymous
              has the correct response header
              behaves like returning response status
                returns unauthorized
        as authenticated user
          behaves like rejects helm packages access
            for user type anonymous
              behaves like returning response status
                returns not_found
  POST /api/v4/projects/:id/packages/helm/api/:channel/charts
    with valid project
      visibility_level: :public, user_role: :developer, shared_examples_name: "process helm upload", expected_status: :created
        behaves like process helm upload
          for user type developer
            with object storage disabled
              without a file from workhorse
                behaves like returning response status
                  returns bad_request
              with correct params
                behaves like package workhorse uploads
                  without a workhorse header
                    logs an error
                    behaves like returning response status
                      returns forbidden
                behaves like creates helm package files
                  creates package files
                behaves like a package tracking event
                  creates a gitlab tracking event push_package
            with object storage enabled
              and direct upload enabled
                behaves like creates helm package files
                  creates package files
                with invalid remote_id: 123123
                  behaves like returning response status
                    returns forbidden
                with invalid remote_id: ../../123123
                  behaves like returning response status
                    returns forbidden
              and direct upload disabled
                behaves like creates helm package files
                  creates package files
      visibility_level: :public, user_role: :reporter, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type reporter
            behaves like returning response status
              returns forbidden
      visibility_level: :public, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type not_a_member
            behaves like returning response status
              returns forbidden
      visibility_level: :public, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
        behaves like rejects helm packages access
          for user type anonymous
            has the correct response header
            behaves like returning response status
              returns unauthorized
      visibility_level: :private, user_role: :developer, shared_examples_name: "process helm upload", expected_status: :created
        behaves like process helm upload
          for user type developer
            with object storage disabled
              without a file from workhorse
                behaves like returning response status
                  returns bad_request
              with correct params
                behaves like package workhorse uploads
                  without a workhorse header
                    logs an error
                    behaves like returning response status
                      returns forbidden
                behaves like creates helm package files
                  creates package files
                behaves like a package tracking event
                  creates a gitlab tracking event push_package
            with object storage enabled
              and direct upload enabled
                behaves like creates helm package files
                  creates package files
                with invalid remote_id: 123123
                  behaves like returning response status
                    returns forbidden
                with invalid remote_id: ../../123123
                  behaves like returning response status
                    returns forbidden
              and direct upload disabled
                behaves like creates helm package files
                  creates package files
      visibility_level: :private, user_role: :guest, shared_examples_name: "rejects helm packages access", expected_status: :forbidden
        behaves like rejects helm packages access
          for user type guest
            behaves like returning response status
              returns forbidden
      visibility_level: :private, user_role: :not_a_member, shared_examples_name: "rejects helm packages access", expected_status: :not_found
        behaves like rejects helm packages access
          for user type not_a_member
            behaves like returning response status
              returns not_found
      visibility_level: :private, user_role: :anonymous, shared_examples_name: "rejects helm packages access", expected_status: :unauthorized
        behaves like rejects helm packages access
          for user type anonymous
            has the correct response header
            behaves like returning response status
              returns unauthorized
    when an invalid token is passed
      behaves like returning response status
        returns unauthorized
    behaves like deploy token for package uploads
      with deploy token headers
        valid token
          behaves like returning response status
            returns success
        invalid token
          behaves like returning response status
            returns unauthorized
    behaves like job token for package uploads
      with job token headers
        valid token
          creates a package with build info
          behaves like returning response status
            returns success
        invalid token
          behaves like returning response status
            returns unauthorized
        invalid user
          behaves like returning response status
            returns success
    behaves like rejects helm access with unknown project id
      with an unknown project
        as anonymous
          behaves like rejects helm packages access
            for user type anonymous
              has the correct response header
              behaves like returning response status
                returns unauthorized
        as authenticated user
          behaves like rejects helm packages access
            for user type anonymous
              behaves like returning response status
                returns not_found
    file size above maximum limit
      behaves like returning response status
        returns bad_request

OmniauthCallbacksController
  omniauth
    when authentication succeeds
      without signed-in user
        increments Prometheus counter
      with signed-in user
        increments Prometheus counter
    for a deactivated user
      allows sign in
      activates the user
      shows reactivation flash message after logging in
    when sign in is not valid
      renders omniauth error page
    when the user is on the last sign in attempt
      when using a form based provider
        locks the user when sign in fails
      when using a button based provider
        does not lock the user when sign in fails
    when sign in fails
      calls through to the failure handler
      increments Prometheus counter
    when a redirect fragment is provided
      when a redirect url is stored
        redirects with fragment
      when a redirect url with a fragment is stored
        redirects with the new fragment
      when no redirect url is stored
        does not redirect with the fragment
    with strategies
      for github
        allows sign in
        creates an authentication event record
        behaves like known sign in
          when the remote IP and the last sign in IP match
            does not notify the user
            sets/updates the encrypted cookie
          when the remote IP and the last sign in IP do not match
            notifies the user when the cookie is expired
            notifies the user when the cookie is for another user
            does not notify the user when remote IP matches an active session
            does not notify the user when the cookie is present and not expired
            when the cookie is not previously set
              notifies the user
              sets the encrypted cookie
            when notify_on_unknown_sign_in global setting is false
              does not notify the user
              does not set a cookie
        when user has no linked provider
          links identity
          and is not allowed to link the provider
            returns 403
        when a user has 2FA enabled
          when a user is unconfirmed
            redirects to login page
          when a user is confirmed
            returns 200 response
        for sign up
          is allowed
          behaves like Onboarding::Redirectable
            is expected to redirect to "/dashboard/projects"
            when the new user already has any accepted group membership
              redirects to activity group path with a flash message
              when the new user already has more than 1 accepted group membership
                redirects to the last member activity group path without a flash message
              when the member has an orphaned source at the time of registering
                is expected to redirect to "/dashboard/projects"
        when OAuth is disabled
          prevents login via POST
          shows warning when attempting login
          allows linking the disabled provider
          for sign up
            is prevented
      for auth0
        does not allow sign in without extern_uid
      for atlassian_oauth2
        when the user and identity already exist
          allows sign-in
          sets the username and caller_id in the context
        for a new user
          denies sign-in if sign-up is enabled, but block_auto_created_users is set
          accepts sign-in if sign-up is enabled
          denies sign-in if sign-up is not enabled
      for salesforce
        without verified email
          does not allow sign in
        with verified email
          allows sign in
    with snowplow tracking
      when sign_in
        does not track the event
      when sign_up
        tracks the event
  #openid_connect
    allows sign in
    behaves like known sign in
      when the remote IP and the last sign in IP match
        does not notify the user
        sets/updates the encrypted cookie
      when the remote IP and the last sign in IP do not match
        notifies the user when the cookie is expired
        notifies the user when the cookie is for another user
        does not notify the user when remote IP matches an active session
        does not notify the user when the cookie is present and not expired
        when the cookie is not previously set
          notifies the user
          sets the encrypted cookie
        when notify_on_unknown_sign_in global setting is false
          does not notify the user
          does not set a cookie
  #saml
    behaves like known sign in
      when the remote IP and the last sign in IP match
        does not notify the user
        sets/updates the encrypted cookie
      when the remote IP and the last sign in IP do not match
        notifies the user when the cookie is expired
        notifies the user when the cookie is for another user
        does not notify the user when remote IP matches an active session
        does not notify the user when the cookie is present and not expired
        when the cookie is not previously set
          notifies the user
          sets the encrypted cookie
        when notify_on_unknown_sign_in global setting is false
          does not notify the user
          does not set a cookie
    for sign up
      denies login if sign up is enabled, but block_auto_created_users is set
      accepts login if sign up is enabled
      denies login if sign up is not enabled
    with GitLab initiated request
      when worth two factors
        expects user to be signed_in
      when not worth two factors
        expects user to provide second factor
    with IdP initiated request
      lets the user know their account isn't linked yet
      redirects to profile account page
      doesn't link a new identity to the user
      sets the username and caller_id in the context
      with IDP bypass two factor request
        behaves like store provider2FA value in session
          sets the session varible for provider 2FA
          when by_pass_two_factor_for_current_session feature flag is false
            does not set the session variable for provider 2FA
    with a blocked user trying to log in when there are hooks set up
      is expected not to raise Exception
    with a non default SAML provider
      authenticate with SAML module
    with IDP bypass two factor request
      behaves like store provider2FA value in session
        sets the session varible for provider 2FA
        when by_pass_two_factor_for_current_session feature flag is false
          does not set the session variable for provider 2FA
  enable admin mode
    when user and admin mode is requested by the same user
      with a regular user
        cannot be enabled
      with an admin user
        when requested first
          can be enabled
        when not requested first
          cannot be enabled
    when user and admin mode is requested by different users
      with a regular user
        cannot be enabled
      with an admin user
        when requested first
          cannot be enabled
        when not requested first
          cannot be enabled

Projects::EnvironmentsController
  GET index
    when a request for the HTML is made
      responds with status code 200
      expires etag cache to force reload environments list
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    when requesting JSON response for folders
      with default parameters
        responds with a flat payload describing available environments
        handles search option properly
        ignores search option if is shorter than a minimum
        supports search within environment folder name
        sets the polling interval header
        can access stop stale environments feature
          maintainers can access the feature
          when user is a reporter
            reporters cannot access the feature
        when enable_environments_search_within_folder FF is disabled
          ignores name inside folder
        validates latest deployment
          responds with the latest deployment for the environment
      when a folder-based nested structure is requested
        responds with a payload containing the latest environment for each folder
      when requesting available environments scope
        responds with a payload describing available environments
        contains values describing environment scopes sizes
      when requesting stopped environments scope
        responds with a payload describing stopped environments
        contains values describing environment scopes sizes
  GET folder
    when using default format
      responds with HTML
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    when using JSON format
      sorts the subfolders lexicographically
      handles search option properly
  GET show
    with valid id
      responds with a status code 200
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    with invalid id
      responds with a status code 404
  GET new
    responds with a status code 200
    behaves like tracking unique visits
      tracks unique visit if the format is HTML
      tracks unique visit if DNT is not enabled
      does not track unique visit if DNT is enabled
      does not track unique visit if the format is JSON
  GET edit
    responds with a status code 200
    behaves like tracking unique visits
      tracks unique visit if the format is HTML
      tracks unique visit if DNT is not enabled
      does not track unique visit if DNT is enabled
      does not track unique visit if the format is JSON
  PATCH #update
    when environment params are valid
      returns ok and the path to the newly created environment
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    when environment params are invalid
      returns bad request
    when name is passed
      ignores name
  PATCH #stop
    when env not available
      returns 404
    when stop action
      returns job url for a stop action when job is build
      returns pipeline url for a stop action when job is bridge
      returns environment url for multiple stop actions
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    when no stop action
      returns env url
  POST #cancel_auto_stop
    when environment is set as auto-stop
      behaves like successful response for #cancel_auto_stop
        when request is html
          redirects to show page
          expires etag caching
        when request is js
          responds as ok
          expires etag caching
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
      when user is reporter
        shows NOT Found
    when environment is not set as auto-stop
      behaves like failed response for #cancel_auto_stop
        when request is html
          redirects to show page
        when request is js
          responds as unprocessable entity
  GET #terminal
    with valid id
      responds with a status code 200
      loads the terminals for the environment
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    with invalid id
      responds with a status code 404
  GET #terminal_websocket_authorize
    with valid workhorse signature
      and valid id
        returns the first terminal for the environment
      and invalid id
        returns 404
    with invalid workhorse signature
      aborts with an exception
  GET #search
    responds with status code 200
    returns matched results
    when query is review
      returns matched results
    when query is empty
      returns matched results
    when query is review/patch-3
      responds with status code 204
    when query is partially matched in the middle of environment name
      responds with status code 204
    when query contains a wildcard character
      prevents wildcard injection
    when query matches case insensitively
      returns matched results
  POST #create
    when environment params are valid
      returns ok and the path to the newly created environment
      behaves like tracking unique visits
        tracks unique visit if the format is HTML
        tracks unique visit if DNT is not enabled
        does not track unique visit if DNT is enabled
        does not track unique visit if the format is JSON
    when environment params are invalid
      returns bad request

Projects::MergeRequests::CreationsController
  GET new
    merge request that removes a submodule
      renders new merge request widget template
    merge request with some commits
      shows total commits
      with artificial limits
        limits total commits
  GET diffs
    when merge request cannot be created
      does not assign diffs var
  GET pipelines
    renders JSON including serialized pipelines
  GET diff_for_path
    when both branches are in the same project
      disables diff notes
      only renders the diffs for the path given
    when the source branch is in a different project to the target
      when the path exists in the diff
        disables diff notes
        only renders the diffs for the path given
      when the path does not exist in the diff
        returns a 404
  GET #branch_to
    fetches the commit if a user has access
    does not load the commit when the user cannot create_merge_request_in
    does not load the commit when the user cannot read the project
    no target_project_id provided
      selects itself as a target project
      project is a fork
        calls to project defaults to selects a correct target project
  POST create
    creates merge request
    when the merge request is not created from the web ide
      counter is not increased
    when the merge request is created from the web ide
      counter is increased
  GET target_projects
    returns target projects JSON

API::Ci::PipelineSchedules
  GET /projects/:id/pipeline_schedules
    authenticated user with valid permissions
      returns list of pipeline_schedules
      avoids N + 1 queries
      when scope is active
        returns matched pipeline schedules
      when scope is inactive
        returns matched pipeline schedules
    authenticated user with invalid permissions
      does not return pipeline_schedules list
    unauthenticated user
      does not return pipeline_schedules list
  GET /projects/:id/pipeline_schedules/:pipeline_schedule_id
    with private project
      behaves like request with schedule ownership
        authenticated user with pipeline schedule ownership
          returns pipeline_schedule details
      behaves like request with project permissions
        authenticated user with project permisions
          returns pipeline_schedule details
      behaves like request with unauthenticated user
        with unauthenticated user
          does not return pipeline_schedule
      behaves like request with non-existing pipeline_schedule
        responds with 404 Not Found if requesting non-existing pipeline_schedule
      authenticated user with no project permissions
        does not return pipeline_schedule
      authenticated user with insufficient project permissions
        does not return pipeline_schedule
    with public project
      behaves like request with schedule ownership
        authenticated user with pipeline schedule ownership
          returns pipeline_schedule details
      behaves like request with project permissions
        authenticated user with project permisions
          returns pipeline_schedule details
      behaves like request with unauthenticated user
        with unauthenticated user
          does not return pipeline_schedule
      behaves like request with non-existing pipeline_schedule
        responds with 404 Not Found if requesting non-existing pipeline_schedule
      authenticated user with no project permissions
        returns pipeline_schedule with no variables
      authenticated user with insufficient project permissions
        returns pipeline_schedule with no variables
      when public pipelines are disabled
        authenticated user with no project permissions
          does not return pipeline_schedule
        authenticated user with insufficient project permissions
          returns pipeline_schedule with no variables
  GET /projects/:id/pipeline_schedules/:pipeline_schedule_id/pipelines
    with private project
      behaves like request with schedule ownership
        authenticated user with pipeline schedule ownership
          returns the details of pipelines triggered from the pipeline schedule
      behaves like request with project permissions
        authenticated user with project permissions
          returns the details of pipelines triggered from the pipeline schedule
      behaves like request with unauthenticated user
        with unauthenticated user
          does not return the details of pipelines triggered from the pipeline schedule
      behaves like request with non-existing pipeline_schedule
        responds with 404 Not Found if requesting for a non-existing pipeline schedule's pipelines
      authenticated user with no project permissions
        does not return the details of pipelines triggered from the pipeline schedule
      authenticated user with insufficient project permissions
        does not return the details of pipelines triggered from the pipeline schedule
    with public project
      behaves like request with schedule ownership
        authenticated user with pipeline schedule ownership
          returns the details of pipelines triggered from the pipeline schedule
      behaves like request with project permissions
        authenticated user with project permissions
          returns the details of pipelines triggered from the pipeline schedule
      behaves like request with unauthenticated user
        with unauthenticated user
          does not return the details of pipelines triggered from the pipeline schedule
      behaves like request with non-existing pipeline_schedule
        responds with 404 Not Found if requesting for a non-existing pipeline schedule's pipelines
      authenticated user with no project permissions
        returns the details of pipelines triggered from the pipeline schedule
      when public pipelines are disabled
        authenticated user with no project permissions
          does not return the details of pipelines triggered from the pipeline schedule
  POST /projects/:id/pipeline_schedules
    authenticated user with valid permissions
      with required parameters
        creates pipeline_schedule
      without required parameters
        does not create pipeline_schedule
      when cron has validation error
        does not create pipeline_schedule
    authenticated user with invalid permissions
      does not create pipeline_schedule
    unauthenticated user
      does not create pipeline_schedule
  PUT /projects/:id/pipeline_schedules/:pipeline_schedule_id
    authenticated user with valid permissions
      updates cron
      when cron has validation error
        does not update pipeline_schedule
    authenticated user with invalid permissions
      as a project maintainer
        does not update pipeline_schedule
      as a project owner
        does not update pipeline_schedule
      with no special role
        does not update pipeline_schedule
    unauthenticated user
      does not update pipeline_schedule
  POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/take_ownership
    as an authenticated user with valid permissions
      updates owner
    as an authenticated user with invalid permissions
      does not update owner
    as an unauthenticated user
      does not update owner
    as the existing owner of the schedule
      accepts the request and leaves the schedule unchanged
  DELETE /projects/:id/pipeline_schedules/:pipeline_schedule_id
    authenticated user with valid permissions
      deletes pipeline_schedule
      responds with 404 Not Found if requesting non-existing pipeline_schedule
      behaves like 412 response
        for a modified resource
          returns 412 with a JSON error
        for an unmodified resource
          returns 204 with an empty body
    authenticated user with invalid permissions
      does not delete pipeline_schedule
    unauthenticated user
      does not delete pipeline_schedule
  POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/play
    authenticated user with `:play_pipeline_schedule` permission
      schedules a pipeline worker
      renders an error if scheduling failed
    authenticated user with insufficient access
      responds with not found
    unauthenticated user
      responds with unauthorized
  POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables
    authenticated user with valid permissions
      with required parameters
        creates pipeline_schedule_variable
      without required parameters
        does not create pipeline_schedule_variable
      when key has validation error
        does not create pipeline_schedule_variable
    authenticated user with invalid permissions
      does not create pipeline_schedule_variable
    unauthenticated user
      does not create pipeline_schedule_variable
  PUT /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables/:key
    authenticated user with valid permissions
      updates pipeline_schedule_variable
    authenticated user with invalid permissions
      does not update pipeline_schedule_variable
    unauthenticated user
      does not update pipeline_schedule_variable
  DELETE /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables/:key
    authenticated user with valid permissions
      deletes pipeline_schedule_variable
      responds with 404 Not Found if requesting non-existing pipeline_schedule_variable
    authenticated user with invalid permissions
      does not delete pipeline_schedule_variable
    unauthenticated user
      does not delete pipeline_schedule_variable

Projects::FeatureFlagsController
  GET index
    when there is no feature flags
      responds with success
    for a list of feature flags
      responds with success
    when the user is a reporter
      responds with not found
  GET #index.json
    returns all feature flags as json response
    returns CRUD paths
    returns the summary of feature flags
    matches json schema
    returns the feature flag iid
    when scope is specified
      when all feature flags are requested
        returns all feature flags
      when enabled feature flags are requested
        returns enabled feature flags
      when disabled feature flags are requested
        returns disabled feature flags
    with version 1 and 2 feature flags
      returns all feature flags as json response
  GET new
    renders the form
  GET #show.json
    returns the feature flag as json response
    matches json schema
    routes based on iid
    when feature flag is not found
      returns 404
    when user is reporter
      returns 404
    with a version 2 feature flag
      returns the feature flag
      returns strategies ordered by id
  GET edit
    with new version flags
      returns successfully
  POST create.json
    returns 200
    creates a new feature flag
    matches json schema
    when the same named feature flag has already existed
      returns 400
      returns an error message
    without the active parameter
      creates a flag with active set to true
    when user is reporter
      returns 404
    when creating a version 2 feature flag
      creates a new feature flag
    when creating a version 2 feature flag with strategies and scopes
      creates a new feature flag with the strategies and scopes
    when creating a version 2 feature flag with a gradualRolloutUserId strategy
      creates the new strategy
    when creating a version 2 feature flag with a flexibleRollout strategy
      creates the new strategy
    when creating a version 2 feature flag with a gitlabUserList strategy
      creates the new strategy
    when version parameter is invalid
      returns a 400
  DELETE destroy.json
    returns 200
    deletes one feature flag
    matches json schema
    when user is reporter
      returns 404
    when the feature flag does not exist
      returns not found
    with a version 2 flag
      deletes the flag
  PUT update.json
    with a version 2 feature flag
      creates a new strategy and scope
      creates a gradualRolloutUserId strategy
      creates a flexibleRollout strategy
      creates a gitlabUserList strategy
      supports switching the associated user list for an existing gitlabUserList strategy
      automatically dissociates the user list when switching the type of an existing gitlabUserList strategy
      does not delete a user list when deleting a gitlabUserList strategy
      returns not found when trying to create a gitlabUserList strategy with an invalid user list id
      returns not found when trying to update a gitlabUserList strategy with a user list from another project
      allows setting multiple gitlabUserList strategies to the same user list
      updates an existing strategy
      updates an existing scope
      deletes an existing strategy
      deletes an existing scope

Projects::SnippetsController
  GET #index
    fetches snippet counts via the snippet count service
    behaves like paginated collection
      renders a page number that is not ouf of range
      redirects to last_page if page number is larger than number of pages
      does not redirect to external sites when provided a host field
    behaves like snippets sort order
      when no sort param is provided
        calls SnippetsFinder with updated_at sort option
      when sort param is provided
        calls SnippetsFinder with the given sort param
    behaves like snippets views
      when rendered
        avoids N+1 database queries
    when the project snippet is private
      when anonymous
        does not include the private snippet
      when signed in as the author
        renders the snippet
      when signed in as a project member
        renders the snippet
  POST #mark_as_spam
    updates the snippet
  GET #show
    when the project snippet is private
      when anonymous
        responds with status 404
      when signed in as the author
        behaves like successful response
          renders the snippet
      when signed in as a project member
        behaves like successful response
          renders the snippet
    when the project snippet does not exist
      when anonymous
        responds with status 404
      when signed in
        responds with status 404
    when the project snippet is public
      when attempting to access from a different project route
        responds with status 404
  GET #raw
    when the project snippet is private
      when anonymous
        responds with status 404
      when signed in as the author
        behaves like successful response
          renders the snippet
      when signed in as a project member
        behaves like successful response
          renders the snippet
    when the project snippet does not exist
      when anonymous
        responds with status 404
      when signed in
        responds with status 404
    when the project snippet is public
      when attempting to access from a different project route
        responds with status 404
  GET #show for embeddable content
    when snippet is private
      responds with status 404
    when snippet is public
      renders the blob from the repository
      does not show the blobs expanded by default
      when param expanded is set
        shows all blobs expanded
    when the project is private
      when snippet is public
        responds with status 404
  GET #raw
    when repository is empty
      CRLF line ending
        returns LF line endings by default
        when line_ending parameter present
          does not convert line endings
    when repository is not empty
      sends the blob
      behaves like project cache control headers
        when project is public
          returns cache_control public header to true
        when project is private
          returns cache_control public header to true
        when project is internal
          returns cache_control public header to true
      behaves like content disposition headers
        sets content disposition to inline
        when inline param is false
          sets content disposition to attachment

Groups::DependencyProxyForContainersController
  GET #manifest
    feature enabled
      behaves like without a token
        is expected to respond with numeric status code unauthorized
      behaves like without permission
        with invalid user
          is expected to respond with numeric status code unauthorized
        with valid user that does not have access
          is expected to respond with numeric status code not_found
        with deploy token from a different group,
          is expected to respond with numeric status code not_found
        with revoked deploy token
          is expected to respond with numeric status code unauthorized
        with expired deploy token
          is expected to respond with numeric status code unauthorized
        with deploy token with insufficient scopes
          is expected to respond with numeric status code not_found
        when a group is not found
          is expected to respond with numeric status code not_found
        when user is not found
          is expected to respond with numeric status code unauthorized
      remote token request fails
        proxies status from the remote token request
      remote manifest request fails
        proxies status from the remote manifest request
      a valid user
        behaves like a successful manifest pull
          sends a file
          returns Content-Disposition: attachment
        behaves like a package tracking event
          creates a gitlab tracking event pull_manifest
        with workhorse response
          returns Workhorse send-dependency instructions
          behaves like with invalid path
            with invalid image
              raises an error
            with invalid tag
              raises an error
      a valid deploy token
        behaves like a successful manifest pull
          sends a file
          returns Content-Disposition: attachment
        pulling from a subgroup
          behaves like a successful manifest pull
            sends a file
            returns Content-Disposition: attachment
    behaves like not found when disabled
      feature disabled
        returns 404
  GET #blob
    feature enabled
      behaves like without a token
        is expected to respond with numeric status code unauthorized
      behaves like without permission
        with invalid user
          is expected to respond with numeric status code unauthorized
        with valid user that does not have access
          is expected to respond with numeric status code not_found
        with deploy token from a different group,
          is expected to respond with numeric status code not_found
        with revoked deploy token
          is expected to respond with numeric status code unauthorized
        with expired deploy token
          is expected to respond with numeric status code unauthorized
        with deploy token with insufficient scopes
          is expected to respond with numeric status code not_found
        when a group is not found
          is expected to respond with numeric status code not_found
        when user is not found
          is expected to respond with numeric status code unauthorized
      a valid user
        behaves like a successful blob pull
          sends a file
          returns Content-Disposition: attachment
        behaves like a package tracking event
          creates a gitlab tracking event pull_blob_from_cache
        when cache entry does not exist
          returns Workhorse send-dependency instructions
      a valid deploy token
        behaves like a successful blob pull
          sends a file
          returns Content-Disposition: attachment
        pulling from a subgroup
          behaves like a successful blob pull
            sends a file
            returns Content-Disposition: attachment
    behaves like not found when disabled
      feature disabled
        returns 404
  POST #authorize_upload_blob
    behaves like without permission
      with invalid user
        is expected to respond with numeric status code unauthorized
      with valid user that does not have access
        is expected to respond with numeric status code not_found
      with deploy token from a different group,
        is expected to respond with numeric status code not_found
      with revoked deploy token
        is expected to respond with numeric status code unauthorized
      with expired deploy token
        is expected to respond with numeric status code unauthorized
      with deploy token with insufficient scopes
        is expected to respond with numeric status code not_found
      when a group is not found
        is expected to respond with numeric status code not_found
      when user is not found
        is expected to respond with numeric status code unauthorized
    behaves like authorize action with permission
      with a valid user
        sends Workhorse local file instructions
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
        sends Workhorse remote object instructions
  POST #upload_blob
    behaves like without permission
      with invalid user
        is expected to respond with numeric status code unauthorized
      with valid user that does not have access
        is expected to respond with numeric status code not_found
      with deploy token from a different group,
        is expected to respond with numeric status code not_found
      with revoked deploy token
        is expected to respond with numeric status code unauthorized
      with expired deploy token
        is expected to respond with numeric status code unauthorized
      with deploy token with insufficient scopes
        is expected to respond with numeric status code not_found
      when a group is not found
        is expected to respond with numeric status code not_found
      when user is not found
        is expected to respond with numeric status code unauthorized
    with a valid user
      creates a blob
      behaves like a package tracking event
        creates a gitlab tracking event pull_blob
      behaves like namespace statistics refresh
        updates namespace statistics
  POST #authorize_upload_manifest
    behaves like without permission
      with invalid user
        is expected to respond with numeric status code unauthorized
      with valid user that does not have access
        is expected to respond with numeric status code not_found
      with deploy token from a different group,
        is expected to respond with numeric status code not_found
      with revoked deploy token
        is expected to respond with numeric status code unauthorized
      with expired deploy token
        is expected to respond with numeric status code unauthorized
      with deploy token with insufficient scopes
        is expected to respond with numeric status code not_found
      when a group is not found
        is expected to respond with numeric status code not_found
      when user is not found
        is expected to respond with numeric status code unauthorized
    behaves like authorize action with permission
      with a valid user
        sends Workhorse local file instructions
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[fog][WARNING] fog: the specified s3 bucket name(dependency_proxy) is not a valid dns name, which will negatively impact performance.  For details see: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
        sends Workhorse remote object instructions
  POST #upload_manifest
    behaves like without permission
      with invalid user
        is expected to respond with numeric status code unauthorized
      with valid user that does not have access
        is expected to respond with numeric status code not_found
      with deploy token from a different group,
        is expected to respond with numeric status code not_found
      with revoked deploy token
        is expected to respond with numeric status code unauthorized
      with expired deploy token
        is expected to respond with numeric status code unauthorized
      with deploy token with insufficient scopes
        is expected to respond with numeric status code not_found
      when a group is not found
        is expected to respond with numeric status code not_found
      when user is not found
        is expected to respond with numeric status code unauthorized
    with a valid user
      behaves like a package tracking event
        creates a gitlab tracking event pull_manifest
      behaves like with invalid path
        with invalid image
          raises an error
        with invalid tag
          raises an error
      with no existing manifest
        creates a manifest
        behaves like namespace statistics refresh
          updates namespace statistics
      with existing stale manifest
        updates the existing manifest
        behaves like namespace statistics refresh
          updates namespace statistics

Projects::CommitsController
  signed in
    GET commits_root
      no ref is provided
        redirects to the default branch of the project
    GET show
      loads tags for commits
      with file path
        valid branch, valid file
          is expected to respond with 200
        HEAD, valid file
          is expected to respond with 200
        valid branch, invalid file
          is expected to respond with 404
        invalid branch, valid file
          is expected to respond with 404
        branch with invalid format, valid file
          is expected to respond with 404
      with an invalid limit
        uses the default limit
        when limit is a hash
          uses the default limit
      when tag has a non-ASCII encoding
        does not raise an exception
      when the ref name ends in .atom
        when the ref does not exist with the suffix
          renders as atom
          renders summary with type=html
        when the ref exists with the suffix
          renders as HTML
        when the ref does not exist
          returns 404 page
      with markdown cache
        preloads markdown cache for commits
    GET /commits/:id/signatures
      valid branch
        is expected to respond with 200
      invalid branch format
        is expected to respond with 404

getting user information
  no parameters are provided
    mentions the missing required parameters
  looking up a user by username
    the user is an active user
      can access user profile fields
      behaves like a working graphql query
        returns a successful response
      assignedMergeRequests
        can be found
        behaves like a working graphql query
          returns a successful response
        applying filters
          filtering by IID without specifying a project
            return an argument error that mentions the missing fields
          filtering by project path and IID
            selects the correct MRs
          filtering by project path
            selects the correct MRs
          filtering by author
            finds the authored mrs
          filtering by reviewer
            finds the assigned mrs
        the current user does not have access
          cannot be found
      reviewRequestedMergeRequests
        can be found
        behaves like a working graphql query
          returns a successful response
        applying filters
          filtering by IID without specifying a project
            return an argument error that mentions the missing fields
          filtering by project path and IID
            selects the correct MRs
          filtering by project path
            selects the correct MRs
          filtering by author
            finds the authored mrs
          filtering by assignee
            finds the authored mrs
        the current user does not have access
          cannot be found
      authoredMergeRequests
        can be found
        behaves like a working graphql query
          returns a successful response
        applying filters
          filtering by IID without specifying a project
            return an argument error that mentions the missing fields
          filtering by assignee
            finds the assigned mrs
          filtering by reviewer
            finds the assigned mrs
          filtering by project path and IID
            selects the correct MRs
          filtering by project path
            selects the correct MRs
        the current user does not have access
          cannot be found
    the user is private
      we only request basic fields
        behaves like a working graphql query
          returns a successful response
      we request the groupMemberships
        cannot be found
        behaves like a working graphql query
          returns a successful response
        the current user is the user
          can be found
      we request the projectMemberships
        cannot be found
        behaves like a working graphql query
          returns a successful response
        the current user is the user
          can be found
      we request the authoredMergeRequests
        cannot be found
        behaves like a working graphql query
          returns a successful response
        the current user is the user
          can be found
      we request the assignedMergeRequests
        cannot be found
        behaves like a working graphql query
          returns a successful response
        the current user is the user
          can be found
    the user is project bot
      we only request basic fields
        behaves like a working graphql query
          returns a successful response
  authored merge requests
    returns merge requests for the current user for the specified group

Jira referenced paths
  behaves like redirects to jira path
    redirects to canonical path with legacy prefix
    redirects to canonical path
  contains @ before the first /
    behaves like redirects to jira path
      redirects to canonical path with legacy prefix
      redirects to canonical path
  including commit path
    behaves like redirects to jira path
      redirects to canonical path with legacy prefix
      redirects to canonical path
  including tree path
    behaves like redirects to jira path
      redirects to canonical path with legacy prefix
      redirects to canonical path
  malicious path
    behaves like redirects to jira path
      redirects to canonical path with legacy prefix
      redirects to canonical path
  regular paths with legacy prefix
    jira_path: "/-/jira/group/group_project", redirect_path: "/group/group_project"
      redirects to canonical path
    jira_path: "/-/jira/group/group_project/commit/1234567", redirect_path: "/group/group_project/commit/1234567"
      redirects to canonical path
    jira_path: "/-/jira/group/group_project/tree/1234567", redirect_path: "/group/group_project/-/tree/1234567"
      redirects to canonical path
  when tree path has an @
    does not do a redirect

JwtController
  POST /jwt/auth
    returns 404
  authenticating against container registry
    behaves like container registry authenticator
      existing service
        is expected to respond with numeric status code ok
        returning custom http code
          is expected to respond with numeric status code http_version_not_supported
      when using authenticated request
        using CI token
          project with enabled CI
            is expected to have received new(#<Project id:819 namespace605/project-577>>, #<User id:1266 @user618>, #<ActionController::Parameters {"service"=>"container_registry", "auth_type"=>:build} permitted: true>) 1 time
            behaves like user logging
              logs username and ID
          project with disabled CI
            is expected to respond with numeric status code unauthorized
          using deploy tokens
            authenticates correctly
            does not log a user
          using personal access tokens
            authenticates correctly
            behaves like rejecting a blocked user
              with blocked user
                behaves like with invalid credentials
                  returns a generic error message
            behaves like user logging
              logs username and ID
            behaves like a token that expires today
              fails authentication
        using User login
          is expected to have received new(nil, #<User id:1280 @user627>, #<ActionController::Parameters {"service"=>"container_registry", "auth_type"=>:gitlab_or_ldap} permitted: true>) 1 time
          does not cause session based checks to be activated
          behaves like rejecting a blocked user
            with blocked user
              behaves like with invalid credentials
                returns a generic error message
          when passing a flat array of scopes
            is expected to have received new(nil, #<User id:1283 @user630>, #<ActionController::Parameters {"service"=>"container_registry", "scopes"=>["scope1", "scope2"], "auth_type"=>:gitlab_or_ldap} permitted: true>) 1 time
            behaves like user logging
              logs username and ID
          when user has 2FA enabled
            without personal token
              behaves like with invalid credentials
                returns a generic error message
            with personal token
              accepts the authorization attempt
        using invalid login
          when internal auth is enabled
            behaves like with invalid credentials
              returns a generic error message
          when internal auth is disabled
            behaves like with invalid credentials
              returns a generic error message
      when using unauthenticated request
        accepts the authorization attempt
        allows read access
      unknown service
        is expected to respond with numeric status code not_found
    behaves like parses a space-delimited list of scopes
      is expected to have received new(nil, #<User id:1287 @user634>, #<ActionController::Parameters {"service"=>"container_registry", "scopes"=>["scope1", "scope2"], "auth_type"=>:gitlab_or_ldap} permitted: true>) 1 time
    when jwt_auth_space_delimited_scopes feature flag is disabled
      behaves like container registry authenticator
        existing service
          is expected to respond with numeric status code ok
          returning custom http code
            is expected to respond with numeric status code http_version_not_supported
        when using authenticated request
          using CI token
            project with enabled CI
              is expected to have received new(#<Project id:824 namespace610/project-582>>, #<User id:1288 @user635>, #<ActionController::Parameters {"service"=>"container_registry", "auth_type"=>:build} permitted: true>) 1 time
              behaves like user logging
                logs username and ID
            project with disabled CI
              is expected to respond with numeric status code unauthorized
            using deploy tokens
              authenticates correctly
              does not log a user
            using personal access tokens
              authenticates correctly
              behaves like rejecting a blocked user
                with blocked user
                  behaves like with invalid credentials
                    returns a generic error message
              behaves like user logging
                logs username and ID
              behaves like a token that expires today
                fails authentication
          using User login
            is expected to have received new(nil, #<User id:1302 @user644>, #<ActionController::Parameters {"service"=>"container_registry", "auth_type"=>:gitlab_or_ldap} permitted: true>) 1 time
            does not cause session based checks to be activated
            behaves like rejecting a blocked user
              with blocked user
                behaves like with invalid credentials
                  returns a generic error message
            when passing a flat array of scopes
              is expected to have received new(nil, #<User id:1305 @user647>, #<ActionController::Parameters {"service"=>"container_registry", "scopes"=>["scope1", "scope2"], "auth_type"=>:gitlab_or_ldap} permitted: true>) 1 time
              behaves like user logging
                logs username and ID
            when user has 2FA enabled
              without personal token
                behaves like with invalid credentials
                  returns a generic error message
              with personal token
                accepts the authorization attempt
          using invalid login
            when internal auth is enabled
              behaves like with invalid credentials
                returns a generic error message
            when internal auth is disabled
              behaves like with invalid credentials
                returns a generic error message
        when using unauthenticated request
          accepts the authorization attempt
          allows read access
        unknown service
          is expected to respond with numeric status code not_found
      behaves like parses a space-delimited list of scopes
        is expected to have received new(nil, #<User id:1309 @user651>, #<ActionController::Parameters {"service"=>"container_registry", "scopes"=>["scope1 scope2"], "auth_type"=>:gitlab_or_ldap} permitted: true>) 1 time
  authenticating against dependency proxy
    with personal access token
      behaves like with valid credentials
        returns token successfully
      behaves like a token that expires today
        fails authentication
    with user credentials token
      behaves like with valid credentials
        returns token successfully
    with group deploy token
      behaves like with valid credentials
        returns token successfully
    with project deploy token
      behaves like returning response status
        returns forbidden
    with revoked group deploy token
      behaves like returning response status
        returns unauthorized
    with group deploy token with insufficient scopes
      behaves like returning response status
        returns unauthorized
    with invalid credentials
      behaves like returning response status
        returns unauthorized

API::Namespaces
  GET /namespaces
    when unauthenticated
      returns authentication error
    when authenticated as admin
      returns correct attributes
      admin: returns an array of all namespaces
      admin: returns an array of matched namespaces
    when authenticated as a regular user
      returns correct attributes when user can admin group
      returns correct attributes when user cannot admin group
      user: returns an array of namespaces
      admin: returns an array of matched namespaces
      with owned_only param
        returns only owned groups
  GET /namespaces/:id
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when unauthenticated
      returns authentication error
      returns authentication error
    when authenticated as regular user
      when requested namespace is not owned by user
        when requesting group
          returns not-found
        when requesting personal namespace
          returns not-found
      when requested namespace is owned by user
        behaves like namespace reader
          when namespace exists
            when requested by ID
              when requesting group
                behaves like can access namespace
                  returns namespace details
              when requesting personal namespace
                behaves like can access namespace
                  returns namespace details
              when requesting project_namespace
                returns not-found
            when requested by path
              when requesting group
                behaves like can access namespace
                  returns namespace details
              when requesting personal namespace
                behaves like can access namespace
                  returns namespace details
              when requesting project_namespace
                returns not-found
          when namespace doesn't exist
            returns not-found
    when authenticated as admin
      when requested namespace is not owned by user
        when requesting group
          behaves like can access namespace
            returns namespace details
        when requesting personal namespace
          behaves like can access namespace
            returns namespace details
      when requested namespace is owned by user
        behaves like namespace reader
          when namespace exists
            when requested by ID
              when requesting group
                behaves like can access namespace
                  returns namespace details
              when requesting personal namespace
                behaves like can access namespace
                  returns namespace details
              when requesting project_namespace
                returns not-found
            when requested by path
              when requesting group
                behaves like can access namespace
                  returns namespace details
              when requesting personal namespace
                behaves like can access namespace
                  returns namespace details
              when requesting project_namespace
                returns not-found
          when namespace doesn't exist
            returns not-found
  GET /namespaces/:namespace/exists
    when unauthenticated
      returns authentication error
      when requesting project_namespace
        returns authentication error
    when authenticated
      returns JSON indicating the namespace exists and a suggestion
      supports dot in namespace path
      returns JSON indicating the namespace does not exist without a suggestion
      checks the existence of a namespace in case-insensitive manner
      checks the existence within the parent namespace only
      ignores nested namespaces when checking for top-level namespace
      ignores paths of groups present in other hierarchies when making suggestions
      ignores top-level namespaces when checking with parent_id
      ignores namespaces of other parent namespaces when checking with parent_id
      behaves like rate limited endpoint
        when rate limiter enabled
          logs request and declines it when endpoint called more than the threshold
        when rate limiter is disabled
          does not log request and does not block the request
      when requesting project_namespace
        returns JSON indicating the namespace does not exist without a suggestion

Groups::UploadsController
  behaves like handle uploads
    behaves like handle uploads authorize
      POST #authorize
        when a user is not authorized to upload a file
          returns 404 status
        when id is not passed as a param
          returns 404 status
        when a user can upload a file
          and the request bypassed workhorse
            raises an exception
          and request is sent by gitlab-workhorse to authorize the request
            when using local storage
              behaves like a local file
                behaves like a valid response
                  responds with status 200
                  uses the gitlab-workhorse content type
                  responds with status 200, location of uploads store and object details
            when using remote storage
              when direct upload is enabled
                behaves like a valid response
                  responds with status 200
                  uses the gitlab-workhorse content type
                  responds with status 200, location of uploads remote store and object details
              when direct upload is disabled
                behaves like a local file
                  behaves like a valid response
                    responds with status 200
                    uses the gitlab-workhorse content type
                    responds with status 200, location of uploads store and object details
    POST #create
      when a user is not authorized to upload a file
        returns 404 status
      when a user can upload a file
        without params['file']
          returns an error
        with valid image
          returns a content with original filename, new link, and correct type.
          creates a corresponding Upload record
        with valid non-image file
          returns a content with original filename, new link, and correct type.
    GET #show
      when the secret is invalid
        responds with status 404
      when accessing a specific upload via different model
        responds with status 404
      when the upload does not have a MIME type that Rails knows
        falls back to the null type
      when the model is public
        when not signed in
          when the file exists
            responds with status 200
          when neither the uploader nor the model exists
            responds with status 404
          when the file doesn't exist
            responds with status 404
        when signed in
          when the file exists
            responds with status 200
          when the file doesn't exist
            responds with status 404
      when the model is private
        when not signed in
          when the file exists
            when the file is an image
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
              responds with the appropriate status code
            when the file is not an image
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
              redirects to the sign in page
          when the file doesn't exist
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
            redirects to the sign in page
        when signed in
          when the user has access to the project
            when the file exists
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
              responds with status 200
            when the file doesn't exist
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
              responds with status 404
          when the user doesn't have access to the model
            when the file exists
              when the file is an image
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
                responds with the appropriate status code
              when the file is not an image
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
                responds with status 404
            when the file doesn't exist
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
              responds with status 404
  with a moved group
    redirects to a file with the proper extension
  GET #show
    when the group is public
      when not signed in
        responds with appropriate status
        when uploader class does not match the upload
          responds with status 404
        when filename does not match
          responds with status 404
      when signed in
        when the user doesn't have access to the model
          responds with status 200
    when the group is private
      when not signed in
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
        responds with appropriate status
      when signed in
        when the user doesn't have access to the model
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
EscapeUtils.escape_url is deprecated. Use CGI.escape instead, performance is similar
          responds with status 200

task completion status response
  task list completion status for issues
    behaves like taskable completion status provider
      with a description of ""
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "Lorem ipsum"
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [ ] task 1\n              - [x] task 2 "
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [ ] task 1\n              - [ ] task 2 "
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [x] task 1\n              - [x] task 2 "
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [ ] task 1"
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [x] task 1"
        is expected to respond with numeric status code ok
        returns the expected results
  task list completion status for merge_requests
    behaves like taskable completion status provider
      with a description of ""
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "Lorem ipsum"
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [ ] task 1\n              - [x] task 2 "
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [ ] task 1\n              - [ ] task 2 "
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [x] task 1\n              - [x] task 2 "
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [ ] task 1"
        is expected to respond with numeric status code ok
        returns the expected results
      with a description of "- [x] task 1"
        is expected to respond with numeric status code ok
        returns the expected results

Projects::Clusters::IntegrationsController
  POST create_or_update
    behaves like #create_or_update action
      authorization
        behaves like a secure endpoint
          is allowed for admin when admin mode enabled
          is denied for admin when admin mode disabled
          it is allowed for project maintainers
            is expected to be allowed for owner. Expected: 200,201,204,302 Got: 302
            is expected to be allowed for maintainer. Expected: 200,201,204,302 Got: 302
            is expected to be denied for developer. Expected: 401,404 Got: 404
            is expected to be denied for reporter. Expected: 401,404 Got: 404
            is expected to be denied for guest. Expected: 401,404 Got: 404
            is expected to be denied for user. Expected: 401,404 Got: 404
            is expected to be denied for external. Expected: 401,404 Got: 404
      functionality
        redirects on success
        redirects on error

Emails::PagesDomains
  #pages_domain_enabled_email
    is expected to have body including "has been enabled"
    behaves like a pages domain verification email
      has the expected content
      behaves like a pages domain email
        has the expected content
        behaves like an email sent to a user
          is sent to user's global notification email address
          with group notification email
            is sent to user's group notification email
        behaves like an email sent from GitLab
          has the characteristics of an email sent from GitLab
        behaves like it should not have Gmail Actions links
          is expected not to have body including "ViewAction"
        behaves like a user cannot unsubscribe through footer link
          does not have a List-Unsubscribe header or a body link
  #pages_domain_disabled_email
    is expected to have body including "has been disabled"
    behaves like a pages domain verification email
      has the expected content
      behaves like a pages domain email
        has the expected content
        behaves like an email sent to a user
          is sent to user's global notification email address
          with group notification email
            is sent to user's group notification email
        behaves like an email sent from GitLab
          has the characteristics of an email sent from GitLab
        behaves like it should not have Gmail Actions links
          is expected not to have body including "ViewAction"
        behaves like a user cannot unsubscribe through footer link
          does not have a List-Unsubscribe header or a body link
    behaves like notification about upcoming domain removal
      when domain is not scheduled for removal
        asks user to remove it
      when domain is scheduled for removal
        notifies user that domain will be removed automatically
  #pages_domain_verification_succeeded_email
    is expected to have body including "successfully verified"
    behaves like a pages domain verification email
      has the expected content
      behaves like a pages domain email
        has the expected content
        behaves like an email sent to a user
          is sent to user's global notification email address
          with group notification email
            is sent to user's group notification email
        behaves like an email sent from GitLab
          has the characteristics of an email sent from GitLab
        behaves like it should not have Gmail Actions links
          is expected not to have body including "ViewAction"
        behaves like a user cannot unsubscribe through footer link
          does not have a List-Unsubscribe header or a body link
  #pages_domain_verification_failed_email
    behaves like a pages domain email
      has the expected content
      behaves like an email sent to a user
        is sent to user's global notification email address
        with group notification email
          is sent to user's group notification email
      behaves like an email sent from GitLab
        has the characteristics of an email sent from GitLab
      behaves like it should not have Gmail Actions links
        is expected not to have body including "ViewAction"
      behaves like a user cannot unsubscribe through footer link
        does not have a List-Unsubscribe header or a body link
    behaves like notification about upcoming domain removal
      when domain is not scheduled for removal
        asks user to remove it
      when domain is scheduled for removal
        notifies user that domain will be removed automatically
  #pages_domain_auto_ssl_failed_email
    says that we failed to obtain certificate
    behaves like a pages domain email
      has the expected content
      behaves like an email sent to a user
        is sent to user's global notification email address
        with group notification email
          is sent to user's group notification email
      behaves like an email sent from GitLab
        has the characteristics of an email sent from GitLab
      behaves like it should not have Gmail Actions links
        is expected not to have body including "ViewAction"
      behaves like a user cannot unsubscribe through footer link
        does not have a List-Unsubscribe header or a body link

Projects::DesignManagement::Designs::RawImagesController
  GET #show
    when the design is not an LFS file
      serves files with `Content-Disposition` header set to attachment plus the filename
      serves files with Workhorse
      behaves like project cache control headers
        when project is public
          returns cache_control public header to true
        when project is private
          returns cache_control public header to true
        when project is internal
          returns cache_control public header to true
      when the user does not have permission
        is expected to respond with numeric status code not_found
      when design does not exist
        is expected to respond with numeric status code not_found
      sha param
        is expected not to eq "c12000b1bfbdff192486174a598f95f28976450a"
        when sha is the newest version sha
          behaves like a successful request for sha
            is expected to respond with numeric status code ok
        when sha is the oldest version sha
          behaves like a successful request for sha
            is expected to respond with numeric status code ok
        when sha is nil
          behaves like a successful request for sha
            is expected to respond with numeric status code ok
    when the design is an LFS file
      serves files with `Content-Disposition: attachment`
      sets appropriate caching headers
    behaves like a controller that can serve LFS files
      when lfs is enabled
        when the project is linked to the LfsObject
          serves the file
          and lfs uses object storage
            responds with redirect to file
            sets content disposition
        when project is not linked to the LfsObject
          does not serve the file
        when the project is part of a fork network
          when the project is the root of the fork network
            behaves like a controller that correctly serves lfs files within a fork network
              is expected not to eq #<Project id:844 namespace628/project-601>>
              does not serve the file if no members are linked to the LfsObject
              serves the file when the fork network root is linked to the LfsObject
              serves the file when the fork network member is linked to the LfsObject
          when the project is a downstream member of the fork network
            behaves like a controller that correctly serves lfs files within a fork network
              is expected not to eq #<Project id:849 namespace633/project-606>>
              does not serve the file if no members are linked to the LfsObject
              serves the file when the fork network root is linked to the LfsObject
              serves the file when the fork network member is linked to the LfsObject
      when lfs is not enabled
        delivers ASCII file (PENDING: Calling spec asked to skip testing LFS disabled scenario)

Query.ciConfig
  returns the correct structure
  behaves like a working graphql query
    returns a successful response
  when the config file includes other files
    returns the correct structure with included files
    behaves like a working graphql query
      returns a successful response
  when the config file has multiple includes
    returns correct includes
    behaves like a working graphql query
      returns a successful response
  skip_verify_project_sha
    when the sha is from the main project
      behaves like when the sha exists in the main project
        when skip_verify_project_sha is not provided
          behaves like content is valid
            returns the expected data without validation errors
        when skip_verify_project_sha is false
          behaves like content is valid
            returns the expected data without validation errors
        when skip_verify_project_sha is true
          behaves like content is valid
            returns the expected data without validation errors
    when the sha is from a fork project
      when the sha is associated with a main project ref
        behaves like when the sha exists in the main project
          when skip_verify_project_sha is not provided
            behaves like content is valid
              returns the expected data without validation errors
          when skip_verify_project_sha is false
            behaves like content is valid
              returns the expected data without validation errors
          when skip_verify_project_sha is true
            behaves like content is valid
              returns the expected data without validation errors
      when the sha is not associated with a main project ref
        when skip_verify_project_sha is not provided
          behaves like returning error
            returns an error
        when skip_verify_project_sha is false
          behaves like returning error
            returns an error
        when skip_verify_project_sha is true
          behaves like content is valid
            returns the expected data without validation errors
    when the sha is invalid
      behaves like when the sha exists in the main project
        when skip_verify_project_sha is not provided
          behaves like content is valid
            returns the expected data without validation errors
        when skip_verify_project_sha is false
          behaves like content is valid
            returns the expected data without validation errors
        when skip_verify_project_sha is true
          behaves like content is valid
            returns the expected data without validation errors

API::ErrorTracking::ProjectSettings
  # order random
  GET /projects/:id/error_tracking/settings
    when authenticated as maintainer
      behaves like returns project settings
        returns correct project settings
      when integrated_error_tracking feature disabled
        behaves like returns project settings with false for integrated
          is expected to eq {"active"=>true, "api_url"=>"https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project",...>"Sentry Project", "sentry_external_url"=>"https://sentrytest.gitlab.com/sentry-org/sentry-project"}
    without a project setting
      behaves like returns no project settings
        returns no project settings
    when authenticated as developer
      behaves like returns 403
        rejects request
    when authenticated as non-member
      behaves like returns 404
        rejects request
    when unauthenticated
      behaves like returns 401
        rejects request
  PUT /projects/:id/error_tracking/settings
    when authenticated
      as maintainer
        when integrated
          with existing setting
            updates a setting
          without setting
            creates a setting
          when ::Projects::Operations::UpdateService responds with an error
            behaves like returns error from UpdateService
              returns errors
        when integrated_error_tracking feature disabled
          behaves like returns 404
            rejects request
        when integrated param is invalid
          behaves like returns 400 with `integrated` param required or invalid
            returns 400
        when integrated param is missing
          behaves like returns 400 with `integrated` param required or invalid
            returns 400
      as developer
        behaves like returns 403
          rejects request
      as non-member
        behaves like returns 404
          rejects request
    when unauthorized
      behaves like returns 401
        rejects request
  PATCH /projects/:id/error_tracking/settings
    when authenticated as maintainer
      updates enabled flag
      with integrated_error_tracking feature enabled
        behaves like returns project settings
          returns correct project settings
      with integrated_error_tracking feature disabled
        behaves like returns project settings with false for integrated
          is expected to eq {"active"=>false, "api_url"=>"https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project"...>"Sentry Project", "sentry_external_url"=>"https://sentrytest.gitlab.com/sentry-org/sentry-project"}
      when active is invalid
        returns active is invalid if non boolean
      when active is empty
        returns 400
      with integrated param
        when integrated_error_tracking feature enabled
          updates the integrated flag
      without a project setting
        behaves like returns no project settings
          returns no project settings
      when ::Projects::Operations::UpdateService responds with an error
        when integrated
          behaves like returns error from UpdateService
            returns errors
        without integrated
          behaves like returns error from UpdateService
            returns errors
    when authenticated as developer
      behaves like returns 403
        rejects request
    when authenticated as non-member
      behaves like returns 404
        rejects request
    when unauthenticated
      behaves like returns 401
        rejects request

pypi package details
  has the correct metadata
  behaves like a package detail
    behaves like a working graphql query
      returns a successful response
      behaves like matching the package details schema
        matches the JSON schema
    with pipelines
      behaves like a working graphql query
        returns a successful response
        behaves like matching the package details schema
          matches the JSON schema
  behaves like a package with files
    has the right amount of files
    has the basic package files data
    with package files pending destruction
      does not return them

Adding an AwardEmoji
  when the user does not have permission
    behaves like a mutation that does not create an AwardEmoji
      is expected not to change `AwardEmoji.count`
    behaves like a mutation that returns a top-level access error
      is expected to contain exactly "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
  when the user has permission
    when the given awardable is not an Awardable
      behaves like a mutation that does not create an AwardEmoji
        is expected not to change `AwardEmoji.count`
      behaves like a mutation that returns top-level errors
        is expected to include /was provided invalid value for awardableId/
    when the given awardable is an Awardable but still cannot be awarded an emoji
      behaves like a mutation that does not create an AwardEmoji
        is expected not to change `AwardEmoji.count`
      behaves like a mutation that returns top-level errors
        is expected to contain exactly "You cannot add emoji reactions to this resource."
    when the given awardable is an Awardable
      creates an emoji
      returns the emoji
      marking Todos as done
        type: :issue, expectation: true
          is expected to eq true
        type: :merge_request, expectation: true
          is expected to eq true
        type: :project_snippet, expectation: false
          is expected to eq false
        for notes
          regular Notes
            marks the Todo as done
          PersonalSnippet Notes
            does not mark the Todo as done
      when there were active record validation errors
        returns an empty awardEmoji
        behaves like a mutation that does not create an AwardEmoji
          is expected not to change `AwardEmoji.count`
        behaves like a mutation that returns errors in the response
          is expected to contain exactly "Error 1" and "Error 2"

RunnerCreate
  # order random
  when runnerType is GROUP_TYPE
    behaves like when user does not have permissions
      returns an error
    when user has permissions
      when user is group owner
        behaves like when runner is created successfully
          is expected to start with "glrt-"
        behaves like when model is invalid returns error
          is expected to contain exactly "Tags list can not be empty when runner is not allowed to pick untagged jobs" and "Maximum timeout needs to be at least 10 minutes"
        when group_id is missing
          returns an error
        when group_id is malformed
          returns an error
        when group_id does not exist
          returns an error
      when user is admin in admin mode
        behaves like when runner is created successfully
          is expected to start with "glrt-"
        behaves like when model is invalid returns error
          is expected to contain exactly "Tags list can not be empty when runner is not allowed to pick untagged jobs" and "Maximum timeout needs to be at least 10 minutes"
  when runnerType is INSTANCE_TYPE
    behaves like when user does not have permissions
      returns an error
    when user has permissions
      behaves like when runner is created successfully
        is expected to start with "glrt-"
      behaves like when model is invalid returns error
        is expected to contain exactly "Tags list can not be empty when runner is not allowed to pick untagged jobs" and "Maximum timeout needs to be at least 10 minutes"
  when runnerType is PROJECT_TYPE
    behaves like when user does not have permissions
      returns an error
    when user has permissions
      when user is group owner
        behaves like when runner is created successfully
          is expected to start with "glrt-"
        behaves like when model is invalid returns error
          is expected to contain exactly "Tags list can not be empty when runner is not allowed to pick untagged jobs" and "Maximum timeout needs to be at least 10 minutes"
        when project_id is missing
          returns an error
        when project_id is malformed
          returns an error
        when project_id does not exist
          returns an error
      when user is admin in admin mode
        behaves like when runner is created successfully
          is expected to start with "glrt-"
        behaves like when model is invalid returns error
          is expected to contain exactly "Tags list can not be empty when runner is not allowed to pick untagged jobs" and "Maximum timeout needs to be at least 10 minutes"

Import::BulkImportsController
  when user is signed in
    when bulk_import feature flag is enabled
      POST configure
        sets the session variables
        strips access token with spaces
        passes namespace_id to status
        when no params are passed in
          clears out existing session
        when URL is invalid
          redirects to initial import page
        when token scope is invalid
          redirects to initial import page
        when instance version is incompatible
          redirects to initial import page
      GET status
        serialized group data
          returns serialized group data
          forwards pagination headers
          when filtering
            returns filtered result
        when host url is local or not http
          denies network request
          denies network request
          denies network request
          when local requests are allowed
            with https://localhost:3000
              allows network request
            with http://192.168.0.1
              allows network request
          when namespace_id is provided
            renders 404 if user does not have access to namespace
            passes namespace to template
        when connection error occurs
          returns 422
          clears session
      GET realtime_changes
        returns bulk imports created by current user
        sets a Poll-Interval header
      POST create
        executes BulkImports::CreateService
        when entity destination_name is specified
          replaces destination_name with destination_slug and executes BulkImports::CreateService
        when source type is project
          returns 422
        when request exceeds rate limits
          prevents user from starting a new migration
    when feature is disabled
      POST configure
        returns 404
      GET status
        returns 404
  when user is signed out
    POST configure
      redirects to sign in page
    GET status
      redirects to sign in page

getting a tree in a project
  when path does not exist
    returns empty tree
    returns null commit
  when ref does not exist
    returns empty tree
    returns null commit
  when ref and path exist
    returns tree
    returns blobs, subtrees and submodules inside tree
    returns tree latest commit
  when the ref points to a gpg-signed commit with a user
    returns the expected signature data
  when the ref points to a X.509-signed commit
    returns the expected signature data
    returns expected certificate data
  when the ref points to a SSH-signed commit
    returns the expected signature data
  when current user is nil
    returns empty project

Deleting a release
  when the current user has access to update releases
    deletes the release
    returns the deleted release
    does not remove the Git tag associated with the deleted release
    returns no errors
    validation
      when the release does not exist
        returns the release as null
        returns an errors-at-data message
      when the project does not exist
        behaves like unauthorized or not found error
          returns a top-level error with message
  when the current user doesn't have access to update releases
    when the current user is a Reporter
      behaves like unauthorized or not found error
        returns a top-level error with message
    when the current user is a Guest
      behaves like unauthorized or not found error
        returns a top-level error with message
    when the current user is a public user
      behaves like unauthorized or not found error
        returns a top-level error with message

Bulk update issues
  # order random
  when user can update all issues
    updates all issues
    when current user cannot read the specified project
      returns a resource not found error
    when setting arguments to null or none
      updates all issues
  when trying to update more than the max allowed
    restricts updating more than 100 issues at the same time
  when user can not update all issues
    updates only issues that the user can update
  when the `bulk_update_issues_mutation` feature flag is disabled
    returns a resource not available error
  when update service returns an error
    returns an error message

Setting Draft status of a merge request
  returns an error if the user is not allowed to update the merge request
  marks the merge request as Draft
  does not do anything if the merge request was already marked `Draft`
  when passing Draft false as input
    does not do anything if the merge reqeust was not marked draft
    unmarks the merge request as `Draft`

Project Environments query
  # order random
  returns the specified fields of the environment
  user permissions
    returns user permissions of the environment
    when fetching user permissions for multiple environments
      limits the result
  with cluster agent
    returns the cluster agent of the environment
    when the cluster is not authorized in the project
      does not return the cluster agent of the environment
  nested environments
    with query
      can fetch nested environments
      when user is guest
        returns nothing
    when using pagination
      supports pagination
  last deployments of environments
    returns all last deployments of the environment
    executes the same number of queries in single environment and multiple environments

Create an issue
  the user is not allowed to create an issue
    behaves like a mutation that returns a top-level access error
      is expected to contain exactly "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
  when user has permissions to create an issue
    creates the issue
    behaves like has spam protection
      #check_spam_action_response!
        when the object is spam (DISALLOW)
          and no CAPTCHA is available
            behaves like disallow response
              informs the client that the request was denied as spam
          and a CAPTCHA is required
            behaves like disallow response
              informs the client that the request was denied as spam
        when the object is not spam (CONDITIONAL ALLOW)
          and no CAPTCHA is required
            does not return a top-level error
          and a CAPTCHA is required
            informs the client that the request may be retried after solving the CAPTCHA
    when creating an issue of type TASK
      creates an issue with TASK type
    when position params are provided
      sets the correct position

API::GroupContainerRepositories
  GET /groups/:id/registry/repositories
    behaves like rejected container repository access
      for guest
        returns forbidden
    behaves like rejected container repository access
      for anonymous
        returns not_found
    behaves like returns repositories for allowed users
      for reporter
        returns a list of repositories
        returns a matching schema
    behaves like a package tracking event
      creates a gitlab tracking event list_repositories
    with invalid group id
      returns not found
    with URL-encoded path of the group
      behaves like rejected container repository access
        for guest
          returns forbidden
      behaves like rejected container repository access
        for anonymous
          returns not_found
      behaves like returns repositories for allowed users
        for reporter
          returns a list of repositories
          returns a matching schema

Admin::SessionsController
  #new
    for regular users
      shows error page
    for admin users
      renders a password form
      already in admin mode
        redirects to original location
  #create
    for regular users
      shows error page
    for admin users
      sets admin mode with a valid password
      fails with an invalid password
      fails if not requested first
      fails if request period expired
      when using two-factor authentication via OTP
        requests two factor after a valid password is provided
        can login with valid otp
        cannot login with invalid otp
        with password authentication disabled
          allows 2FA stage of non-password login
        on a read-only instance
          does not attempt to write to the database with valid otp
          does not attempt to write to the database with invalid otp
          does not attempt to write to the database with backup code
      when using two-factor authentication via WebAuthn
        requests two factor after a valid password is provided
        can login with valid auth
        cannot login with invalid auth
  #destroy
    for regular users
      shows error page
    for admin users
      disables admin mode and redirects to main page

API::Admin::PlanLimits PlanLimits
  GET /application/plan_limits
    behaves like GET request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    as an admin user
      no params
        returns plan limits
      correct plan name in params
        returns plan limits
      invalid plan name in params
        returns validation error
  PUT /application/plan_limits
    behaves like PUT request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    as an admin user
      correct params
        updates multiple plan limits
        updates single plan limits
      empty params
        fails to update plan limits
      params with wrong type
        fails to update plan limits
      missing plan_name in params
        fails to update plan limits
      additional undeclared params
        updates only declared plan limits

API::Pages
  DELETE /projects/:id/pages
    behaves like DELETE request permissions for admin mode
      behaves like when admin
        behaves like makes request
          returns
        behaves like makes request
          returns
      behaves like when user
        returns
        behaves like makes request
          returns
    when Pages is disabled
      behaves like 404 response
        returns 404
    when Pages is enabled
      when Pages are deployed
        returns 204
        removes the pages
      when pages are not deployed
        returns 204
      when there is no project
        returns 404

Converts a work item to a new type
  # order random
  when user has permissions to convert the work item type
    converts the work item
    when work item type does not exist
      returns an error
    behaves like has spam protection
      #check_spam_action_response!
        when the object is spam (DISALLOW)
          and no CAPTCHA is available
            behaves like disallow response
              informs the client that the request was denied as spam
          and a CAPTCHA is required
            behaves like disallow response
              informs the client that the request was denied as spam
        when the object is not spam (CONDITIONAL ALLOW)
          and no CAPTCHA is required
            does not return a top-level error
          and a CAPTCHA is required
            informs the client that the request may be retried after solving the CAPTCHA
  when user is not allowed to update a work item
    behaves like a mutation that returns a top-level access error
      is expected to contain exactly "The resource that you are attempting to access does not exist or you don't have permission to perform this action"

Query.project(fullPath).pipelines.job(id)
  scalar fields
    retrieves scalar fields
    when fetching by name
      retrieves scalar fields
  .detailedStatus
    retrieves detailed status
  .stage
    returns appropriate data

Admin::ImpersonationsController
  DELETE destroy
    when not signed in
      redirects to the sign in page
    when signed in
      when not impersonating
        responds with status 404
        doesn't sign us in
      when impersonating
        when the impersonator is not admin (anymore)
          responds with status 404
          doesn't sign us in as the impersonator
        when the impersonator is admin
          when the impersonator is blocked
            responds with status 404
            doesn't sign us in as the impersonator
          when the impersonator is not blocked
            behaves like successfully stops impersonating
              redirects to the impersonated user's page
              signs us in as the impersonator
              clears token session keys
            and the user has a temporary oauth e-mail address
              behaves like successfully stops impersonating
                redirects to the impersonated user's page
                signs us in as the impersonator
                clears token session keys

getting Alert Management Alert counts by status
  with alert data
    without project permissions
      is expected to equal nil
      behaves like a working graphql query
        returns a successful response
    with project permissions
      returns the correct counts for each status
      behaves like a working graphql query
        returns a successful response
      with search criteria
        returns the correct counts for each status
        behaves like a working graphql query
          returns a successful response

Reposition and move issue within board lists
  when the board_id is not a board
    behaves like returns an error
      fails with error
  when the user cannot read the issue board
    behaves like returns an error
      fails with error
  when user has access to resources
    when repositioning an issue
      repositions an issue
    when moving an issue to a different list
      moves issue to a different list
    when moving an issue using position_in_list
      repositions an issue
  when user has no access to resources
    the user is not allowed to update the issue
      behaves like returns an error
        fails with error
    when the user can not read board
      behaves like returns an error
        fails with error

JiraConnect::EventsController
  #installed
    saves the jira installation data
    saves the correct values
    behaves like verifies asymmetric JWT token
      when token is valid
        renders successful
      when token is invalid
        renders unauthorized
    when the shared_secret param is missing
      returns 422
    when an installation already exists
      validates the JWT token in authorization header and returns 200 without creating a new installation
      uses the JiraConnectInstallations::UpdateService
      when parameters include a new shared secret and base_url
        updates the installation
      when the new base_url is invalid
        renders 422
    when enforce_jira_base_url_https
      behaves like generates JWT validation claims
        is expected to receive new(anything, {:aud=>"https://test.host/-/jira_connect", :iss=>anything, :qsh=>anything}) 1 time
    when not enforce_jira_base_url_https
      behaves like generates JWT validation claims
        is expected to receive new(anything, {:aud=>"http://test.host/-/jira_connect", :iss=>anything, :qsh=>anything}) 1 time
  #uninstalled
    behaves like verifies asymmetric JWT token
      when token is valid
        renders successful
      when token is invalid
        renders unauthorized
    when JWT is invalid
      does not delete the installation
    when JWT is valid
      calls the DestroyService and returns ok in case of success
      calls the DestroyService and returns unprocessable_entity in case of failure

Emails::Releases
  #new_release_email
    contains a message with the new release tag
    contains the release assets
    contains the release notes
    behaves like an email sent from GitLab
      has the characteristics of an email sent from GitLab
    behaves like an email with X-GitLab headers containing project details
      has X-GitLab-Project headers
    when the release has a name
      shows the correct subject
    when the release does not have a name
      shows the correct subject
    release notes with attachment
      renders absolute links

Getting designs related to an issue
  is not too deep for anonymous users
  behaves like a working graphql query
    returns a successful response
  behaves like a noteable graphql type we can query
    .discussions
      can fetch discussions
      can fetch discussion noteable
    .notes
      can fetch notes

Clusters::Agents::DashboardController
  # order random
  GET show
    with authorized user
      sets the kas cookie
      returns not found
      with k8s_dashboard feature flag disabled
        does not set the kas cookie
        returns not found
    with unauthorized user
      does not set the kas cookie
      returns not found

Project.user_access_authorized_agents
  # order random
  with group authorization
    returns the authorized agent
    when user is developer in the agent management project
      returns the project information as well
    when user is reporter
      returns nothing
  with project authorization
    returns the authorized agent
    when user is developer in the agent management project
      returns the project information as well
    when user is reporter
      returns nothing
  when deployment project is not authorized to user_access to the agent
    returns empty

IssuableCollections
  #page_count_for_relation
    row count is known
      returns the number of pages
    row_count is unknown
      page_param: nil, expected: 2
        returns current page + 1 if the row count is unknown
      page_param: 1, expected: 2
        returns current page + 1 if the row count is unknown
      page_param: "1", expected: 2
        returns current page + 1 if the row count is unknown
      page_param: 2, expected: 3
        returns current page + 1 if the row count is unknown
  #finder_options
    scalar params
      only allows allowlisted params
    array params
      only allows allowlisted params
    search using an issue iid
      mutates the search into a filter by iid

Projects::Analytics::CycleAnalytics::SummaryController
  GET "show"
    succeeds
    when analytics_disabled features are disabled
      renders 404
    when user is not part of the project
      renders 404
    when filters are applied
      filters by author username
      filters by milestone title

API::Ci::Runner
  /api/v4/runners
    POST /api/v4/runners/verify
      behaves like runner migrations backoff
        when executing locking database migrations
          returns 429 error
          with runner_migrations_backoff disabled
            does not return 429
      when no token is provided
        returns 400 error
      when invalid token is provided
        returns 403 error
      when valid token is provided
        verifies Runner credentials
        updates contacted_at
        with glrt-prefixed token
          verifies Runner credentials
          does not update contacted_at
        with non-expiring runner token
          verifies Runner credentials
        behaves like storing arguments in the application context for the API
          places the expected params in the application context
        when system_id is provided
          creates a runner_manager
      when non-expired token is provided
        verifies Runner credentials
      when expired token is provided
        does not verify Runner credentials

ChecksCollaboration
  #can_collaborate_with_project?
    is true if the user can push to the project
    is true when the user can push to a branch of the project
    when the user has forked the project
      is true
      is false when the project is archived

Query.project.job
  # order random
  when the user can read jobs on the project
    returns the job that matches the given ID
    when no job matches the given ID
      returns null
  when the user cannot read jobs on the project
    returns null

Subscriptions::Notes::Deleted
  # order random
  when user is authorized
    receives note id that is removed
    when last discussion note is deleted
      receives note id that is removed
    when note is confidential
      receives note id that is removed
  when user is unauthorized
    does not receive any data

Projects::Aws::ConfigurationController
  # order random
  when accessed by authorized members
    returns successful
    when feature flag is disabled
      renders not found
  when accessed by unauthorized members
    returns not found on GET request

groups autocomplete
  #issues
    issue_types: nil, expected: :all
      returns the correct response
    issue_types: "", expected: :all
      returns the correct response
    issue_types: "invalid", expected: :none
      returns the correct response
    issue_types: "issue", expected: :issue
      returns the correct response
    issue_types: "incident", expected: :incident
      returns the correct response
  #milestones
    returns correct response

Mutations::Achievements::Delete
  # order random
  when the user does not have permission
    does not revoke any achievements
    behaves like a mutation that returns a top-level access error
      is expected to contain exactly "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
  when the user has permission
    deletes the achievement
    when the params are invalid
      returns the validation error
    when the achievement_id is invalid
      returns the validation error
    when the feature flag is disabled
      returns the relevant error

Admin::DashboardController
  #index
    retrieves Redis versions
    with pending_delete projects
      does not retrieve projects that are pending deletion

getting branch protection for a branch rule
  # order random
  when the user does have read_protected_branch abilities
    includes allow_force_push
    behaves like a working graphql query
      returns a successful response
  when the user does not have read_protected_branch abilities
    is expected not to be present
    behaves like a working graphql query
      returns a successful response

Repositioning an ImageDiffNote
  updates the note
  when the note is not a DiffNote
    behaves like a mutation that returns top-level errors
      is expected to include /does not represent an instance of DiffNote/
  when a position arg is nil
    does not set the property to nil
  when all position args are nil
    behaves like a mutation that returns top-level errors
      is expected to include /At least one property of `UpdateDiffImagePositionInput` must be set/

abuse_report
  # order random
  returns abuse report with labels
  behaves like a working graphql query that returns data
    contains data
    behaves like a working graphql query
      returns a successful response
  when current user is not an admin
    does not contain any data
    behaves like a working graphql query
      returns a successful response

AcmeChallengesController
  #show
    with right domain and token
      renders acme challenge file content
    when domain is invalid
      renders not found
    when token is invalid
      renders not found

GroupMember
  behaves like a working graphql query
    returns a successful response
  behaves like a working membership object query
    contains edge to expected project
    contains correct access level

PipelineSchedulecreate
  # order random
  when authorized
    when success
      is expected to eq []
    when failure
      when params are invalid
        is expected to contain exactly "Cron  is invalid syntax" and "Cron timezone  is invalid syntax"
      when variables have duplicate name
        returns error
  when unauthorized
    behaves like a mutation on an unauthorized resource
      behaves like a mutation that returns top-level errors
        is expected to contain exactly "The resource that you are attempting to access does not exist or you don't have permission to perform this action"

getting a list of work item types for a project
  when user has access to the project
    returns all default work item types
    behaves like a working graphql query
      returns a successful response
  when user doesn't have access to the project
    does not return the project

Delete a timelog
  when the user is not allowed to delete a timelog
    behaves like a mutation that returns a top-level access error
      is expected to contain exactly "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
  when user has permissions to delete a timelog
    deletes the timelog

getting a list of work item types for a group
  when user has access to the group
    returns all default work item types
    behaves like a working graphql query
      returns a successful response
  when user doesn't have access to the group
    does not return the group

Removing an incident timeline event
  # order random
  removes incident timeline event

MetricsController
  #index
    accessed from whitelisted ip
      behaves like providing metrics
        returns prometheus metrics
        prometheus metrics are disabled
          returns proper response
    accessed from ip in whitelisted range
      behaves like providing metrics
        returns prometheus metrics
        prometheus metrics are disabled
          returns proper response
    accessed from not whitelisted ip
      returns the expected error response
  #system
    accessed from whitelisted ip
      behaves like providing system stats
        renders system stats JSON
    accessed from ip in whitelisted range
      behaves like providing system stats
        renders system stats JSON
    accessed from not whitelisted ip
      returns the expected error response

SpammableActions::CaptchaCheck::HtmlFormatActionsSupport
  #convert_html_spam_params_to_headers
    converts params to headers
  #with_captcha_check_html_format
    when spammable.render_recaptcha? is true
      renders :captcha_check
    when spammable.render_recaptcha? is false
      yields to block

MetricsController
  # order random
  behaves like Base action controller
    security headers
      Cross-Origin-Opener-Policy
        sets the header
        when coop_header feature flag is disabled
          does not set the header

PlanningHierarchy
  GET #planning_hierarchy
    renders planning hierarchy

RedirectsForMissingPathOnTree
  #redirect_to_root_path
    redirects to the tree path with a notice

Projects::PipelinesSettingsController
  GET show
    redirects with 302 status code

getting a repository in a project
  behaves like a working graphql query
    returns a successful response

Admin::Topics::AvatarsController
  removes avatar from DB by calling destroy

Analytics::CycleAnalytics::ValueStreamActions
  # order random
  #namespace
    raises NotImplementedError
Knapsack report was generated. Preview:
{
  "spec/requests/api/projects_spec.rb": 336.73490678000053,
  "spec/requests/api/branches_spec.rb": 187.41811543199947,
  "spec/requests/rack_attack_global_spec.rb": 142.53706979299932,
  "spec/controllers/projects/notes_controller_spec.rb": 123.7668682500007,
  "spec/requests/api/wikis_spec.rb": 78.29951204199824,
  "spec/requests/api/usage_data_queries_spec.rb": 72.03200376099994,
  "spec/requests/api/graphql/project/issues_spec.rb": 57.07294570100021,
  "spec/controllers/projects/merge_requests/drafts_controller_spec.rb": 47.18806107000091,
  "spec/requests/api/helm_packages_spec.rb": 30.93652722600018,
  "spec/controllers/omniauth_callbacks_controller_spec.rb": 30.274949575999926,
  "spec/controllers/projects/environments_controller_spec.rb": 22.29731100599929,
  "spec/controllers/projects/merge_requests/creations_controller_spec.rb": 34.920851090000724,
  "spec/requests/api/ci/pipeline_schedules_spec.rb": 28.722552847999395,
  "spec/controllers/projects/feature_flags_controller_spec.rb": 16.60029073899932,
  "spec/controllers/projects/snippets_controller_spec.rb": 22.309279069000695,
  "spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb": 16.98672431399973,
  "spec/controllers/projects/commits_controller_spec.rb": 23.32130183299887,
  "spec/requests/api/graphql/user_query_spec.rb": 18.15357050700004,
  "spec/requests/jira_routing_spec.rb": 17.318071083000177,
  "spec/requests/jwt_controller_spec.rb": 15.809513611999137,
  "spec/requests/api/namespaces_spec.rb": 12.761863120000271,
  "spec/controllers/groups/uploads_controller_spec.rb": 13.30918365999969,
  "spec/requests/api/task_completion_status_spec.rb": 11.48044827800004,
  "spec/requests/projects/clusters/integrations_controller_spec.rb": 13.183113562001381,
  "spec/mailers/emails/pages_domains_spec.rb": 6.434129260998816,
  "spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb": 10.47752293999838,
  "spec/requests/api/graphql/ci/config_spec.rb": 8.91969021299883,
  "spec/requests/api/error_tracking/project_settings_spec.rb": 5.51005721600086,
  "spec/requests/api/graphql/packages/pypi_spec.rb": 9.837691138000082,
  "spec/requests/api/graphql/mutations/award_emojis/add_spec.rb": 9.004049974999361,
  "spec/requests/api/graphql/mutations/ci/runner/create_spec.rb": 8.654733606999798,
  "spec/controllers/import/bulk_imports_controller_spec.rb": 3.7552654490009445,
  "spec/requests/api/graphql/project/tree/tree_spec.rb": 6.981818261001536,
  "spec/requests/api/graphql/mutations/releases/delete_spec.rb": 8.396884600000703,
  "spec/requests/api/graphql/mutations/issues/bulk_update_spec.rb": 6.77003551999951,
  "spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb": 7.783088346999648,
  "spec/requests/api/graphql/project/environments_spec.rb": 6.695884415999899,
  "spec/requests/api/graphql/mutations/issues/create_spec.rb": 6.48225225600072,
  "spec/requests/api/group_container_repositories_spec.rb": 6.33191898000041,
  "spec/controllers/admin/sessions_controller_spec.rb": 4.4992215980000765,
  "spec/requests/api/admin/plan_limits_spec.rb": 2.786761014000149,
  "spec/requests/api/pages/pages_spec.rb": 3.084547427999496,
  "spec/requests/api/graphql/mutations/work_items/convert_spec.rb": 4.381084607999583,
  "spec/requests/api/graphql/ci/job_spec.rb": 4.205953536000379,
  "spec/controllers/admin/impersonations_controller_spec.rb": 3.9967380950001825,
  "spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb": 2.6993139999995037,
  "spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb": 3.5572586380003486,
  "spec/controllers/jira_connect/events_controller_spec.rb": 1.9702078549998987,
  "spec/mailers/emails/releases_spec.rb": 3.084685122999872,
  "spec/requests/api/graphql/project/issue/designs/notes_spec.rb": 2.442312191000383,
  "spec/requests/clusters/agents/dashboard_controller_spec.rb": 2.572698240999671,
  "spec/requests/api/graphql/project/user_access_authorized_agents_spec.rb": 2.6307283160003863,
  "spec/controllers/concerns/issuable_collections_spec.rb": 1.2690529560004506,
  "spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb": 1.893016499998339,
  "spec/requests/api/ci/runner/runners_verify_post_spec.rb": 1.561787374999767,
  "spec/controllers/concerns/checks_collaboration_spec.rb": 2.763781196999844,
  "spec/requests/api/graphql/project/job_spec.rb": 2.6614371630003006,
  "spec/requests/api/graphql/subscriptions/notes/deleted_spec.rb": 2.1017890850016556,
  "spec/requests/projects/aws/configuration_controller_spec.rb": 2.2330359349998616,
  "spec/requests/groups/autocomplete_sources_spec.rb": 2.1378435019996687,
  "spec/requests/api/graphql/mutations/achievements/delete_spec.rb": 1.7060197050013812,
  "spec/controllers/admin/dashboard_controller_spec.rb": 1.5989041530010581,
  "spec/requests/api/graphql/project/branch_rules/branch_protection_spec.rb": 1.7795620699998835,
  "spec/requests/api/graphql/mutations/notes/reposition_image_diff_note_spec.rb": 1.6731449060007435,
  "spec/requests/api/graphql/abuse_report_spec.rb": 1.342453891000332,
  "spec/controllers/acme_challenges_controller_spec.rb": 2.158353441000145,
  "spec/requests/api/graphql/user/group_member_query_spec.rb": 0.9009071039999981,
  "spec/requests/api/graphql/mutations/ci/pipeline_schedule/create_spec.rb": 1.6089146110007277,
  "spec/requests/api/graphql/project/work_item_types_spec.rb": 1.2207733800005371,
  "spec/requests/api/graphql/mutations/timelogs/delete_spec.rb": 1.3970146570009092,
  "spec/requests/api/graphql/group/work_item_types_spec.rb": 1.0150757749997865,
  "spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb": 1.3794735980009136,
  "spec/controllers/metrics_controller_spec.rb": 0.680942249000509,
  "spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb": 0.8009664009987318,
  "spec/requests/metrics_controller_spec.rb": 0.28282195900101215,
  "spec/requests/concerns/planning_hierarchy_spec.rb": 0.9070481929993548,
  "spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb": 0.738814476000698,
  "spec/controllers/projects/pipelines_settings_controller_spec.rb": 0.6963117089999287,
  "spec/requests/api/graphql/project/container_expiration_policy_spec.rb": 0.6696556700007932,
  "spec/controllers/admin/topics/avatars_controller_spec.rb": 0.3570382840007369,
  "spec/controllers/concerns/analytics/cycle_analytics/value_stream_actions_spec.rb": 0.1894666860007419
}

Knapsack global time execution for tests: 26m 07s

Pending: (Failures listed here are expected and do not affect your suite's status)

  1) Projects::DesignManagement::Designs::RawImagesController GET #show behaves like a controller that can serve LFS files when lfs is not enabled delivers ASCII file
     # Calling spec asked to skip testing LFS disabled scenario
     # ./spec/support/shared_examples/controllers/repository_lfs_file_load_shared_examples.rb:152

Failures:

  1) API::Projects GET /users/:user_id/contributed_projects/ with a private profile user does not have access to view the private profile returns no projects
     Failure/Error: expect(json_response).to be_empty
       expected `[{"_links"=>{"cluster_agents"=>"http://localhost/api/v4/projects/95/cluster_agents", "events"=>"http:..."=>"http://localhost/namespace27/my-project", "wiki_access_level"=>"enabled", "wiki_enabled"=>true}].empty?` to be truthy, got false
     # ./spec/requests/api/projects_spec.rb:1905:in `block (5 levels) in <top (required)>'
     # ./spec/spec_helper.rb:440:in `block (3 levels) in <top (required)>'
     # ./spec/support/sidekiq_middleware.rb:18:in `with_sidekiq_server_middleware'
     # ./spec/spec_helper.rb:431:in `block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:427:in `block (3 levels) in <top (required)>'
     # ./lib/gitlab/application_context.rb:66:in `with_raw_context'
     # ./spec/spec_helper.rb:427:in `block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:267:in `block (2 levels) in <top (required)>'
     # ./spec/support/system_exit_detected.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/support/fast_quarantine.rb:22:in `block (2 levels) in <top (required)>'
     # ./spec/support/database/prevent_cross_joins.rb:106:in `block (3 levels) in <top (required)>'
     # ./spec/support/database/prevent_cross_joins.rb:60:in `with_cross_joins_prevented'
     # ./spec/support/database/prevent_cross_joins.rb:106:in `block (2 levels) in <top (required)>'

Finished in 26 minutes 9 seconds (files took 44.34 seconds to load)
2779 examples, 1 failure, 1 pending

Failed examples:

rspec ./spec/requests/api/projects_spec.rb:1899 # API::Projects GET /users/:user_id/contributed_projects/ with a private profile user does not have access to view the private profile returns no projects

Randomized with seed 1666

[TEST PROF INFO] Time spent in factories: 09:22.112 (35.7% of total time)
Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected
RSpec exited with 1.
[job-metrics] Updating job metrics tag for the CI/CD job.
RSPEC_RETRIED_TESTS_REPORT_PATH: rspec/retried_tests-5328358281.txt
Retrying the failing examples in a new RSpec process...
$ gem install junit_merge --no-document --version 0.1.2
Successfully installed nokogiri-1.15.4-x86_64-linux
Successfully installed junit_merge-0.1.2
2 gems installed
==> 'gem install junit_merge --no-document --version 0.1.2' succeeded in 1 seconds.
Running RSpec command: bin/rspec -Ispec -rspec_helper --color --failure-exit-code 1 --error-exit-code 2 --format documentation --format Support::Formatters::JsonFormatter --out rspec/rspec-retry-5328358281.json --format RspecJunitFormatter --out rspec/rspec-retry-5328358281.xml --only-failures --pattern "spec/{commands,controllers,mailers,requests}{,/**/}*_spec.rb"
/builds/gitlab-org/gitlab/ee/app/services/remote_development/service_response_factory.rb:41: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/workspaces/create_service.rb:28: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/workspaces/reconcile_service.rb:38: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/app/services/remote_development/workspaces/update_service.rb:28: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/agent_config/main.rb:32: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/agent_config/updater.rb:11: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/authorizer.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/authorizer.rb:13: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/creator.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/creator.rb:19: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/devfile_fetcher.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/devfile_fetcher.rb:16: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/devfile_flattener.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:17: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/editor_component_injector.rb:18: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/personal_access_token_creator.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/personal_access_token_creator.rb:17: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:43: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:54: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:102: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:126: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:159: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:202: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/post_flatten_devfile_validator.rb:235: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/pre_flatten_devfile_validator.rb:24: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/pre_flatten_devfile_validator.rb:52: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:17: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:18: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/project_cloner_component_injector.rb:23: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/volume_component_injector.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/volume_component_injector.rb:13: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/volume_component_injector.rb:14: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:24: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:25: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_creator.rb:28: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/create/workspace_variables_creator.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/main.rb:43: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/update/authorizer.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/update/updater.rb:13: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/agent_infos_observer.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_extractor.rb:14: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_extractor.rb:16: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_to_infos_converter.rb:14: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/input/params_validator.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/output/rails_infos_observer.rb:11: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/output/workspaces_to_rails_infos_converter.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/orphaned_workspaces_observer.rb:12: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_from_agent_infos_updater.rb:15: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_to_be_returned_finder.rb:16: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
/builds/gitlab-org/gitlab/ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_to_be_returned_updater.rb:11: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
Run options: include {:last_run_status=>"failed"}

Test environment set up in 0.365757193 seconds

API::Projects
  GET /users/:user_id/contributed_projects/
    with a private profile
      user does not have access to view the private profile
        returns no projects

Finished in 8.94 seconds (files took 37.17 seconds to load)
1 example, 0 failures

[TEST PROF INFO] Time spent in factories: 00:03.609 (32.96% of total time)
Loading rspec/rspec-5328358281.json...
Merged rspec/rspec-retry-5328358281.json adding 4 results.
Saved rspec/rspec-5328358281.json.
A test was flaky and succeeded after being retried. Checking to see if flaky test is part of this MR...
Flaky test was not part of this MR.
section_end:1697711797:step_script
section_start:1697711797:after_script
Running after_script
Running after script...
$ echo -e "\e[0Ksection_start:`date +%s`:report_results_section[collapsed=true]\r\e[0KReport results"
section_start:1697711798:report_results_section[collapsed=true]
Report results
$ if [ "$CREATE_RAILS_TEST_FAILURE_ISSUES" == "true" ]; then # collapsed multi-line command
Reporting slow tests in MR 134621
=> Reporting 1 tests in rspec/rspec-5328358281.json
=> Reporting 1 tests in rspec/rspec-retry-5328358281.json
$ echo -e "\e[0Ksection_end:`date +%s`:report_results_section\r\e[0K"
section_end:1697711800:report_results_section

$ tooling/bin/push_job_metrics || true
[job-metrics] Pushing job metrics file for the CI/CD job.
[job-metrics] Pushed 4 CI job metric entries to InfluxDB.
section_end:1697711801:after_script
section_start:1697711801:archive_cache
Saving cache for successful job
Not uploading cache ruby-gems-debian-bullseye-ruby-3.0-16 due to policy
section_end:1697711802:archive_cache
section_start:1697711802:upload_artifacts_on_success
Uploading artifacts for successful job
Uploading artifacts...
WARNING: auto_explain/: no matching files. Ensure that the artifact path is relative to the working directory (/builds/gitlab-org/gitlab) 
coverage/: found 4 matching artifact files and directories 
crystalball/: found 2 matching artifact files and directories 
WARNING: deprecations/: no matching files. Ensure that the artifact path is relative to the working directory (/builds/gitlab-org/gitlab) 
knapsack/: found 4 matching artifact files and directories 
rspec/: found 19 matching artifact files and directories 
WARNING: tmp/capybara/: no matching files. Ensure that the artifact path is relative to the working directory (/builds/gitlab-org/gitlab) 
log/*.log: found 17 matching artifact files and directories 
WARNING: Upload request redirected                  location=https://gitlab.com/api/v4/jobs/5328358281/artifacts?artifact_format=zip&artifact_type=archive&expire_in=31d new-url=https://gitlab.com
WARNING: Retrying...                                context=artifacts-uploader error=request redirected
Uploading artifacts as "archive" to coordinator... 201 Created  id=5328358281 responseStatus=201 Created token=64_Fm3NK
Uploading artifacts...
rspec/rspec-*.xml: found 2 matching artifact files and directories 
WARNING: Upload request redirected                  location=https://gitlab.com/api/v4/jobs/5328358281/artifacts?artifact_format=gzip&artifact_type=junit&expire_in=31d new-url=https://gitlab.com
WARNING: Retrying...                                context=artifacts-uploader error=request redirected
Uploading artifacts as "junit" to coordinator... 201 Created  id=5328358281 responseStatus=201 Created token=64_Fm3NK
section_end:1697711806:upload_artifacts_on_success
section_start:1697711806:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1697711806:cleanup_file_variables
Job succeeded