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

Add spike report #210

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
Binary file added images/mock-db.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/stubbing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
163 changes: 163 additions & 0 deletions tests/integration/SPIKE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<h3> Report on testing CLI with EvalAI server on Production/Staging branch on CI/CD pipeline </h3>

Testing is a crucial part of the CI/CD process. Unit tests cover individual units in the code by using a stubbing
approach i.e. pre-defined responses that will be used for a specific request. However, this does not give a complete
picture of how all the components interact.

![Stubbing Image](../../images/stubbing.png)

Currently on the CI/CD pipeline for the EvalAI-CLI project, only unit tests are run. In the actual application, we use
the CLI in integration with the EvalAI server. To test this complete setup, integration tests are required.

The following is a SPIKE report on implementing integration tests to check the interaction of CLI with the server.

<h5> Environment Setup </h5>
In addition to the basic setup for the CLI, the server environment needs to be set up.

For the environment setup, the alternatives are:

<h4> Run EvalAI server in development environment in Travis VM </h4>

The server should be set up on Travis-CI VM so as to:
1. Ensure that the tests run fast.
2. Avoid any errors/build failures caused due to issues in the evalapi server.
3. Avoid blocking of CI process when for example, the evalapi server is down.

For this setup to work, the EvalAI server needs to be set up as follows:
1. Creating token setup for users required for the test (e.g. participant1, participant2, host1, host2, etc.)
2. Setting up the database that the server will be modifying: as our objective is only to test the interaction
between the CLI and the server, this part can be mocked.

![Mock database](../../images/mock-db.png)

However, setting up the environment this way can take a lot of time. On the Travis VM, setting up the server took about
8-10 minutes on average. This makes the method unsuitable for regular testing on CI/CD pipeline. But, this can be
implemented successfully on the Production/Staging branches where updates are less frequent. For example, the build can
Comment on lines +33 to +35
Copy link
Member

Choose a reason for hiding this comment

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

@nikochiko
Can you try if https://docs.travis-ci.com/user/build-stages/ is feasible as we can try to run unit test and integration test in parallel. Using this, we can get feedback from Unit Test and maybe, integration test will only run on some branches.

Copy link
Contributor Author

@nikochiko nikochiko Dec 17, 2019

Choose a reason for hiding this comment

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

Aha. Right. I think that's a good choice. While the unit tests take only 35-45 seconds, and the integration tests take 8-10 minutes, it wouldn't make much difference even if they were run at the same time paralelly. But we can set the integration tests to only run after the unit tests are passing. This way, a lot of time will be saved if unit tests are already failing. And integration tests can be implemented on more branches. I hope this is what you mean... !? Please correct me if I'm wrong 😅. I will add this in the report 😄

