Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(repository-tests): run repository-tests on cloudant #3968

Merged
merged 1 commit into from
Nov 19, 2019

Conversation

agnes512
Copy link
Contributor

@agnes512 agnes512 commented Oct 18, 2019

closes #3437

Create acceptance-repository-cloudant folder.

  • Modify tests in replace-by-id need to be modified to run the replacement operation on Cloudant ( it needs an extra property _rev to do so).
  • Set up Travis task: it needs to run the script(docker.setup.js) to set up the docker image.
  • the docker.setup.js file is based on @jannyHou 's PR. I modified it a bit, now it can be used to set up the local test as well with customized names. ( see README).
  • Add local test setup and README file to allow run repo tests on Cloudant ( or on docker) locally.

Checklist

👉 Read and sign the CLA (Contributor License Agreement) 👈

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

👉 Check out how to submit a PR 👈

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

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

Nice start!

.travis.yml Outdated Show resolved Hide resolved
@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 7 times, most recently from 0b7f930 to 04b9553 Compare October 21, 2019 14:51
@@ -34,6 +34,11 @@ export function createSuiteForReplaceById(
})
id: MixedIdType;

// cloudant needs this property to do replacement method
// see cloundant README file for more details
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
Member

Choose a reason for hiding this comment

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

I find it suboptimal to force all connector tests (SQL, MongoDB, etc.) to use _rev property. Let's find a way how to allow individual connectors to provide any extra properties via CrudFeatures.

Copy link
Member

Choose a reason for hiding this comment

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

I see that you added revisionTokenRequired flag to fix test failures.

Personally, I'd prefer to find a way how to define _rev property only when running on Cloudant, so that we are not using _rev property when testing e.g. MongoDB.

Having said that, I don't have any solution I could offer from the top of my head, so it's probably better to accept the current proposal for now and get this pull request landed sooner rather than later 👍

@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 7 times, most recently from aec5e27 to 037dce5 Compare November 15, 2019 18:12
.travis.yml Outdated Show resolved Hide resolved
.travis.yml Outdated Show resolved Hide resolved
.travis.yml Outdated Show resolved Hide resolved
.travis.yml Outdated Show resolved Hide resolved
.travis.yml Outdated Show resolved Hide resolved
@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 2 times, most recently from 821b0b3 to 3689039 Compare November 15, 2019 21:24
.travis.yml Outdated Show resolved Hide resolved
@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 2 times, most recently from 636b9ae to 850873a Compare November 17, 2019 16:10
@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 5 times, most recently from 20e2a51 to 110e32a Compare November 17, 2019 16:55
@agnes512 agnes512 requested a review from bajtos November 17, 2019 17:23
@agnes512 agnes512 marked this pull request as ready for review November 17, 2019 17:25
Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

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

Great job, @agnes512 👏 I am happy to see that you managed to find a working solution for running our tests against Cloudant 👍

Let's discuss & improve the implementation details now.

docker.setup.js Outdated
// // we don't pass any node flags, so we can call _mocha instead the wrapper
// const mochaBin = require.resolve('mocha/bin/_mocha');

process.env.CLOUDANT_DATABASE = 'testdb';
Copy link
Member

Choose a reason for hiding this comment

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

Since this docker setup is specific to Cloudant, can you please move the setup script to acceptance/repository-cloudant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file will be removed once the release is done. The script is from #3968. I use it here to check if it sets up travis correctly and takes reasonable time to finish.

Copy link
Contributor

@jannyHou jannyHou Nov 18, 2019

Choose a reason for hiding this comment

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

@bajtos Thank you for the technical feedback of the setup script, it's actually added in https://github.com/strongloop/loopback-connector-cloudant/blob/master/docker.setup.js, @agnes512 put it in her PR before that script merged into the master.

To be honest, to save the time, the code in that script is mostly copied from an existing script that has been running for test from 2 years ago 🙈 , so for some of your questions I don't quite know the answer, but I'll try :p

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for the technical feedback of the setup script, it's actually added in https://github.com/strongloop/loopback-connector-cloudant/blob/master/docker.setup.js, @agnes512 put it in her PR before that script merged into the master.

I see, makes sense.

