Skip to content

Add unit tests for CollaborationResource #6900

Description

@mengw15

Task Summary

CollaborationResource (amber/src/main/scala/org/apache/texera/web/resource/CollaborationResource.scala) is at 0% — all 87 tracked lines are unhit, and there is no spec. It looks websocket-bound but is not: the only dependency is the javax.websocket.Session interface, which mocks cleanly with the ScalaMock already on amber's test classpath. send is a one-hop session.getAsyncRemote.sendText, and every event carries a "type" discriminator from @JsonTypeInfo on CollabWebSocketEvent, so assertions are plain string matches. Roughly 70% of the file — about 60 of the 87 unhit lines — never touches SqlServer, and that is what this issue targets; the two DB-backed branches are scoped out below.

Behavior to add

Add amber/src/test/scala/org/apache/texera/web/resource/CollaborationResourceSpec.scala. Build a mockSession(id) helper returning a Session whose getId is fixed and whose getAsyncRemote.sendText is expectable.

Session lifecycle (no DB)

  • myOnOpen registers the session in sessionIdSessionMap.
  • myOnClose removes it and drops sessionIdWIdMap/wIdSessionIdsMap bookkeeping for the sender.

WIdRequest (no DB) — the authenticated path records sessionIdUIdMap(sessId) == uId; the anonymous path records sessionIdWIdMap(sessId) == DUMMY_WID. With two sessions on the same wid, assert both appear in wIdSessionIdsMap(wId) — the line building that set uses set.union(Set(senderSessId)), which returns a new set rather than mutating, and only survives because the result is reassigned. A multi-session test pins that.

Fan-out (no DB)CommandRequest and RestoreVersionRequest: with three sessions, two on wid 1 and one on wid 2, assert the same-wid peer receives exactly one message, the sender receives none, and the other workflow's session is untouched.

HeartBeatRequest (no DB) — a single HeartBeatResponse back to the sender only.

TryLockRequest, DUMMY_WID branch (no DB) — sends WorkflowAccessEvent(workflowReadonly = false) then LockGrantedEvent.

AcquireLockRequest (no DB) — pre-seed wIdLockHolderSessionIdMap; assert the previous holder gets ReleaseLockEvent, the requester gets LockGrantedEvent, and the holder map flips.

Out of scope

Two branches reach WorkflowAccessResource.hasWriteAccess and therefore SqlServer: the read-only TryLockRequest rejection, and the lock hand-off inside myOnClose. Leave both uncovered. Everything above runs in a single JVM against a mocked interface with no database, no filesystem and no network — keep the spec that way rather than pulling in MockTexeraDB, which would spawn an embedded Postgres process for two branches.

Ordering hazard — do not skip

The five object-level maps (sessionIdSessionMap, sessionIdWIdMap, sessionIdUIdMap, wIdSessionIdsMap, wIdLockHolderSessionIdMap) are JVM-wide mutable state. Clear all five in beforeEach or the suite becomes order-dependent — that is the only realistic flakiness vector here. There are no clocks, threads or temp files involved. Also note wIdLockHolderSessionIdMap deliberately stores a null sentinel for "no holder"; tests must distinguish absent-key from null-value.

Task Type

  • Refactor / Cleanup
  • DevOps / Deployment / CI
  • Testing / QA
  • Documentation
  • Performance
  • Other

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions