Skip to content
This repository has been archived by the owner on Aug 1, 2023. It is now read-only.

test: adds tests for adding and modifying mfs hamt shards #54

Merged
merged 4 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"bl": "^3.0.0",
"bs58": "^4.0.1",
"chai": "^4.2.0",
"cids": "~0.5.7",
"cids": "~0.7.1",
"cross-env": "^5.2.0",
"detect-node": "^2.0.4",
"dir-compare": "^1.7.1",
Expand All @@ -50,10 +50,10 @@
"expose-loader": "~0.7.5",
"form-data": "^2.3.3",
"go-ipfs-dep": "~0.4.20",
"hat": "0.0.3",
"ipfs": "~0.35.0",
"ipfs-http-client": "^30.1.1",
"ipfs-repo": "~0.26.1",
"hat": "~0.0.3",
"ipfs": "0.36.2",
"ipfs-http-client": "^32.0.0",
"ipfs-repo": "~0.26.6",
"ipfs-unixfs": "~0.1.16",
"ipfsd-ctl": "~0.42.2",
"ipns": "~0.5.1",
Expand All @@ -67,6 +67,7 @@
"ncp": "^2.0.0",
"pretty-bytes": "^5.1.0",
"random-fs": "^1.0.3",
"readable-stream-buffer-stream": "~0.0.2",
"rimraf": "^2.6.3",
"stream-to-promise": "^2.2.0",
"transform-loader": "~0.2.4"
Expand Down
155 changes: 131 additions & 24 deletions test/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const {
spawnInitAndStartJsDaemon,
stopDaemon
} = require('./utils/daemon')
const bufferStream = require('readable-stream-buffer-stream')

const SHARD_THRESHOLD = 1000

class ExpectedError extends Error {

Expand Down Expand Up @@ -102,20 +105,6 @@ const compareErrors = (expectedMessage, ...ops) => {
})
}

// TODO: remove after https://github.com/crypto-browserify/randombytes/pull/16 released
const MAX_BYTES = 65536
function randomBytes (num) {
if (num < 1) return Buffer.alloc(0)
if (num <= MAX_BYTES) return crypto.randomBytes(num)

const chunks = Array(Math.floor(num / MAX_BYTES))
.fill(MAX_BYTES)
.concat(num % MAX_BYTES)
.map(n => crypto.randomBytes(n))

return Buffer.concat(chunks)
}

