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

feat: modular interface tests #785

Merged
merged 20 commits into from
Jul 4, 2018
Merged

Conversation

alanshaw
Copy link
Contributor

@alanshaw alanshaw commented Jun 8, 2018

This PR updates js-ipfs-api to use the new interface-ipfs-core tests. This gives us fine grained control over what tests we run.

Please see the description on the PR for more information on the reasons behind this change.

This also enables a bunch of tests that weren't previously being run 🎉 ...and removes a LOT of duplicated code for running the interface tests.

requires ipfs-inactive/interface-js-ipfs-core#290

// as an empty object
'should not put dag-cbor node with wrong multicodec'
]
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... is this really the preferred approach? I foresee people changing the test title and not understanding why things are failing. I kind of liked when the tests explicitly communicated that it was known it wasn't working with go-ipfs or js-ipfs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right, there's a trade off here that I should have drawn more attention to - if a test name is changed in interface-ipfs-core and it is skipped in the consumer then it will begin to fail.

These PRs propose to put the responsibility on the implementation to know what tests should be skipped. I don't believe the interface should change based on the implementation/platform/environment. I also don't believe the interface should need to know about all possible implementations. It feels appropriate to me that the implementation should know and encapsulate this information, leaving interface-ipfs-core as a point of truth, dictating the interface that implementations need to conform to.

I see the advantages as:

  • Not having to send a separate PR to interface-ipfs-core when enabling already skipped tests or temporarily disabling flaky/buggy/not implemented tests - these PRs are not really for interface-ipfs-core, they are for js-ipfs or js-ipfs-api, but they leak into interface-ipfs-core because that's currently the only way to skip/unskip
  • Having a central location when you can easily see and manage all the tests that are skipped
  • Not having to maintain hacks and skips for tests based on all implementations that will ever exist in interface-ipfs-core e.g. withPhp, withJava, withRuby
    • Also if another Go implementation or JS implementation pops up, I don't want the interface to be skipping tests for them when it might not be appropriate to do so
  • Discouraging misuse of implementation specific checks, for example I've seen !withGo be used when devs actually mean withJs, which could easily cause problems in the future when being used against a Java or a Ruby backend (super minor, but worth noting)

The disadvantage:

  • If a test name is changed in interface-ipfs-core and it is skipped in the consumer then it will begin to fail

I rate the disadvantage as low impact. The frequency of test name changes is low (IMHO) and the chances of a test name changing and it also being a test that is skipped is also low. We should also be striving for no skips which would eradicate the risk completely.

It's your call, and I'm happy to move these back into interface-ipfs-core - I believe the other changes in these PRs are still valuable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also worth mentioning - we already have a scattering of where this information is held. We have implementation specific skips in interface-ipfs-core (go/js), but platform dependent (browser/node.js) skips in js-ipfs.

For example, some suites don't work in the browser so aren't included https://github.com/ipfs/js-ipfs/blob/2e9418465c863b129300ea5f0c8b32590edc7729/test/core/interface/interface.spec.js#L17-L23 and we have the same thing for functionality that isn't implemented e.g. repo tests simply just not included in js-ipfs because it's not all implemented yet.

These PRs would put all of that information in the same place, which I think is a win.

I'd like to at least try things this way around and if it becomes an issue then we change it back?

What do you think @diasdavid - is worth a try? I'd like to move forwards on these PRs soon because they're becoming difficult to keep up to date with master!

Thank you, much ❤️

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for putting so much care and thought into this, @alanshaw ❤️

I won't block you from moving forward but I have one last request. Can we treat the test suite as something definitive and everytime there is something that is skipped (i.e. does not work with go-ipfs) it is up to the implementation to skip the test but also print a log saying that says "go-ipfs incompatible" or something that clearly communicates to the dev that there is missing stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a think about what to do. Some ideas off the top of my head:

Option 1

// instead of
{
  skip: ['test1', 'test2']
}
// if passed as an object then interpret it as { skippedTest: 'reason' }
{
  skip: {
    'test1': 'go-ipfs incompatible',
    'test2': 'another reason'
  }
}

and causes output in the console like:

...
  ✓ other test
  - test1 (go-ipfs incompatible)
  - test2 (another reason)
...

Option 2

// instead of
{
  skip: ['test1', 'test2']
}
// if skip array item is an object, extract name & reason
{
  skip: [
    { name: 'test1', reason: 'go-ipfs incompatible' },
    { name: 'test2', reason: 'another reason' }
  ]
}

Too verbose?


Option 3

// instead of
{
  skip: ['test1', 'test2']
}
// explicit skip reasons object
{
  skip: ['test1', 'test2'],
  skipReasons: {
    'test1': 'go-ipfs incompatible',
    'test2': 'another reason'
  }
}

Too weird i think, and detached from skip test names.

...I think option 1 is my fav

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say Option 1 given the example but since some test titles are actually long, Option 2 might serve us better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diasdavid is it nice?:

skip specific test

screen shot 2018-06-26 at 23 08 11

skip entire subsystem

screen shot 2018-06-26 at 23 07 26

tests.pubsub(CommonFactory.create({
spawnOptions: {
args: ['--enable-pubsub-experiment'],
initOptions: { bits: 1024 }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use 1024 for all tests? It would make things way faster.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems this was actually lost with this change, before all tests used 1024.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood! Thanks :)

}
}))

tests.types(defaultCommonFactory, { skip: true })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why skip?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were not being run before and they fail right now - I'll add a comment


tests.types(defaultCommonFactory, { skip: true })

tests.util(defaultCommonFactory, { skip: true })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why skip?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were not being run before and they fail right now - I'll add a comment

