From de24260c2bb2e5e99939a28348e074ea7fd4388b Mon Sep 17 00:00:00 2001 From: troymc Date: Thu, 25 Feb 2016 09:07:57 +0100 Subject: [PATCH 1/8] add diagram to monitoring section of docs --- .../_static/monitoring_system_diagram.png | Bin 0 -> 43931 bytes docs/source/monitoring.md | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 docs/source/_static/monitoring_system_diagram.png diff --git a/docs/source/_static/monitoring_system_diagram.png b/docs/source/_static/monitoring_system_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..6b654eac95ae0291c26333597d2341b74089df4f GIT binary patch literal 43931 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 U(z8LA0|Pwdq?9Bp#ErlI50G6q#Q*>R literal 0 HcmV?d00001 diff --git a/docs/source/monitoring.md b/docs/source/monitoring.md index 436a42aa..4d61cbc4 100644 --- a/docs/source/monitoring.md +++ b/docs/source/monitoring.md @@ -1,21 +1,31 @@ # Monitoring -BigchainDB uses [statsd](https://github.com/etsy/statsd) for monitoring. To fully take advantage of this functionality requires some additional infrastructure: an agent to listen for metrics (e.g. [telegraf](https://github.com/influxdata/telegraf)), a time-series database (e.g. [influxdb](https://influxdata.com/time-series-platform/influxdb/)), and a frontend to display analytics (e.g. [Grafana](http://grafana.org/)). +BigchainDB uses [StatsD](https://github.com/etsy/statsd) for monitoring. We require some additional infrastructure to take full advantage of its functionality: -For ease of use, we've provided a docker compose file that sets up all these services for testing. Simply run in the BigchainDB directory: +* an agent to listen for metrics: [Telegraf](https://github.com/influxdata/telegraf), +* a time-series database: [InfluxDB](https://influxdata.com/time-series-platform/influxdb/), and +* a frontend to display analytics: [Grafana](http://grafana.org/). +We put each of those inside its own Docker container. The whole system is illustrated below. + +![BigchainDB monitoring system diagram: Application metrics flow from servers running BigchainDB to Telegraf to InfluxDB to Grafana](./_static/monitoring_system_diagram.png) + +For ease of use, we've created a Docker [_Compose file_](https://docs.docker.com/compose/compose-file/) (named `docker-compose-monitor.yml`) to define the monitoring system setup. To use it, just go to to the top `bigchaindb` directory and run: ```text $ docker-compose -f docker-compose-monitor.yml build $ docker-compose -f docker-compose-monitor.yml up ``` -and point a browser tab to `http://localhost:3000/dashboard/script/bigchaindb_dashboard.js`. Login and password are `admin` by default. If BigchainDB is running and processing transactions, you should see analytics—if not, [start BigchainDB](installing.html#run-bigchaindb) and load some test transactions: +then point a browser tab to: +[http://localhost:3000/dashboard/script/bigchaindb_dashboard.js](http://localhost:3000/dashboard/script/bigchaindb_dashboard.js) + +The login and password are `admin` by default. If BigchainDB is running and processing transactions, you should see analytics—if not, [start BigchainDB](installing.html#run-bigchaindb) and load some test transactions: ```text $ bigchaindb-benchmark load ``` -and refresh the page after a few seconds. +then refresh the page after a few seconds. If you're not interested in monitoring, don't worry: BigchainDB will function just fine without any monitoring setup. From 5fd12a8b3f49eee48bfb385666a25e7fa246b04f Mon Sep 17 00:00:00 2001 From: troymc Date: Thu, 25 Feb 2016 16:18:51 +0100 Subject: [PATCH 2/8] Add Python Style Guide, update CONTRIBUTING.md --- CONTRIBUTING.md | 28 ++++++++------- PYTHON_STYLE_GUIDE.md | 79 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 PYTHON_STYLE_GUIDE.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0975b0c..8e3a517b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,8 +18,8 @@ To contribute code or documentation, you need a [GitHub account](https://github. Familiarize yourself with how we do coding and documentation in the BigchainDB project, including: -* our Python Style Guide (coming soon) -* [our documentation strategy](./docs/README.md) (including code documentation) +* [our Python Style Guide](PYTHON_STYLE_GUIDE.md) (includes how we write tests) +* [our documentation strategy](./docs/README.md) (including in-code documentation) * the GitHub Flow (workflow) * [GitHub Guide: Understanding the GitHub Flow](https://guides.github.com/introduction/flow/) * [Scott Chacon's blog post about GitHub Flow](http://scottchacon.com/2011/08/31/github-flow.html) @@ -63,27 +63,29 @@ git checkout -b new-branch-name ### Step 5 - Make Edits, git add, git commit -With your new branch checked out locally, make changes or additions to the code or documentation, git add them, and git commit them. +With your new branch checked out locally, make changes or additions to the code or documentation. Remember to: + +* follow [our Python Style Guide](PYTHON_STYLE_GUIDE.md). +* write and run tests for any new or changed code. There's a section in [our Python Style Guide](PYTHON_STYLE_GUIDE.md) about writing and running tests. +* add or update documentation as necessary. Follow [our documentation strategy](./docs/README.md). + +As you go, git add and git commit your changes or additions, e.g. ```text -git add new-or-changed-file +git add new-or-changed-file-1 +git add new-or-changed-file-2 git commit -m "Short description of new or changed things" ``` -Remember to write tests for new code. If you don't, our code (test) coverage will go down, and we won't be able to accept your code. (We have some hard checks that run on all new pull requests and code coverage is one of them.) - -Please run all existing tests to make sure you didn't break something. Do: -```text -py.test -v -``` - -Remember to write or modify documentation to reflect your additions or changes. - You will want to merge changes from upstream (i.e. the original repository) into your new branch from time to time, using something like: ```text git fetch upstream git merge upstream/develop ``` +Once you're done commiting a set of new things and you're ready to submit them for inclusion, please be sure to run all the tests (as per the instructions at the end of our [Python Style Guide](PYTHON_STYLE_GUIDE.md)). + +(When you submit your pull request [following the instructions below], we run all the tests automatically, so we will see if some are failing. If you don't know why some tests are failing, you can still submit your pull request, but be sure to note the failing tests and to ask for help with resolving them.) + ### Step 6 - Push Your New Branch to origin Make sure you've commited all the additions or changes you want to include in your pull request. Then push your new branch to origin (i.e. _your_ remote bigchaindb repository). diff --git a/PYTHON_STYLE_GUIDE.md b/PYTHON_STYLE_GUIDE.md new file mode 100644 index 00000000..9d23e0c0 --- /dev/null +++ b/PYTHON_STYLE_GUIDE.md @@ -0,0 +1,79 @@ +# Python Style Guide + +This guide starts out with our general Python coding style guidelines and ends with a section on how we write & run (Python) tests. + +## General Python Coding Style Guidelines + +Our starting point is [PEP8](https://www.python.org/dev/peps/pep-0008/), the standard "Style Guide for Python Code." Many Python IDEs will check your code against PEP8. (Note that PEP8 isn't frozen; it actually changes over time, but slowly.) + +BigchainDB uses Python 3.4+, so you can ignore all PEP8 guidelines specific to Python 2. + +### Python Docstrings + +PEP8 says some things about docstrings, but not what to put in them or how to structure them. [PEP257](https://www.python.org/dev/peps/pep-0257/) was one proposal for docstring conventions, but we prefer [Google-style docstrings](https://google.github.io/styleguide/pyguide.html?showone=Comments#Comments) instead: they're easier to read and the [napoleon extension](http://www.sphinx-doc.org/en/stable/ext/napoleon.html) for Sphinx lets us turn them into nice-looking documentation. Here are some references on Google-style docstrings: + +* [Google's docs on Google-style docstrings](https://google.github.io/styleguide/pyguide.html?showone=Comments#Comments) +* [napoleon's docs include an overview of Google-style docstrings](http://sphinxcontrib-napoleon.readthedocs.org/en/latest/index.html) +* [Example Google-style docstrings](http://sphinxcontrib-napoleon.readthedocs.org/en/latest/example_google.html) (from napoleon's docs) + +### Maximum Line Length + +PEP8 has some [maximum line length guidelines](https://www.python.org/dev/peps/pep-0008/#id17), starting with "Limit all lines to a maximum of 79 characters" but "for flowing long blocks of text with fewer structural restrictions (docstrings or comments), the line length should be limited to 72 characters." + +We discussed this at length, and it seems that the consensus is: try to keep line lengths less than 79/72 characters, unless you have a special situation where longer lines would improve readability. (The basic reason is that 79/72 works for everyone, and BigchainDB is an open source project.) + +### Single or Double Quotes? + +Python lets you use single or double quotes. PEP8 says you can use either, as long as you're consistent. We try to stick to using single quotes, except in cases where using double quotes is more readable. For example: +```python +print('This doesn\'t look so nice.') +print("Doesn't this look nicer?") +``` + +### Breaking Strings Across Multiple Lines + +Should we use parentheses or slashes (`\`) to break strings across multiple lines, i.e. +```python +my_string = ('This is a very long string, so long that it will not fit into just one line ' + 'so it must be split across multiple lines.') +# or +my_string = 'This is a very long string, so long that it will not fit into just one line ' \ + 'so it must be split across multiple lines.' +``` + +It seems the preference is for slashes, but using parentheses is okay too. (There are good arguments either way. Arguing about it seems like a waste of time.) + +### Using the % operator or `format()` to Format Strings + +Given the choice: +```python +x = 'name: %s; score: %d' % (name, n) +# or +x = 'name: {}; score: {}'.format(name, n) +``` + +we use the `format()` version. It's newer and doesn't require you to remember a bunch of arcane markup. + + +## Writing (Python) Tests + +We write tests for our Python code using the [pytest](http://pytest.org/latest/) framework. + +All tests go in the `bigchaindb/tests` directory or one of its subdirectories. You can use the tests already in there as templates or examples. + +To run all the tests, first make sure you have RethinkDB running: +```text +$ rethinkdb +``` + +then in another terminal, do: +```text +$ py.test -v +``` + +If that doesn't work (e.g. maybe you are running in a conda virtual environment), try: +```text +$ python -m pytest -v +``` + +We use [Travis CI](https://travis-ci.com/), so that whenever someone creates a new BigchainDB pull request on GitHub, Travis CI gets the new code and does _a bunch of stuff_. You can find out what we tell Travis CI to do in [the `.travis.yml` file](.travis.yml): it tells Travis CI how to install BigchainDB, how to run all the tests, and what to do "after success" (e.g. run `codecov`). (We use [Codecov](https://codecov.io/) to get a rough estimate of our test coverage.) From 2a611c7d3250057d5afbd5d7a33fff26e1e55467 Mon Sep 17 00:00:00 2001 From: troymc Date: Thu, 25 Feb 2016 17:26:42 +0100 Subject: [PATCH 3/8] Make Sylvain's suggested changes to py style guide --- PYTHON_STYLE_GUIDE.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/PYTHON_STYLE_GUIDE.md b/PYTHON_STYLE_GUIDE.md index 9d23e0c0..d416ad65 100644 --- a/PYTHON_STYLE_GUIDE.md +++ b/PYTHON_STYLE_GUIDE.md @@ -52,7 +52,7 @@ x = 'name: %s; score: %d' % (name, n) x = 'name: {}; score: {}'.format(name, n) ``` -we use the `format()` version. It's newer and doesn't require you to remember a bunch of arcane markup. +we use the `format()` version. The [official Python documentation says](https://docs.python.org/2/library/stdtypes.html#str.format), "This method of string formatting is the new standard in Python 3, and should be preferred to the % formatting described in String Formatting Operations in new code." ## Writing (Python) Tests @@ -61,6 +61,8 @@ We write tests for our Python code using the [pytest](http://pytest.org/latest/) All tests go in the `bigchaindb/tests` directory or one of its subdirectories. You can use the tests already in there as templates or examples. +### Standard Ways to Run All Tests + To run all the tests, first make sure you have RethinkDB running: ```text $ rethinkdb @@ -76,4 +78,25 @@ If that doesn't work (e.g. maybe you are running in a conda virtual environment) $ python -m pytest -v ``` +You can also run all tests via `setup.py`, using: +```text +$ python setup.py test +``` + +### Using `docker-compose` to Run the Tests + +You can use `docker-compose` to run the tests. (You don't have to start RethinkDB first: `docker-compose` does that on its own, when it reads the `docker-compose.yml` file.) + +First, build the images (~once), using: +```text +$ docker-compose build +``` + +then run the tests using: +```text +$ docker-compose run --rm bigchaindb py.test -v +``` + +### Automated Testing of All Pull Requests + We use [Travis CI](https://travis-ci.com/), so that whenever someone creates a new BigchainDB pull request on GitHub, Travis CI gets the new code and does _a bunch of stuff_. You can find out what we tell Travis CI to do in [the `.travis.yml` file](.travis.yml): it tells Travis CI how to install BigchainDB, how to run all the tests, and what to do "after success" (e.g. run `codecov`). (We use [Codecov](https://codecov.io/) to get a rough estimate of our test coverage.) From 24f8d7e5097dd64658180f93530d7398fd21d0e2 Mon Sep 17 00:00:00 2001 From: troymc Date: Sat, 27 Feb 2016 11:57:55 +0100 Subject: [PATCH 4/8] Changed Docker instructions slightly in docs --- docs/source/installing.md | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/docs/source/installing.md b/docs/source/installing.md index ff51539c..7cd451f3 100644 --- a/docs/source/installing.md +++ b/docs/source/installing.md @@ -91,7 +91,7 @@ For those who like using Docker and wish to experiment with BigchainDB in non-production environments, we currently maintain a `dockerfile` that can be used to build an image for `bigchaindb`, along with a `docker-compose.yml` file to manage a "standalone node", consisting mainly of two containers: one for -RethinkDB, and another for `bigchaindb`. +RethinkDB, and another for BigchainDB. Assuming you have `docker` and `docker-compose` installed, you would proceed as follows. @@ -112,27 +112,21 @@ stored on your host machine under ` ~/.bigchaindb_docker/config`: $ docker-compose run --rm bigchaindb bigchaindb configure ``` -You can load test transactions via: +You can then start it up (in the background, as a daemon) using: +```text +$ docker-compose up -d +``` + +then you can load test transactions via: ```text $ docker-compose run --rm bigchaindb bigchaindb-benchmark load ``` -You should then be able to start `bigchaindb`, via: -```text -$ docker-compose run --rm bigchaindb bigchaindb start -``` +If you're on Linux, you can probably view the RethinkDB dashboard at: -or -```text -$ docker-compose up -``` +[http://localhost:58080/](http://localhost:58080/) -You should be able to view the RethinkDB dashboard at: -```text -http://docker_host:58080/ -``` - -where `docker_host` is the IP or hostname of the machine running the Docker -engine. If you are developing on Linux, this most likely will be `localhost`, -whereas if you are running docker-machine (e.g.: on Mac OS X) this will be the +If that doesn't work, then replace `localhost` +with the IP or hostname of the machine running the Docker engine. +If you are running docker-machine (e.g.: on Mac OS X) this will be the IP of the Docker machine (`docker-machine ip machine_name`). From ffdd7cad61d9db4e204c44aa041e62905e991323 Mon Sep 17 00:00:00 2001 From: ryan Date: Mon, 29 Feb 2016 14:01:43 +0100 Subject: [PATCH 5/8] docker images now come from bigchaindb dockerhub account --- docker-compose-monitor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-monitor.yml b/docker-compose-monitor.yml index ee7fe3a4..6865931d 100644 --- a/docker-compose-monitor.yml +++ b/docker-compose-monitor.yml @@ -10,7 +10,7 @@ influxdb: PRE_CREATE_DB: "telegraf" grafana: - image: rhsimplex/grafana-bigchaindb-docker + image: bigchaindb/grafana-bigchaindb-docker tty: true ports: - "3000:3000" @@ -18,7 +18,7 @@ grafana: - influxdb:localhost statsd: - image: rhsimplex/docker-telegraf-statsd + image: bigchaindb/docker-telegraf-statsd ports: - "8125:8125/udp" links: From d60062e7306131b9faa0dbd6eccf99061fc1db06 Mon Sep 17 00:00:00 2001 From: troymc Date: Mon, 29 Feb 2016 14:14:19 +0100 Subject: [PATCH 6/8] Improve install docs for non-Linux users --- docs/source/installing.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/installing.md b/docs/source/installing.md index 7cd451f3..fded0eaf 100644 --- a/docs/source/installing.md +++ b/docs/source/installing.md @@ -2,6 +2,12 @@ We're developing BigchainDB Server ("BigchainDB") on Ubuntu 14.04, but it should work on any OS that runs RethinkDB Server and Python 3.4+. (BigchainDB is built on top of RethinkDB Server.) +BigchainDB Server is intended to be run on each server in a large distributed cluster of servers; it's not very useful running by itself on a single computer. That's _why_ we're developing it on Ubuntu 14.04: it's one of the more common server operating systems. + +Mac OS X users may get the best results [running BigchainDB with Docker](https://bigchaindb.readthedocs.org/en/develop/installing.html#run-bigchaindb-with-docker). + +Windows users may get the best results [running BigchainDB in a VM with Vagrant](https://bigchaindb.readthedocs.org/en/develop/installing.html#how-to-install-bigchaindb-on-a-vm-with-vagrant). + ## Install and Run RethinkDB Server The RethinkDB documentation has instructions for how to install RethinkDB Server on a variety of operating systems. Do that (using their instructions for your OS): [Install RethinkDB Server](http://rethinkdb.com/docs/install/). From 752c5741e4d47a4496af9511429f55aae228ef35 Mon Sep 17 00:00:00 2001 From: troymc Date: Mon, 29 Feb 2016 14:22:42 +0100 Subject: [PATCH 7/8] Add comment on coming clients/drivers in docs --- docs/source/installing.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/installing.md b/docs/source/installing.md index fded0eaf..9ff24298 100644 --- a/docs/source/installing.md +++ b/docs/source/installing.md @@ -4,9 +4,11 @@ We're developing BigchainDB Server ("BigchainDB") on Ubuntu 14.04, but it should BigchainDB Server is intended to be run on each server in a large distributed cluster of servers; it's not very useful running by itself on a single computer. That's _why_ we're developing it on Ubuntu 14.04: it's one of the more common server operating systems. -Mac OS X users may get the best results [running BigchainDB with Docker](https://bigchaindb.readthedocs.org/en/develop/installing.html#run-bigchaindb-with-docker). +Mac OS X users may get the best results [running BigchainDB Server with Docker](https://bigchaindb.readthedocs.org/en/develop/installing.html#run-bigchaindb-with-docker). -Windows users may get the best results [running BigchainDB in a VM with Vagrant](https://bigchaindb.readthedocs.org/en/develop/installing.html#how-to-install-bigchaindb-on-a-vm-with-vagrant). +Windows users may get the best results [running BigchainDB Server in a VM with Vagrant](https://bigchaindb.readthedocs.org/en/develop/installing.html#how-to-install-bigchaindb-on-a-vm-with-vagrant). + +(Right now, there are no BigchainDB clients/drivers. Those will be able to run on a much larger array of operating systems. They're coming soon.) ## Install and Run RethinkDB Server From bd6e16b836af13a7f2cc2c6d926d42a7c200c63b Mon Sep 17 00:00:00 2001 From: vrde Date: Mon, 29 Feb 2016 14:28:02 +0100 Subject: [PATCH 8/8] Fix bug related to config overwrite --- bigchaindb/commands/bigchain.py | 2 +- tests/test_commands.py | 19 +++++++++++++++++++ tests/utils/test_config_utils.py | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 33d37822..35b2de2f 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -45,7 +45,7 @@ def run_configure(args, skip_if_exists=False): if config_file_exists and not args.yes: want = input('Config file `{}` exists, do you want to override it? ' '(cannot be undone) [y/n]: '.format(config_path)) - if not want: + if want != 'y': return # Patch the default configuration with the new values diff --git a/tests/test_commands.py b/tests/test_commands.py index faa455d0..57ebdbe9 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -144,3 +144,22 @@ def test_run_configure_when_config_does_not_exist(monkeypatch, args = Namespace(config='foo', yes=True) return_value = run_configure(args) assert return_value is None + + +def test_run_configure_when_config_does_exist(monkeypatch, + mock_write_config, + mock_generate_key_pair, + mock_bigchaindb_backup_config): + value = {} + def mock_write_config(newconfig, filename=None): + value['return'] = newconfig + + from bigchaindb.commands.bigchain import run_configure + monkeypatch.setattr('os.path.exists', lambda path: True) + monkeypatch.setattr('builtins.input', lambda question: '\n') + monkeypatch.setattr('bigchaindb.config_utils.write_config', mock_write_config) + + args = Namespace(config='foo', yes=None) + run_configure(args) + assert value == {} + diff --git a/tests/utils/test_config_utils.py b/tests/utils/test_config_utils.py index b95db9aa..57539246 100644 --- a/tests/utils/test_config_utils.py +++ b/tests/utils/test_config_utils.py @@ -5,7 +5,7 @@ import pytest import bigchaindb -ORIGINAL_CONFIG = copy.deepcopy(bigchaindb.config) +ORIGINAL_CONFIG = copy.deepcopy(bigchaindb._config) @pytest.fixture(scope='function', autouse=True)