Skip to content

Commit

Permalink
tests and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
AmeanAsad committed Oct 24, 2023
1 parent 9de35fc commit c06a2b6
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 10 deletions.
20 changes: 13 additions & 7 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ export class Saturn {

const options = Object.assign({}, this.opts, { format: 'car', jwt }, opts)
const url = this.createRequestURL(cidPath, options)

const log = {
url,
startTime: new Date()
Expand Down Expand Up @@ -218,6 +217,7 @@ export class Saturn {
* @param {string} cidPath
* @param {object} [opts={}]
* @param {('car'|'raw')} [opts.format]
* @param {boolean} [opts.raceNodes]
* @param {string} [opts.url]
* @param {number} [opts.connectTimeout=5000]
* @param {number} [opts.downloadTimeout=0]
Expand Down Expand Up @@ -267,8 +267,13 @@ export class Saturn {
if (fallbackCount > this.opts.fallbackLimit) {
return
}
const origins = nodes.slice(i, i + Saturn.defaultRaceCount)
opts.origins = origins
if (opts.raceNodes) {
const origins = nodes.slice(i, i + Saturn.defaultRaceCount).map((node) => node.url)
opts.origins = origins
} else {
opts.url = nodes[i].url
}

try {
yield * fetchContent()
return
Expand All @@ -286,17 +291,17 @@ export class Saturn {
/**
*
* @param {string} cidPath
* @param {boolean} race
* @param {object} [opts={}]
* @param {('car'|'raw')} [opts.format]
* @param {boolean} [opts.raceNodes]
* @param {number} [opts.connectTimeout=5000]
* @param {number} [opts.downloadTimeout=0]
* @returns {Promise<AsyncIterable<Uint8Array>>}
*/
async * fetchContent (cidPath, race = false, opts = {}) {
async * fetchContent (cidPath, opts = {}) {
let res, controller, log

if (race) {
if (opts.raceNodes) {
({ res, controller, log } = await this.fetchCIDWithRace(cidPath, opts))
} else {
({ res, controller, log } = await this.fetchCID(cidPath, opts))
Expand Down Expand Up @@ -329,6 +334,7 @@ export class Saturn {
* @param {string} cidPath
* @param {object} [opts={}]
* @param {('car'|'raw')} [opts.format]
* @param {boolean} [opts.raceNodes]
* @param {number} [opts.connectTimeout=5000]
* @param {number} [opts.downloadTimeout=0]
* @returns {Promise<Uint8Array>}
Expand All @@ -344,7 +350,7 @@ export class Saturn {
* @returns {URL}
*/
createRequestURL (cidPath, opts) {
let origin = opts.url || opts.origins[0] || opts.cdnURL
let origin = opts.url || (opts.origins && opts.origins[0]) || opts.cdnURL
origin = addHttpPrefix(origin)
const url = new URL(`${origin}/ipfs/${cidPath}`)

Expand Down
69 changes: 68 additions & 1 deletion test/fallback.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,74 @@ describe('Client Fallback', () => {

const saturn = new Saturn({ storage: mockStorage, clientKey: CLIENT_KEY, clientId: 'test' })

const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4', { url: 'node1.saturn.ms' })
const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4')

const buffer = await concatChunks(cid)
const actualContent = String.fromCharCode(...buffer)
const expectedContent = 'hello world\n'

assert.strictEqual(actualContent, expectedContent)
server.close()
mock.reset()
})

test('Content Fallback fetches a cid properly with race', async (t) => {
const handlers = [
mockOrchHandler(5, TEST_DEFAULT_ORCH, 'saturn.ms'),
mockJWT(TEST_AUTH),
mockSaturnOriginHandler(TEST_ORIGIN_DOMAIN, 0, true),
...mockNodesHandlers(5, TEST_ORIGIN_DOMAIN)
]
const server = getMockServer(handlers)
server.listen(MSW_SERVER_OPTS)

const expectedNodes = generateNodes(3, TEST_ORIGIN_DOMAIN)

// Mocking storage object
const mockStorage = {
get: async (key) => expectedNodes,
set: async (key, value) => { return null }
}
t.mock.method(mockStorage, 'get')
t.mock.method(mockStorage, 'set')

const saturn = new Saturn({ storage: mockStorage, clientKey: CLIENT_KEY, clientId: 'test' })
// const origins =

const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4', { raceNodes: true })

const buffer = await concatChunks(cid)
const actualContent = String.fromCharCode(...buffer)
const expectedContent = 'hello world\n'

assert.strictEqual(actualContent, expectedContent)
server.close()
mock.reset()
})

test('Content Fallback with race fetches from consecutive nodes on failure', async (t) => {
const handlers = [
mockOrchHandler(5, TEST_DEFAULT_ORCH, 'saturn.ms'),
mockJWT(TEST_AUTH),
mockSaturnOriginHandler(TEST_ORIGIN_DOMAIN, 0, true),
...mockNodesHandlers(5, TEST_ORIGIN_DOMAIN, 2)
]
const server = getMockServer(handlers)
server.listen(MSW_SERVER_OPTS)

const expectedNodes = generateNodes(5, TEST_ORIGIN_DOMAIN)

// Mocking storage object
const mockStorage = {
get: async (key) => expectedNodes,
set: async (key, value) => { return null }
}
t.mock.method(mockStorage, 'get')
t.mock.method(mockStorage, 'set')

const saturn = new Saturn({ storage: mockStorage, clientKey: CLIENT_KEY, clientId: 'test' })

const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4', { raceNodes: true })

const buffer = await concatChunks(cid)
const actualContent = String.fromCharCode(...buffer)
Expand Down
13 changes: 11 additions & 2 deletions test/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,23 @@ export function mockJWT (authURL) {
*
* @param {number} count - amount of nodes to mock
* @param {string} originDomain - saturn origin domain.
* @param {number} failures
* @returns {RestHandler<any>[]}
*/
export function mockNodesHandlers (count, originDomain) {
export function mockNodesHandlers (count, originDomain, failures = 0) {
if (failures > count) {
throw Error('failures number cannot exceed node count')
}
const nodes = generateNodes(count, originDomain)

const handlers = nodes.map((node) => {
const handlers = nodes.map((node, idx) => {
const url = `${node.url}/ipfs/:cid`
return rest.get(url, (req, res, ctx) => {
if (idx < failures) {
return res(
ctx.status(504)
)
}
const filepath = getFixturePath('hello.car')
const fileContents = fs.readFileSync(filepath)
return res(
Expand Down

0 comments on commit c06a2b6

Please sign in to comment.