be triggered whenever there is a change in the Production/Staging branches of either EvalAI or evalai-cli. On the
production/staging branches, the test time can be further optimized by a minute or so as of now (and maybe more in the
future) if they are made to run in parallel as jobs (See [build stages](https://docs.travis-ci.com/user/build-stages/).

Another solution can be to set up build stages for unit tests and integration tests. This makes sure that the integration
tests are run only if the unit tests are already passing. This can save a lot of time in development.

P.S.: When I tried to set up the environment locally and on Travis, Celery threw some errors which made it to
stop working. Still looking into this issue. See: https://travis-ci.com/nikochiko/evalai-cli/jobs/267038723

<h4> Testing with evalapi server </h4>

This is the more hassle-free approach. Direct tests can be written against the evalapi server. Users can be created for
Copy link
Member

Choose a reason for hiding this comment

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

Using Auth Token for live project, of either Production or Staging, is not a good practice from security point of view. It would be better if you can try encrypting Auth Token in Environment Variable as defined in: https://docs.travis-ci.com/user/environment-variables/#defining-encrypted-variables-in-travisyml

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh thank you so much for the resource. I didn't know this could be done 😄 Will add this in the report.

testing purposes and few challenges (preferably those used for tutorial purposes) can be used for realistic testing.

For better implementation of this approach, the credentials of the test user can be stored as encrypted variables in
Travis-CI (see [Encrypting Environment Variables](https://docs.travis-ci.com/user/environment-variables/#defining-encrypted-variables-in-travisyml)).
The problem that arises here is that this variable would only be accessible to the repository owner. Encrypted variables
are also not available for testing pull requests from forks. Therefore, if other developers want to test new code, they
will have to set up their own Travis-CI and add an auth token themselves. A better way around this can be to add
functionality within the EvalAI server to allow for such testing with mock databases as mentioned above.

For a very rough example of the code, I used auth token from a user I created for this task.

See [code comparison](https://github.com/Cloud-CV/evalai-cli/pull/208) on GitHub.


<h4> The Tests: </h4>
For the tests, it is convenient to take a testing approach as creating tests for each command one-at-a-time and covering
all its corner cases.

For example, the test cases for `challenges` and `challenge` commands can have a
checklist with these cases:

* `evalai challenges`

Invokes: `evalai.challenges.challenges`

Cases:

* With few challenges
* With no challenges
* Exception when host URL is unreachable
* Exception when user is not authenticated

* `evalai challenges ongoing`

Invokes: `evalai.challenges.ongoing`

Cases:

* With few ongoing challenges
* With no ongoing challenges
* Exception when host URL is unreachable
* Exception when user is not authenticated

Similarly for:

* `evalai.challenges.future`
* `evalai.challenges.past`

* `evalai challenge <challenge_id>`

Invokes: `evalai.challenges.challenge`

Cases:

* When challenge exists
* When challenge does not exist
* When host URL is unreachable
* When user is not authenticated

* `evalai challenges --participant`

Invokes: `evalai.challenges.challenges` with `participant=True`

Cases:

* When user has participated in few challenges
* When user has not participated in any challenges

Similarly for `evalai challenges --host`

<h4> The Conclusion: </h4>

* Testing CLI with EvalAI server will require much setup, and possibly changes in the EvalAI server to enable testing.
* Among the setup approaches, the second one (testing against evalapi) is better in the short term if the credentials
don't become an issue. With this approach, there would be almost no extra work required. An example challenge can be
created as a tutorial for new users and can be used for testing as well.
* However in the long term, the first approach (testing against a development environment)should be preferred as it
allows for more complete testing with more control over the server. With this approach, the work on the setup would
take around 2-3 weeks.
* The tests will also be easier to write while testing against the live evalapi server while writing in the other
scenario would also include adding mock challenges, submissions, participant teams, etc. A rough estimate would be
around 8 weeks for writing complete tests in the first case and 10-12 weeks for the second case.
* Overall:

Taking the approach to write tests against the live evalapi server can take just over 8 weeks.

A summary of this approach is as follows:
* Lightweight, faster to implement
* Testing time will not be much (currently it is around 40 seconds, adding these tests, it would be around 1 minute on
Travis).
* Can be implemented more frequently on the CI/CD as it is light-weight
* However, the approach is crude and more prone to errors
* Development on CLI project can come to a halt when the server is down
* Less freedom while writing tests as the data needs to be present on the live server
* Exposing the credentials of the test user could become a potential issue
* Currently, the API does not have functionality to create challenges/phases or load additional data on the database,
except for making submissions. But later, writing tests for such conditions can be problematic as the database being
used for tests is the same as that being used for production.
* As a walkaround, functionality can be added inside EvalAI server to allow developer testing with temporary mock
databases.

Taking the approach to write tests for a developer environment setup on the Travis VM can take around 12-16 weeks for a
complete setup.

The summary for this:
* More complex, heavyweight
* Testing time will be greatly increased. Setting up the server takes around 8-10 minutes.
* Should only be used for final checks for Production/Staging branches on the CI/CD pipeline due to being slow.
* Mocking the database adds additional complexity. (As a workaround, a separate branch can be maintained on the main
EvalAI project -- such as `production-mockdb` -- where we allow for this functionality. Then while setting up the
server, that branch can be cloned with `git clone --branch production-mockdb` and then running `docker-compose` up for
that)
* Allows for more freedom on the type of tests to be written. More customizable
* Will not be a problem even if more functionality is added in the CLI
* More suitable for long-term