datahuborg/datahub

View on GitHub
Managing and Testing.rst

Summary

Maintainability
Test Coverage
Managing and Testing
********************

================
Managing DataHub
================

----------------------
Basic Vagrant Commands
----------------------

.. code-block:: bash

    $ cd /path/to/datahub

    # Start the VM, creating one if it doesn't exist
    $ vagrant up

    # Stop the VM
    $ vagrant halt

    # Delete the VM completely
    $ vagrant destroy

    # Get a shell in the VM
    $ vagrant ssh

---------------------
Basic Docker Commands
---------------------

The above Vagrant commands are sufficient for running DataHub, but if you need to troubleshoot or develop with DataHub, you will want to learn about Docker. Docker isolates processes and their dependencies by containerizing parts of a system into lightweight VMs.

Docker can be a little odd to work with at first. Below are some common Docker commands. For Docker tutorials and documentation, see `<https://docs.docker.com/engine/userguide/>`_.

DataHub is composed of 3 process containers and 2 data containers.

- ``web`` runs nginx, a reverse proxy. It listens on ports 80 and 443, serves static content, and proxies dynamic requests to the app container.
- ``app`` runs gunicorn, a wsgi Python server. It listens on port 8000, but only to requests from other containers. app is where DataHub's code lives.
- ``db`` runs a Postgres server. It listens on port 5432, but only to connections from other containers.
- ``data`` holds user uploads and the Postgres data.
- ``logs`` holds log files for the web, app, and db containers.

After sshing into Vagrant:

.. code-block:: bash

    # List all Docker containers and their statuses
    $ sudo docker ps -a
    CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                      NAMES
    886051b04caf        datahuborg/nginx      "nginx -g 'daemon off"   22 seconds ago      Up 3 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   web
    fcff60382ffd        datahuborg/datahub    "gunicorn --config=pr"   22 seconds ago      Up 3 seconds        8000/tcp                                   app
    03f076daa71e        datahuborg/postgres   "/docker-entrypoint.s"   22 seconds ago      Up 14 seconds       5432/tcp                                   db
    78d6af962797        datahuborg/postgres   "/bin/true"              22 seconds ago      Created                                                        data
    e41f0f5135db        datahuborg/postgres   "/bin/true"              22 seconds ago      Created                                                        logs

    # Container lifecycle
    $ sudo docker start app
    $ sudo docker stop app
    $ sudo docker restart app

    # Diagnosing a container
    $ sudo docker logs app

    # Connecting to a container's bash terminal
    $ sudo docker exec -ti app /bin/bash

Because the server is containerized, most server commands must be run in a container. Docker commands can be complicated, so several common tasks have been made into scripts under ``/vagrant/provisions/docker``.

.. code-block:: bash

    $ dh-build-images
    $ dh-create-dev-containers
    $ dh-create-prod-containers
    $ dh-rebuild-and-collect-static-files
    $ dh-run-test-container
    $ dh-start-containers
    $ dh-stop-containers
    $ dh-remove-all-containers
    $ dh-back-up-single-database
    $ dh-back-up-all-databases
    $ dh-restore-database
    $ dh-run-pgcli
    $ dh-codeclimate

Example Docker commands:

.. code-block:: bash

    # View nginx's access logs
    $ sudo docker run --rm \
      --volumes-from logs \
      datahuborg/postgres \
      cat /var/log/nginx/access.log

    # Run Django migrations
    $ sudo docker run --rm \
      --net=datahub_dev \
      --volumes-from app \
      datahuborg/datahub \
      python src/manage.py migrate --noinput
    
    # Collect changes to Django's static files so the web container
    # can see them.
    $ sudo docker run --rm \
      --volumes-from app \
      datahuborg/datahub \
      python src/manage.py collectstatic --noinput

    # Pip install -r requirements.txt
    $ sudo docker exec app pip install -r requirements.txt

    # Note that `--rm` means it creates an ephemeral container. A new
    # lightweight VM is created just for that command, and is then
    # deleted as soon as it exits. That is useful for a number of
    # reasons, but it also means exiting the container may take a few
    # seconds as Docker deletes the container.

    # It is possible to execute commands inside of running containers
    # instead of creating ephemeral containers which share volumes,
    # but it is not recommended as you can change the expected state
    # of a container.
    #
    # Get a shell in an active container:
    $ sudo docker exec -ti app /bin/bash

    # See Docker's builtin help
    $ docker help


===============
Testing DataHub
===============

To run tests or use the python debugger, you will need to connect to the test container.

.. code-block:: bash

    $ vagrant ssh
    $ sudo dh-run-test-container


You can exit the testing container by typing control-d or via the command ``exit``.

----------------
Functional Tests
----------------

DataHub uses Selenium and PhantomJS to test functionality from an end user's perspective. Both are installed as part of DataHub's Vagrant setup.

Once in the test container, you can run all functional tests with:

.. code-block:: bash

    $ sh /datahub/src/scripts/run-functional-tests.sh

Browser screenshots are saved in ``src/functional_tests/screenshots`` on teardown

    
You can run individual functional tests with:

.. code-block:: bash

    $ python manage.py test functional_tests.test_login_auth          # tests authentication
    $ python manage.py test functional_tests.test_layout_and_styling  # tests main page layout
    $ python manage.py test functional_tests.test_db                  # tests data control and sharing

Functional test files are saved in ``src/functional_tests``.

-----------------
Integration Tests
-----------------

Integration tests verify that DataHub's components behave as expected when used as a whole with a database.

Once in the test container, you can run all integration tests with:

.. code-block:: bash

    $ sh /datahub/src/scripts/run-integration-tests.sh

----------
Unit Tests
----------

Unit tests are used to test DataHub's components in isolation from the database and each other.

Once in the test container, you can run all unit tests with:

.. code-block:: bash

    $ sh /datahub/src/scripts/run-unit-tests.sh


You can run individual unit tests:

.. code-block:: bash

    $ python manage.py test inventory  # tests models
    $ python manage.py test www        # tests home page
    $ python manage.py test account    # tests account management views
    $ python manage.py test core       # tests datahub core database access
    $ python manage.py test browser    # tests datahub core views
    $ python manage.py test api        # tests datahub RESTful API

Unit test files are saved in a ``test`` directory in their related application directory.
e.g.: ``src/browser/tests``, ``src/core/tests``