[docs] Add murano test runner information
Targets blueprint simulated-execution-mode-murano-engine Change-Id: Ie811b49f27551d0e8765fd9516f16f54026e888f
This commit is contained in:
parent
4d78a7b34f
commit
1bacb1e70a
223
doc/source/draft/appdev-guide/app_unit_tests.rst
Normal file
223
doc/source/draft/appdev-guide/app_unit_tests.rst
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
.. _app-unit-tests:
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
======================
|
||||||
|
Application unit tests
|
||||||
|
======================
|
||||||
|
|
||||||
|
Murano applications are written in :ref:`MuranoPL <murano-pl>`.
|
||||||
|
To make the development of applications easier and enable application
|
||||||
|
testing, a special framework was created. So it is possible to add
|
||||||
|
unit tests to an application package and check if the application is in
|
||||||
|
actual state. Also, application deployment can be simulated with unit tests,
|
||||||
|
so you do not need to run the murano engine.
|
||||||
|
|
||||||
|
A separate service that is called *murano-test-runner* is used to run
|
||||||
|
MuranoPL unit tests.
|
||||||
|
|
||||||
|
All application test cases should be:
|
||||||
|
|
||||||
|
* Specified in the MuranoPL class, inherited from
|
||||||
|
`io.murano.test.testFixture <https://git.openstack.org/cgit/openstack/murano/tree/murano/engine/system/test_fixture.py>`_
|
||||||
|
|
||||||
|
This class supports loading object model with the corresponding `load(json)`
|
||||||
|
function. Also it contains a minimal set of assertions such as
|
||||||
|
``assertEqual`` and etc.
|
||||||
|
|
||||||
|
Note, that test class has the following reserved methods are:
|
||||||
|
|
||||||
|
* *initialize* is executed once, like in any other murano application
|
||||||
|
* *setUp* is executed before each test case
|
||||||
|
* *tearDown* is executed after each test case
|
||||||
|
|
||||||
|
* Named with *test* prefix
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
usage: murano-test-runner [-h] [--config-file CONFIG_FILE]
|
||||||
|
[--os-auth-url OS_AUTH_URL]
|
||||||
|
[--os-username OS_USERNAME]
|
||||||
|
[--os-password OS_PASSWORD]
|
||||||
|
[--os-project-name OS_PROJECT_NAME]
|
||||||
|
[-l [</path1, /path2> [</path1, /path2> ...]]] [-v]
|
||||||
|
[--version]
|
||||||
|
<PACKAGE_FQN>
|
||||||
|
[<testMethod1, className.testMethod2> [<testMethod1, className.testMethod2> ...]]
|
||||||
|
|
||||||
|
positional arguments:
|
||||||
|
<PACKAGE_FQN>
|
||||||
|
Full name of application package that is going to be
|
||||||
|
tested
|
||||||
|
<testMethod1, className.testMethod2>
|
||||||
|
List of method names to be tested
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
--config-file CONFIG_FILE
|
||||||
|
Path to the murano config
|
||||||
|
--os-auth-url OS_AUTH_URL
|
||||||
|
Defaults to env[OS_AUTH_URL]
|
||||||
|
--os-username OS_USERNAME
|
||||||
|
Defaults to env[OS_USERNAME]
|
||||||
|
--os-password OS_PASSWORD
|
||||||
|
Defaults to env[OS_PASSWORD]
|
||||||
|
--os-project-name OS_PROJECT_NAME
|
||||||
|
Defaults to env[OS_PROJECT_NAME]
|
||||||
|
-l [</path1 /path2> [</path1 /path2> ...]], --load_packages_from [</path1 /path2> [</path1 /path2> ...]]
|
||||||
|
Directory to search packages from. Will be used instead of
|
||||||
|
directories, provided in the same option in murano configuration file.
|
||||||
|
-v, --verbose increase output verbosity
|
||||||
|
--version show program's version number and exit
|
||||||
|
|
||||||
|
|
||||||
|
The fully qualified name of a package is required to specify the test location.
|
||||||
|
It can be an application package that contains one or several classes with all
|
||||||
|
the test cases, or a separate package. You can specify a class name to
|
||||||
|
execute all the tests located in it, or specify a particular test case name.
|
||||||
|
|
||||||
|
Authorization parameters can be provided in the murano configuration file, or
|
||||||
|
with higher priority :option:`-os-` parameters.
|
||||||
|
|
||||||
|
Consider the following example of test execution for the Tomcat application.
|
||||||
|
Tests are located in the same package with application, but in a separate class
|
||||||
|
called ``io.murano.test.TomcatTest``. It contains ``testDeploy1`` and
|
||||||
|
``testDeploy2`` test cases.
|
||||||
|
The application package is located in the */package/location/directory*
|
||||||
|
(murano-apps repository e.g). As the result of the following command, both
|
||||||
|
test cases from the specified package and class will be executed.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
murano-test-runner io.murano.apps.apache.Tomcat io.murano.test.TomcatTest -l /package/location/directory /io.murano/location -v
|
||||||
|
|
||||||
|
The following command runs a single *testApacheDeploy* test case from the
|
||||||
|
application package.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
murano-test-runner io.murano.apps.apache.Tomcat io.murano.test.TomcatTest.testDeploy1
|
||||||
|
|
||||||
|
The main purpose of MuranoPL unit test framework is to enable mocking.
|
||||||
|
Special :ref:`yaql` functions are registered for that:
|
||||||
|
|
||||||
|
`def inject(target, target_method, mock_object, mock_name)`
|
||||||
|
``inject`` to set up mock for *class* or *object*, where mock definition is a *name of the test class method*
|
||||||
|
|
||||||
|
`def inject(target, target_method, yaql_expr)`
|
||||||
|
``inject`` to set up mock for *a class* or *object*, where mock definition is a *YAQL expression*
|
||||||
|
|
||||||
|
Parameters description:
|
||||||
|
|
||||||
|
**target**
|
||||||
|
MuranoPL class name (namespaces can be used or full class name
|
||||||
|
in quotes) or MuranoPL object
|
||||||
|
|
||||||
|
**target_method**
|
||||||
|
Method name to mock in target
|
||||||
|
|
||||||
|
**mock_object**
|
||||||
|
Object, where mock definition is contained
|
||||||
|
|
||||||
|
**mock_name**
|
||||||
|
Name of method, where mock definition is contained
|
||||||
|
|
||||||
|
**yaql_expr**
|
||||||
|
YAQL expression, parameters are allowed
|
||||||
|
|
||||||
|
So the user is allowed to specify mock functions in the following ways:
|
||||||
|
|
||||||
|
* Specify a particular method name
|
||||||
|
* Provide a YAQL expression
|
||||||
|
|
||||||
|
Consider how the following functions may be used in the MuranoPL class with
|
||||||
|
unit tests:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
Namespaces:
|
||||||
|
=: io.murano.test
|
||||||
|
sys: io.murano.system
|
||||||
|
|
||||||
|
Extends: TestFixture
|
||||||
|
|
||||||
|
Name: TomcatTest
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
initialize:
|
||||||
|
Body:
|
||||||
|
# Object model can be loaded from json file, or provided
|
||||||
|
# directly in MuranoPL code as a yaml insertion.
|
||||||
|
- $.appJson: new(sys:Resources).json('tomcat-for-mock.json')
|
||||||
|
- $.heatOutput: new(sys:Resources).json('output.json')
|
||||||
|
- $.log: logger('test')
|
||||||
|
- $.agentCallCount: 0
|
||||||
|
|
||||||
|
# Mock method to replace the original one
|
||||||
|
agentMock:
|
||||||
|
Arguments:
|
||||||
|
- template:
|
||||||
|
Contract: $
|
||||||
|
- resources:
|
||||||
|
Contract: $
|
||||||
|
- timeout:
|
||||||
|
Contract: $
|
||||||
|
Default: null
|
||||||
|
Body:
|
||||||
|
- $.log.info('Mocking murano agent')
|
||||||
|
- $.assertEqual('Deploy Tomcat', $template.Name)
|
||||||
|
- $.agentCallCount: $.agentCallCount + 1
|
||||||
|
|
||||||
|
# Mock method, that returns predefined heat stack output
|
||||||
|
getStackOut:
|
||||||
|
Body:
|
||||||
|
- $.log.info('Mocking heat stack')
|
||||||
|
- Return: $.heatOutput
|
||||||
|
|
||||||
|
testDeploy1:
|
||||||
|
Body:
|
||||||
|
# Loading object model
|
||||||
|
- $.env: $this.load($.appJson)
|
||||||
|
|
||||||
|
# Set up mock for the push method of *io.murano.system.HeatStack* class
|
||||||
|
- inject(sys:HeatStack, push, $.heatOutput)
|
||||||
|
|
||||||
|
# Set up mock for the concrete object with mock method name
|
||||||
|
- inject($.env.stack, output, $.heatOutput)
|
||||||
|
|
||||||
|
# Set up mock with YAQL function
|
||||||
|
- inject('io.murano.system.Agent', call, $this, agentMock)
|
||||||
|
|
||||||
|
# Mocks will be called instead of original function during the deployment
|
||||||
|
- $.env.deploy()
|
||||||
|
|
||||||
|
# Check, that mock worked correctly
|
||||||
|
- $.assertEqual(1, $.agentCallCount)
|
||||||
|
|
||||||
|
|
||||||
|
testDeploy2:
|
||||||
|
Body:
|
||||||
|
- inject(sys:HeatStack, push, $this, getStackOut)
|
||||||
|
- inject(sys:HeatStack, output, $this, getStackOut)
|
||||||
|
|
||||||
|
# Mock is defined with YAQL function and it will print the original variable (agent template)
|
||||||
|
- inject(sys:Agent, call, withOriginal(t => $template) -> $.log.info('{0}', $t))
|
||||||
|
|
||||||
|
- $.env: $this.load($.appJson)
|
||||||
|
- $.env.deploy()
|
||||||
|
|
||||||
|
- $isDeployed: $.env.applications[0].getAttr(deployed, false, 'io.murano.apps.apache.Tomcat')
|
||||||
|
- $.assertEqual(true, $isDeployed)
|
||||||
|
|
||||||
|
Provided methods are test cases for the Tomcat application. Object model and
|
||||||
|
heat stack output are predefined and located in the package ``Resources``
|
||||||
|
directory. By changing some object model or heat stack parameters, different
|
||||||
|
cases may be tested without a real deployment. Note, that some asserts are used
|
||||||
|
in those example. The first one is checked, that agent call function was called
|
||||||
|
only once as needed. And assert from the second test case checks for a variable
|
||||||
|
value at the end of the application deployment.
|
||||||
|
|
||||||
|
Test cases examples can be found in :file:`TomcatTest.yaml` class of the
|
||||||
|
Apache Tomcat application located at `murano-apps repository <https://git.openstack.org/cgit/openstack/murano-apps/tree/Tomcat/package/Classes/TomcatTest.yaml>`_.
|
||||||
|
You can run test cases with the commands provided above.
|
@ -1,12 +1,12 @@
|
|||||||
.. _murano-pl:
|
.. _murano-pl:
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
MuranoPL Reference
|
MuranoPL Reference
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
To develop applications, murano project refers to Murano Programming
|
To develop applications, murano project refers to Murano Programming
|
||||||
Language (MuranoPL). It is represented by easily readable YAML and
|
Language (MuranoPL). It is represented by easily readable YAML and
|
||||||
YAQL languages. The sections below describe these languages.
|
YAQL languages. The sections below describe these languages.
|
||||||
|
@ -86,6 +86,7 @@ Developing Applications
|
|||||||
appdev-guide/murano_pl
|
appdev-guide/murano_pl
|
||||||
appdev-guide/murano_packages
|
appdev-guide/murano_packages
|
||||||
appdev-guide/app_migrating
|
appdev-guide/app_migrating
|
||||||
|
appdev-guide/app_unit_tests
|
||||||
appdev-guide/examples
|
appdev-guide/examples
|
||||||
appdev-guide/use_cases
|
appdev-guide/use_cases
|
||||||
appdev-guide/faq
|
appdev-guide/faq
|
||||||
|
@ -99,6 +99,7 @@ Developing Applications
|
|||||||
draft/appdev-guide/murano_pl
|
draft/appdev-guide/murano_pl
|
||||||
draft/appdev-guide/murano_packages
|
draft/appdev-guide/murano_packages
|
||||||
draft/appdev-guide/app_migrating
|
draft/appdev-guide/app_migrating
|
||||||
|
draft/appdev-guide/app_unit_tests
|
||||||
draft/appdev-guide/examples
|
draft/appdev-guide/examples
|
||||||
draft/appdev-guide/use_cases
|
draft/appdev-guide/use_cases
|
||||||
draft/appdev-guide/faq
|
draft/appdev-guide/faq
|
||||||
|
Loading…
Reference in New Issue
Block a user