Skip to content

Commit 39e3043

Browse files
authored
Merge pull request #20 from FIL-Builders/codex/synapse-v1-final-review
[codex] harden Synapse upload result coverage
2 parents 1ee35b2 + 8c96b54 commit 39e3043

2 files changed

Lines changed: 96 additions & 14 deletions

File tree

cli/src/commands/upload.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,16 @@ export const uploadCommand = {
115115
})
116116

117117
const cidStr = result.pieceCid.toString()
118-
const copyResults = result.copies.map((copy: any) => ({
119-
dataSetId: copy.dataSetId,
118+
const copyResults = result.copies.map((copy) => ({
119+
dataSetId: copy.dataSetId.toString(),
120120
datasetScannerUrl: datasetScannerUrl(copy.dataSetId, chain),
121121
url: copy.retrievalUrl,
122-
pieceId: copy.pieceId,
123-
providerId: copy.providerId,
122+
pieceId: copy.pieceId.toString(),
123+
providerId: copy.providerId.toString(),
124124
isNewDataSet: copy.isNewDataSet,
125125
providerRole: copy.role,
126126
}))
127-
const copyFailures = result.failedAttempts.map((failure: any) => ({
127+
const copyFailures = result.failedAttempts.map((failure) => ({
128128
providerId: failure.providerId.toString(),
129129
role: failure.role,
130130
error: formatFailedAttemptError(failure),

cli/tests/synapse-commands.test.ts

Lines changed: 91 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ afterEach(async () => {
115115
describe('top-level upload commands', () => {
116116
test('upload prepares storage, executes funding, uploads, and maps copy results', async () => {
117117
const filePath = await tempFile('upload.txt', 'data')
118-
const contexts = [{ id: 'ctx-primary' }]
118+
const contexts = [{ id: 'ctx-primary' }, { id: 'ctx-secondary' }]
119119
const execute = mock(async () => ({ hash: '0xprepare' }))
120120

121121
synapseStorage.createContexts.mockImplementation(async () => contexts)
@@ -125,8 +125,8 @@ describe('top-level upload commands', () => {
125125
synapseStorage.upload.mockImplementation(async () => ({
126126
pieceCid: cid('baga-upload'),
127127
size: 4,
128-
requestedCopies: 3,
129-
complete: false,
128+
requestedCopies: 2,
129+
complete: true,
130130
copies: [
131131
{
132132
dataSetId: 42n,
@@ -136,12 +136,20 @@ describe('top-level upload commands', () => {
136136
isNewDataSet: true,
137137
role: 'primary',
138138
},
139+
{
140+
dataSetId: 43n,
141+
retrievalUrl: 'https://backup.example/piece/baga-upload',
142+
pieceId: 8n,
143+
providerId: 79n,
144+
isNewDataSet: false,
145+
role: 'secondary',
146+
},
139147
],
140148
failedAttempts: [
141149
{
142150
providerId: 78n,
143151
role: 'secondary',
144-
error: 'temporarily unavailable',
152+
error: 'replaced after transient failure',
145153
explicit: false,
146154
},
147155
],
@@ -150,7 +158,7 @@ describe('top-level upload commands', () => {
150158
const result = await uploadCommand.run(
151159
commandContext({
152160
args: { path: filePath },
153-
options: { copies: 3, withCDN: true },
161+
options: { copies: 2, withCDN: true },
154162
})
155163
)
156164

@@ -159,7 +167,7 @@ describe('top-level upload commands', () => {
159167
{ client: fakeWalletClient, source: 'foc-cli' },
160168
])
161169
expect(synapseStorage.createContexts).toHaveBeenCalledWith({
162-
copies: 3,
170+
copies: 2,
163171
withCDN: true,
164172
})
165173
expect(synapseStorage.prepare).toHaveBeenCalledWith({
@@ -171,13 +179,13 @@ describe('top-level upload commands', () => {
171179
contexts,
172180
withCDN: true,
173181
})
174-
expect(result.status).toBe('partially_uploaded')
182+
expect(result.status).toBe('uploaded')
175183
expect(result.result).toEqual({
176184
pieceCid: 'baga-upload',
177185
pieceScannerUrl: 'https://pdp.vxb.ai/calibration/piece/baga-upload',
178186
size: 4,
179-
requestedCopies: 3,
180-
complete: false,
187+
requestedCopies: 2,
188+
complete: true,
181189
copyResults: [
182190
{
183191
dataSetId: '42',
@@ -188,6 +196,80 @@ describe('top-level upload commands', () => {
188196
isNewDataSet: true,
189197
providerRole: 'primary',
190198
},
199+
{
200+
dataSetId: '43',
201+
datasetScannerUrl: 'https://pdp.vxb.ai/calibration/dataset/43',
202+
url: 'https://backup.example/piece/baga-upload',
203+
pieceId: '8',
204+
providerId: '79',
205+
isNewDataSet: false,
206+
providerRole: 'secondary',
207+
},
208+
],
209+
copyFailures: [
210+
{
211+
providerId: '78',
212+
role: 'secondary',
213+
error: 'replaced after transient failure',
214+
explicit: false,
215+
},
216+
],
217+
})
218+
})
219+
220+
test('upload reports partial status when Synapse commits fewer copies than requested', async () => {
221+
const filePath = await tempFile('partial.txt', 'data')
222+
const contexts = [
223+
{ id: 'ctx-primary' },
224+
{ id: 'ctx-secondary-a' },
225+
{ id: 'ctx-secondary-b' },
226+
]
227+
228+
synapseStorage.createContexts.mockImplementation(async () => contexts)
229+
synapseStorage.upload.mockImplementation(async () => ({
230+
pieceCid: cid('baga-partial'),
231+
size: 4,
232+
requestedCopies: 3,
233+
complete: false,
234+
copies: [
235+
{
236+
dataSetId: 42n,
237+
retrievalUrl: 'https://provider.example/piece/baga-partial',
238+
pieceId: 7n,
239+
providerId: 77n,
240+
isNewDataSet: true,
241+
role: 'primary',
242+
},
243+
],
244+
failedAttempts: [
245+
{
246+
providerId: 78n,
247+
role: 'secondary',
248+
error: 'temporarily unavailable',
249+
explicit: false,
250+
},
251+
],
252+
}))
253+
254+
const result = await uploadCommand.run(
255+
commandContext({
256+
args: { path: filePath },
257+
options: { copies: 3 },
258+
})
259+
)
260+
261+
expect(result.status).toBe('partially_uploaded')
262+
expect(result.result).toMatchObject({
263+
pieceCid: 'baga-partial',
264+
requestedCopies: 3,
265+
complete: false,
266+
copyResults: [
267+
{
268+
dataSetId: '42',
269+
pieceId: '7',
270+
providerId: '77',
271+
providerRole: 'primary',
272+
},
191273
],
192274
copyFailures: [
193275
{

0 commit comments

Comments
 (0)