describe('files', function () {
this.timeout(50 * 1000)

Expand Down Expand Up @@ -165,7 +154,7 @@ describe('files', function () {
})

it('uses raw nodes for leaf data', () => {
const data = randomBytes(1024 * 300)
const data = crypto.randomBytes(1024 * 300)
const testLeavesAreRaw = (daemon) => {
return addFile(daemon, data)
.then(file => checkNodeTypes(daemon, file))
Expand Down Expand Up @@ -207,7 +196,7 @@ describe('files', function () {
})

describe('has the same hashes for', () => {
const testHashesAreEqual = (daemon, data, options) => {
const testHashesAreEqual = (daemon, data, options = {}) => {
return daemon.api.add(data, options)
.then(files => files[0].hash)
}
Expand Down Expand Up @@ -255,7 +244,7 @@ describe('files', function () {
})

it('big files', () => {
const data = randomBytes(1024 * 3000)
const data = crypto.randomBytes(1024 * 3000)

return compare(
testHashesAreEqual(go, data),
Expand All @@ -264,8 +253,8 @@ describe('files', function () {
})

it('files that have had data appended', () => {
const initialData = randomBytes(1024 * 300)
const appendedData = randomBytes(1024 * 300)
const initialData = crypto.randomBytes(1024 * 300)
const appendedData = crypto.randomBytes(1024 * 300)

return compare(
appendData(go, initialData, appendedData),
Expand All @@ -275,16 +264,17 @@ describe('files', function () {

it('files that have had data overwritten', () => {
const bytes = 1024 * 300
const initialData = randomBytes(bytes)
const newData = randomBytes(bytes)
const initialData = crypto.randomBytes(bytes)
const newData = crypto.randomBytes(bytes)

return compare(
overwriteData(go, initialData, newData),
overwriteData(js, initialData, newData)
)
})

it('small files with CIDv1', () => {
// requires go-ipfs v0.4.21
it.skip('small files with CIDv1', () => {
const data = Buffer.from([0x00, 0x01, 0x02])
const options = {
cidVersion: 1
Expand All @@ -296,8 +286,9 @@ describe('files', function () {
)
})

it('big files with CIDv1', () => {
const data = randomBytes(1024 * 3000)
// requires go-ipfs v0.4.21
it.skip('big files with CIDv1', () => {
const data = crypto.randomBytes(1024 * 3000)
const options = {
cidVersion: 1
}
Expand All @@ -307,5 +298,121 @@ describe('files', function () {
testHashesAreEqual(js, data, options)
)
})

it('trickle DAGs', () => {
const chunkSize = 262144
const buffer = Buffer.alloc(chunkSize, 0)
const data = bufferStream(chunkSize, {
generator: (size, callback) => {
callback(null, buffer.slice(0, size))
}
})
const options = {
cidVersion: 0,
trickle: true,
chunker: 'size-10',
pin: false,
preload: false
}

return compare(
testHashesAreEqual(go, data, options),
testHashesAreEqual(js, data, options)
)
})

it('hamt shards', () => {
const data = crypto.randomBytes(100)
const files = []
const dir = `/shard-${Date.now()}`

for (let i = 0; i < SHARD_THRESHOLD + 1; i++) {
files.push({
path: `${dir}/file-${i}.txt`,
content: data
})
}

return compare(
testHashesAreEqual(go, files),
testHashesAreEqual(js, files)
)
})

it('updating mfs hamt shards', () => {
const dir = `/shard-${Date.now()}`
const data = crypto.randomBytes(100)
const nodeGrContent = Buffer.from([0, 1, 2, 3, 4])
const superModuleContent = Buffer.from([5, 6, 7, 8, 9])
const files = [{
path: `${dir}/node-gr`,
content: nodeGrContent
}, {
path: `${dir}/yanvoidmodule`,
content: crypto.randomBytes(5)
}, {
path: `${dir}/methodify`,
content: crypto.randomBytes(5)
}, {
path: `${dir}/fis-msprd-style-loader_0_13_1`,
content: crypto.randomBytes(5)
}, {
path: `${dir}/js-form`,
content: crypto.randomBytes(5)
}, {
path: `${dir}/vivanov-sliceart`,
content: crypto.randomBytes(5)
}]

for (let i = 0; i < SHARD_THRESHOLD; i++) {
files.push({
path: `${dir}/file-${i}.txt`,
content: data
})
}

// will operate on sub-shard three levels deep
const testHamtShardHashesAreEqual = async (daemon, data) => {
const addedFiles = await daemon.api.add(data)
const hash = addedFiles[addedFiles.length - 1].hash

await daemon.api.files.cp(`/ipfs/${hash}`, dir)

const node = await daemon.api.object.get(hash)
const meta = UnixFs.unmarshal(node.data)

expect(meta.type).to.equal('hamt-sharded-directory')

await daemon.api.files.write(`${dir}/supermodule_test`, superModuleContent, {
create: true
})
await daemon.api.files.stat(`${dir}/supermodule_test`)
await daemon.api.files.stat(`${dir}/node-gr`)

expect(await daemon.api.files.read(`${dir}/node-gr`)).to.deep.equal(nodeGrContent)
expect(await daemon.api.files.read(`${dir}/supermodule_test`)).to.deep.equal(superModuleContent)

await daemon.api.files.rm(`${dir}/supermodule_test`)

try {
await daemon.api.files.stat(`${dir}/supermodule_test`)
} catch (err) {
expect(err.message).to.contain('not exist')
}

const stats = await daemon.api.files.stat(dir)
const nodeAfterUpdates = await daemon.api.object.get(stats.hash)
const metaAfterUpdates = UnixFs.unmarshal(nodeAfterUpdates.data)

expect(metaAfterUpdates.type).to.equal('hamt-sharded-directory')

return stats.hash
}

return compare(
testHamtShardHashesAreEqual(go, files),
testHamtShardHashesAreEqual(js, files)
)
})
})
})
8 changes: 8 additions & 0 deletions test/utils/daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ const spawnInitAndStartDaemon = (factory, options) => {
webRTCStar: {
Enabled: false
}
},
// enabled sharding for go
Experimental: {
ShardingEnabled: true
}
},
// enabled sharding for js
args: factory.options.type === 'js' ? [
'--enable-sharding-experiment'
] : undefined,
profile: 'test'
}, options)

Expand Down