@@ -3,13 +3,16 @@ import assert from 'node:assert/strict'
3
3
import { describe , mock , test } from 'node:test'
4
4
5
5
import { Saturn } from '#src/index.js'
6
- import { concatChunks , generateNodes , getMockServer , mockJWT , mockNodesHandlers , mockOrchHandler , mockSaturnOriginHandler , MSW_SERVER_OPTS } from './test-utils.js'
6
+ import { concatChunks , generateNodes , getMockServer , HTTP_STATUS_GONE , mockJWT , mockNodesHandlers , mockOrchHandler , mockSaturnOriginHandler , MSW_SERVER_OPTS } from './test-utils.js'
7
7
8
8
const TEST_DEFAULT_ORCH = 'https://orchestrator.strn.pl/nodes'
9
9
const TEST_NODES_LIST_KEY = 'saturn-nodes'
10
10
const TEST_AUTH = 'https://fz3dyeyxmebszwhuiky7vggmsu0rlkoy.lambda-url.us-west-2.on.aws/'
11
11
const TEST_ORIGIN_DOMAIN = 'saturn.ms'
12
12
const CLIENT_KEY = 'key'
13
+
14
+ const experimental = true
15
+
13
16
describe ( 'Client Fallback' , ( ) => {
14
17
test ( 'Nodes are loaded from the orchestrator if no storage is passed' , async ( t ) => {
15
18
const handlers = [
@@ -21,7 +24,7 @@ describe('Client Fallback', () => {
21
24
const expectedNodes = generateNodes ( 2 , TEST_ORIGIN_DOMAIN )
22
25
23
26
// No Storage is injected
24
- const saturn = new Saturn ( { clientKey : CLIENT_KEY } )
27
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , experimental } )
25
28
const mockOpts = { orchURL : TEST_DEFAULT_ORCH }
26
29
27
30
await saturn . _loadNodes ( mockOpts )
@@ -50,7 +53,7 @@ describe('Client Fallback', () => {
50
53
t . mock . method ( mockStorage , 'get' )
51
54
t . mock . method ( mockStorage , 'set' )
52
55
53
- const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY } )
56
+ const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , experimental } )
54
57
55
58
// Mocking options
56
59
const mockOpts = { orchURL : TEST_DEFAULT_ORCH }
@@ -87,7 +90,7 @@ describe('Client Fallback', () => {
87
90
t . mock . method ( mockStorage , 'get' )
88
91
t . mock . method ( mockStorage , 'set' )
89
92
90
- const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY } )
93
+ const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , experimental } )
91
94
92
95
// Mocking options
93
96
const mockOpts = { orchURL : TEST_DEFAULT_ORCH }
@@ -126,7 +129,7 @@ describe('Client Fallback', () => {
126
129
t . mock . method ( mockStorage , 'get' )
127
130
t . mock . method ( mockStorage , 'set' )
128
131
129
- const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , clientId : 'test' } )
132
+ const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
130
133
131
134
const cid = saturn . fetchContentWithFallback ( 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4' )
132
135
@@ -159,7 +162,7 @@ describe('Client Fallback', () => {
159
162
t . mock . method ( mockStorage , 'get' )
160
163
t . mock . method ( mockStorage , 'set' )
161
164
162
- const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , clientId : 'test' } )
165
+ const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
163
166
// const origins =
164
167
165
168
const cid = saturn . fetchContentWithFallback ( 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4' , { raceNodes : true } )
@@ -193,7 +196,7 @@ describe('Client Fallback', () => {
193
196
t . mock . method ( mockStorage , 'get' )
194
197
t . mock . method ( mockStorage , 'set' )
195
198
196
- const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , clientId : 'test' } )
199
+ const saturn = new Saturn ( { storage : mockStorage , clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
197
200
198
201
const cid = saturn . fetchContentWithFallback ( 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4' , { raceNodes : true } )
199
202
@@ -215,7 +218,7 @@ describe('Client Fallback', () => {
215
218
216
219
const server = getMockServer ( handlers )
217
220
server . listen ( MSW_SERVER_OPTS )
218
- const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' } )
221
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
219
222
220
223
const fetchContentMock = mock . fn ( async function * ( cidPath , opts ) {
221
224
yield Buffer . from ( 'chunk1' )
@@ -243,7 +246,7 @@ describe('Client Fallback', () => {
243
246
244
247
const server = getMockServer ( handlers )
245
248
server . listen ( MSW_SERVER_OPTS )
246
- const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' } )
249
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
247
250
248
251
const fetchContentMock = mock . fn ( async function * ( cidPath , opts ) { throw new Error ( 'Fetch error' ) } ) // eslint-disable-line
249
252
saturn . fetchContent = fetchContentMock
@@ -264,6 +267,70 @@ describe('Client Fallback', () => {
264
267
server . close ( )
265
268
} )
266
269
270
+ test ( 'Should abort fallback on 410s' , async ( ) => {
271
+ const numNodes = 3
272
+ const handlers = [
273
+ mockOrchHandler ( numNodes , TEST_DEFAULT_ORCH , 'saturn.ms' ) ,
274
+ mockJWT ( TEST_AUTH ) ,
275
+ ...mockNodesHandlers ( numNodes , TEST_ORIGIN_DOMAIN , 3 , HTTP_STATUS_GONE )
276
+ ]
277
+
278
+ const server = getMockServer ( handlers )
279
+ server . listen ( MSW_SERVER_OPTS )
280
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
281
+ await saturn . loadNodesPromise
282
+
283
+ let error
284
+ try {
285
+ for await ( const _ of saturn . fetchContentWithFallback ( 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4' ) ) { // eslint-disable-line
286
+ // This loop body shouldn't be reached.
287
+ }
288
+ } catch ( e ) {
289
+ error = e
290
+ }
291
+ const logs = saturn . logs
292
+
293
+ assert ( error )
294
+ assert . strictEqual ( logs . length , 1 )
295
+ mock . reset ( )
296
+ server . close ( )
297
+ } )
298
+
299
+ test ( 'Should abort fallback on specific errors' , async ( ) => {
300
+ const numNodes = 3
301
+ const handlers = [
302
+ mockOrchHandler ( numNodes , TEST_DEFAULT_ORCH , 'saturn.ms' ) ,
303
+ mockJWT ( TEST_AUTH ) ,
304
+ ...mockNodesHandlers ( numNodes , TEST_ORIGIN_DOMAIN , 3 , HTTP_STATUS_GONE )
305
+ ]
306
+
307
+ const server = getMockServer ( handlers )
308
+ server . listen ( MSW_SERVER_OPTS )
309
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
310
+ await saturn . loadNodesPromise
311
+
312
+ let callCount = 0
313
+ const fetchContentMock = mock . fn ( async function * ( cidPath , opts ) {
314
+ callCount ++
315
+ yield ''
316
+ throw new Error ( 'file does not exist' )
317
+ } )
318
+
319
+ saturn . fetchContent = fetchContentMock
320
+
321
+ let error
322
+ try {
323
+ for await ( const _ of saturn . fetchContentWithFallback ( 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4' ) ) { // eslint-disable-line
324
+ }
325
+ } catch ( e ) {
326
+ error = e
327
+ }
328
+
329
+ assert ( error )
330
+ assert . strictEqual ( callCount , 1 )
331
+ mock . reset ( )
332
+ server . close ( )
333
+ } )
267
334
test ( 'Handles fallback with chunk overlap correctly' , async ( ) => {
268
335
const numNodes = 3
269
336
const handlers = [
@@ -274,7 +341,7 @@ describe('Client Fallback', () => {
274
341
275
342
const server = getMockServer ( handlers )
276
343
server . listen ( MSW_SERVER_OPTS )
277
- const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' } )
344
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
278
345
279
346
let callCount = 0
280
347
const fetchContentMock = mock . fn ( async function * ( cidPath , opts ) {
@@ -313,7 +380,7 @@ describe('Client Fallback', () => {
313
380
314
381
const server = getMockServer ( handlers )
315
382
server . listen ( MSW_SERVER_OPTS )
316
- const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' } )
383
+ const saturn = new Saturn ( { clientKey : CLIENT_KEY , clientId : 'test' , experimental } )
317
384
318
385
let callCount = 0
319
386
let fetchContentMock = mock . fn ( async function * ( cidPath , opts ) {
0 commit comments