Repository navigation
Expand file tree
/
Copy pathembed-output.test.ts
More file actions
105 lines (99 loc) · 3.95 KB
/
Copy pathembed-output.test.ts
File metadata and controls
105 lines (99 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { describe, expect, it, vi } from 'vitest'
import { runEmbeddedCli } from './embed'
import { writeStderr } from './output/io'
const identity = { endpoint: 'https://sim.test', apiKey: 'fixture', workspaceId: 'workspace' }
function download(chunks: Uint8Array[], cancel = vi.fn()): Response {
let position = 0
return new Response(
new ReadableStream<Uint8Array>(
{
pull(controller) {
const chunk = chunks[position++]
if (chunk) controller.enqueue(chunk)
else controller.close()
},
cancel,
},
{ highWaterMark: 0 }
),
{ headers: { 'content-type': 'application/json' } }
)
}
describe('embedded output through the real command tree', () => {
it('preserves JSON, whitespace and split UTF-8 across arbitrary response chunks', async () => {
const content = ' {"city":"東京","emoji":"🛠️","lines":"one\\ntwo"}\n\n'
const bytes = Buffer.from(content)
const result = await runEmbeddedCli(['files', 'get', 'file'], {
...identity,
transport: async () => download([...bytes].map((byte) => Uint8Array.of(byte))),
})
expect(result.exitCode, result.stderr).toBe(0)
expect(result.stdout).toBe(content)
expect(JSON.parse(result.stdout)).toEqual(JSON.parse(content))
})
it('stops oversized stdout at capture, cancels the body and reports incomplete output', async () => {
let produced = 0
const cancel = vi.fn()
const chunk = new Uint8Array(1024 * 1024).fill(120)
const transport = vi.fn(
async () =>
new Response(
new ReadableStream<Uint8Array>(
{
pull(controller) {
if (produced++ < 24) controller.enqueue(chunk)
else controller.close()
},
cancel,
},
{ highWaterMark: 0 }
),
{ headers: { 'content-type': 'text/plain' } }
)
)
const result = await runEmbeddedCli(['files', 'get', 'file'], { ...identity, transport })
expect(result.exitCode).toBe(1)
expect(Buffer.byteLength(result.stdout)).toBeLessThanOrEqual(16 * 1024 * 1024)
expect(result.stderr).toContain('output limit')
expect(result.stderr).toContain('Do not repeat a mutation')
expect(produced).toBeLessThan(24)
expect(cancel).toHaveBeenCalledTimes(1)
expect(transport).toHaveBeenCalledTimes(1)
})
it('keeps overflow sticky if command code catches it and puts its warning before captured stderr', async () => {
const requests = vi.fn(async () => {
const block = 'x'.repeat(1024 * 1024)
try {
for (let index = 0; index < 17; index++) writeStderr(block)
} catch {
/** A command can catch an output failure after a mutation already committed. */
}
return Response.json({ data: { id: 'created', name: 'New workflow' } })
})
const result = await runEmbeddedCli(['workflows', 'create', '--name', 'New workflow'], {
...identity,
transport: requests,
})
expect(result.exitCode).toBe(1)
expect(JSON.parse(result.stdout).id).toBe('created')
expect(result.stderr.split('\n')[0]).toContain('output limit')
expect(result.stderr.split('\n')[0]).toContain('Do not repeat a mutation')
expect(Buffer.byteLength(result.stderr)).toBeLessThan(16 * 1024 * 1024 + 1024)
expect(requests).toHaveBeenCalledTimes(1)
})
it('keeps a simultaneous healthy invocation independent of an overflowing one', async () => {
const [failed, healthy] = await Promise.all([
runEmbeddedCli(['files', 'get', 'large'], {
...identity,
transport: async () => download([new Uint8Array(17 * 1024 * 1024)]),
}),
runEmbeddedCli(['files', 'get', 'small'], {
...identity,
transport: async () => download([Buffer.from('{"ok":'), Buffer.from('true}')]),
}),
])
expect(failed.exitCode).toBe(1)
expect(failed.stdout).toBe('')
expect(healthy).toEqual({ exitCode: 0, stdout: '{"ok":true}', stderr: '' })
})
})