Merge "Merge branch 'development'"
[ric-plt/a1.git] / docs / developer-guide.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
3
4 Developer-Guide
5 ===============
6
7 .. contents::
8    :depth: 3
9    :local:
10
11 Tech Stack
12 ----------
13
14 -  OpenAPI3
15 -  Connexion
16 -  Flask with Gevent serving
17 -  Python3.7
18
19 Version bumping
20 ---------------
21
22 This project follows semver. When changes are made, the versions are in:
23
24 1) ``docs/release-notes.rst``
25
26 2) ``setup.py``
27
28 3) ``container-tag.yaml``
29
30 4) ``integration_tests/a1mediator/Chart.yaml``
31
32 6) ``a1/openapi.yaml`` (this is an API version, not a software version; no need to bump on patch changes)
33
34 7) in the it/dep repo that contains a1 helm chart, ``values.yaml``, ``Chart.yml``
35
36
37 Version bumping rmr
38 --------------------
39 rmr is a critical dependency of A1. Bumping the rmr version dependency requires changes in:
40
41 1) ``Dockerfile``
42
43 2) ``Dockerfile-Unit-Test``
44
45 3) ``integration_tests/Dockerfile``
46
47 rmr-python is the python binding to rmr . Installing rmr per the above does not install it.
48 Bumping the rmr python version dependency requires changes in:
49
50 1) ``setup.py``
51
52 2) ``integration_tests/Dockerfile``
53
54 Run the integration tests after attempting this.
55
56
57 Unit Testing
58 ------------
59 Note,  before this will work, for the first time on the machine running the tests, run ``./install_deps.sh``. This is only needed once on the machine.
60 Also, this requires the python packages ``tox`` and ``pytest``.
61
62 ::
63
64    tox
65    open htmlcov/index.html
66
67 Alternatively, you can run the unit tests in Docker (this is somewhat less nice because you don't get the pretty HTML)
68
69 ::
70
71    docker build  --no-cache -t a1test:latest -f Dockerfile-Unit-Test
72
73 Integration testing
74 -------------------
75 This tests A1’s external API with two test receivers. This depends on helm+k8s, meaning you cannot run this if this is not installed.
76
77 Unlike the unit tests, however, this does not require rmr to be installed on the base system, as everything
78 runs in Docker, and the Dockerfiles provide/install rmr.
79
80 First, build the latest A1 you are testing (from the root):
81 ::
82
83     docker build  --no-cache -t a1:latest .
84
85 Note that this step also runs the unit tests, since running the unit tests are part of the Dockerfile for A1.
86
87 If you've never run the integration tests before, build the test receiver, which is referenced in the helm chart:
88 ::
89
90     cd integration_tests
91     docker build  --no-cache -t testreceiver:latest .
92
93 Finally, run all the tests from the root (this requires the python packages ``tox``, ``pytest``, and ``tavern``).
94 ::
95
96    tox -c tox-integration.ini
97
98 This script:
99 1. Deploys 3 helm charts into a local kubernetes installation
100 2. Port forwards a pod ClusterIP to localhost
101 3. Uses “tavern” to run some tests against the server
102 4. Barrages the server with apache bench
103 5. Tears everything down
104
105 Unless you're a core A1 developer, you should probably stop here. The below instructions
106 are for running A1 locally, without docker, and is much more involved (however useful when developing a1).
107
108 Running locally
109 ---------------
110
111 1. Before this will work, for the first time on that machine, run ``./install_deps.sh``
112
113 2. It also requires rmr-python installed. (The dockerfile does this)
114
115 3. Create a ``local.rt`` file and copy it into ``/opt/route/local.rt``.
116    Note, the example one in ``integration_tests`` will need to be modified for
117    your scenario and machine.
118
119 4. Copy a ric manifest into ``/opt/ricmanifest.json`` and an rmr mapping
120    table into ``/opt/rmr_string_int_mapping.txt``. You can use the test
121    ones packaged if you want:
122
123    ::
124
125      cp tests/fixtures/ricmanifest.json /opt/ricmanifest.json
126      cp tests/fixtures/rmr_string_int_mapping.txt /opt/rmr_string_int_mapping.txt
127
128 5. Then:
129
130    ::
131
132      sudo pip install -e .
133      set -x LD_LIBRARY_PATH /usr/local/lib/; set -x RMR_SEED_RT /opt/route/local.rt ; set -x RMR_RCV_RETRY_INTERVAL 500; set -x RMR_RETRY_TIMES 10;
134      /usr/bin/run.py
135
136
137 There are also two test receivers in ``integration_tests`` you can run locally.
138 The first is meant to be used with the ``control_admission`` policy
139 (that comes in test fixture ric manifest):
140
141 ::
142
143    set -x LD_LIBRARY_PATH /usr/local/lib/; set -x RMR_SEED_RT /opt/route/local.rt ; python receiver.py
144
145 The second can be used against the ``test_policy`` policy to test the
146 async nature of A1, and to test race conditions. You can start it with
147 several env variables as follows:
148
149 ::
150
151    set -x LD_LIBRARY_PATH /usr/local/lib/; set -x RMR_SEED_RT /opt/route/local.rt ; set -x TEST_RCV_PORT 4563; set -x TEST_RCV_RETURN_MINT 10001; set -x TEST_RCV_SEC_DELAY 5; set -x TEST_RCV_RETURN_PAYLOAD '{"ACK_FROM": "DELAYED_TEST", "status": "SUCCESS"}' ; python receiver.py
152
153 To test the async nature of A1, trigger a call to ``test_policy``, which
154 will target the delayed receiver, then immediately call
155 ``control_admission``. The ``control_admission`` policy return should be
156 returned immediately, whereas the ``test_policy`` should return after
157 about ``TEST_RCV_SEC_DELAY 5``. The ``test_policy`` should not block A1
158 while it is sleeping, and both responses should be correct.
159
160 ::
161
162    curl -v -X PUT -H "Content-Type: application/json" -d '{}' localhost:10000/ric/policies/test_policy
163    curl -v -X PUT -H "Content-Type: application/json" -d '{ "enforce":true, "window_length":10, "blocking_rate":20, "trigger_threshold":10 }' localhost:10000/ric/policies/admission_control_policy
164    curl -v localhost:10000/ric/policies/admission_control_policy
165    curl -v localhost:10000/a1-p/healthcheck