# Cornell: record & replay mock server
[](https://app.travis-ci.com/github/hiredscorelabs/cornell)
[](https://www.python.org/downloads/release/python-390/)
[](https://hub.docker.com/r/hiredscorelabs/cornell)
<p align="center">
<img src="https://imgur.com/ShxP4AI.png" alt="Cornell Logo">
</p>
> Cornell makes it dead simple, via its record and replay features to perform end-to-end testing in a fast and isolated testing environment.
When your application integrates with multiple web-based services, end-to-end testing is crucial before deploying to production.
Mocking is often a tedious task. It becomes even more tiresome when working with multiple APIs from multiple vendors.
[vcrpy](https://github.com/kevin1024/vcrpy) is an awesome library that records and replays HTTP interactions for unit tests. Its output is saved to reusable "cassette" files.
By wrapping vcrpy with Flask, Cornell provides a lightweight record and replay server that can be easily used during distributed system testing and simulate all HTTP traffic needed for your tests.
## Basic Use Case
When you're working with distributed systems, the test client entry point triggers a cascade of events that eventually send HTTP requests to an external server

With Cornell server started, it will act as a proxy (**record mode**) between the outgoing HTTP requests and the external server and will record all relevant interactions.
Once interactions are recorded, Cornell can work in replay mode, replacing the external server entirely, short-circuiting the calls and instead, replying back instantly with the previously recorded response.

## Installation
To install from [PyPI](https://pypi.org/project/cornell/), all you need to do is this:
```bash
pip install cornell
```
## Usage
```bash
Usage: cornell_server.py [OPTIONS]
Usage Examples: Record mode: `cornell --forward_uri="https://remote_server/api" --record -cd custom_cassette_dir`
Replay mode: `cornell -cd custom_cassette_dir
Options:
-p, --port INTEGER
-ff, --forward_uri TEXT Must be provided in case of recording mode
-, --record-once / --record-all
Record each scenario only once, ignore the
rest
-r, --record Start server in record mode
-fp, --fixed-path Fixed cassettes path. If enabled, Cornell
will support only one server for recording
-cd, --cassettes-dir TEXT Cassettes parent directory, If not
specified, Cornell parent dir will be used
-re, --record-errors BOOLEAN If enabled, Cornell will record erroneous
responses
--help Show this message and exit.
```
## Demo - Full Example
Start Cornell in record mode:
```
cornell -ff https://api.github.com/ --record -cd cassettes
```
This will start the server in record-proxy mode on port `9000`, and will forward all requests to `https://api.github.com/`

When cornell is in record mode, it will forward all request to the specified forwarding URL, for example:
```
requests.get("http://127.0.0.1:9000/github/repos/kevin1024/vcrpy/license").json()
```
or
```
requests.get("http://127.0.0.1:9000/github/repos/kevin1024/vcrpy/contents").json()
```
or you can browse to the URL using your browser

Cornell will forward the request to the specified URL and will record both the request and the response.
The yaml cassettes will be recorded to a dedicated directory (by default, `cassettes` in the root dir)
For example:

__Note__
By default, `cassettes` directory will be created in cornell's root dir and will contain the cassette by destination hierarchy.
Use `-cd` to specify custom directory for your cassettes.
Mind that `-cd <custom_dir> should match for both record and replay modes
Once all the necessary interactions were recorded, stop cornell server using *ctrl+c*.
Once stopped, all interactions will be mapped via an auto-generated `index.yaml` file.
__Note__
In case the `index.yaml` is already present, it will be updated with new interactions. Otherwise, a new file will be created.
__Note__
Cornell doesn't record interactions with an erroneous response, by default (i.e response with 404, will omitted). If you wish to enable this option, run cornell with --record-errors flag
In this specific example, we can see that the 2 requests are mapped to the saved cassettes:

### Start cornell as docker container
```bash
docker run hiredscorelabs/cornell:latest
```
### Build cornell as docker container
```bash
docker build -t cornell .
docker run cornell --help
```
You will probably need to import cassettes from a local directory from your computer.
To do that, use the following command to mount a local directory as a volume in the container.
```bash
docker run -v ~/cassettes:/var/cassettes cornell -cd /var/cassettes
```
In some case, you want to use another port with cornell. If you need to do that, you should use
docker port mapping as in the following where cornell will listen on port `9020`.
```bash
docker run -p 9020:9000 cornell
```
## Features
### Request Matchers
In addition to the [vcrpy matchers](https://vcrpy.readthedocs.io/en/latest/configuration.html#request-matching), cornell provides the following custom request matchers:
- [OData](https://www.odata.org/getting-started/basic-tutorial/) request query matcher
- [SOAP](https://stoplight.io/api-types/soap-api/) request body matcher
### Environment Variables
Since Cornell is a testing server it's executed by default with `FLASK_ENV=local`.
You can modify this as described in [flask configuration](https://flask.palletsprojects.com/en/2.0.x/config/#configuration-handling)
### Advanced Features
Can be found in the [documentation](https://hiredscorelabs.github.io/cornell/docs/examples/)
## Contributing
Yes please! contributions are more than welcome!
Please follow [PEP8](https://www.python.org/dev/peps/pep-0008/) and the [Python Naming Conventions](https://pep8.org/#prescriptive-naming-conventions)
Add tests when you're adding new functionality and make sure all the existing tests are happy and green :)
To set up development environment:
```sh
python -m venv venv
source venv/bin/activate
make configure
```
## Running Tests
To run tests, run the following command
```bash
python -m venv venv
source venv/bin/activate
make test
```
Raw data
{
"_id": null,
"home_page": "https://hiredscorelabs.github.io/cornell/",
"name": "cornell",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Yael Mintz",
"author_email": "yaelmi3@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/36/42/cfb270d02cec151723b35f0b56274030968416f0a487e836a6a70b4baaa5/cornell-1.1.0.tar.gz",
"platform": null,
"description": "# Cornell: record & replay mock server\n\n[](https://app.travis-ci.com/github/hiredscorelabs/cornell)\n[](https://www.python.org/downloads/release/python-390/)\n[](https://hub.docker.com/r/hiredscorelabs/cornell)\n\n<p align=\"center\">\n <img src=\"https://imgur.com/ShxP4AI.png\" alt=\"Cornell Logo\">\n</p>\n\n\n> Cornell makes it dead simple, via its record and replay features to perform end-to-end testing in a fast and isolated testing environment.\n\nWhen your application integrates with multiple web-based services, end-to-end testing is crucial before deploying to production.\nMocking is often a tedious task. It becomes even more tiresome when working with multiple APIs from multiple vendors.\n\n[vcrpy](https://github.com/kevin1024/vcrpy) is an awesome library that records and replays HTTP interactions for unit tests. Its output is saved to reusable \"cassette\" files.\n\nBy wrapping vcrpy with Flask, Cornell provides a lightweight record and replay server that can be easily used during distributed system testing and simulate all HTTP traffic needed for your tests.\n\n## Basic Use Case\n\nWhen you're working with distributed systems, the test client entry point triggers a cascade of events that eventually send HTTP requests to an external server\n\n \n\nWith Cornell server started, it will act as a proxy (**record mode**) between the outgoing HTTP requests and the external server and will record all relevant interactions.\nOnce interactions are recorded, Cornell can work in replay mode, replacing the external server entirely, short-circuiting the calls and instead, replying back instantly with the previously recorded response.\n\n \n\n\n## Installation \n\nTo install from [PyPI](https://pypi.org/project/cornell/), all you need to do is this:\n\n```bash \n pip install cornell\n```\n\n## Usage\n\n```bash\nUsage: cornell_server.py [OPTIONS]\n\n Usage Examples: Record mode: `cornell --forward_uri=\"https://remote_server/api\" --record -cd custom_cassette_dir`\n Replay mode: `cornell -cd custom_cassette_dir\n\nOptions:\n -p, --port INTEGER\n -ff, --forward_uri TEXT Must be provided in case of recording mode\n -, --record-once / --record-all\n Record each scenario only once, ignore the\n rest\n\n -r, --record Start server in record mode\n -fp, --fixed-path Fixed cassettes path. If enabled, Cornell\n will support only one server for recording\n\n -cd, --cassettes-dir TEXT Cassettes parent directory, If not\n specified, Cornell parent dir will be used\n\n -re, --record-errors BOOLEAN If enabled, Cornell will record erroneous\n responses\n --help Show this message and exit.\n```\n\n## Demo - Full Example\n\n\nStart Cornell in record mode:\n\n```\ncornell -ff https://api.github.com/ --record -cd cassettes\n```\n\nThis will start the server in record-proxy mode on port `9000`, and will forward all requests to `https://api.github.com/`\n\n\n\nWhen cornell is in record mode, it will forward all request to the specified forwarding URL, for example:\n\n```\nrequests.get(\"http://127.0.0.1:9000/github/repos/kevin1024/vcrpy/license\").json()\n```\nor\n```\nrequests.get(\"http://127.0.0.1:9000/github/repos/kevin1024/vcrpy/contents\").json()\n```\n\nor you can browse to the URL using your browser\n\n\n\nCornell will forward the request to the specified URL and will record both the request and the response.\n\n\nThe yaml cassettes will be recorded to a dedicated directory (by default, `cassettes` in the root dir)\n\nFor example:\n\n\n\n\n__Note__\n\n By default, `cassettes` directory will be created in cornell's root dir and will contain the cassette by destination hierarchy.\n Use `-cd` to specify custom directory for your cassettes.\n Mind that `-cd <custom_dir> should match for both record and replay modes\n\nOnce all the necessary interactions were recorded, stop cornell server using *ctrl+c*.\nOnce stopped, all interactions will be mapped via an auto-generated `index.yaml` file.\n\n__Note__\n\n In case the `index.yaml` is already present, it will be updated with new interactions. Otherwise, a new file will be created.\n\n__Note__\n\n Cornell doesn't record interactions with an erroneous response, by default (i.e response with 404, will omitted). If you wish to enable this option, run cornell with --record-errors flag\n\nIn this specific example, we can see that the 2 requests are mapped to the saved cassettes:\n\n\n\n### Start cornell as docker container\n```bash\ndocker run hiredscorelabs/cornell:latest\n```\n\n### Build cornell as docker container\n\n```bash\ndocker build -t cornell .\ndocker run cornell --help\n```\n\nYou will probably need to import cassettes from a local directory from your computer. \nTo do that, use the following command to mount a local directory as a volume in the container.\n\n```bash\ndocker run -v ~/cassettes:/var/cassettes cornell -cd /var/cassettes\n```\n\nIn some case, you want to use another port with cornell. If you need to do that, you should use\ndocker port mapping as in the following where cornell will listen on port `9020`.\n\n```bash\ndocker run -p 9020:9000 cornell\n```\n\n## Features\n\n### Request Matchers\n\nIn addition to the [vcrpy matchers](https://vcrpy.readthedocs.io/en/latest/configuration.html#request-matching), cornell provides the following custom request matchers:\n\n- [OData](https://www.odata.org/getting-started/basic-tutorial/) request query matcher\n- [SOAP](https://stoplight.io/api-types/soap-api/) request body matcher\n\n\n### Environment Variables\n\nSince Cornell is a testing server it's executed by default with `FLASK_ENV=local`.\nYou can modify this as described in [flask configuration](https://flask.palletsprojects.com/en/2.0.x/config/#configuration-handling)\n\n### Advanced Features\n\nCan be found in the [documentation](https://hiredscorelabs.github.io/cornell/docs/examples/)\n\n## Contributing\n\nYes please! contributions are more than welcome!\n\nPlease follow [PEP8](https://www.python.org/dev/peps/pep-0008/) and the [Python Naming Conventions](https://pep8.org/#prescriptive-naming-conventions)\n\nAdd tests when you're adding new functionality and make sure all the existing tests are happy and green :)\n\nTo set up development environment:\n```sh\n python -m venv venv\n source venv/bin/activate\n make configure\n```\n\n\n## Running Tests\n\nTo run tests, run the following command\n\n```bash\n python -m venv venv\n source venv/bin/activate\n make test\n```",
"bugtrack_url": null,
"license": "MIT",
"summary": "Cornell: record & replay mock server",
"version": "1.1.0",
"project_urls": {
"Documentation": "https://hiredscorelabs.github.io/cornell/",
"Homepage": "https://hiredscorelabs.github.io/cornell/",
"Source": "https://github.com/hiredscorelabs/cornell"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3642cfb270d02cec151723b35f0b56274030968416f0a487e836a6a70b4baaa5",
"md5": "63374cd2538114daec960517fede9d66",
"sha256": "f29c15572dcd5015ea14cf21256837a486d3fd4440b9d15f48c722814314f1f3"
},
"downloads": -1,
"filename": "cornell-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "63374cd2538114daec960517fede9d66",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 19025,
"upload_time": "2023-09-19T04:58:32",
"upload_time_iso_8601": "2023-09-19T04:58:32.716070Z",
"url": "https://files.pythonhosted.org/packages/36/42/cfb270d02cec151723b35f0b56274030968416f0a487e836a6a70b4baaa5/cornell-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-19 04:58:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hiredscorelabs",
"github_project": "cornell",
"travis_ci": true,
"coveralls": true,
"github_actions": true,
"circle": true,
"lcname": "cornell"
}