Contributing Guide¶
How to configure developer environment¶
System configuration¶
We assume you have a linux based system. Technically everything should be doable using docker on Windows, but we did not try it.
Hosts¶
You’ll need to set up mapping in: /etc/hosts
from olcms.dev.local
to localhost IP,
for example:
127.0.2.1 olcms.dev.local
Note
It is required for local swift datastore, due to swift internal details container must be
resolvable under the same domain/ip on both localhost (so your browser can access it)
and inside django container (so django can access it), since localhost
won’t work, as well as using raw IP, best way I could thought of was just using a domain.
Docker¶
You’ll need to install docker
(any recent version) and docker-compose
(any recent version, tested on 1.17.1
).
Also make sure you have rights to call docker command, to check it see if
docker info
exits successfully
Setting the system up¶
touch .local.dev.env
./dev.sh build
./dev.sh init
./dev.sh up
Sanity check¶
Run ./dev.sh ps
and see all services are up.
Basic set-up¶
- See “Creating user accounts”
Developer environment features¶
Email Server¶
In development, it is often nice to be able to see emails that are being sent from your application. For that reason local SMTP server MailHog with a web interface is available as docker container.
With MailHog running, to view messages that are sent by your application,
open your browser and go to http://127.0.0.1:8025
Youtube¶
To work with the upload of videos to youtube service developer needs to create locally .local.dev.env file, next to .dev.env.
In this file add two variables: YOUTUBE_SECRET_JSON and YOUTUBE_OAUTH2_JSON. As values for this variables use data from olcms-secrets project under yoututbe group. Management of the youtube account is done in cellery tasks. To see logs from this operations open logs for celleryworker process in the docker compose. Also remember to set correctly environment variable YT_PLAYLIST_ID with the correct id.
Note
See “Obtaining youtube credentials” on how to obtain youtube credentials.
Run elasticsearch locally¶
We use different indexing service locally than in production. Locally we use whoosh, and elasticsearch on production. Main reason for this difference is that Elasitc search eats a lot of RAM.
To use elastic search locally follow instructions below:
To start a local cluster using elastic search you can use:
docker-compose -f docker-compose-elasticsearch.yml
and then usuall up
, run django bash
(and so on).
You can access elastic search gui, by using: http://localhost:9200/_plugin/gui/#/inspect
.
Common developer tasks¶
Creating users¶
- To create normal user account just go create account normally, to verify
emails go to
http://localhost:8025
where all emails sent from the system are presented. - To create superuser just call:
./dev.sh manage createsuperuser
.
Running tests¶
To run all tests call: ./dev.sh test
(this takes some time), once you
isolate failing tests you may re-run just them: ./dev.sh test www.content_item
.
Running linter¶
Run ./dev.sh lint
.
Starting bash shell in the container¶
Run ./dev.sh bash
.
Generate translation files¶
Start shell in the container ./dev.sh bash
and then do following:
cd /app
./manage.py makemessages
— this will extract strings from all applications.cd www/templates
./manage.py makemessages
— this will extract strings from templates
Not so common developement tasks¶
Debugging selenium tests¶
If your selenium tests start to fail, here is what you can do:
When you run tests screenshots and page HTML dumps are stored in the
screenshots
, usually there are more than one screen-shoot per test. File names have following format:test_name-specifier.extension
, where specifier describes the screen-shots/page dump. At the end of each test (both for successes and failures) final screen-shots is stored it hasfinal
specifier, so the name looks like:www.integration_tests.test_content_item.ContentItemTest.test_add_content_item_with_default_author.final.png
.Screenshots are easiest way of spotting errors in your tests.
Try adding more screenshots
self.save_screenshot("before-submit")
at critical moments of failing test.If the tests are failing locally skip to the next (
Running selenium tests on a local browse
) section.If tests fail only on CI and not on your computer you might try running
stress-ng
locally this will simulate noisy-neighbours on CI and hopefully enable you to reproduce.If tests fail on CI, things get harder. Start with running ssh console on our CI instance: Click launch SSH console on the failing job.
Now you can start tests manually (starting with
docker-compose -f dev.yaml run django bash
).To pinpoint the issue I usually used pudb (console debugger).
Running selenium tests on a local browser¶
Easiest way to pinpoint selenium failures is to run selenium tests on your local browser.
You’ll need to:
Download geckodriver and add it to path. You can use this handy script (taken from
Dockerfile-dev
.curl https://ocs-pl.oktawave.com/v1/AUTH_385fff76-290b-43da-b2fc-96b1c08bce24/tools/geckodriver.xz | xzcat > /usr/local/bin/geckodriver && \ # Verify file integrity (did checksumming myself) sha256sum /usr/local/bin/geckodriver | grep --quiet 469052c6bf2c4f6e0b07f32d50ba0ff21b20e83d132468ec389050734dd23142 && \ chmod +x /usr/local/bin/geckodriver
There might be some way to run tests in docker, on the local browser but I have no idea how to configure it, so in this case we’ll just run django outside of container.
Create a virtualenv on python 3.5
Install all requirements:
pip install -r requirements/local.txt && pip install -r requirements/test.txt
Source proper variables:
source compose/django/entrypoint-local.sh
.If you want to use search:
./manage.py rebuild_index
../manage.py test
. Browser should start, and you’ll see what selenium does.It is useful to run
./manage.py test
in debugging mode and then manually stepping through the code.
Debugging indexes¶
When you encounter incorrect search results in development enviorment, inspecting index contents can help:
from whoosh.index import open_dir
ix = open_dir("whoosh_index_dir")
print(list(ix.searcher().documents()))
Debugging hanging tests¶
If selenium hangs you can try to debug it by sending USR1 signal to ./manage.py test
,
eg. by execing to container and then running: pkill -USR1 -f test
.
This will dump current stack-trace to stacktrace.log
log in your OLCMS folder.
Obtaining youtube credentials¶
ref:See here <obtain-youtube-credentials>.
How to add a new feature¶
- First get in touch with us e.g. by creating an issue: https://bitbucket.org/olcms/www/issues?status=new&status=open.
- Then write the feature.
- Make sure to add enough tests too keep coverage 100%.
What to test¶
For now I want to have 100% coverage on Python code, and good coverage on in the functional Selenium UI tests.
- Create unit tests that cover everything, except UI templating stuff.
- Explicitly test for permissions — check that users without permission have no access.
- Test rest framework. Test permissions there as well.
- Create automatic selenium tests for UI, Focus here on pure frontend aspects of the system.
How to test¶
Django unittest facilities are explained here: https://docs.djangoproject.com/en/1.10/topics/testing/tools/
Integration tests live in www.integration_tests
, while unit tests are inside
each application.
Selenium¶
Selenium is slightly harder to use. Start with extending: LiveServerBrowserTestCase
,
it runs firefox browser using a virtual framebuffer. Then you have access to selenium driver
using (unsurprisingly) self.driver
.
There are some helper methods in SeleniumUtilsMixin
,
most notably you’ll use self.login
(LiveServerBrowserTestCase
extends that mixin)
that logs in self.user
to OLCMS using the browser.