Files
water/docs/superpowers/plans/2026-07-16-app-controller-concurrency-test.md
yuhaiming 70e2356f22 fix(app): 修复 AppController 安全与查询问题
- 加强异常处理、类型安全和图片上传校验
- 优化设备相关查询,避免重复访问数据源
- 补充并记录并发测试与审查修复实施计划
2026-07-17 08:20:44 +08:00

3.1 KiB

AppController Concurrency Test Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Add repeatable 32-thread unit concurrency tests for the singleton AppController without live infrastructure.

Architecture: Create one standalone JUnit 5 test class with a shared controller instance and mocked collaborators. A fixed thread pool, ready latch, start latch, and bounded Future#get synchronize each test; concurrent collections retain observations for deterministic assertions after workers finish.

Tech Stack: Java 17, JUnit 5, Mockito, AssertJ, Spring MockMultipartFile, Maven Surefire.

Global Constraints

  • Do not modify production code unless a concurrency failure is reproduced.
  • Use exactly 32 worker threads per test.
  • Do not connect to MySQL, Redis, MQTT, or OSS.
  • Every future must have a bounded timeout.
  • Use one shared AppController instance within each test.

Task 1: Add AppController Concurrency Coverage

Files:

  • Create: water-modules/water-app/src/test/java/org/dromara/app/controller/AppControllerConcurrencyTest.java

Interfaces:

  • Consumes: AppController.switchDevice(String), uploadImage(MultipartFile), and editScheduleStatus(AppScheduleBo).

  • Produces: three repeatable JUnit concurrency tests and shared executor helpers.

  • Step 1: Create the concurrency test fixture

Add Mockito mocks for all constructor dependencies, construct one controller per test, register an ObjectMapper in a GenericApplicationContext, and add a helper that submits 32 workers behind ready/start latches.

  • Step 2: Add concurrent timestamp formatting test

Run 32 workers with 100 calls each. Capture every startTime, require 3,200 successful responses and invocations, and parse every captured value with strict yyyy-MM-dd HH:mm:ss formatting.

  • Step 3: Add concurrent image validation test

Run 32 workers with 50 uploads each, cycling through JPEG, PNG, GIF, WebP, and BMP signatures. Require 1,600 successful responses and OSS calls.

  • Step 4: Add concurrent schedule payload isolation test

Run 32 workers with 20 unique schedules each. Scope LoginHelper.getUserId() to each worker, generate a unique device and detail marker per schedule, capture MQTT payloads in a ConcurrentHashMap, and verify all 640 payloads contain their matching values.

  • Step 5: Run the focused concurrency test
mvn -pl water-modules/water-app -am "-DskipTests=false" "-Dmaven.test.skip=false" "-Dprofiles.active=dev" "-Dtest=AppControllerConcurrencyTest" "-Dsurefire.failIfNoSpecifiedTests=false" test

Expected: 3 tests pass with zero failures, errors, and timeouts.

  • Step 6: Run the full water-app suite and diff checks
mvn -pl water-modules/water-app -am "-DskipTests=false" "-Dmaven.test.skip=false" "-Dprofiles.active=dev" test
git diff --check

Expected: reactor BUILD SUCCESS; all tests pass; git diff --check exits 0.