To be honest, to save the time, the code in that script is mostly copied from an existing script that has been running for test from 2 years ago

Sure, no need to refactor the script if it's working well as it is now. I am going to mark all my comments for docker.setup.js as resolved then.

docker.setup.js Outdated Show resolved Hide resolved
docker.setup.js Outdated Show resolved Hide resolved
docker.setup.js Outdated
async.waterfall(
[
dockerStart('ibmcom/couchdb3:latest'),
sleep(ms('2s')),
Copy link
Member

Choose a reason for hiding this comment

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

I am little bit concerned about the hard-coded delay. In many cases, the docker will start faster and we wait unnecessarily long. In some edge cases, the docker may not start fast enough, in which case the subsequent steps will fail (assuming they detect & handle this error correctly).

Is there any reasonable easy way how to replace this sleep with poll-based approach? E.g. every 100ms check if the docker container has started. If yes then the wait is over, if not then sleep 100ms and try again.

Feel free to leave this out of this pull request though.

docker.setup.js Outdated Show resolved Hide resolved
package.json Outdated
@@ -62,7 +66,8 @@
"docs:prepare": "./docs/bin/build-preview-site.sh",
"docs:start": "cd docs/_preview && bundle exec jekyll serve --no-w --i",
"mocha": "node packages/build/bin/run-mocha \"packages/*/dist/__tests__/**/*.js\" \"extensions/*/dist/__tests__/**/*.js\" \"examples/*/dist/__tests__/**/*.js\" \"packages/cli/test/**/*.js\" \"packages/build/test/*/*.js\"",
"posttest": "npm run lint"
"posttest": "npm run lint",
"docker:setup": "node ./docker.setup.js"
Copy link
Member

Choose a reason for hiding this comment

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

Since the Docker setup is specific to Cloudant, can we move this npm script to acceptance/repository-cloudant/package.json please?

Copy link
Contributor

Choose a reason for hiding this comment

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

it will be loaded from dependency loopback-connector-cloudant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jannyHou I moved the whole script to the acceptance/repo-cloudant. But I am okay with either way~

@@ -34,6 +34,11 @@ export function createSuiteForReplaceById(
})
id: MixedIdType;

// cloudant needs this property to do replacement method
// see cloundant README file for more details
Copy link
Member

Choose a reason for hiding this comment

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

I find it suboptimal to force all connector tests (SQL, MongoDB, etc.) to use _rev property. Let's find a way how to allow individual connectors to provide any extra properties via CrudFeatures.

expect(toJSON(found)).to.deepEqual(
// use containDeep instead of deepEqual because cloudant changes _rev value after
// replacement
expect(toJSON(found)).to.containDeep(
Copy link
Member

Choose a reason for hiding this comment

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

I am concerned that by changing from deepEqual to containDeep we are allowing many more changes than just a different _rev value. For example, if the connector and/or the database adds new properties, this assertion will happily accept that, even though such behavior is most likely not wanted.

Let's find a way how to deal with _rev changes via a new CrudFeatures flag in such way that only changes in the _rev property is allowed and only when testing against Cloudant/CouchDB.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated in the fifth commit.

expect(toJSON(found)).to.deepEqual(
// use containDeep instead of deepEqual because cloudant changes _rev value after
// replacement
expect(toJSON(found)).to.containDeep(
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

- Use the `couchDB3:latest` image, and rename the container as
`cloudant-testdb`.

- Start the container, and create an admin and password for this image at
Copy link
Member

Choose a reason for hiding this comment

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

Can we automate this and the previous step please? In other repository acceptance packages, the docker-based setup requires the developer to run a single script only. Can we perhaps tell people to use npm docker:setup? (See also my other comments suggesting to move that script to this package.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, and README is updated. ( the script is run in this folder now)

@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 3 times, most recently from ef41ae7 to c2eb73c Compare November 18, 2019 18:52
const docker = new require('dockerode')();
const http = require('http');
const ms = require('ms');
const fs = require('fs-extra');
Copy link
Contributor

Choose a reason for hiding this comment

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

fs-extra isn't listed in package.json.. but it also doesn't appear to really be fully utilized here since the only method used is in fs from core.

Copy link
Contributor

Choose a reason for hiding this comment

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

true fs is enough

@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 2 times, most recently from 82a5e08 to 2750e01 Compare November 18, 2019 19:25
Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

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

LGTM 👍


```bash
source setup.sh <HOST> <PORT> <USER> <PASSWORD> <DATABASE>
CLOUDANT_USER=<USER> CLOUDANT_PASSWORD=<PASSWORD> CLOUDANT_DATABASE=<DATABASE> node docker.setup.sh
Copy link
Member

Choose a reason for hiding this comment

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

node docker.setup.sh looks suspicious - node typically expects .js files, not .sh. I think it's just a typo?

Suggested change
CLOUDANT_USER=<USER> CLOUDANT_PASSWORD=<PASSWORD> CLOUDANT_DATABASE=<DATABASE> node docker.setup.sh
CLOUDANT_USER=<USER> CLOUDANT_PASSWORD=<PASSWORD> CLOUDANT_DATABASE=<DATABASE> node docker.setup.js

BTW why node docker.setup.js and not npm run docker:setup? Should we modify Travis CI config to call node docker.setup.js too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch!

And right, I think

CLOUDANT_USERNAME=<USER> CLOUDANT_PASSWORD=<PASSWORD> CLOUDANT_DATABASE=<DATABASE> npm run docker:setup

also allows users to have their own configurations 👍 changed.

@@ -34,6 +34,11 @@ export function createSuiteForReplaceById(
})
id: MixedIdType;

// cloudant needs this property to do replacement method
// see cloundant README file for more details
Copy link
Member

Choose a reason for hiding this comment

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

I see that you added revisionTokenRequired flag to fix test failures.

Personally, I'd prefer to find a way how to define _rev property only when running on Cloudant, so that we are not using _rev property when testing e.g. MongoDB.

Having said that, I don't have any solution I could offer from the top of my head, so it's probably better to accept the current proposal for now and get this pull request landed sooner rather than later 👍

*
* Default: `false`
*/
revisionTokenRequired: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick - feel free to ignore.

The _rev value is not always required, is it? For example, when creating a new model instance, the _rev must not be provided, at least AFAIK.

Maybe hasRevisionToken would be a better name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

make sense

@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 2 times, most recently from 477e642 to f55ef5b Compare November 19, 2019 19:40
Copy link
Contributor

@nabdelgadir nabdelgadir left a comment

Choose a reason for hiding this comment

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

LGTM 👍

acceptance/repository-cloudant/package.json Outdated Show resolved Hide resolved
crudRepositoryTestSuite(
CLOUDANT_CONFIG,
// Workaround for https://github.com/microsoft/TypeScript/issues/31840
DefaultTransactionalRepository as CrudRepositoryCtor,
Copy link
Contributor

Choose a reason for hiding this comment

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

Since it doesn't support transactions, I think you should change this to DefaultCrudRepository like in the MongoDB one.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Cloudant uses _rev to handle the update conflict, it doesn't handle transaction like sql dbs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right, I just copied it from MySQL :p

packages/repository-tests/src/crud/replace-by-id.suite.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@jannyHou jannyHou left a comment

Choose a reason for hiding this comment

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

👍 Almost there! LGTM after addressing comment from Nora and Ryan.
On a second thought I agree on keeping the setup script in this repository. Easy to maintain. the cloudant connector still uses the old script.

acceptance/repository-cloudant/package.json Outdated Show resolved Hide resolved
crudRepositoryTestSuite(
CLOUDANT_CONFIG,
// Workaround for https://github.com/microsoft/TypeScript/issues/31840
DefaultTransactionalRepository as CrudRepositoryCtor,
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Cloudant uses _rev to handle the update conflict, it doesn't handle transaction like sql dbs.

@agnes512 agnes512 force-pushed the cloudant-repo-tests branch 2 times, most recently from 7fabac1 to ee20f11 Compare November 19, 2019 22:35
@agnes512 agnes512 merged commit a54c588 into master Nov 19, 2019
@agnes512 agnes512 deleted the cloudant-repo-tests branch November 19, 2019 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Run repository tests for Cloudant
5 participants