summaryrefslogtreecommitdiffhomepage
path: root/packages/enterprise/test
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-12-01 16:35:03 -0500
committerDax Raad <[email protected]>2025-12-01 16:35:07 -0500
commit3d99dc78dbff982cde6dd61a0629b7ee9de1a8f3 (patch)
tree4c8dabb52db7c26d2d412c1be861f7599168a7d3 /packages/enterprise/test
parent95c3a8b80505fcb3140989daf6fece3377aa3b95 (diff)
downloadopencode-3d99dc78dbff982cde6dd61a0629b7ee9de1a8f3.tar.gz
opencode-3d99dc78dbff982cde6dd61a0629b7ee9de1a8f3.zip
core: reduce latency when loading shared sessions through event compaction
Diffstat (limited to 'packages/enterprise/test')
-rw-r--r--packages/enterprise/test/core/share.test.ts269
-rw-r--r--packages/enterprise/test/core/storage.test.ts67
2 files changed, 336 insertions, 0 deletions
diff --git a/packages/enterprise/test/core/share.test.ts b/packages/enterprise/test/core/share.test.ts
new file mode 100644
index 000000000..d3bf6a2c2
--- /dev/null
+++ b/packages/enterprise/test/core/share.test.ts
@@ -0,0 +1,269 @@
+import { describe, expect, test, afterAll } from "bun:test"
+import { Share } from "../../src/core/share"
+import { Storage } from "../../src/core/storage"
+import { Identifier } from "@opencode-ai/util/identifier"
+
+describe.concurrent("core.share", () => {
+ test("should create a share", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ expect(share.sessionID).toBe(sessionID)
+ expect(share.secret).toBeDefined()
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should sync data to a share", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello" },
+ },
+ ]
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data,
+ })
+
+ const events = await Storage.list({ prefix: ["share_event", share.id] })
+ expect(events.length).toBe(1)
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should sync multiple batches of data", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data1: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello" },
+ },
+ ]
+
+ const data2: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part2", sessionID, messageID: "msg1", type: "text", text: "World" },
+ },
+ ]
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data1,
+ })
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data2,
+ })
+
+ const events = await Storage.list({ prefix: ["share_event", share.id] })
+ expect(events.length).toBe(2)
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should retrieve synced data", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello" },
+ },
+ {
+ type: "part",
+ data: { id: "part2", sessionID, messageID: "msg1", type: "text", text: "World" },
+ },
+ ]
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data,
+ })
+
+ const result = await Share.data(share.id)
+
+ expect(result.length).toBe(2)
+ expect(result[0].type).toBe("part")
+ expect(result[1].type).toBe("part")
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should retrieve data from multiple syncs", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data1: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello" },
+ },
+ ]
+
+ const data2: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part2", sessionID, messageID: "msg2", type: "text", text: "World" },
+ },
+ ]
+
+ const data3: Share.Data[] = [
+ { type: "part", data: { id: "part3", sessionID, messageID: "msg3", type: "text", text: "!" } },
+ ]
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data1,
+ })
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data2,
+ })
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data3,
+ })
+
+ const result = await Share.data(share.id)
+
+ expect(result.length).toBe(3)
+ const parts = result.filter((d) => d.type === "part")
+ expect(parts.length).toBe(3)
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should return latest data when syncing duplicate parts", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data1: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello" },
+ },
+ ]
+
+ const data2: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello Updated" },
+ },
+ ]
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data1,
+ })
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data: data2,
+ })
+
+ const result = await Share.data(share.id)
+
+ expect(result.length).toBe(1)
+ const [first] = result
+ expect(first.type).toBe("part")
+ expect(first.type === "part" && first.data.type === "text" && first.data.text).toBe("Hello Updated")
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should return empty array for share with no data", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const result = await Share.data(share.id)
+
+ expect(result).toEqual([])
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should throw error for invalid secret", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Test" },
+ },
+ ]
+
+ expect(async () => {
+ await Share.sync({
+ share: { id: share.id, secret: "invalid-secret" },
+ data,
+ })
+ }).toThrow()
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ test("should throw error for non-existent share", async () => {
+ const sessionID = Identifier.descending()
+ const data: Share.Data[] = [
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Test" },
+ },
+ ]
+
+ expect(async () => {
+ await Share.sync({
+ share: { id: "non-existent-id", secret: "some-secret" },
+ data,
+ })
+ }).toThrow()
+ })
+
+ test("should handle different data types", async () => {
+ const sessionID = Identifier.descending()
+ const share = await Share.create({ sessionID })
+
+ const data: Share.Data[] = [
+ { type: "session", data: { id: sessionID, status: "running" } as any },
+ { type: "message", data: { id: "msg1", sessionID } as any },
+ {
+ type: "part",
+ data: { id: "part1", sessionID, messageID: "msg1", type: "text", text: "Hello" },
+ },
+ ]
+
+ await Share.sync({
+ share: { id: share.id, secret: share.secret },
+ data,
+ })
+
+ const result = await Share.data(share.id)
+
+ expect(result.length).toBe(3)
+ expect(result.some((d) => d.type === "session")).toBe(true)
+ expect(result.some((d) => d.type === "message")).toBe(true)
+ expect(result.some((d) => d.type === "part")).toBe(true)
+
+ await Share.remove({ id: share.id, secret: share.secret })
+ })
+
+ afterAll(async () => {
+ const files = await Storage.list()
+ for (const file of files) {
+ Storage.remove(file)
+ }
+ })
+})
diff --git a/packages/enterprise/test/core/storage.test.ts b/packages/enterprise/test/core/storage.test.ts
new file mode 100644
index 000000000..27e51384c
--- /dev/null
+++ b/packages/enterprise/test/core/storage.test.ts
@@ -0,0 +1,67 @@
+import { describe, expect, test, afterAll } from "bun:test"
+import { Storage } from "../../src/core/storage"
+
+describe("core.storage", () => {
+ test("should list files with start and end range", async () => {
+ await Storage.write(["test", "users", "user1"], { name: "user1" })
+ await Storage.write(["test", "users", "user2"], { name: "user2" })
+ await Storage.write(["test", "users", "user3"], { name: "user3" })
+ await Storage.write(["test", "users", "user4"], { name: "user4" })
+ await Storage.write(["test", "users", "user5"], { name: "user5" })
+
+ const result = await Storage.list({ prefix: ["test", "users"], start: "user2", end: "user4" })
+
+ expect(result).toEqual([
+ ["test", "users", "user3"],
+ ["test", "users", "user4"],
+ ])
+ })
+
+ test("should list files with start only", async () => {
+ const result = await Storage.list({ prefix: ["test", "users"], start: "user3" })
+
+ expect(result).toEqual([
+ ["test", "users", "user4"],
+ ["test", "users", "user5"],
+ ])
+ })
+
+ test("should list files with limit", async () => {
+ const result = await Storage.list({ prefix: ["test", "users"], limit: 3 })
+
+ expect(result).toEqual([
+ ["test", "users", "user1"],
+ ["test", "users", "user2"],
+ ["test", "users", "user3"],
+ ])
+ })
+
+ test("should list all files without prefix", async () => {
+ const result = await Storage.list()
+
+ expect(result.length).toBeGreaterThan(0)
+ })
+
+ test("should list all files with prefix", async () => {
+ const result = await Storage.list({ prefix: ["test", "users"] })
+
+ expect(result).toEqual([
+ ["test", "users", "user1"],
+ ["test", "users", "user2"],
+ ["test", "users", "user3"],
+ ["test", "users", "user4"],
+ ["test", "users", "user5"],
+ ])
+ })
+
+ afterAll(async () => {
+ const testFiles = await Storage.list({ prefix: ["test"] })
+
+ for (const file of testFiles) {
+ await Storage.remove(file)
+ }
+
+ const remainingFiles = await Storage.list({ prefix: ["test"] })
+ expect(remainingFiles).toEqual([])
+ })
+})