-
Notifications
You must be signed in to change notification settings - Fork 104
feat: modularise tests by command, add tools to skip and only #290
Conversation
c0afce8 to
c351f5e
Compare
|
This hits a lot of points that Victor and I wanted to try and look into this quarter. I really like the way this is laid out and the removal of the I would love to help take this through to competition. |
BREAKING CHANGE: Consumers of this test suite now have fine grained control over what tests are run. Tests can now be skipped and "onlyed" (run only specific tests). This can be done on a test, command and sub-system level. See the updated usage guide for instructions: https://github.com/ipfs/interface-ipfs-core/blob/master/README.md#usage. This means that tests skips depending on implementation (e.g. go/js), environment (e.g. node/browser) or platform (e.g. macOS/linux/windows) that were previously present in this suite have been removed. Consumers of this library should add their own skips based on the implementation that's being tested and the environment/platform that the tests are running on. The following other breaking changes have been made: 1. The common object passed to test suites has changed. It must now be a function that returns a common object (same shape and functions as before). 2. The `ipfs.ls` tests (not MFS `ipfs.files.ls`) is now a root level suite. You'll need to import it and use like `tests.ls(createCommon)` to have those tests run. 3. The `generic` suite (an alias to `miscellaneous`) has been removed. See #290 for more details. License: MIT Signed-off-by: Alan Shaw <[email protected]>
|
I appreciate this is a massive PR to review, but a lot of it is mechanical changes. Please read the PR description above first (a lot of this is echoed in the changes to the README). Just to highlight how things have moved around: Each sub-system (dag, files, swarm etc.) is now a folder with an All the tests for
BREAKING CHANGE: Consumers of this test suite now have fine grained control over what tests are run. Tests can now be skipped and "onlyed" (run only specific tests). This can be done on a test, command and sub-system level. See the updated usage guide for instructions. This means that tests skips depending on implementation (e.g. go/js), environment (e.g. node/browser) or platform (e.g. macOS/linux/windows) that were previously present in this suite have been removed. Consumers of this library should add their own skips based on the implementation that's being tested and the environment/platform that the tests are running on. The following other breaking changes have been made:
|
travisperson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a first long pass. I'll double back and take another look at a bit to refresh my eyes.
| }) | ||
|
|
||
| // This works because dag-cbor will just treat pbNode as a regular object | ||
| it.skip('should not put dag-pb node with wrong multicodec', (done) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this skip be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly, but it is currently skipped:
| ipfs.dht.provide(new CID(res[0].hash), (err) => { | ||
| expect(err).to.not.exist() | ||
| done() | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe many of these tests will work anymore as there will never be any peers on the dht to provide too, and there isn't much of a reason to provide to self.
The dht for go-ipfs I know will error if no peers are connected when running provides [0]. Should this be valid, and an issue opened for go-ipfs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve run these tests against js-ipfs and js-ipfs-api (talks to go-ipfs) and they all pass, so the tests that could fail might already be skipped...I’ll check and get back to you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DHT tests are completely commented out in js-ipfs currently 😟 https://github.com/ipfs/js-ipfs/blob/master/test/core/interface/dht.js
Some tests in js-ipfs-api were already skipped, but not any provide tests. I will investigate further...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Historically there were only a couple of DHT tests. The suite was increased with #288 which led me to found some issues with the http-api.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weirdly, these tests just started failing for me. I'll fix.
js/src/swarm/peers.js
Outdated
| const it = getIt(options) | ||
| const common = createCommon() | ||
|
|
||
| describe('.swarm', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is .swarm.peers right?
| expect(err).to.not.exist() | ||
| ipfs = nodes[0] | ||
| done() | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have an extra node
| spawnNodes(2, factory, (err, nodes) => { | ||
| expect(err).to.not.exist() | ||
| ipfs = nodes[0] | ||
| done() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have an extra node?
|
Sorry for the late adding of reviewers, I realised that this is a change that'll affect you all so I'd like you to all see it and know what is going on 🚀 |
jacobheun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to this, it's a great step towards better tests.
js/src/block/get.js
Outdated
| const dirtyChai = require('dirty-chai') | ||
| const multihash = require('multihashes') | ||
| const CID = require('cids') | ||
| const Buffer = require('safe-buffer').Buffer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for safe-buffer anymore.
js/src/bootstrap/rm.js
Outdated
| const { getDescribe, getIt } = require('../utils/mocha') | ||
|
|
||
| const expect = chai.expect | ||
| chai.use(dirtyChai) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are going to get describe and it through a local module, better to also pick expect from it, saving 4 lines from each module (and avoiding forgetting about it in the future).
js/src/bootstrap/rm.js
Outdated
| const expect = chai.expect | ||
| chai.use(dirtyChai) | ||
|
|
||
| const invalidArg = 'this/Is/So/Invalid/' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move it inside the module.exports
| module.exports = (createCommon, options) => { | ||
| const describe = getDescribe(options) | ||
| const it = getIt(options) | ||
| const common = createCommon() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does common need to created here, if there are no options for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to create a common object for each command now that they have been split into modules since it tracks nodes that are created so that they can be destroyed when teardown is called.
// Before:
tests.files(common)
// -> calls:
tests.files.add(common) // teardown destroys nodes created for files.add
tests.files.get(common) // teardown destroys nodes created for files.add AND files.get - ruh roh!
// etc.
// Now:
tests.files(createCommon)
// -> calls:
tests.files.add(createCommon) // teardown destroys nodes created for files.add
tests.files.get(createCommon) // teardown destroys nodes created for files.getThe alternative would be to make the common object smarter - to remove nodes from it's nodes array when teardown is called. However I was thinking that if we were to ever run these suites concurrently (please! one day!) then things would break.
From the PR description:
This work is backwards compatible with the previous API so no changes to dependent code needs to be made.I wanted this to be backwards compatible, but quickly ran into an issue where thecommonobject we pass to suites expects to only be used once. I started to pass it to multiple suites and theteardownfunction was trying to tear down nodes that were already stopped! So, unfortunately breaking change:commonshould now be a function that creates acommonobject for use with the tests. I'll submit PR's to js-ipfs (ipfs/js-ipfs#1389) and js-ipfs-api (ipfs-inactive/js-ipfs-http-client#785) to deal with this.
js/src/dag/put.js
Outdated
| }, done) | ||
| }) | ||
|
|
||
| it('should not put dag-cbor node with wrong multicodec', function (done) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to use function if no special timeout needs to be added.
js/src/dag/tree.js
Outdated
|
|
||
| const chai = require('chai') | ||
| const dirtyChai = require('dirty-chai') | ||
| const { series, eachSeries } = require('async') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use require('async/series') as a good practice to avoid requiring the whole module into our codebase.
js/src/dht/findpeer.js
Outdated
| }) | ||
| }) | ||
|
|
||
| it('should fail to find other peer if peer does not exist', function (done) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If no special timeout, please use a arrow func
js/src/dht/findpeer.js
Outdated
| it('should fail to find other peer if peer does not exist', function (done) { | ||
| nodeA.dht.findpeer('Qmd7qZS4T7xXtsNFdRoK1trfMs5zU94EpokQ9WFtxdPxsZ', (err, peer) => { | ||
| expect(err).to.not.exist() | ||
| expect(peer).to.be.equal(null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick s/to.be.equal(null)/to.not.exist()
js/src/dht/findprovs.js
Outdated
| const common = createCommon() | ||
|
|
||
| describe('.dht.findprovs', function () { | ||
| this.timeout(80 * 1000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove the global timeout in favor of by test timeout.
|
It seems a really better approach! Thanks @alanshaw |
js/src/pubsub/peers.js
Outdated
| ], done) | ||
| }) | ||
|
|
||
| describe('.peers', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you want to drop this describe as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes! thanks :D
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
BREAKING CHANGE: Consumers of this test suite now have fine grained control over what tests are run. Tests can now be skipped and "onlyed" (run only specific tests). This can be done on a test, command and sub-system level. See the updated usage guide for instructions: https://github.com/ipfs/interface-ipfs-core/blob/master/README.md#usage. This means that tests skips depending on implementation (e.g. go/js), environment (e.g. node/browser) or platform (e.g. macOS/linux/windows) that were previously present in this suite have been removed. Consumers of this library should add their own skips based on the implementation that's being tested and the environment/platform that the tests are running on. The following other breaking changes have been made: 1. The common object passed to test suites has changed. It must now be a function that returns a common object (same shape and functions as before). 2. The `ipfs.ls` tests (not MFS `ipfs.files.ls`) is now a root level suite. You'll need to import it and use like `tests.ls(createCommon)` to have those tests run. 3. The `generic` suite (an alias to `miscellaneous`) has been removed. See #290 for more details. License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
Added originally in #308 License: MIT Signed-off-by: Alan Shaw <[email protected]>
Originally from PR #267 License: MIT Signed-off-by: Alan Shaw <[email protected]>
As per original PR #311 License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
License: MIT Signed-off-by: Alan Shaw <[email protected]>
0d50c67 to
7a9c4d0
Compare
|
I think I've addressed all the feedback now, if there's no further comments then I'll merge this in tomorrow. Thank you and much ❤️ for your time and thoughts. |
daviddias
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put it on a boat 🚢 \o/
travisperson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there is a lingering file js/src/bitswap.js that should be removed.
License: MIT Signed-off-by: Alan Shaw <[email protected]>

This PR modularises tests by command and provides tools for consumers of this library to use skip/only on a command basis.
repo.versionandrepo.statare implemented butrepo.gcis not. This allows us to import tests forrepo.versionandrepo.statwithout failing the suite but also import and skip tests forrepo.gcfor visibility until the implementation is completewithGogoes away because we can just run the tests we want to run on any given implementationisNodegoes away because we can just run the tests we want to run on any given platformThis work is backwards compatible with the previous API so no changes to dependant code needs to be made.I wanted this to be backwards compatible, but quickly ran into an issue where thecommonobject we pass to suites expects to only be used once. I started to pass it to multiple suites and theteardownfunction was trying to tear down nodes that were already stopped! So, unfortunately breaking change:commonshould now be a function that creates acommonobject for use with the tests. I'll submit PR's to js-ipfs (ipfs/js-ipfs#1389) and js-ipfs-api (ipfs-inactive/js-ipfs-http-client#785) to deal with this.running tests by command
N.B. you can still run a whole sub-system suite like this:
skipping tests for a specific command
skipping specific tests
only
The idea here is that
onlycan be used during development/bug fixing to run only problematic tests without having tonpm linkand find the test(s) to add.onlyto.running only tests for a specific command
running only specific tests