Mock os.makedirs
[functest-kubernetes.git] / functest_kubernetes / k8stest.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2018 All rights reserved
4 # This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10
11 """
12 Define the parent for Kubernetes testing.
13 """
14
15 from __future__ import division
16
17 import logging
18 import os
19 import re
20 import subprocess
21 import time
22 import yaml
23
24 from xtesting.core import testcase
25
26
27 class E2ETesting(testcase.TestCase):
28     """Kubernetes test runner"""
29     # pylint: disable=too-many-instance-attributes
30
31     __logger = logging.getLogger(__name__)
32
33     config = '/root/.kube/config'
34     gcr_repo = os.getenv("MIRROR_REPO", "gcr.io")
35     k8s_gcr_repo = os.getenv("MIRROR_REPO", "k8s.gcr.io")
36
37     def __init__(self, **kwargs):
38         super(E2ETesting, self).__init__(**kwargs)
39         self.cmd = []
40         self.dir_results = "/home/opnfv/functest/results"
41         self.res_dir = os.path.join(self.dir_results, self.case_name)
42         self.result = 0
43         self.start_time = 0
44         self.stop_time = 0
45         self.output_log_name = 'functest-kubernetes.log'
46         self.output_debug_log_name = 'functest-kubernetes.debug.log'
47
48     def run_kubetest(self, **kwargs):  # pylint: disable=too-many-branches
49         """Run the test suites"""
50         cmd_line = [
51             'ginkgo', '--nodes={}'.format(kwargs.get("nodes", 1)),
52             '--noColor', '/usr/local/bin/e2e.test', '--',
53             '-kubeconfig', self.config,
54             '-provider', 'skeleton', '-report-dir', self.res_dir]
55         for arg in kwargs.get("ginkgo", {}):
56             cmd_line.extend(['-ginkgo.{}'.format(arg), kwargs["ginkgo"][arg]])
57         if "NON_BLOCKING_TAINTS" in os.environ:
58             cmd_line.extend(
59                 ['-non-blocking-taints', os.environ["NON_BLOCKING_TAINTS"]])
60         cmd_line.extend(['-disable-log-dump', 'true'])
61         self._generate_repo_list_file()
62         self.__logger.info("Starting k8s test: '%s'.", cmd_line)
63         env = os.environ.copy()
64         env["KUBE_TEST_REPO_LIST"] = "{}/repositories.yml".format(self.res_dir)
65         process = subprocess.Popen(cmd_line, stdout=subprocess.PIPE,
66                                    stderr=subprocess.STDOUT, env=env)
67         boutput = process.stdout.read()
68         with open(os.path.join(self.res_dir, 'e2e.log'), 'wb') as foutput:
69             foutput.write(boutput)
70         grp = re.search(
71             r'^(FAIL|SUCCESS)!.* ([0-9]+) Passed \| ([0-9]+) Failed \|'
72             r' ([0-9]+) Pending \| ([0-9]+) Skipped',
73             boutput.decode("utf-8", errors="ignore"),
74             re.MULTILINE | re.DOTALL)
75         assert grp
76         self.details['passed'] = int(grp.group(2))
77         self.details['failed'] = int(grp.group(3))
78         self.details['pending'] = int(grp.group(4))
79         self.details['skipped'] = int(grp.group(5))
80         self.__logger.debug("details: %s", self.details)
81         self.result = self.details['passed'] * 100 / (
82             self.details['passed'] + self.details['failed'] +
83             self.details['pending'])
84         self.__logger.debug("result: %s", self.result)
85         if grp.group(1) == 'FAIL':
86             grp2 = re.search(
87                 r'^(Summarizing [0-9]+ Failure.*)Ran',
88                 boutput.decode("utf-8", errors="ignore"),
89                 re.MULTILINE | re.DOTALL)
90             if grp2:
91                 self.__logger.error(grp2.group(1))
92
93     def run(self, **kwargs):
94         if not os.path.exists(self.res_dir):
95             os.makedirs(self.res_dir)
96         if not os.path.isfile(self.config):
97             self.__logger.error(
98                 "Cannot run k8s testcases. Config file not found")
99             return self.EX_RUN_ERROR
100         self.start_time = time.time()
101         try:
102             self.run_kubetest(**kwargs)
103             res = self.EX_OK
104         except Exception:  # pylint: disable=broad-except
105             self.__logger.exception("Error with running kubetest:")
106             res = self.EX_RUN_ERROR
107         self.stop_time = time.time()
108         return res
109
110     def _generate_repo_list_file(self):
111         """Generate the repositories list for the test."""
112         # The list is taken from
113         # https://github.com/kubernetes/kubernetes/blob/master/test/utils/image/manifest.go
114         # It may needs update regularly
115         gcr_repo = os.getenv("GCR_REPO", self.gcr_repo)
116         k8s_gcr_repo = os.getenv("K8S_GCR_REPO", self.k8s_gcr_repo)
117         repo_list = {
118             "GcAuthenticatedRegistry": "{}/authenticated-image-pulling".format(
119                 gcr_repo),
120             "E2eRegistry":             "{}/kubernetes-e2e-test-images".format(
121                 gcr_repo),
122             "PromoterE2eRegistry":     "{}/e2e-test-images".format(
123                 k8s_gcr_repo),
124             "BuildImageRegistry":      "{}/build-image".format(k8s_gcr_repo),
125             "InvalidRegistry":         "invalid.com/invalid",
126             "GcEtcdRegistry":          "{}".format(k8s_gcr_repo),
127             "GcRegistry":              "{}".format(k8s_gcr_repo),
128             "SigStorageRegistry":      "{}/sig-storage".format(k8s_gcr_repo),
129             "PrivateRegistry":         "{}/k8s-authenticated-test".format(
130                 gcr_repo),
131             "SampleRegistry":          "{}/google-samples".format(gcr_repo),
132             "GcrReleaseRegistry":      "{}/gke-release".format(gcr_repo),
133             "MicrosoftRegistry":       "mcr.microsoft.com",
134         }
135         with open("{}/repositories.yml".format(self.res_dir), 'w') as file:
136             yaml.dump(repo_list, file)