Avoid tuples when printing multiple strings
[functest.git] / utils / functest_utils.py
1 #!/usr/bin/env python
2 #
3 # jose.lausuch@ericsson.com
4 # valentin.boucher@orange.com
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10
11 import json
12 import os
13 import os.path
14 import re
15 import requests
16 import shutil
17 import socket
18 import subprocess
19 import sys
20 import urllib2
21 import yaml
22 from git import Repo
23
24
25 # ----------------------------------------------------------
26 #
27 #               INTERNET UTILS
28 #
29 # -----------------------------------------------------------
30 def check_internet_connectivity(url='http://www.opnfv.org/'):
31     """
32     Check if there is access to the internet
33     """
34     try:
35         urllib2.urlopen(url, timeout=5)
36         return True
37     except urllib2.URLError:
38         return False
39
40
41 def download_url(url, dest_path):
42     """
43     Download a file to a destination path given a URL
44     """
45     name = url.rsplit('/')[-1]
46     dest = dest_path + "/" + name
47     try:
48         response = urllib2.urlopen(url)
49     except (urllib2.HTTPError, urllib2.URLError):
50         return False
51
52     with open(dest, 'wb') as f:
53         shutil.copyfileobj(response, f)
54     return True
55
56
57 # ----------------------------------------------------------
58 #
59 #               CI UTILS
60 #
61 # -----------------------------------------------------------
62 def get_git_branch(repo_path):
63     """
64     Get git branch name
65     """
66     repo = Repo(repo_path)
67     branch = repo.active_branch
68     return branch.name
69
70
71 def get_installer_type(logger=None):
72     """
73     Get installer type (fuel, apex, joid, compass)
74     """
75     try:
76         installer = os.environ['INSTALLER_TYPE']
77     except KeyError:
78         if logger:
79             logger.error("Impossible to retrieve the installer type")
80         installer = "Unknown_installer"
81
82     return installer
83
84
85 def get_scenario(logger=None):
86     """
87     Get scenario
88     """
89     try:
90         scenario = os.environ['DEPLOY_SCENARIO']
91     except KeyError:
92         if logger:
93             logger.error("Impossible to retrieve the scenario")
94         scenario = "Unknown_scenario"
95
96     return scenario
97
98
99 def get_version(logger=None):
100     """
101     Get version
102     """
103     # Use the build tag to retrieve the version
104     # By default version is unknown
105     # if launched through CI the build tag has the following format
106     # jenkins-<project>-<installer>-<pod>-<job>-<branch>-<id>
107     # e.g. jenkins-functest-fuel-opnfv-jump-2-daily-master-190
108     # use regex to match branch info
109     rule = "daily-(.+?)-[0-9]*"
110     build_tag = get_build_tag(logger)
111     m = re.search(rule, build_tag)
112     if m:
113         return m.group(1)
114     else:
115         return "unknown"
116
117
118 def get_pod_name(logger=None):
119     """
120     Get PoD Name from env variable NODE_NAME
121     """
122     try:
123         return os.environ['NODE_NAME']
124     except KeyError:
125         if logger:
126             logger.error(
127                 "Unable to retrieve the POD name from environment. " +
128                 "Using pod name 'unknown-pod'")
129         return "unknown-pod"
130
131
132 def get_build_tag(logger=None):
133     """
134     Get build tag of jenkins jobs
135     """
136     try:
137         build_tag = os.environ['BUILD_TAG']
138     except KeyError:
139         if logger:
140             logger.error("Impossible to retrieve the build tag")
141         build_tag = "unknown_build_tag"
142
143     return build_tag
144
145
146 def push_results_to_db(db_url, project, case_name, logger, pod_name,
147                        version, scenario, criteria, build_tag, payload):
148     """
149     POST results to the Result target DB
150     """
151     url = db_url + "/results"
152     installer = get_installer_type(logger)
153     params = {"project_name": project, "case_name": case_name,
154               "pod_name": pod_name, "installer": installer,
155               "version": version, "scenario": scenario, "criteria": criteria,
156               "build_tag": build_tag, "details": payload}
157
158     headers = {'Content-Type': 'application/json'}
159     try:
160         r = requests.post(url, data=json.dumps(params), headers=headers)
161         if logger:
162             logger.debug(r)
163         return True
164     except Exception, e:
165         print ("Error [push_results_to_db('%s', '%s', '%s', " +
166                "'%s', '%s', '%s', '%s', '%s', '%s')]:" %
167                (db_url, project, case_name, pod_name, version,
168                 scenario, criteria, build_tag, payload)), e
169         return False
170
171
172 def get_resolvconf_ns():
173     """
174     Get nameservers from current resolv.conf
175     """
176     nameservers = []
177     rconf = open("/etc/resolv.conf", "r")
178     line = rconf.readline()
179     while line:
180         ip = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b", line)
181         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
182         if ip:
183             result = sock.connect_ex((ip.group(), 53))
184             if result == 0:
185                 nameservers.append(ip.group())
186         line = rconf.readline()
187     return nameservers
188
189
190 def get_ci_envvars():
191     """
192     Get the CI env variables
193     """
194     ci_env_var = {
195         "installer": os.environ.get('INSTALLER_TYPE'),
196         "scenario": os.environ.get('DEPLOY_SCENARIO')}
197     return ci_env_var
198
199
200 def execute_command(cmd, logger=None,
201                     exit_on_error=True,
202                     info=False,
203                     error_msg="",
204                     verbose=True):
205     if not error_msg:
206         error_msg = ("The command '%s' failed." % cmd)
207     msg_exec = ("Executing command: '%s'" % cmd)
208     if verbose:
209         if logger:
210             if info:
211                 logger.info(msg_exec)
212             else:
213                 logger.debug(msg_exec)
214         else:
215             print(msg_exec)
216     p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
217     while True:
218         line = p.stdout.readline().replace('\n', '')
219         if not line:
220             break
221         if logger:
222             if info:
223                 logger.info(line)
224             else:
225                 logger.debug(line)
226         else:
227             print line
228     p.communicate()
229     if p.returncode != 0:
230         if verbose:
231             if logger:
232                 logger.error(error_msg)
233             else:
234                 print(error_msg)
235         if exit_on_error:
236             sys.exit(1)
237
238     return p.returncode
239
240
241 def get_deployment_dir(logger=None):
242     """
243     Returns current Rally deployment directory
244     """
245     with open(os.environ["CONFIG_FUNCTEST_YAML"]) as f:
246         functest_yaml = yaml.safe_load(f)
247     f.close()
248     deployment_name = functest_yaml.get("rally").get("deployment_name")
249     rally_dir = functest_yaml.get("general").get("directories").get(
250         "dir_rally_inst")
251     cmd = ("rally deployment list | awk '/" + deployment_name +
252            "/ {print $2}'")
253     p = subprocess.Popen(cmd, shell=True,
254                          stdout=subprocess.PIPE,
255                          stderr=subprocess.STDOUT)
256     deployment_uuid = p.stdout.readline().rstrip()
257     if deployment_uuid == "":
258         if logger:
259             logger.error("Rally deployment not found.")
260         exit(-1)
261     deployment_dir = (rally_dir + "/tempest/for-deployment-" +
262                       deployment_uuid)
263     return deployment_dir