Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

chore: move pin tests from ipfs core to interface tests #594

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
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
30 changes: 17 additions & 13 deletions SPEC/PIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

> Adds an IPFS object to the pinset and also stores it to the IPFS repo. pinset is the set of hashes currently pinned (not gc'able).

##### `ipfs.pin.add(hash, [options])`
##### `ipfs.pin.add(source, [options])`

Where:

- `hash` is an IPFS multihash.
- `source` is a [CID], an array of CIDs or an (async) iterable that yields CIDs
- `options` is an object that can contain the following keys
- `recursive` (`boolean`) - Recursively pin the object linked. Type: bool. Default: `true`
- `timeout` (`number`|`string`) - Throw an error if the request does not complete within the specified milliseconds timeout. If `timeout` is a string, the value is parsed as a [human readable duration](https://www.npmjs.com/package/parse-duration). There is no timeout by default.
Expand All @@ -21,9 +21,9 @@ Where:

| Type | Description |
| -------- | -------- |
| `Promise<{ cid: CID }>` | An array of objects that represent the files that were pinned |
| `AsyncIterable<{ cid: CID }>` | An async iterable that yields objects containing the CIDs that were pinned |

an array of objects is returned, each of the form:
Each yielded object has the form:

```JavaScript
{
Expand All @@ -34,10 +34,12 @@ an array of objects is returned, each of the form:
**Example:**

```JavaScript
const pinset = await ipfs.pin.add('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u')
console.log(pinset)
for await (const pin of ipfs.pin.add(new CID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u'))) {
console.log(pin)
}

// Logs:
// [ { cid: CID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u') } ]
// { cid: CID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u') }
```

A great source of [examples][] can be found in the tests for this API.
Expand Down Expand Up @@ -77,26 +79,28 @@ A great source of [examples][] can be found in the tests for this API.

> Remove a hash from the pinset

##### `ipfs.pin.rm(hash, [options])`
##### `ipfs.pin.rm(source, [options])`

Where:
- `hash` is a multihash.
- `source` is a [CID], an array of CIDs or an (async) iterable that yields CIDs
- `options` is an object that can contain the following keys
- 'recursive' - Recursively unpin the object linked. Type: bool. Default: `true`

**Returns**

| Type | Description |
| -------- | -------- |
| `Promise<{ cid: CID }>` | An array of unpinned objects |
| `AsyncIterable<{ cid: CID }>` | An async iterable that yields objects containing the CIDs that were unpinned |

**Example:**

```JavaScript
const pinset = await ipfs.pin.rm('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u')
console.log(pinset)
for await (const unpinned of ipfs.pin.rm(new CID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u'))) {
console.log(unpinned)
}

// prints the hashes that were unpinned
// [ { cid: CID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u') } ]
// { cid: CID('QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u') }
```

A great source of [examples][] can be found in the tests for this API.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"is-ipfs": "~0.6.1",
"it-all": "^1.0.1",
"it-concat": "^1.0.0",
"it-drain": "^1.0.0",
"it-last": "^1.0.1",
"it-pushable": "^1.3.1",
"multiaddr": "^7.2.1",
Expand Down
11 changes: 6 additions & 5 deletions src/block/rm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
const { getDescribe, getIt, expect } = require('../utils/mocha')
const hat = require('hat')
const all = require('it-all')
const last = require('it-last')
const drain = require('it-drain')

/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
/**
Expand Down Expand Up @@ -142,13 +144,12 @@ module.exports = (common, options) => {
format: 'raw',
hashAlg: 'sha2-256'
})
await ipfs.pin.add(cid.toString())
await drain(ipfs.pin.add(cid))

const result = await all(ipfs.block.rm(cid))
const result = await last(ipfs.block.rm(cid))

expect(result).to.be.an('array').and.to.have.lengthOf(1)
expect(result[0]).to.have.property('error')
expect(result[0].error.message).to.include('pinned')
expect(result).to.have.property('error').that.is.an('Error')
.with.property('message').that.includes('pinned')
})
})
}
5 changes: 3 additions & 2 deletions src/name/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const delay = require('delay')
const CID = require('cids')
const all = require('it-all')
const last = require('it-last')
const drain = require('it-drain')

/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
/**
Expand Down Expand Up @@ -121,7 +122,7 @@ module.exports = (common, options) => {
// go only has 1 possible error https://github.com/ipfs/go-ipfs/blob/master/namesys/interface.go#L51
// so here we just expect an Error and don't match the error type to expiration
try {
await last(ipfs.name.resolve(nodeId))
await drain(ipfs.name.resolve(nodeId))
} catch (error) {
expect(error).to.exist()
}
Expand Down Expand Up @@ -170,7 +171,7 @@ module.exports = (common, options) => {

it('should fail to resolve /ipns/ipfs.a', async () => {
try {
await last(ipfs.name.resolve('ipfs.a'))
await drain(ipfs.name.resolve('ipfs.a'))
} catch (error) {
expect(error).to.exist()
}
Expand Down
4 changes: 2 additions & 2 deletions src/pin/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ module.exports = (common, options) => {
after(() => common.clean())

it('should add a pin', async () => {
const pinset = await ipfs.pin.add(fixtures.files[0].cid, { recursive: false })
expect(pinset.map(p => p.cid.toString())).to.include(fixtures.files[0].cid)
const pinset = await all(ipfs.pin.add(fixtures.files[0].cid, { recursive: false }))
expect(pinset.map(p => p.cid)).to.deep.include(fixtures.files[0].cid)
})
})
}
3 changes: 2 additions & 1 deletion src/pin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const { createSuite } = require('../utils/suite')
const tests = {
ls: require('./ls'),
rm: require('./rm'),
add: require('./add')
add: require('./add'),
core: require('./pins')
}

module.exports = createSuite(tests)
52 changes: 29 additions & 23 deletions src/pin/ls.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const { fixtures } = require('./utils')
const { getDescribe, getIt, expect } = require('../utils/mocha')
const all = require('it-all')
const drain = require('it-drain')

/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
/**
Expand All @@ -23,22 +24,21 @@ module.exports = (common, options) => {
ipfs = (await common.spawn()).api
// two files wrapped in directories, only root CID pinned recursively
const dir = fixtures.directory.files.map((file) => ({ path: file.path, content: file.data }))
await all(ipfs.add(dir, { pin: false, cidVersion: 0 }))
await ipfs.pin.add(fixtures.directory.cid, { recursive: true })
await drain(ipfs.add(dir, { pin: false, cidVersion: 0 }))
await drain(ipfs.pin.add(fixtures.directory.cid, { recursive: true }))
// a file (CID pinned recursively)
await all(ipfs.add(fixtures.files[0].data, { pin: false, cidVersion: 0 }))
await ipfs.pin.add(fixtures.files[0].cid, { recursive: true })
await drain(ipfs.add(fixtures.files[0].data, { pin: false, cidVersion: 0 }))
await drain(ipfs.pin.add(fixtures.files[0].cid, { recursive: true }))
// a single CID (pinned directly)
await all(ipfs.add(fixtures.files[1].data, { pin: false, cidVersion: 0 }))
await ipfs.pin.add(fixtures.files[1].cid, { recursive: false })
await drain(ipfs.add(fixtures.files[1].data, { pin: false, cidVersion: 0 }))
await drain(ipfs.pin.add(fixtures.files[1].cid, { recursive: false }))
})

after(() => common.clean())

// 1st, because ipfs.add pins automatically
it('should list all recursive pins', async () => {
const pinset = (await all(ipfs.pin.ls({ type: 'recursive' })))
.map(p => ({ ...p, cid: p.cid.toString() }))
const pinset = await all(ipfs.pin.ls({ type: 'recursive' }))

expect(pinset).to.deep.include({
type: 'recursive',
Expand All @@ -51,8 +51,7 @@ module.exports = (common, options) => {
})

it('should list all indirect pins', async () => {
const pinset = (await all(ipfs.pin.ls({ type: 'indirect' })))
.map(p => ({ ...p, cid: p.cid.toString() }))
const pinset = await all(ipfs.pin.ls({ type: 'indirect' }))

expect(pinset).to.not.deep.include({
type: 'recursive',
Expand All @@ -77,8 +76,7 @@ module.exports = (common, options) => {
})

it('should list all types of pins', async () => {
const pinset = (await all(ipfs.pin.ls()))
.map(p => ({ ...p, cid: p.cid.toString() }))
const pinset = await all(ipfs.pin.ls())

expect(pinset).to.not.be.empty()
// check the three "roots"
Expand Down Expand Up @@ -107,15 +105,19 @@ module.exports = (common, options) => {
it('should list all direct pins', async () => {
const pinset = await all(ipfs.pin.ls({ type: 'direct' }))
expect(pinset).to.have.lengthOf(1)
expect(pinset[0].type).to.equal('direct')
expect(pinset[0].cid.toString()).to.equal(fixtures.files[1].cid)
expect(pinset).to.deep.include({
type: 'direct',
cid: fixtures.files[1].cid
})
})

it('should list pins for a specific hash', async () => {
const pinset = await all(ipfs.pin.ls(fixtures.files[0].cid))
expect(pinset).to.have.lengthOf(1)
expect(pinset[0].type).to.equal('recursive')
expect(pinset[0].cid.toString()).to.equal(fixtures.files[0].cid)
expect(pinset).to.deep.include({
type: 'recursive',
cid: fixtures.files[0].cid
})
})

it('should throw an error on missing direct pins for existing path', () => {
Expand All @@ -136,22 +138,26 @@ module.exports = (common, options) => {
it('should list indirect pins for a specific path', async () => {
const pinset = await all(ipfs.pin.ls(`/ipfs/${fixtures.directory.cid}/files/ipfs.txt`, { type: 'indirect' }))
expect(pinset).to.have.lengthOf(1)
expect(pinset[0].type).to.equal(`indirect through ${fixtures.directory.cid}`)
expect(pinset[0].cid.toString()).to.equal(fixtures.directory.files[1].cid)
expect(pinset).to.deep.include({
type: `indirect through ${fixtures.directory.cid}`,
cid: fixtures.directory.files[1].cid
})
})

it('should list recursive pins for a specific hash', async () => {
const pinset = await all(ipfs.pin.ls(fixtures.files[0].cid, { type: 'recursive' }))
expect(pinset).to.have.lengthOf(1)
expect(pinset[0].type).to.equal('recursive')
expect(pinset[0].cid.toString()).to.equal(fixtures.files[0].cid)
expect(pinset).to.deep.include({
type: 'recursive',
cid: fixtures.files[0].cid
})
})

it('should list pins for multiple CIDs', async () => {
const pinset = await all(ipfs.pin.ls([fixtures.files[0].cid, fixtures.files[1].cid]))
const cids = pinset.map(p => p.cid.toString())
expect(cids).to.include(fixtures.files[0].cid)
expect(cids).to.include(fixtures.files[1].cid)
const cids = pinset.map(p => p.cid)
expect(cids).to.deep.include(fixtures.files[0].cid)
expect(cids).to.deep.include(fixtures.files[1].cid)
})
})
}
Loading