Petr Hracek: Container testing in the OpenShift with the Meta-Test-Family

In my last article, I have mentioned, we can use the Meta-Test-Family (MTF) to validate  “standalone” containers. Without proper testing, we should not ship any container. We should guarantee that given service in container works properly.

Next possible way, how to test containers is with OpenShift environment.

This article describes how to test container in the “orchestrated” OpenShift world.

Fedora alone contains huge amount of containers.

MTF installation

Before we can start with the testing itself, we have to install MTF.

To install MTF from official Fedora repository, type:

sudo dnf install -y meta-test-family

To install MTF from COPR repository, which contains development version and should not be used on a production environment, type:

sudo dnf copr enable phracek/meta-test-family
sudo dnf install -y meta-test-family

To install MTF directly from GitHub, type:

git clone git@github.com:fedora-modularity/meta-test-family.git
cd meta-test-family
sudo python setup.py install

Now we can start with testing container in the OpenShift environment.

Prepare test for the OpenShift

Running your containers locally is dead-simple — just do `docker run`. But that’s not how you run your application in production — it’s OpenShift’s business. In order to make sure that your containers are orchestrated well, you should test them in such environment. Bear in mind that standalone and orchestrated environments are different.

What is difference between “standalone” and “orchestrated” containers?

Standalone containers can be executed easily with a single command. Managing such containers is not so easy: you need to figure out persistent storage, backups, updates, routing, scaling — all the things you get for free with orchestrators.

OpenShift environment has security restrictions, differences in persistent storage logic, expects a pod to be stateless, support for updates, multi-node environment, native source-to-image support and much much more.  Deploying orchestrator is not an easy task. This is the reason why we decided to add support for OpenShift to MTF so you can easily test your containerized application in an orchestrated environment. I’ll show how.

Before running and preparation the OpenShift environment, you have to create a test and a configuration file, for MTF, in YAML format. These two files have to be in the same directory and tests will be executed from the directory.

Configuration file for MTF

document: modularity-testing
version: 1
name: memcached
service:
    port: 11211
module:
    openshift:
        container: docker.io/modularitycontainers/memcached

What does it mean each fields in YAML config file for MTF:

  • service.port – port, where the service is available.
  • module.openshift – configuration part relevant only for OpenShift environment
  • module.openshift.container – Reference to container, which will be used for testing in OpenShift.

Test for memcached container

Memcached test for container looks like this:

$ cat sanity1.py

import pexpect
from avocado import main
from avocado.core import exceptions
from moduleframework import module_framework
from moduleframework import common

class SanityCheck1(module_framework.AvocadoTest):

"""
:avocado: enable
"""
def test_smoke(self):
    self.start()
    session = pexpect.spawn("telnet %s %s " % (self.ip_address,self.getConfig()['service']['port']))
    session.sendline('set Test 0 100 4rnn')
    session.sendline('JournalDevrnn')
    common.print_info("Expecting STORED")
    session.expect('STORED')
    common.print_info("STORED was catched")
    session.close()

if __name__ == '__main__':
    main()

This test connects to memcached via telnet on given ip_address and port. Port is specified in configuration file for MTF. I will speak about ip_address in following sections.

How to prepare the OpenShift environment for container testing

Let’s say, we don’t have installed the OpenShift environment on our laptop or PC. This can be done by MTF.

MTF provides a command mtf-env-set.

$ sudo MODULE=openshift OPENSHIFT_LOCAL=yes mtf-env-set
Setting environment for module: openshift
Preparing environment ...
Loaded config for name: memcached
Starting OpenShift
Starting OpenShift using openshift/origin:v3.6.0 ...
OpenShift server started.

The server is accessible via web console at:
https://127.0.0.1:8443

You are logged in as:
User: developer
Password: <any value="">

To login as administrator:
oc login -u system:admin</any>

What the command does? In this case, If parameter OPENSHIFT_LOCAL is specified, it checks if packages origin and origin-clients are installed . If not, then it installs them.

Container testing is in this case performed on local machine. In case, we would like to test containers on remote OpenShift instance, this step can be ignored. In case the parameter is missed, then tests are going to be executed on remote OpenShift instance specified by parameter OPENSHIFT_IP. Let’s write about it later on.

By this step, environment for container testing is ready.

Alone container testing

Now let’s test container either on local instance or on remote instance.

For running test we use command mtf.

Container testing is different only by parameters specified in mtf command.

Testing on local OpenShift instance

$ sudo MODULE=openshift OPENSHIFT_LOCAL=yes mtf sanity1.py

In this case, sanity1.py uses 127.0.0.1 as a self.ip_address

Testing on remote OpenShift instance

$ sudo OPENSHIFT_IP=<ip_address> OPENSHIFT_USER=<username> OPENSHIFT_PASSWD=<passwd> mtf sanity1.py

In this case, sanity1.py uses OPENSHIFT_IP as a self.ip_address.

