Flush stdout as it can be redirected to log
[functest.git] / docs / devguide / index.rst
1 ******************************
2 OPNFV FUNCTEST developer guide
3 ******************************
4
5 .. toctree::
6    :numbered:
7    :maxdepth: 2
8
9
10 ============
11 Introduction
12 ============
13
14 Functest is a project dealing with functional testing.
15 Functest produces its own internal test cases but can also be considered
16 as a framework to support feature project testing.
17 Functest developed a test API and defined a test collection framework
18 that can be used by any OPNFV project.
19
20 Therefore there are many ways to contribute to Functest. You can:
21
22  * Develop new internal test cases
23  * Integrate the tests from your feature project
24  * Develop the framework to ease the integration of external test cases
25  * Develop the API / Test collection framework
26  * Develop dashboards or automatic reporting portals
27
28 This document describes how, as a developer, you may interact with the
29 Functest project. The first section details the main working areas of
30 the project. The Second part is a list of "How to" to help you to join
31 the Functest family whatever your field of interest is.
32
33
34 ========================
35 Functest developer areas
36 ========================
37
38
39 Functest High level architecture
40 ================================
41
42 Functest is project delivering a test container dedicated to OPNFV.
43 It includes the tools, the scripts and the test scenarios.
44
45 Functest can be described as follow::
46
47  +----------------------+
48  |                      |
49  |   +--------------+   |                  +-------------------+
50  |   |              |   |    Public        |                   |
51  |   | Tools        |   +------------------+      OPNFV        |
52  |   | Scripts      |   |                  | System Under Test |
53  |   | Scenarios    |   +------------------+                   |
54  |   |              |   |    Management    |                   |
55  |   +--------------+   |                  +-------------------+
56  |                      |
57  |    Functest Docker   |
58  |                      |
59  +----------------------+
60
61 Functest internal test cases
62 ============================
63 The internal test cases in Colorado are:
64
65  * healthcheck
66  * vping_ssh
67  * vping_userdata
68  * odl
69  * tempest_smoke_serial
70  * rally_sanity
71  * tempest_full_parallel
72  * rally_full
73  * vims
74
75 By internal, we mean that this particular test cases have been
76 developped and/or integrated by functest contributors and the associated
77 code is hosted in the Functest repository.
78 An internal case can be fully developped or a simple integration of
79 upstream suites (e.g. Tempest/Rally developped in OpenStack are just
80 integrated in Functest).
81 The structure of this repository is detailed in `[1]`_.
82 The main internal test cases are in the testcases subfolder of the
83 repository, the internal test cases are:
84
85  * Controllers: odl, onos, ocl
86  * OpenStack: healthcheck, vping_ssh, vping_userdata, tempest_*, rally_*
87  * VNF: vims
88
89 If you want to create a new test case you will have to create a new
90 folder under the testcases directory.
91
92 Functest external test cases
93 ============================
94 The external test cases are inherited from other OPNFV projects,
95 especially the feature projects.
96
97 The external test cases are:
98
99  * promise
100  * doctor
101  * onos
102  * bgpvpn
103  * copper
104  * moon
105  * security_scan
106  * sfc-odl
107  * sfc-onos
108  * parser
109  * domino
110  * multisite
111
112
113 Note that security_scan has been bootstraped in Functest but is
114 considered as an external test case as it gets its own repository.
115
116 The code to run these test cases may be directly in the repository of
117 the project. We have also a **features** sub directory under testcases
118 directory that may be used (it can be usefull if you want to reuse
119 Functest library).
120
121
122 Functest framework
123 ==================
124
125 Functest can be considered as a framework.
126 Functest is release as a docker file, including tools, scripts and a CLI
127 to prepare the environement and run tests.
128 It simplifies the integration of external test suites in CI pipeline
129 and provide commodity tools to collect and display results.
130
131 Since Colorado, test categories also known as tiers have been created to
132 group similar tests, provide consistant sub-lists and at the end optimize
133 test duration for CI (see How To section).
134
135 see http://artifacts.opnfv.org/functest/docs/userguide/index.html for
136 details.
137
138
139 Test collection framework
140 =========================
141
142 The OPNFV testing group created a test collection database to collect
143 the test results from CI:
144
145
146  http://testresults.opnfv.org/test/swagger/spec.html
147  Authentication: opnfv/api@opnfv
148
149 Any test project running on any lab integrated in CI can push the
150 results to this database.
151 This database can be used to see the evolution of the tests and compare
152 the results versus the installers, the scenarios or the labs.
153
154
155 Overall Architecture
156 --------------------
157 The Test result management can be summarized as follows::
158
159   +-------------+    +-------------+    +-------------+
160   |             |    |             |    |             |
161   |   Test      |    |   Test      |    |   Test      |
162   | Project #1  |    | Project #2  |    | Project #N  |
163   |             |    |             |    |             |
164   +-------------+    +-------------+    +-------------+
165            |               |               |
166            V               V               V
167        +-----------------------------------------+
168        |                                         |
169        |         Test Rest API front end         |
170        |  http://testresults.opnfv.org/test      |
171        |                                         |
172        +-----------------------------------------+
173            A                |
174            |                V
175            |     +-------------------------+
176            |     |                         |
177            |     |    Test Results DB      |
178            |     |         Mongo DB        |
179            |     |                         |
180            |     +-------------------------+
181            |
182            |
183      +----------------------+
184      |                      |
185      |    test Dashboard    |
186      |                      |
187      +----------------------+
188
189 Test API description
190 --------------------
191 The Test API is used to declare pods, projects, test cases and test
192 results. Pods are the pods used to run the tests.
193 The results pushed in the database are related to pods, projects and
194 cases. If you try to push results of test done on non referenced pod,
195 the API will return an error message.
196
197 An additional method dashboard has been added to post-process
198 the raw results in release Brahmaputra (deprecated in Colorado).
199
200 The data model is very basic, 4 objects are created:
201
202   * Pods
203   * Projects
204   * Testcases
205   * Results
206
207 Pods::
208
209   {
210     "id": <ID>,
211     "details": <URL description of the POD>,
212     "creation_date": "YYYY-MM-DD HH:MM:SS",
213     "name": <The POD Name>,
214     "mode": <metal or virtual>,
215     "role": <ci-pod or community-pod or single-node>
216   },
217
218 Projects::
219
220   {
221     "id": <ID>,
222     "name": <Name of the Project>,
223     "creation_date": "YYYY-MM-DD HH:MM:SS",
224     "description": <Short description>
225   },
226
227 Testcases::
228
229   {
230     "id": <ID>,
231     "name":<Name of the test case>,
232     "project_name":<Name of belonged project>,
233     "creation_date": "YYYY-MM-DD HH:MM:SS",
234     "description": <short description>,
235     "url":<URL for longer description>
236   },
237
238 Results::
239
240   {
241     "_id": <ID>,
242     "case_name": <Reference to the test case>,
243     "project_name": <Reference to project>,
244     "pod_name": <Reference to POD where the test was executed>,
245     "installer": <Installer Apex or Compass or Fuel or Joid>,
246     "version": <master or Colorado or Brahmaputra>,
247     "start_date": "YYYY-MM-DD HH:MM:SS",
248     "stop_date": "YYYY-MM-DD HH:MM:SS",
249     "build_tag": <such as "jenkins-functest-fuel-baremetal-daily-master-108">,
250     "scenario": <Scenario on which the test was executed>,
251     "criteria": <PASS or FAILED>,
252     "trust_indicator": <0~1>
253   }
254
255 The API can described as follows. For detailed information, please go to
256
257  http://testresults.opnfv.org/test/swagger/spec.html
258  Authentication: opnfv/api@opnfv
259
260 Please notes that POST/DELETE/PUT operations for test or study purpose via
261 swagger website is not allowed, because it will change the real data in
262 the database.
263
264 Version:
265
266  +--------+--------------------------+-----------------------------------------+
267  | Method | Path                     | Description                             |
268  +========+==========================+=========================================+
269  | GET    | /versions                | Get all supported API versions          |
270  +--------+--------------------------+-----------------------------------------+
271
272
273 Pods:
274
275  +--------+----------------------------+-----------------------------------------+
276  | Method | Path                       | Description                             |
277  +========+============================+=========================================+
278  | GET    | /api/v1/pods               | Get the list of declared Labs (PODs)    |
279  +--------+----------------------------+-----------------------------------------+
280  | POST   | /api/v1/pods               | Declare a new POD                       |
281  |        |                            | Content-Type: application/json          |
282  |        |                            | {                                       |
283  |        |                            | "name": "pod_foo",                      |
284  |        |                            | "mode": "metal",                        |
285  |        |                            | "role": "ci-pod",                       |
286  |        |                            | "details": "it is a ci pod"             |
287  |        |                            | }                                       |
288  +--------+----------------------------+-----------------------------------------+
289  | GET    | /api/v1/pods/{pod_name}    | Get a declared POD                      |
290  +--------+----------------------------+-----------------------------------------+
291
292 Projects:
293
294  +--------+----------------------------+-----------------------------------------+
295  | Method | Path                       | Description                             |
296  +========+============================+=========================================+
297  | GET    | /api/v1/projects           | Get the list of declared projects       |
298  +--------+----------------------------+-----------------------------------------+
299  | POST   | /api/v1/projects           | Declare a new test project              |
300  |        |                            | Content-Type: application/json          |
301  |        |                            | {                                       |
302  |        |                            | "name": "project_foo",                  |
303  |        |                            | "description": "whatever you want"      |
304  |        |                            | }                                       |
305  +--------+----------------------------+-----------------------------------------+
306  | DELETE | /api/v1/projects/{project} | Delete a test project                   |
307  +--------+----------------------------+-----------------------------------------+
308  | GET    | /api/v1/projects/{project} | Get details on a {project}              |
309  |        |                            |                                         |
310  +--------+----------------------------+-----------------------------------------+
311  | PUT    | /api/v1/projects/{project} | Update a test project                   |
312  |        |                            |                                         |
313  |        |                            | Content-Type: application/json          |
314  |        |                            | {                                       |
315  |        |                            | <the field(s) you want to modify>       |
316  |        |                            | }                                       |
317  +--------+----------------------------+-----------------------------------------+
318
319
320 Testcases:
321
322  +--------+----------------------------+-----------------------------------------+
323  | Method | Path                       | Description                             |
324  +========+============================+=========================================+
325  | GET    | /api/v1/projects/{project}/| Get the list of testcases of {project}  |
326  |        | cases                      |                                         |
327  +--------+----------------------------+-----------------------------------------+
328  | POST   | /api/v1/projects/{project}/| Add a new test case to {project}        |
329  |        | cases                      | Content-Type: application/json          |
330  |        |                            | {                                       |
331  |        |                            | "name": "case_foo",                     |
332  |        |                            | "description": "whatever you want"      |
333  |        |                            | "url": "whatever you want"              |
334  |        |                            | }                                       |
335  +--------+----------------------------+-----------------------------------------+
336  | DELETE | /api/v1/projects/{project}/| Delete a test case                      |
337  |        | cases/{case}               |                                         |
338  +--------+----------------------------+-----------------------------------------+
339  | GET    | /api/v1/projects/{project}/| Get a declared test case                |
340  |        | cases/{case}               |                                         |
341  +--------+----------------------------+-----------------------------------------+
342  | PUT    | /api/v1/projects/{project}?| Modify a test case of {project}         |
343  |        | cases/{case}               |                                         |
344  |        |                            | Content-Type: application/json          |
345  |        |                            | {                                       |
346  |        |                            | <the field(s) you want to modify>       |
347  |        |                            | }                                       |
348  +--------+----------------------------+-----------------------------------------+
349
350 Results:
351
352  +--------+----------------------------+------------------------------------------+
353  | Method | Path                       | Description                              |
354  +========+============================+==========================================+
355  | GET    | /api/v1/results            | Get all the test results                 |
356  +--------+----------------------------+------------------------------------------+
357  | POST   | /api/v1/results            | Add a new test results                   |
358  |        |                            | Content-Type: application/json           |
359  |        |                            | {                                        |
360  |        |                            | "project_name": "project_foo",           |
361  |        |                            | "scenario": "odl-l2",                    |
362  |        |                            | "stop_date": "2016-05-28T14:42:58.384Z", |
363  |        |                            | "trust_indicator": 0.5,                  |
364  |        |                            | "case_name": "vPing",                    |
365  |        |                            | "build_tag": "",                         |
366  |        |                            | "version": "Colorado",                   |
367  |        |                            | "pod_name": "pod_foo",                   |
368  |        |                            | "criteria": "PASS",                      |
369  |        |                            | "installer": "fuel",                     |
370  |        |                            | "start_date": "2016-05-28T14:41:58.384Z",|
371  |        |                            | "details": <your results>                |
372  |        |                            | }                                        |
373  +--------+----------------------------+------------------------------------------+
374  | GET    | /api/v1/results?           | Get the test results of {case}           |
375  |        | case={case}                |                                          |
376  +--------+----------------------------+------------------------------------------+
377  | GET    | /api/v1/results?           | Get the test results of build_tag        |
378  |        | build_tag={tag}            | {tag}.                                   |
379  +--------+----------------------------+------------------------------------------+
380  | GET    | /api/v1/results?           | Get last {N} records of test results     |
381  |        | last={N}                   |                                          |
382  +--------+----------------------------+------------------------------------------+
383  | GET    | /api/v1/results?           | Get the test results of scenario         |
384  |        | scenario={scenario}        | {scenario}.                              |
385  +--------+----------------------------+------------------------------------------+
386  | GET    | /api/v1/results?           | Get the test results of trust_indicator  |
387  |        | trust_indicator={ind}      | {ind}.                                   |
388  +--------+----------------------------+------------------------------------------+
389  | GET    | /api/v1/results?           | Get the test results of last days        |
390  |        | period={period}            | {period}.                                |
391  +--------+----------------------------+------------------------------------------+
392  | GET    | /api/v1/results?           | Get the test results of {project}        |
393  |        | project={project}          |                                          |
394  +--------+----------------------------+------------------------------------------+
395  | GET    | /api/v1/results?           | Get the test results of version          |
396  |        | version={version}          | {version}.                               |
397  +--------+----------------------------+------------------------------------------+
398  | GET    | /api/v1/results?           | Get the test results of criteria         |
399  |        | criteria={criteria}        | {criteria}.                              |
400  +--------+----------------------------+------------------------------------------+
401  | GET    | /api/v1/results?           | get the results on pod {pod}             |
402  |        | pod={pod}                  |                                          |
403  +--------+----------------------------+------------------------------------------+
404  | GET    | /api/v1/results?           | Get the test results of installer {inst} |
405  |        | installer={inst}           |                                          |
406  +--------+----------------------------+------------------------------------------+
407  | GET    | /api/v1/results?           | Get the results according to combined    |
408  |        | <query conditions>         | query conditions supported above         |
409  +--------+----------------------------+------------------------------------------+
410  | GET    | /api/v1/results/{result_id}| Get the test result by result_id         |
411  +--------+----------------------------+------------------------------------------+
412
413
414 Dashboard:
415
416  +--------+----------------------------+-----------------------------------------+
417  | Method | Path                       | Description                             |
418  +========+============================+=========================================+
419  | GET    |/dashboard/v1/results?      | Get all the dashboard ready results of  |
420  |        |&project={project}          | {case} of the project {project}         |
421  |        |&case={case}                |                                         |
422  +--------+----------------------------+-----------------------------------------+
423  | GET    |/dashboard/v1/results?      | Get all the dashboard ready results of  |
424  |        |&project={project}          | {case} of the project {project}         |
425  |        |&case={case}                | version {version}                       |
426  |        |&version={version}          |                                         |
427  +--------+----------------------------+-----------------------------------------+
428  | GET    |/dashboard/v1/results?      | Get all the dashboard ready results of  |
429  |        |&project={project}          | {case} of the project {project}         |
430  |        |&case={case}                | since {days} days                       |
431  |        |&period={days}              |                                         |
432  +--------+----------------------------+-----------------------------------------+
433  | GET    |/dashboard/v1/results?      | Get all the dashboard ready results of  |
434  |        |&project={project}          | {case} of the project {project}         |
435  |        |&case={case}                | installed by {installer}                |
436  |        |&installer={installer}      |                                         |
437  +--------+----------------------------+-----------------------------------------+
438  | GET    |/dashboard/v1/results?      | Get all the dashboard ready results of  |
439  |        |&project={project}          | {case} of the project {project}         |
440  |        |&case={case}                | on POD {pod}                            |
441  |        |&pod={pod}                  |                                         |
442  +--------+----------------------------+-----------------------------------------+
443  | GET    |/dashboard/v1/results?      | Get all the dashboard ready results of  |
444  |        |&project={project}          | {case} of the project {project}         |
445  |        |&case={case}                | and combined by other query conditions  |
446  |        |&<query conditions>         | supported above.                        |
447  +--------+----------------------------+-----------------------------------------+
448  | GET    |/dashboard/v1/projects?     | Get all the dashboard ready projects    |
449  +--------+----------------------------+-----------------------------------------+
450
451 The code of the API is hosted in the releng repository `[6]`_.
452 The test API has been dockerized and may be installed locally in your
453 lab. See `[15]`_ for details.
454
455 Dashboard
456 =========
457
458 Dashboard is used to provide a consistant view of the results collected
459 in CI.
460 The results with dashboard method are post-processed from raw results.
461 Please note that dashboard results are not stored. Only raw results are
462 stored.
463
464 Release Brahmaputra
465 -------------------
466
467 Dashboard url: http://testresults.opnfv.org/dashboard/
468
469 Release Colorado
470 ----------------
471 Since Colorado, it was decided to adopt ELK framework. Mongo DB results
472 are extracted to feed Elasticsearch database (`[7]`_).
473
474 Dashboard url: http://testresults.opnfv.org/kibana_dashboards/
475
476 Credentials for a guest account: opnfvuser/kibana
477
478
479 Automatic reporting
480 ===================
481
482 An automatic reporting page has been created in order to provide a
483 consistant view of the scenarios.
484 In this page each scenario is evaluated according to test criteria.
485 The code for the automatic reporting is available at `[8]`_.
486
487 The results are collected from the centralized database every day and,
488 per scenario. A score is calculated based on the results from the last
489 50 days. This score is the addition of single test scores. Each test
490 case has a success criteria reflected in the criteria field from the
491 results.
492
493 Considering an instance of a scenario os-odl_l2-nofeature-ha, the
494 scoring is the addition of the scores of all the runnable tests from the
495 categories (tiers healthcheck, smoke, controller and feature)
496 corresponding to this scenario.
497
498
499  +---------------------+---------+---------+---------+---------+
500  | Test                | Apex    | Compass | Fuel    |  Joid   |
501  +=====================+=========+=========+=========+=========+
502  | vPing_ssh           |    X    |    X    |    X    |    X    |
503  +---------------------+---------+---------+---------+---------+
504  | vPing_userdata      |    X    |    X    |    X    |    X    |
505  +---------------------+---------+---------+---------+---------+
506  | tempest_smoke_serial|    X    |    X    |    X    |    X    |
507  +---------------------+---------+---------+---------+---------+
508  | rally_sanity        |    X    |    X    |    X    |    X    |
509  +---------------------+---------+---------+---------+---------+
510  | odl                 |    X    |    X    |    X    |    X    |
511  +---------------------+---------+---------+---------+---------+
512  | promise             |         |         |    X    |    X    |
513  +---------------------+---------+---------+---------+---------+
514  | security_scan       |    X    |         |         |         |
515  +---------------------+---------+---------+---------+---------+
516  | copper              |    X    |         |         |    X    |
517  +---------------------+---------+---------+---------+---------+
518
519 All the testcases listed in the table are runnable on
520 os-odl_l2-nofeature scenarios.
521 If no result is available or if all the results are failed, the test
522 case get 0 point.
523 If it was succesfull at least once but no anymore during the 4 runs,
524 the case get 1 point (it worked once).
525 If at least 3 of the last 4 runs were successful, the case get 2 points.
526 If the last 4 runs of the test are successful, the test get 3 points.
527
528 In the example above, the target score for fuel/os-odl_l2-nofeature-ha
529 is 3x6 = 18 points.
530
531 The scenario is validated per installer when we got 3 points for all
532 individual test cases (e.g 18/18).
533 Please note that complex or long duration tests are not considered for
534 the scoring. The success criteria are not always easy to define and may
535 require specific hardware configuration. These results however provide
536 a good level of trust on the scenario.
537
538 A web page is automatically generated every day to display the status.
539 This page can be found at `[9]`_. For the status, click on Status menu,
540 you may also get feedback for vims and tempest_smoke_serial test cases.
541
542 Any validated scenario is stored in a local file on the web server. In
543 fact as we are using a sliding windows to get results, it may happen
544 that a successful scenarios is no more run (because considered as
545 stable) and then the number of iterations (4 needed) would not be
546 sufficient to get the green status.
547
548 Please note that other test cases e.g. sfc_odl, bgpvpn, moon) need also
549 ODL configuration addons and as a consequence specific scenario.
550 There are not considered as runnable on the generic odl_l2 scenario.
551
552 =======
553 How TOs
554 =======
555
556 How Functest works?
557 ===================
558
559 The installation and configuration of the Functest docker image is
560 described in `[1]`_.
561
562 The procedure to start tests is described  in `[2]`_
563
564
565 How can I contribute to Functest?
566 =================================
567
568 If you are already a contributor of any OPNFV project, you can
569 contribute to functest. If you are totally new to OPNFV, you must first
570 create your Linux Foundation account, then contact us in order to
571 declare you in the repository database.
572
573 We distinguish 2 levels of contributors:
574
575  * the standard contributor can push patch and vote +1/0/-1 on any Functest patch
576  * The commitor can vote -2/-1/0/+1/+2 and merge
577
578 Functest commitors are promoted by the Functest contributors.
579
580
581 Where can I find some help to start?
582 ====================================
583
584 This guide is made for you. You can also have a look at the project wiki
585 page `[10]`_.
586 There are references on documentation, video tutorials, tips...
587
588 You can also directly contact us by mail with [Functest] prefix in the
589 title at opnfv-tech-discuss@lists.opnfv.org or on the IRC chan
590 #opnfv-functest.
591
592
593 What kind of testing do you do in Functest?
594 ===========================================
595
596 Functest is focusing on Functional testing. The results must be PASS or
597 FAIL. We do not deal with performance and/or qualification tests.
598 We consider OPNFV as a black box and execute our tests from the jumphost
599 according to Pharos reference technical architecture.
600
601 Upstream test suites are integrated (Rally/Tempest/ODL/ONOS,...).
602 If needed Functest may bootstrap temporarily testing activities if they
603 are identified but not covered yet by an existing testing project (e.g
604 security_scan before the creation of the security repository)
605
606
607 How test constraints are defined?
608 =================================
609
610 Test constraints are defined according to 2 paramaters:
611
612  * The scenario (DEPLOY_SCENARIO env variable)
613  * The installer (INSTALLER_TYPE env variable)
614
615 A scenario is a formal description of the system under test.
616 The rules to define a scenario are described in `[4]`_
617
618 These 2 constraints are considered to determinate if the test is runnable
619 or not (e.g. no need to run onos suite on odl scenario).
620
621 In the test declaration for CI, the test owner shall indicate these 2
622 constraints. The file testcases.yaml `[5]`_ must be patched in git to
623 include new test cases. A more elaborated system based on template is
624 planned for next releases
625
626 For each dependency, it is possible to define a regex::
627
628     name: promise
629     criteria: 'success_rate == 100%'
630     description: >-
631         Test suite from Promise project.
632     dependencies:
633         installer: '(fuel)|(joid)'
634         scenario: ''
635
636 In the example above, it means that promise test will be runnable only
637 with joid or fuel installers on any scenario.
638
639 The vims criteria means any installer and exclude onos and odl with
640 bgpvpn scenarios::
641
642     name: vims
643     criteria: 'status == "PASS"'
644     description: >-
645         This test case deploys an OpenSource vIMS solution from Clearwater
646         using the Cloudify orchestrator. It also runs some signaling traffic.
647     dependencies:
648         installer: ''
649         scenario: '(ocl)|(nosdn)|^(os-odl)((?!bgpvpn).)*$'
650
651
652
653
654 How to write and check constaint regex?
655 =======================================
656
657 Regex are standard regex. You can have a look at  `[11]`_
658
659 You can also easily test your regex via an online regex checker such as `[12]`_.
660 Put your scenario in the TEST STRING window (e.g. os-odl_l3-ovs-ha), put
661 your regex in the REGULAR EXPRESSION window, then you can test your rule
662 .
663
664
665 How to know which test I can run?
666 =================================
667
668 You can use the API `[13]`_. The static declaration is in git `[5]`_
669
670 If you are in a Functest docker container (assuming that the
671 environement has been prepared): just use the CLI.
672
673 You can get the list per Test cases or by Tier::
674
675     # functest testcase list
676     healthcheck
677     vping_ssh
678     vping_userdata
679     tempest_smoke_serial
680     rally_sanity
681     odl
682     doctor
683     security_scan
684     tempest_full_parallel
685     rally_full
686     vims
687     # functest tier list
688     - 0. healthcheck:
689     ['healthcheck']
690     - 1. smoke:
691     ['vping_ssh', 'vping_userdata', 'tempest_smoke_serial', 'rally_sanity']
692     - 2. sdn_suites:
693     ['odl']
694     - 3. features:
695     ['doctor', 'security_scan']
696     - 4. openstack:
697     ['tempest_full_parallel', 'rally_full']
698     - 5. vnf:
699     ['vims']
700
701
702 How to manually start Functest tests?
703 =====================================
704
705 Assuming that you are connected on the jumphost and that the system is
706 "Pharos compliant", i.e the technical architecture is compatible with
707 the one defined in the Pharos project::
708
709     # docker pull opnfv/functest:latest
710     # envs="-e INSTALLER_TYPE=fuel -e INSTALLER_IP=10.20.0.2 -e DEPLOY_SCENARIO=os-odl_l2-nofeature-ha -e CI_DEBUG=true"
711     # sudo docker run --privileged=true -id ${envs} opnfv/functest:latest /bin/bash
712
713
714 Then you must connect to the docker container and source the
715 credentials::
716
717     # docker ps (copy the id)
718     # docker exec -ti <container_id> bash
719     # source $creds
720
721
722 You must first check if the environment is ready::
723
724     # functest env status
725     Functest environment ready to run tests.
726
727
728 If not ready, prepare the env by launching::
729
730     # functest env prepare
731     Functest environment ready to run tests.
732
733 Once the Functest env is ready, you can use the CLI to start tests.
734
735 You can run test cases per test case or per tier:
736  # functest testcase run <case name> or # functest tier run  <tier name>
737
738
739 e.g::
740
741     # functest testcase run tempest_smoke_serial
742     # functest tier run features
743
744
745 If you want to run all the tests you can type::
746
747     # functest testcase run all
748
749
750 If you want to run all the tiers (same at the end that running all the
751 test cases) you can type::
752
753     # functest tier run all
754
755
756 How to declare my tests in Functest?
757 ====================================
758
759 If you want to add new internal test cases, you can submit patch under
760 the testcases directory of Functest repository.
761
762 For feature test integration, the code can be kept into your own
763 repository. The Functest files to be modified are:
764
765  * functest/docker/Dockerfile: get your code in Functest container
766  * functest/ci/testcases.yaml: reference your test and its associated constraints
767  * functest/ci/exec_test.sh: run your test from CI and CLI
768
769
770 Dockerfile
771 ----------
772
773 This file lists the repositories (internal or external) to be cloned in
774 the Functest container. You can also add external packages::
775
776  RUN git clone https://gerrit.opnfv.org/gerrit/<your project> ${repos_dir}/<your project>
777
778 testcases.yaml
779 --------------
780
781 All the test cases that must be run from CI / CLI must be declared in
782 ci/testcases.yaml.
783
784 This file is used to get the constraints related to the test::
785
786     name: <my_super_test_case>
787     criteria: <not used yet in Colorado, could be > 'PASS', 'rate > 90%'
788     description: >-
789         <the description of your super test suite>
790     dependencies:
791         installer: regex related to installer e.g. 'fuel', '(apex)||(joid)'
792         scenario: regex related to the scenario e.g. 'ovs*no-ha'
793
794
795 You must declare your test case in one of the category (tier).
796
797 If you are integrating test suites from a feature project, the default
798 category is **features**.
799
800
801 exec_test.sh
802 ------------
803
804 This file is used to start your test. It is used in CI but also by the
805 CLI.
806
807 You just patch the file in git and add a line::
808
809
810     "<my_super_test_case>")
811         python ${FUNCTEST_REPO_DIR}/testcases/features/mycase.py
812     ;;
813
814
815 Note you can use python or bash scripts (or any language assuming that
816 the packages have been properly preinstalled but we recommand python or
817 bash..).
818
819
820 How to select my list of tests for CI?
821 ======================================
822
823 Functest can be run automatically from CI, a jenkins job is usually
824 called after an OPNFV fresh installation.
825 By default we try to run all the possible tests (see `[14]` called from
826 Functest jenkins job)::
827
828     cmd="python ${FUNCTEST_REPO_DIR}/ci/run_tests.py -t all ${flags}"
829
830
831 Each case can be configured as daily and/or weekly task.
832 When executing run_tests.py, a check based on the jenkins build tag will
833 be considered to detect whether it is a daily and/or a weekly test.
834
835 in your CI you can customize the list of test you want to run by case or
836 by tier, just change the line::
837
838     cmd="python ${FUNCTEST_REPO_DIR}/ci/run_tests.py -t <whatever you want> ${flags}"
839
840 e.g.::
841
842     cmd="python ${FUNCTEST_REPO_DIR}/ci/run_tests.py -t healthcheck,smoke ${flags}"
843
844 This command will run all the test cases of the first 2 tiers, i.e.
845 healthcheck, vping_ssh, vping_userdata, tempest_smoke_serial and
846 rally_sanity.
847
848
849 How to push your results into the Test Database
850 ===============================================
851
852 The test database is used to collect test results. By default it is
853 enabled only for CI tests from Production CI pods.
854
855 The architecture and associated API is described in previous chapter.
856 If you want to push your results from CI, you just have to call the API
857 at the end of your script.
858
859 You can also reuse a python function defined in functest_utils.py::
860
861     def push_results_to_db(db_url, case_name, logger, pod_name,version, payload):
862       """
863       POST results to the Result target DB
864       """
865       url = db_url + "/results"
866       installer = get_installer_type(logger)
867       params = {"project_name": "functest", "case_name": case_name,
868                 "pod_name": pod_name, "installer": installer,
869                 "version": version, "details": payload}
870
871       headers = {'Content-Type': 'application/json'}
872       try:
873           r = requests.post(url, data=json.dumps(params), headers=headers)
874           if logger:
875               logger.debug(r)
876           return True
877       except Exception, e:
878           print "Error [push_results_to_db('%s', '%s', '%s', '%s', '%s')]:" \
879               % (db_url, case_name, pod_name, version, payload), e
880           return False
881
882
883 ==========
884 References
885 ==========
886
887 _`[1]`: http://artifacts.opnfv.org/functest/docs/configguide/index.html Functest configuration guide
888
889 _`[2]`: http://artifacts.opnfv.org/functest/docs/userguide/index.html functest user guide
890
891 _`[3]`: https://wiki.opnfv.org/opnfv_test_dashboard Brahmaputra dashboard
892
893 _`[4]`: https://wiki.opnfv.org/display/INF/CI+Scenario+Naming
894
895 _`[5]`: https://git.opnfv.org/cgit/functest/tree/ci/testcases.yaml
896
897 _`[6]`: https://git.opnfv.org/cgit/releng/tree/utils/test/result_collection_api
898
899 _`[7]`: https://git.opnfv.org/cgit/releng/tree/utils/test/scripts
900
901 _`[8]`: https://git.opnfv.org/cgit/releng/tree/utils/test/reporting/functest
902
903 _`[9]`: http://testresults.opnfv.org/reporting/
904
905 _`[10]`: https://wiki.opnfv.org/opnfv_functional_testing
906
907 _`[11]`: https://docs.python.org/2/howto/regex.html
908
909 _`[12]`: https://regex101.com/
910
911 _`[13]`: http://testresults.opnfv.org/test/api/v1/projects/functest/cases
912
913 _`[14]`: https://git.opnfv.org/cgit/releng/tree/jjb/functest/functest-daily.sh
914
915 _`[15]`: https://git.opnfv.org/cgit/releng/tree/utils/test/result_collection_api/README.rst
916
917 OPNFV main site: opnfvmain_.
918
919 OPNFV functional test page: opnfvfunctest_.
920
921 IRC support chan: #opnfv-functest
922
923 _opnfvmain: http://www.opnfv.org
924
925 _opnfvfunctest: https://wiki.opnfv.org/opnfv_functional_testing
926
927 _`OpenRC`: http://docs.openstack.org/user-guide/common/cli_set_environment_variables_using_openstack_rc.html
928
929 _`Rally installation procedure`: https://rally.readthedocs.org/en/latest/tutorial/step_0_installation.html
930
931 _`config_test.py` : https://git.opnfv.org/cgit/functest/tree/testcases/config_functest.py
932
933 _`config_functest.yaml` : https://git.opnfv.org/cgit/functest/tree/testcases/config_functest.yaml