Amador Pahim

Testing, Virtualization

oVirt Functional Tests using Avocado

apahim

Avocado Framework is the new generation Testing Framework born to replace Autotest/Virttest. Avocado is extremely flexible and can be easily used to test anything. If you want to learn more about Avocado, please visit this site: avocado-framework.github.io.

The avocado and ovirt-engine-sdk-python installations are quite simple. Usually it’s all about configure the repositories and install the packages. Please refer to the projects pages for additional information: www.ovirt.org and avocado-framework.github.io.

Direct to the point, here is the basic Avocado test structure we are going to use:

from avocado import Test
from avocado import main

class TestOvirt(Test):
    def setUp(self):
        pass

    def test(self):
        pass

    def tearDown(self):
        pass

Running the code above, just to set a baseline, we have:

$ avocado run test-ovirt.py
JOB ID     : dd1eeea72b83ca7700d18f0297df3c0d74f5343d
JOB LOG    : $HOME/avocado/job-results/job-2016-04-10T11.14-dd1eeea/job.log
TESTS      : 1
 (1/1) test-ovirt.py:TestOvirt.test: PASS
RESULTS    : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0
JOB HTML   : $HOME/avocado/job-results/job-2016-04-10T11.14-dd1eeea/html/results.html
TIME       : 0.00 s

For this example, we will assert the first Data Center name is ‘Default’. Ok, it’s a meaningless test, but it serves for this post purpose.

Let’s import the oVirt API:

from ovirtsdk.api import API

Then, in the setUp(), let’s try to connect to the oVirt API:

    def setUp(self):
        try:
            self.api = API(url = 'https://ovirt',
                                  username = '[email protected]',
                                  password = 'admin',
                                  insecure=True,
                                  debug=False)
        except Exception as details:
            self.error(str(details))

For the tearDown(), we will disconnect from the API:

    def tearDown(self):
        self.api.disconnect()

Now, the test will look like this:

    def test_dc_name(self):
        dc_name = self.api.datacenters.list()[0].name
        self.assertEqual(dc_name, 'Default')

Notice we are using the oVirt API to get the first DC name and then using Avocado to assert it’s equal to ‘Default’. The full script will look like below:

#!/usr/bin/python
from avocado import Test
from avocado import main
from ovirtsdk.api import API

class TestOvirt(Test):
    def setUp(self):
        try:
            self.api = API(url = 'https://ovirt',
                                  username = '[email protected]',
                                  password = 'admin',
                                  insecure=True,
                                  debug=False)
        except Exception as details:
            self.error(str(details))

    def test_dc_name(self):
        dc_name = self.api.datacenters.list()[0].name
        self.assertEqual(dc_name, 'Default')

    def tearDown(self):
        try:
            self.api.disconnect()
        except Exception as details:
            self.error(str(details))

if __name__ == '__main__':
    main()

There’s an issue in NSS when using Avocado and oVirt Python SDK together that makes the the NSS DataBase initialization fail. This is consequence of the fork that happens in Avocado to run the oVirt test as a sub-process. Avocado initializes NSS when importing yum module and then oVirt also tries to initialize the already initialized NSS to use pycurl. This case is documented here: https://github.com/avocado-framework/avocado/issues/1112.

The workaround is to export the environment variable NSS_STRICT_NOFORK with the value DISABLED:

$ export NSS_STRICT_NOFORK=DISABLED

Now we can run our test:

$ avocado run test-ovirt.py
JOB ID     : 05a20693893cde83ad9c860d9242128485bcf05d
JOB LOG    : $HOME/avocado/job-results/job-2016-04-10T16.34-05a2069/job.log
TESTS      : 1
 (1/1) test-ovirt.py:TestOvirt.test_dc_name: PASS
RESULTS    : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0
JOB HTML   : $HOME/avocado/job-results/job-2016-04-10T16.34-05a2069/html/results.html
TIME       : 0.46 s

Let’s add one more test to check the DataCenter status:

#!/usr/bin/python
from avocado import Test
from avocado import main
from ovirtsdk.api import API
 
 
class TestOvirt(Test):
 
    def setUp(self):
        try:
            self.api = API(url = 'https://ovirt',
                           username = '[email protected]',
                           password = 'admin',
                           insecure=True,
                           debug=False)
        except Exception as details:
            self.error(str(details))
 
    def test_dc_name(self):
        dc_name = self.api.datacenters.list()[0].name
        self.assertEqual(dc_name, 'Default')
 
    def test_dc_status(self):
        dc_status = self.api.datacenters.list()[0].get_status().get_state()
        self.assertEqual(dc_status, 'Up')
 
    def tearDown(self):
        try:
            self.api.disconnect()
        except Exception as details:
            self.error(str(details))
 
if __name__ == '__main__':
    main()

Running Avocado again:

$ avocado run test-ovirt.py
JOB ID     : 74288315c4c405334e3df5db64e8be6bfe58e239
JOB LOG    : $HOME/avocado/job-results/job-2016-04-20T09.43-7428831/job.log
TESTS      : 2
 (1/2) test-ovirt.py:TestOvirt.test_dc_name: PASS
 (2/2) test-ovirt.py:TestOvirt.test_dc_status: FAIL
RESULTS    : PASS 1 | ERROR 0 | FAIL 1 | SKIP 0 | WARN 0 | INTERRUPT 0
JOB HTML   : $HOME/avocado/job-results/job-2016-04-20T09.43-7428831/html/results.html
TIME       : 0.99 s

So, our first test passed, but the second did not. Checking the logs:

$ tail -n 13 $HOME/avocado/job-results/job-2016-04-20T09.43-7428831/job.log
2016-04-20 09:43:33,047 test             L0138 INFO | START test-ovirt.py:TestOvirt.test_dc_status
2016-04-20 09:43:33,559 stacktrace       L0036 ERROR| 
2016-04-20 09:43:33,559 stacktrace       L0039 ERROR| Reproduced traceback from: /usr/lib/python2.7/site-packages/avocado-0.34.0-py2.7.egg/avocado/core/test.py:393
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR| Traceback (most recent call last):
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR|   File "test-ovirt.py", line 25, in test_dc_status
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR|     self.assertEqual(dc_status, 'Up')
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR|   File "/usr/lib64/python2.7/unittest/case.py", line 551, in assertEqual
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR|     assertion_func(first, second, msg=msg)
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR|   File "/usr/lib64/python2.7/unittest/case.py", line 544, in _baseAssertEqual
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR|     raise self.failureException(msg)
2016-04-20 09:43:33,560 stacktrace       L0042 ERROR| AssertionError: 'uninitialized' != 'Up'
2016-04-20 09:43:33,560 stacktrace       L0043 ERROR| 
2016-04-20 09:43:33,561 test             L0525 ERROR| FAIL test-ovirt.py:TestOvirt.test_dc_status - AssertionError: 'uninitialized' != 'Up'

Also, we can open the html report:

$ firefox $HOME/avocado/job-results/job-2016-04-20T09.43-7428831/html/results.html
02

The reason our second test did not PASS was the DataCenter status not currently ‘Up’.

That’s it. Hope this is enough to illustrate how you can benefit from Avocado using and the oVirt Python SDK all together.

Bye.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top