From e8955b16cbf2393368ac8576c2cc47d3c0c2930c Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sun, 21 Oct 2018 01:59:02 +0200 Subject: [PATCH 1/2] fix: pin.ls ignored opts when hash was present Adds tests to guard against issue described in https://github.com/ipfs/js-ipfs-api/pull/875 License: MIT Signed-off-by: Marcin Rataj --- src/pin/ls.js | 95 +++++++++++++++++++++++++++++++++++++++++++----- src/pin/utils.js | 12 ++++++ 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/src/pin/ls.js b/src/pin/ls.js index c9542071..a246ca87 100644 --- a/src/pin/ls.js +++ b/src/pin/ls.js @@ -31,10 +31,25 @@ module.exports = (createCommon, options) => { function populate () { series([ - cb => ipfs.add(fixtures.files[0].data, { pin: false }, cb), - cb => ipfs.pin.add(fixtures.files[0].cid, { recursive: true }, cb), - cb => ipfs.add(fixtures.files[1].data, { pin: false }, cb), - cb => ipfs.pin.add(fixtures.files[1].cid, { recursive: false }, cb) + cb => { // two files wrapped in a directory, root CID pinned recursively + const dir = fixtures.directory.files.map((file) => ({ path: file.path, content: file.data })) + ipfs.files.add(dir, { pin: false }, (err, res) => { + if (err) return cb(err) + ipfs.pin.add(fixtures.directory.cid, { recursive: true }, cb) + }) + }, + cb => { // a file (CID pinned recursively) + ipfs.files.add(fixtures.files[0].data, { pin: false }, (err, res) => { + if (err) return cb(err) + ipfs.pin.add(fixtures.files[0].cid, { recursive: true }, cb) + }) + }, + cb => { // a single CID (pinned directly) + ipfs.files.add(fixtures.files[1].data, { pin: false }, (err, res) => { + if (err) return cb(err) + ipfs.pin.add(fixtures.files[1].cid, { recursive: false }, cb) + }) + } ], done) } }) @@ -42,21 +57,24 @@ module.exports = (createCommon, options) => { after((done) => common.teardown(done)) // 1st, because ipfs.add pins automatically - it('should list recursive pins', (done) => { + it('should list all recursive pins', (done) => { ipfs.pin.ls({ type: 'recursive' }, (err, pinset) => { expect(err).to.not.exist() expect(pinset).to.deep.include({ type: 'recursive', hash: fixtures.files[0].cid }) + expect(pinset).to.deep.include({ + type: 'recursive', + hash: fixtures.directory.cid + }) done() }) }) - it('should list indirect pins', (done) => { + it('should list all indirect pins', (done) => { ipfs.pin.ls({ type: 'indirect' }, (err, pinset) => { expect(err).to.not.exist() - // because the pinned files have no links expect(pinset).to.not.deep.include({ type: 'recursive', hash: fixtures.files[0].cid @@ -65,14 +83,24 @@ module.exports = (createCommon, options) => { type: 'direct', hash: fixtures.files[1].cid }) + expect(pinset).to.not.deep.include({ + type: 'recursive', + hash: fixtures.directory.cid + }) done() }) }) - it('should list pins', (done) => { + it('should list all types of pins', (done) => { ipfs.pin.ls((err, pinset) => { expect(err).to.not.exist() expect(pinset).to.not.be.empty() + expect(pinset).to.have.lengthOf(15) + // check the three "roots" + expect(pinset).to.deep.include({ + type: 'recursive', + hash: fixtures.directory.cid + }) expect(pinset).to.deep.include({ type: 'recursive', hash: fixtures.files[0].cid @@ -85,9 +113,16 @@ module.exports = (createCommon, options) => { }) }) - it('should list pins (promised)', () => { + it('should list all types of pins (promised)', () => { return ipfs.pin.ls() .then((pinset) => { + expect(pinset).to.not.be.empty() + expect(pinset).to.have.lengthOf(15) + // check our three "roots" + expect(pinset).to.deep.include({ + type: 'recursive', + hash: fixtures.directory.cid + }) expect(pinset).to.deep.include({ type: 'recursive', hash: fixtures.files[0].cid @@ -99,7 +134,7 @@ module.exports = (createCommon, options) => { }) }) - it('should list direct pins', (done) => { + it('should list all direct pins', (done) => { ipfs.pin.ls({ type: 'direct' }, (err, pinset) => { expect(err).to.not.exist() expect(pinset).to.deep.include({ @@ -130,5 +165,45 @@ module.exports = (createCommon, options) => { }]) }) }) + + it('should throw an error on missing direct pins for a specific path', (done) => { + // alice.txt is an indirect pin, so lookup for direct one should throw an error + ipfs.pin.ls(`/ipfs/${fixtures.directory.cid}/files/ipfs.txt`, { type: 'direct' }, (err, pinset) => { + expect(pinset).to.not.exist() + expect(err).to.not.be.empty() + expect(err.message).to.be.equal(`path '/ipfs/${fixtures.directory.cid}/files/ipfs.txt' is not pinned`) + done() + }) + }) + + it('should throw an error on missing link for a specific path', (done) => { + ipfs.pin.ls(`/ipfs/${fixtures.directory.cid}/I-DONT-EXIST.txt`, { type: 'direct' }, (err, pinset) => { + expect(pinset).to.not.exist() + expect(err).to.not.be.empty() + expect(err.message).to.be.equal('no link by that name') + done() + }) + }) + + it('should list indirect pins for a specific path', (done) => { + ipfs.pin.ls(`/ipfs/${fixtures.directory.cid}/files/ipfs.txt`, { type: 'indirect' }, (err, pinset) => { + expect(err).to.not.exist() + expect(pinset).to.deep.include({ + type: `indirect through ${fixtures.directory.cid}`, + hash: fixtures.directory.files[1].cid + }) + done() + }) + }) + + it('should list recursive pins for a specific hash (promised)', () => { + return ipfs.pin.ls(fixtures.files[0].cid, { type: 'recursive' }) + .then((pinset) => { + expect(pinset).to.deep.equal([{ + type: 'recursive', + hash: fixtures.files[0].cid + }]) + }) + }) }) } diff --git a/src/pin/utils.js b/src/pin/utils.js index 09debd8c..3c8e8899 100644 --- a/src/pin/utils.js +++ b/src/pin/utils.js @@ -3,6 +3,18 @@ const loadFixture = require('aegir/fixtures') exports.fixtures = Object.freeze({ + directory: Object.freeze({ + cid: 'QmVJV2VF9Qf7rJUFdimhpZDhkyyumM1i4CjjGcss5rqJPa', + files: Object.freeze([Object.freeze({ + path: 'test-folder/ipfs-add.js', + data: loadFixture('js/test/fixtures/test-folder/ipfs-add.js', 'interface-ipfs-core'), + cid: 'QmU7wetVaAqc3Meurif9hcYBHGvQmL5QdpPJYBoZizyTNL' + }), Object.freeze({ + path: 'test-folder/files/ipfs.txt', + data: loadFixture('js/test/fixtures/test-folder/files/ipfs.txt', 'interface-ipfs-core'), + cid: 'QmdFyxZXsFiP4csgfM5uPu99AvFiKH62CSPDw5TP92nr7w' + })]) + }), files: Object.freeze([Object.freeze({ data: loadFixture('test/fixtures/testfile.txt', 'interface-ipfs-core'), cid: 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP' From b791922de13597b8da8f7a1ab87d6f16d9142737 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sun, 21 Oct 2018 19:21:38 +0200 Subject: [PATCH 2/2] feat: additional tests for indirect pin.ls License: MIT Signed-off-by: Marcin Rataj --- src/pin/ls.js | 64 ++++++++++++++++++++++++++++++------------------ src/pin/utils.js | 9 ++++--- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/pin/ls.js b/src/pin/ls.js index a246ca87..691350e1 100644 --- a/src/pin/ls.js +++ b/src/pin/ls.js @@ -31,25 +31,18 @@ module.exports = (createCommon, options) => { function populate () { series([ - cb => { // two files wrapped in a directory, root CID pinned recursively + // two files wrapped in directories, only root CID pinned recursively + cb => { const dir = fixtures.directory.files.map((file) => ({ path: file.path, content: file.data })) - ipfs.files.add(dir, { pin: false }, (err, res) => { - if (err) return cb(err) - ipfs.pin.add(fixtures.directory.cid, { recursive: true }, cb) - }) + ipfs.add(dir, { pin: false, cidVersion: 0 }, cb) }, - cb => { // a file (CID pinned recursively) - ipfs.files.add(fixtures.files[0].data, { pin: false }, (err, res) => { - if (err) return cb(err) - ipfs.pin.add(fixtures.files[0].cid, { recursive: true }, cb) - }) - }, - cb => { // a single CID (pinned directly) - ipfs.files.add(fixtures.files[1].data, { pin: false }, (err, res) => { - if (err) return cb(err) - ipfs.pin.add(fixtures.files[1].cid, { recursive: false }, cb) - }) - } + cb => ipfs.pin.add(fixtures.directory.cid, { recursive: true }, cb), + // a file (CID pinned recursively) + cb => ipfs.add(fixtures.files[0].data, { pin: false, cidVersion: 0 }, cb), + cb => ipfs.pin.add(fixtures.files[0].cid, { recursive: true }, cb), + // a single CID (pinned directly) + cb => ipfs.add(fixtures.files[1].data, { pin: false, cidVersion: 0 }, cb), + cb => ipfs.pin.add(fixtures.files[1].cid, { recursive: false }, cb) ], done) } }) @@ -87,6 +80,14 @@ module.exports = (createCommon, options) => { type: 'recursive', hash: fixtures.directory.cid }) + expect(pinset).to.deep.include({ + type: 'indirect', + hash: fixtures.directory.files[0].cid + }) + expect(pinset).to.deep.include({ + type: 'indirect', + hash: fixtures.directory.files[1].cid + }) done() }) }) @@ -95,7 +96,6 @@ module.exports = (createCommon, options) => { ipfs.pin.ls((err, pinset) => { expect(err).to.not.exist() expect(pinset).to.not.be.empty() - expect(pinset).to.have.lengthOf(15) // check the three "roots" expect(pinset).to.deep.include({ type: 'recursive', @@ -109,6 +109,14 @@ module.exports = (createCommon, options) => { type: 'direct', hash: fixtures.files[1].cid }) + expect(pinset).to.deep.include({ + type: 'indirect', + hash: fixtures.directory.files[0].cid + }) + expect(pinset).to.deep.include({ + type: 'indirect', + hash: fixtures.directory.files[1].cid + }) done() }) }) @@ -117,7 +125,6 @@ module.exports = (createCommon, options) => { return ipfs.pin.ls() .then((pinset) => { expect(pinset).to.not.be.empty() - expect(pinset).to.have.lengthOf(15) // check our three "roots" expect(pinset).to.deep.include({ type: 'recursive', @@ -131,12 +138,21 @@ module.exports = (createCommon, options) => { type: 'direct', hash: fixtures.files[1].cid }) + expect(pinset).to.deep.include({ + type: 'indirect', + hash: fixtures.directory.files[0].cid + }) + expect(pinset).to.deep.include({ + type: 'indirect', + hash: fixtures.directory.files[1].cid + }) }) }) it('should list all direct pins', (done) => { ipfs.pin.ls({ type: 'direct' }, (err, pinset) => { expect(err).to.not.exist() + expect(pinset).to.have.lengthOf(1) expect(pinset).to.deep.include({ type: 'direct', hash: fixtures.files[1].cid @@ -166,11 +182,11 @@ module.exports = (createCommon, options) => { }) }) - it('should throw an error on missing direct pins for a specific path', (done) => { - // alice.txt is an indirect pin, so lookup for direct one should throw an error + it('should throw an error on missing direct pins for existing path', (done) => { + // ipfs.txt is an indirect pin, so lookup for direct one should throw an error ipfs.pin.ls(`/ipfs/${fixtures.directory.cid}/files/ipfs.txt`, { type: 'direct' }, (err, pinset) => { + expect(err).to.exist() expect(pinset).to.not.exist() - expect(err).to.not.be.empty() expect(err.message).to.be.equal(`path '/ipfs/${fixtures.directory.cid}/files/ipfs.txt' is not pinned`) done() }) @@ -178,9 +194,9 @@ module.exports = (createCommon, options) => { it('should throw an error on missing link for a specific path', (done) => { ipfs.pin.ls(`/ipfs/${fixtures.directory.cid}/I-DONT-EXIST.txt`, { type: 'direct' }, (err, pinset) => { + expect(err).to.exist() expect(pinset).to.not.exist() - expect(err).to.not.be.empty() - expect(err.message).to.be.equal('no link by that name') + expect(err.message).to.be.equal(`no link named "I-DONT-EXIST.txt" under ${fixtures.directory.cid}`) done() }) }) diff --git a/src/pin/utils.js b/src/pin/utils.js index 3c8e8899..3ee67f0d 100644 --- a/src/pin/utils.js +++ b/src/pin/utils.js @@ -3,15 +3,16 @@ const loadFixture = require('aegir/fixtures') exports.fixtures = Object.freeze({ + // NOTE: files under 'directory' need to be different than standalone ones in 'files' directory: Object.freeze({ - cid: 'QmVJV2VF9Qf7rJUFdimhpZDhkyyumM1i4CjjGcss5rqJPa', + cid: 'QmY8KdYQSYKFU5hM7F5ioZ5yYSgV5VZ1kDEdqfRL3rFgcd', files: Object.freeze([Object.freeze({ path: 'test-folder/ipfs-add.js', - data: loadFixture('js/test/fixtures/test-folder/ipfs-add.js', 'interface-ipfs-core'), - cid: 'QmU7wetVaAqc3Meurif9hcYBHGvQmL5QdpPJYBoZizyTNL' + data: loadFixture('test/fixtures/test-folder/ipfs-add.js', 'interface-ipfs-core'), + cid: 'QmbKtKBrmeRHjNCwR4zAfCJdMVu6dgmwk9M9AE9pUM9RgG' }), Object.freeze({ path: 'test-folder/files/ipfs.txt', - data: loadFixture('js/test/fixtures/test-folder/files/ipfs.txt', 'interface-ipfs-core'), + data: loadFixture('test/fixtures/test-folder/files/ipfs.txt', 'interface-ipfs-core'), cid: 'QmdFyxZXsFiP4csgfM5uPu99AvFiKH62CSPDw5TP92nr7w' })]) }),