All other parameters remain.

Tests are going to be executed from environment, in our case from notebook or PC, where are stored configuration file and tests to given OpenShift instance.

Test output

$ sudo MODULE=openshift OPENSHIFT_LOCAL=yes mtf sanity1.py
JOB ID : c2b0877ca52a14c6c740582c76f60d4f19eb2d4d
JOB LOG : /root/avocado/job-results/job-2017-12-18T12.32-c2b0877/job.log
(1/1) sanity1.py:SanityCheck1.test_smoke: PASS (13.19 s)
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
JOB TIME : 13.74 s
JOB HTML : /root/avocado/job-results/job-2017-12-18T12.32-c2b0877/results.html

Let’s open log marked bold and have a look on it, what it contains.

[...snip...]['/var/log/messages', '/var/log/syslog', '/var/log/system.log'])
2017-12-18 14:29:36,208 job L0321 INFO | Command line: /bin/avocado run --json /tmp/tmppfZpNe sanity1.py
2017-12-18 14:29:36,208 job L0322 INFO |
2017-12-18 14:29:36,208 job L0326 INFO | Avocado version: 55.0
2017-12-18 14:29:36,208 job L0342 INFO |
2017-12-18 14:29:36,208 job L0346 INFO | Config files read (in order):
2017-12-18 14:29:36,208 job L0348 INFO | /etc/avocado/avocado.conf
2017-12-18 14:29:36,208 job L0348 INFO | /etc/avocado/conf.d/gdb.conf
2017-12-18 14:29:36,208 job L0348 INFO | /root/.config/avocado/avocado.conf
2017-12-18 14:29:36,208 job L0353 INFO |
2017-12-18 14:29:36,208 job L0355 INFO | Avocado config:
2017-12-18 14:29:36,209 job L0364 INFO | Section.Key [...snip...]

:::::::::::::::::::::::: SETUP ::::::::::::::::::::::::

2017-12-18 14:29:36,629 avocado_test L0069 DEBUG|

:::::::::::::::::::::::: START MODULE ::::::::::::::::::::::::

MTF verifies, If application really does not exist in OpenShift environment

2017-12-18 14:29:36,629 process L0389 INFO | Running 'oc get dc memcached -o json'
2017-12-18 14:29:36,842 process L0479 DEBUG| [stderr] Error from server (NotFound): deploymentconfigs.apps.openshift.io "memcached" not found
2017-12-18 14:29:36,846 process L0499 INFO | Command 'oc get dc memcached -o json' finished with 1 after 0.213222980499s

In the next step MTF verifies if POD does not exist in OpenShift.

2017-12-18 14:29:36,847 process L0389 INFO | Running 'oc get pods -o json'
2017-12-18 14:29:37,058 process L0479 DEBUG| [stdout] {
2017-12-18 14:29:37,059 process L0479 DEBUG| [stdout] "apiVersion": "v1",
2017-12-18 14:29:37,059 process L0479 DEBUG| [stdout] "items": [],
2017-12-18 14:29:37,059 process L0479 DEBUG| [stdout] "kind": "List",
2017-12-18 14:29:37,059 process L0479 DEBUG| [stdout] "metadata": {},
2017-12-18 14:29:37,059 process L0479 DEBUG| [stdout] "resourceVersion": "",
2017-12-18 14:29:37,059 process L0479 DEBUG| [stdout] "selfLink": ""
2017-12-18 14:29:37,060 process L0479 DEBUG| [stdout] }
2017-12-18 14:29:37,064 process L0499 INFO | Command 'oc get pods -o json' finished with 0 after 0.211796045303s

Following step creates an application with given label mtf_testing and with the name which is taken from config.yaml file in container tag.

2017-12-18 14:29:37,064 process L0389 INFO | Running 'oc new-app -l mtf_testing=true docker.io/modularitycontainers/memcached --name=memcached'
2017-12-18 14:29:39,022 process L0479 DEBUG| [stdout] --> Found Docker image bbc8bba (5 weeks old) from docker.io for "docker.io/modularitycontainers/memcached"
2017-12-18 14:29:39,022 process L0479 DEBUG| [stdout]
2017-12-18 14:29:39,022 process L0479 DEBUG| [stdout] memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.
2017-12-18 14:29:39,022 process L0479 DEBUG| [stdout]
2017-12-18 14:29:39,022 process L0479 DEBUG| [stdout] Tags: memcached
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout]
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout] * An image stream will be created as "memcached:latest" that will track this image
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout] * This image will be deployed in deployment config "memcached"
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout] * Port 11211/tcp will be load balanced by service "memcached"
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout] * Other containers can access this service through the hostname "memcached"
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout]
2017-12-18 14:29:39,023 process L0479 DEBUG| [stdout] --> Creating resources with label mtf_testing=true ...
2017-12-18 14:29:39,032 process L0479 DEBUG| [stdout] imagestream "memcached" created
2017-12-18 14:29:39,043 process L0479 DEBUG| [stdout] deploymentconfig "memcached" created
2017-12-18 14:29:39,063 process L0479 DEBUG| [stdout] service "memcached" created
2017-12-18 14:29:39,064 process L0479 DEBUG| [stdout] --> Success
2017-12-18 14:29:39,064 process L0479 DEBUG| [stdout] Run 'oc status' to view your app.
2017-12-18 14:29:39,069 process L0499 INFO | Command 'oc new-app -l mtf_testing=true docker.io/modularitycontainers/memcached --name=memcached' finished with 0 after 2.00025391579s