package.json Outdated
@@ -75,6 +74,7 @@
"browser-process-platform": "~0.1.1",
"chai": "^4.1.2",
"cross-env": "^5.1.6",
"detect-node": "^2.0.3",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: this needs to be moved back into dependencies before merging as it's used in the main code

@alanshaw alanshaw force-pushed the feat/modular-interface-tests branch 2 times, most recently from 351dea5 to d5915a4 Compare June 26, 2018 22:03
// bitswap.unwant
{
name: 'should remove a key from the wantlist',
reason: 'FIXME why is this skipped?'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanshaw does it fail when run?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes unfortunately. It was just skipped in interface-ipfs-core before with no explanation.

  1) interface-ipfs-core tests
       .bitswap.unwant
         should remove a key from the wantlist:

      Uncaught AssertionError: expected false to equal true
      + expected - actual

      -false
      +true
      
      at ipfsB.bitswap.wantlist (/Users/alan/Code/protocol-labs/interface-ipfs-core/js/src/bitswap/unwant.js:52:61)
      at f (node_modules/once/once.js:25:25)
      at streamToValue (src/utils/stream-to-json-value.js:30:5)
      at concat (src/utils/stream-to-value.js:12:22)
      at ConcatStream.<anonymous> (node_modules/concat-stream/index.js:37:43)
      at finishMaybe (node_modules/readable-stream/lib/_stream_writable.js:630:14)
      at afterWrite (node_modules/readable-stream/lib/_stream_writable.js:492:3)
      at process._tickCallback (internal/process/next_tick.js:63:19)

    Reduces code repetition, allows test skipping and running only some tests.

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
@alanshaw alanshaw force-pushed the feat/modular-interface-tests branch from 9885db9 to b02e95b Compare June 29, 2018 15:29
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
@daviddias
Copy link
Contributor

y no green CI?

@alanshaw
Copy link
Contributor Author

alanshaw commented Jul 2, 2018

@diasdavid I had this all lined up to be merged asap after interface-ipfs-core@0.70 was released.

After 0.70 was released I saw that there were many issues on CI that didn't appear at all when run locally.

Jenkins had a bad day last week coinciding with the release so it's been difficult and slow to debug and resolve the issues. I now have a PR open on interface-ipfs-core to resolve them ipfs-inactive/interface-js-ipfs-core#319 (🤞 hopefully all of them). It would be rad if you have time to take a quick look.

I'm super anxious to get this and ipfs/js-ipfs#1389 merged asap because they're both depending on 0.69.x still. It's confusing and frustrating the community when trying to add tests to interface-ipfs-core right now 😞

@ghost ghost assigned daviddias Jul 3, 2018
@alanshaw
Copy link
Contributor Author

alanshaw commented Jul 3, 2018

FYI @diasdavid the 2 DAG tests that are failing here will be fixed by this PR #801

0x-r4bbit and others added 2 commits July 4, 2018 12:11
* fix(dag): ensure `dag.put()` allows for optional options

This is to align with API changes made in

ipfs-inactive/interface-js-ipfs-core@011c417

and

ipfs/js-ipfs#1415

License: MIT
Signed-off-by: Pascal Precht <pascal.precht@gmail.com>

* fix(dag): fixes to allow options to be optional

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update interface-ipfs-core dependency

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update ipfsd-ctl dependency

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix: increase timeout for addFromURL with wrap-with-directory

Sadly we can't guarantee ipfs.io will respond within 5s

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
The offline tests create and stop a node. ipfs/kubo#4078 seems to not only be restricted to windows.

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
@alanshaw
Copy link
Contributor Author

alanshaw commented Jul 4, 2018

@diasdavid gr gr gr greeeeeeen!

Copy link
Contributor

@daviddias daviddias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RAD! <3 @alanshaw

@daviddias daviddias merged commit 2426072 into master Jul 4, 2018
@ghost ghost removed the in progress label Jul 4, 2018
danieldaf pushed a commit to danieldaf/js-ipfs-api that referenced this pull request Jul 21, 2018
* feat: uses modular interface tests

    Reduces code repetition, allows test skipping and running only some tests.

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* feat: skip unimplemented files tests and add ls* tests

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix: adds skips for ipfs-inactive#339

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix: adds skips for key and miscellaneous

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* feat: add types and util tests (skipped as currently failing)

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* feat: add pin tests

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix(pubsub): adds skips for tests on windows

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix(config): adds skip for config.replace

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: re-adds bitswap tests

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: move detect-node back to dependencies

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: add skip reasons

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update interface-ipfs-core dependency

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: add reason for pubsub in browser skips

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: add bitswap skips for offline errors

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix: remove skip for test that was removed

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update interface-ipfs-core version

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update deps and test on CI (ipfs-inactive#802)

* chore: update interface-ipfs-core

* fix(dag): `dag.put()` allows for optional options (ipfs-inactive#801)

* fix(dag): ensure `dag.put()` allows for optional options

This is to align with API changes made in

ipfs-inactive/interface-js-ipfs-core@011c417

and

ipfs/js-ipfs#1415

License: MIT
Signed-off-by: Pascal Precht <pascal.precht@gmail.com>

* fix(dag): fixes to allow options to be optional

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update interface-ipfs-core dependency

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* chore: update ipfsd-ctl dependency

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix: increase timeout for addFromURL with wrap-with-directory

Sadly we can't guarantee ipfs.io will respond within 5s

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>

* fix: skip bitswap offline tests on all platforms

The offline tests create and stop a node. ipfs/kubo#4078 seems to not only be restricted to windows.

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants