{
 "ticket": "U32 #69",
 "startedAt": "2026-10-27T00:44:51.392529+08:00",
 "finishedAt": "2026-10-27T00:46:02.297238+08:00",
 "input": "python3 labs/cloud-gateway/run.py --redis-port=<本机Redis端口>",
 "exitCode": 0,
 "environment": {
  "jdk": "java version \"21.0.5\" 2024-10-15 LTS\nJava(TM) SE Runtime Environment (build 21.0.5+9-LTS-239)\nJava HotSpot(TM) 64-Bit Server VM (build 21.0.5+9-LTS-239, mixed mode, sharing)",
  "maven": "Apache Maven 3.9.0 (9b58d2bad23a66be161c4664ef21ce219c2c8584)\nMaven home: /Users/gaochao/develop/env/maven\nJava version: 21.0.5, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home\nDefault locale: zh_CN_#Hans, platform encoding: UTF-8\nOS name: \"mac os x\", version: \"26.7.1\", arch: \"x86_64\", family: \"mac\"",
  "os": "macOS-26.7.1-x86_64-i386-64bit-Mach-O",
  "arch": "x86_64",
  "python": "3.13.12",
  "redisPort": 6391,
  "dependencies": {
   "spring-cloud-commons": "5.0.4",
   "spring-cloud-gateway-server-webflux": "5.0.4",
   "spring-cloud-loadbalancer": "5.0.4",
   "spring-boot": "4.0.9",
   "spring-webflux": "7.0.10",
   "reactor-netty-http": "1.3.8",
   "spring-data-redis": "4.0.8",
   "spring-security-config": "7.0.8"
  }
 },
 "reports": [
  {
   "name": "study.gateway.GatewayHttpTest",
   "tests": "12",
   "failures": "0",
   "errors": "0",
   "skipped": "0"
  },
  {
   "name": "study.gateway.mvc.MvcHttpTest",
   "tests": "1",
   "failures": "0",
   "errors": "0",
   "skipped": "0"
  },
  {
   "name": "study.gateway.proxymvc.ProxyMvcHttpTest",
   "tests": "1",
   "failures": "0",
   "errors": "0",
   "skipped": "0"
  },
  {
   "name": "study.gateway.proxywebflux.ProxyWebfluxHttpTest",
   "tests": "1",
   "failures": "0",
   "errors": "0",
   "skipped": "0"
  }
 ],
 "testCount": 15,
 "results": [
  {
   "name": "jdk",
   "command": [
    "/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home/bin/java",
    "-version"
   ],
   "exitCode": 0,
   "observed": []
  },
  {
   "name": "maven",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-version"
   ],
   "exitCode": 0,
   "observed": []
  },
  {
   "name": "redis",
   "command": [
    "RESP",
    "INFO server",
    "127.0.0.1:6391"
   ],
   "exitCode": 0,
   "observed": [
    "redis_version:8.2.1",
    "os:Darwin 25.6.0 x86_64",
    "arch_bits:64"
   ]
  },
  {
   "name": "test-webflux",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-B",
    "-ntp",
    "-q",
    "-f",
    "/Users/gaochao/develop/workspace/software-engineering-study/labs/cloud-gateway/webflux/pom.xml",
    "-Dspring.data.redis.port=6391",
    "clean",
    "test"
   ],
   "exitCode": 0,
   "observed": [
    "U32 health=PASS oneUpB allDown503 bodyDown200A accepted204False recoveryA200=true",
    "U32 redisQuota=PASS alice200Then429 bob200 empty403 errorAllows200RemainingMinus1 carolFullAfterRecovery=true recovery429=true",
    "U32 redisOwnedKeysDeleted=true ownedKeyCount=6",
    "U32 supplierPolicies=PASS zoneAndHintFallback stickyB unknownCookieFallback weighted2A6B zeroWeightStillA subsetSize1Stable=true",
    "U32 pathQueryHeader=PASS unmatched404ThenRecovery200=true",
    "U32 retry=PASS configured3 finalAttempt4 noRetryAttempt1 postAttempt1=true recovery200=true",
    "U32 timeout=PASS slowHeader504 streamedBody200 elapsedMs=368 route100msNotWholeBodyDeadline=true recovery200=true",
    "U32 directoryCache=PASS directB staleA thenRefreshedB=true labTtl800msNotDefault35s=true",
    "U32 identity=PASS anonBadSignatureIssuerAudienceExpired401 scope403 forgedHeadersRemoved downstreamBearerRequired recovery200=true",
    "U32 directoryRoundRobin=PASS alternating2 empty503ThenA200=true",
    "U32 filterOrder=PASS mergedPreG0R10G20R30 reversePostR30G20R10G0=true",
    "U32 managementMetrics=PASS anonymous401 read403 opsRead200 firstRouteCountPlusOne=true readonlyPostRefresh404=true",
    "U32 untrustedForwarded=PASS forgedXffAndForwardedRemoved=true recovery200=true",
    "U32 redisLinkClosed=true",
    "U32 webfluxUpstreamsClosed=true count=2"
   ]
  },
  {
   "name": "test-mvc",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-B",
    "-ntp",
    "-q",
    "-f",
    "/Users/gaochao/develop/workspace/software-engineering-study/labs/cloud-gateway/mvc/pom.xml",
    "clean",
    "test"
   ],
   "exitCode": 0,
   "observed": [
    "U32 MVC HTTP: Tomcat path/body/headers=200; unmatched=404; empty-lb=503; upstream 200->503->200; targeted close"
   ]
  },
  {
   "name": "test-proxy-mvc",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-B",
    "-ntp",
    "-q",
    "-f",
    "/Users/gaochao/develop/workspace/software-engineering-study/labs/cloud-gateway/proxy-mvc/pom.xml",
    "clean",
    "test"
   ],
   "exitCode": 0,
   "observed": [
    "U32 PROXY MVC HTTP: Tomcat path/query/body/sensitive/skipped/mapper=200; local-forward=FORWARD; bad-prefix=400; unmatched=404; upstream 200->503->200; targeted close"
   ]
  },
  {
   "name": "test-proxy-webflux",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-B",
    "-ntp",
    "-q",
    "-f",
    "/Users/gaochao/develop/workspace/software-engineering-study/labs/cloud-gateway/proxy-webflux/pom.xml",
    "clean",
    "test"
   ],
   "exitCode": 0,
   "observed": [
    "U32 PROXY WEBFLUX HTTP: Netty path/query/body/sensitive/skipped/mapper=200; forward()=remote-POST; bad-prefix=400; unmatched=404; upstream 200->503->200; targeted close"
   ]
  },
  {
   "name": "dependency-webflux",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-B",
    "-ntp",
    "-q",
    "-f",
    "/Users/gaochao/develop/workspace/software-engineering-study/labs/cloud-gateway/webflux/pom.xml",
    "dependency:list",
    "-DoutputFile=/dev/stdout"
   ],
   "exitCode": 0,
   "observed": []
  },
  {
   "name": "maven-report",
   "command": [
    "/Users/gaochao/develop/env/maven/bin/mvn",
    "-version"
   ],
   "exitCode": 0,
   "observed": []
  }
 ],
 "artifacts": {
  "pom.xml": "919b87a501316105c65f2297af7886a287aa49c0d9e0a327f6f8c53cecbcbff3",
  "run.py": "0d301d40a81c6db96b09ebbf6a790a3424a8ad1375c4e6e0f9c447ea31c29530",
  "README.md": "62d375e10f8d9b8db04185b842e69089402e4af866b2c9714d21f9677b49a1ec",
  "mvc/pom.xml": "1e90a8a222b912e1442deffb6cefeacf33a680ad9b8c5cad99e16f8ab2be241e",
  "proxy-mvc/pom.xml": "0922978c65e36b90235818935a980b5928955d620448a753eb673e171b38f8e2",
  "proxy-webflux/pom.xml": "afa712295a23e593a73a25e634738a42d3707178f0632ccf4438585b49686b26",
  "webflux/pom.xml": "10f73ef1434c0839a3752cd851fe9482b5a29b144dcd0b67e9eb86597200e7d5",
  "mvc/src/main/java/study/gateway/mvc/MvcApplication.java": "3a71b56860ae3da5e070c67678b89dd510da312d514ec5a8c71477818f3b3602",
  "mvc/src/test/java/study/gateway/mvc/LoopbackUpstream.java": "917153a0c8750f94142e9e0a6d8bdd178c787d5e4c22f192578a1ee536ad74f8",
  "mvc/src/test/java/study/gateway/mvc/MvcHttpTest.java": "0159ffac68919051f54f609c118f0a69b5a56328c719a2847bbbbd37e895abed",
  "proxy-mvc/src/main/java/study/gateway/proxymvc/ProxyMvcApplication.java": "ff411126ab36bb7ba26b7d35c84084a5633364038d0fc71aac0de969f3bb9ac7",
  "proxy-mvc/src/test/java/study/gateway/proxymvc/LoopbackUpstream.java": "bacf1c15530dd701159f999c15397cb83f518a5f1a82b55724630c9600581f37",
  "proxy-mvc/src/test/java/study/gateway/proxymvc/ProxyMvcHttpTest.java": "e1694b3cab8ce5459d264b385f6e5566b28522e4568cb818c9716a0662c863f4",
  "proxy-webflux/src/main/java/study/gateway/proxywebflux/ProxyWebfluxApplication.java": "1718c82a0a644b0452a0aba5fec9c5aad33f177e7c7ffd48d2280b4d5ae1c457",
  "proxy-webflux/src/test/java/study/gateway/proxywebflux/LoopbackUpstream.java": "8d980674235ef87bddc7536397a99bb43227e118ca7e754ef270895e4cb2b1c3",
  "proxy-webflux/src/test/java/study/gateway/proxywebflux/ProxyWebfluxHttpTest.java": "1a4a72260f9d398e13c5c0f257a38f2694e87f7035338e5bd4057f9bc6e815a4",
  "webflux/src/test/java/study/gateway/GatewayApplication.java": "4a0787832ac3234132af2408242b05007e2c48330c4d684c393989609d468099",
  "webflux/src/test/java/study/gateway/GatewayHttpTest.java": "e2602a9db85c604cbd64506776974e9436e39a2c89929759ff19d83f08e47274",
  "webflux/src/test/java/study/gateway/JwtMaterial.java": "3a4fbd86d1762493cb5b7cb912fd7227b2e30181e4509da38c69907adca3dc33",
  "webflux/src/test/java/study/gateway/LabDirectory.java": "8dabcc0a1f8303a380bfa7446b00850737fef3e31952014d3e744d21cf6640d6",
  "webflux/src/test/java/study/gateway/LabLoadBalancer.java": "021d9514c439b4cfa5aedabd90759ffc3d6cbe078596b27541c869686584ae2f",
  "webflux/src/test/java/study/gateway/RateLimitResources.java": "8c1035ffccd02c050ae331edb4e95d2b57e7ac30124c0df7bd516d8350ff255d",
  "webflux/src/test/java/study/gateway/RedisLink.java": "fc7298c3fba4f8f8c6be87837ebfb9eddf5d720c22df24693a96601d3dcf72a5",
  "webflux/src/test/java/study/gateway/TraceGlobal.java": "9c7183402641ac5aace9d07bd6d34d92f23bbb4fc3cced64eaf226a0b10aa628",
  "webflux/src/test/java/study/gateway/Upstreams.java": "d81cb056ffd3bea22c679cb35ce4350fe6326d77f03ea845ab0763298553eb83",
  "mvc/src/main/resources/application.properties": "6755d092212993cd018ca067beccc87d5f4569d19fda1fa4950fea055edee823",
  "proxy-mvc/src/main/resources/application.properties": "6755d092212993cd018ca067beccc87d5f4569d19fda1fa4950fea055edee823",
  "proxy-webflux/src/main/resources/application.properties": "6755d092212993cd018ca067beccc87d5f4569d19fda1fa4950fea055edee823"
 },
 "logs": "/Users/gaochao/.cache/software-engineering-study/java-depth-impl/u32/run-sthpqups",
 "cleanup": {
  "redisKeys": "request_rate_limiter.{<routeId>.<user>}.tokens/timestamp 由用例删除并逐键 EXISTS 复核",
  "processes": "本入口创建的进程组已回收；Redis 为外部实例，只连其端口，不重启不改配置"
 },
 "limits": [
  "loopback HTTP 与受控上游；无真实注册中心、无集群、无生产网关",
  "限流后端为本机 Redis 单实例；未运行集群、故障转移或哨兵",
  "JWT 由本机 RSA 密钥签发，不是 IdP；管理端点鉴权为本地合成 ops 权限",
  "未运行吞吐/容量压测；容量结论为模型与配置推导"
 ]
}