The step mentioned now verifies if application is really Running and on which IP address is reachable.

2017-12-18 14:29:46,201 process L0389 INFO | Running 'oc get service -o json'
2017-12-18 14:29:46,416 process L0479 DEBUG| [stdout] {
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "apiVersion": "v1",
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "items": [
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] {
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "apiVersion": "v1",
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "kind": "Service",
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "metadata": {
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "annotations": {
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] "openshift.io/generated-by": "OpenShiftNewApp"
2017-12-18 14:29:46,417 process L0479 DEBUG| [stdout] },
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "creationTimestamp": "2017-12-18T13:29:39Z",
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "labels": {
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "app": "memcached",
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "mtf_testing": "true"
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] },
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "name": "memcached",
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "namespace": "myproject",
2017-12-18 14:29:46,418 process L0479 DEBUG| [stdout] "resourceVersion": "2121",
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "selfLink": "/api/v1/namespaces/myproject/services/memcached",
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "uid": "7f50823d-e3f7-11e7-be28-507b9d4150cb"
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] },
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "spec": {
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "clusterIP": "172.30.255.42",
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "ports": [
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] {
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "name": "11211-tcp",
2017-12-18 14:29:46,419 process L0479 DEBUG| [stdout] "port": 11211,
2017-12-18 14:29:46,420 process L0479 DEBUG| [stdout] "protocol": "TCP",
2017-12-18 14:29:46,420 process L0479 DEBUG| [stdout] "targetPort": 11211
2017-12-18 14:29:46,420 process L0499 INFO | Command 'oc get service -o json' finished with 0 after 0.213701963425s
2017-12-18 14:29:46,420 process L0479 DEBUG| [stdout] }
2017-12-18 14:29:46,420 process L0479 DEBUG| [stdout] ],
2017-12-18 14:29:46,420 process L0479 DEBUG| [stdout] "selector": {
2017-12-18 14:29:46,420 process L0479 DEBUG| [stdout] "app": "memcached",
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] "deploymentconfig": "memcached",
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] "mtf_testing": "true"
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] },
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] "sessionAffinity": "None",
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] "type": "ClusterIP"
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] },
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] "status": {
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] "loadBalancer": {}
2017-12-18 14:29:46,421 process L0479 DEBUG| [stdout] }
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] }
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] ],
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] "kind": "List",
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] "metadata": {},
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] "resourceVersion": "",
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] "selfLink": ""
2017-12-18 14:29:46,422 process L0479 DEBUG| [stdout] }

In the last phase, alone tests are executed.

2017-12-18 14:29:46,530 output L0655 DEBUG| Expecting STORED
2017-12-18 14:29:46,531 output L0655 DEBUG| STORED was catched
2017-12-18 14:29:46,632 avocado_test L0069 DEBUG|

:::::::::::::::::::::::: TEARDOWN ::::::::::::::::::::::::

2017-12-18 14:29:46,632 process L0389 INFO | Running 'oc get dc memcached -o json'
2017-12-18 14:29:46,841 process L0479 DEBUG| [stdout] {
2017-12-18 14:29:46,841 process L0479 DEBUG| [stdout] "apiVersion": "v1",
2017-12-18 14:29:46,841 process L0479 DEBUG| [stdout] "kind": "DeploymentConfig",
2017-12-18 14:29:46,841 process L0479 DEBUG| [stdout] "metadata": {

At the end of the tests, let’s verify if service is really not running in OpenShift environment. This can be verified by command oc status:

$ sudo oc status
In project My Project (myproject) on server https://127.0.0.1:8443

You have no services, deployment configs, or build configs.
Run 'oc new-app' to create an application.

We can see, we are able to test arbitrary container and at the end, OpenShift environment is clear.

Summary

As can be seen from this article, writing tests for containers is really easy and we can garant, that container is really working properly as package in RPM world.

In near future, we would like to extend MTF with S2I testing and testing containers with OpenShift templates.

MTF documentation is available here.


Source From: fedoraplanet.org.
Original article title: Petr Hracek: Container testing in the OpenShift with the Meta-Test-Family.
This full article can be read at: Petr Hracek: Container testing in the OpenShift with the Meta-Test-Family.

Advertisement
Premium WordPress products


Random Article You May Like

Leave a Reply

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

*
*