xref: /openbmc/openbmc-build-scripts/scripts/get_unit_test_report.py (revision e08ffba8954d83e68493c6a1d5ca65cb5b776d74)
1229b76a9SAnusha Dathatri#!/usr/bin/python
2229b76a9SAnusha Dathatri
3185d5b59SAnusha Dathatri# This script generates the unit test coverage report for openbmc project.
4229b76a9SAnusha Dathatri#
5229b76a9SAnusha Dathatri# Usage:
658cbe5fbSAnusha Dathatri# get_unit_test_report.py target_dir [url_file]
7229b76a9SAnusha Dathatri#
858cbe5fbSAnusha Dathatri# Positional arguments:
9229b76a9SAnusha Dathatri# target_dir  Target directory in pwd to place all cloned repos and logs.
1058cbe5fbSAnusha Dathatri# url_file    Text file containing url of repositories. Optional.
1158cbe5fbSAnusha Dathatri#             By using this argument, the user can get a report only for
1258cbe5fbSAnusha Dathatri#             specific repositories given in the file.
1358cbe5fbSAnusha Dathatri#             Refer ./scripts/repositories.txt
14229b76a9SAnusha Dathatri#
1558cbe5fbSAnusha Dathatri# Examples:
1658cbe5fbSAnusha Dathatri#     get_unit_test_report.py target_dir
1758cbe5fbSAnusha Dathatri#     get_unit_test_report.py target_dir repositories.txt
18229b76a9SAnusha Dathatri#
19229b76a9SAnusha Dathatri# Output format:
20229b76a9SAnusha Dathatri#
21229b76a9SAnusha Dathatri# ***********************************OUTPUT***********************************
22229b76a9SAnusha Dathatri# https://github.com/openbmc/phosphor-dbus-monitor.git               NO
23229b76a9SAnusha Dathatri# https://github.com/openbmc/phosphor-sel-logger.git;protocol=git    NO
24229b76a9SAnusha Dathatri# ***********************************OUTPUT***********************************
25229b76a9SAnusha Dathatri#
26*e08ffba8SPatrick Williams# Other outputs and errors are redirected to output.log and debug.log in
27*e08ffba8SPatrick Williams# target_dir.
28229b76a9SAnusha Dathatri
29229b76a9SAnusha Dathatriimport argparse
30229b76a9SAnusha Dathatriimport logging
31229b76a9SAnusha Dathatriimport os
32185d5b59SAnusha Dathatriimport re
33229b76a9SAnusha Dathatriimport shutil
34229b76a9SAnusha Dathatriimport subprocess
35229b76a9SAnusha Dathatri
36*e08ffba8SPatrick Williamsimport requests
37*e08ffba8SPatrick Williams
3858cbe5fbSAnusha Dathatri# Repo list not expected to contain UT. Will be moved to a file in future.
39*e08ffba8SPatrick Williamsskip_list = [
40*e08ffba8SPatrick Williams    "openbmc-tools",
41*e08ffba8SPatrick Williams    "inarp",
42*e08ffba8SPatrick Williams    "openbmc",
43*e08ffba8SPatrick Williams    "openbmc.github.io",
44*e08ffba8SPatrick Williams    "phosphor-ecc",
45*e08ffba8SPatrick Williams    "phosphor-pcie-presence",
46*e08ffba8SPatrick Williams    "phosphor-u-boot-env-mgr",
47*e08ffba8SPatrick Williams    "rrd-ipmi-blob",
48*e08ffba8SPatrick Williams    "librrdplus",
49*e08ffba8SPatrick Williams    "openpower-inventory-upload",
50*e08ffba8SPatrick Williams    "openpower-logging",
51*e08ffba8SPatrick Williams    "openpower-power-control",
52*e08ffba8SPatrick Williams    "docs",
53*e08ffba8SPatrick Williams    "openbmc-test-automation",
54*e08ffba8SPatrick Williams    "openbmc-build-scripts",
55*e08ffba8SPatrick Williams    "skeleton",
5658cbe5fbSAnusha Dathatri    "linux",
5758cbe5fbSAnusha Dathatri    # Not active, expected to be archived soon.
58*e08ffba8SPatrick Williams    "ibm-pldm-oem",
59*e08ffba8SPatrick Williams]
6058cbe5fbSAnusha Dathatri
61229b76a9SAnusha Dathatri
62229b76a9SAnusha Dathatri# Create parser.
63*e08ffba8SPatrick Williamstext = """%(prog)s target_dir [url_file]
6458cbe5fbSAnusha Dathatri
6558cbe5fbSAnusha DathatriExample usages:
6658cbe5fbSAnusha Dathatriget_unit_test_report.py target_dir
67*e08ffba8SPatrick Williamsget_unit_test_report.py target_dir repositories.txt"""
6858cbe5fbSAnusha Dathatri
69*e08ffba8SPatrick Williamsparser = argparse.ArgumentParser(
70*e08ffba8SPatrick Williams    usage=text, description="Script generates the unit test coverage report"
71*e08ffba8SPatrick Williams)
72*e08ffba8SPatrick Williamsparser.add_argument(
73*e08ffba8SPatrick Williams    "target_dir",
74*e08ffba8SPatrick Williams    type=str,
75*e08ffba8SPatrick Williams    help="""Name of a non-existing directory in pwd to store all
76*e08ffba8SPatrick Williams                cloned repos, logs and UT reports""",
77*e08ffba8SPatrick Williams)
78*e08ffba8SPatrick Williamsparser.add_argument(
79*e08ffba8SPatrick Williams    "url_file",
80*e08ffba8SPatrick Williams    type=str,
81*e08ffba8SPatrick Williams    nargs="?",
82*e08ffba8SPatrick Williams    help="""Text file containing url of repositories.
8358cbe5fbSAnusha Dathatri                By using this argument, the user can get a report only for
8458cbe5fbSAnusha Dathatri                specific repositories given in the file.
85*e08ffba8SPatrick Williams                Refer ./scripts/repositories.txt""",
86*e08ffba8SPatrick Williams)
87229b76a9SAnusha Dathatriargs = parser.parse_args()
88229b76a9SAnusha Dathatri
8958cbe5fbSAnusha Dathatriinput_urls = []
9058cbe5fbSAnusha Dathatriif args.url_file:
9158cbe5fbSAnusha Dathatri    try:
9258cbe5fbSAnusha Dathatri        # Get URLs from the file.
9358cbe5fbSAnusha Dathatri        with open(args.url_file) as reader:
9458cbe5fbSAnusha Dathatri            file_content = reader.read().splitlines()
9558cbe5fbSAnusha Dathatri            input_urls = list(filter(lambda x: x, file_content))
9658cbe5fbSAnusha Dathatri        if not (input_urls):
9758cbe5fbSAnusha Dathatri            print("Input file {} is empty. Quitting...".format(args.url_file))
9858cbe5fbSAnusha Dathatri            quit()
9958cbe5fbSAnusha Dathatri    except IOError as e:
100*e08ffba8SPatrick Williams        print(
101*e08ffba8SPatrick Williams            "Issue in reading file '{}'. Reason: {}".format(
102*e08ffba8SPatrick Williams                args.url_file, str(e)
103*e08ffba8SPatrick Williams            )
104*e08ffba8SPatrick Williams        )
10558cbe5fbSAnusha Dathatri        quit()
10658cbe5fbSAnusha Dathatri
107229b76a9SAnusha Dathatri
108229b76a9SAnusha Dathatri# Create target working directory.
109229b76a9SAnusha Dathatripwd = os.getcwd()
110229b76a9SAnusha Dathatriworking_dir = os.path.join(pwd, args.target_dir)
111229b76a9SAnusha Dathatritry:
112229b76a9SAnusha Dathatri    os.mkdir(working_dir)
113*e08ffba8SPatrick Williamsexcept OSError:
114*e08ffba8SPatrick Williams    answer = input(
115*e08ffba8SPatrick Williams        "Target directory "
116*e08ffba8SPatrick Williams        + working_dir
117*e08ffba8SPatrick Williams        + " already exists. "
118*e08ffba8SPatrick Williams        + "Do you want to delete [Y/N]: "
119*e08ffba8SPatrick Williams    )
120229b76a9SAnusha Dathatri    if answer == "Y":
121229b76a9SAnusha Dathatri        try:
122229b76a9SAnusha Dathatri            shutil.rmtree(working_dir)
123229b76a9SAnusha Dathatri            os.mkdir(working_dir)
124229b76a9SAnusha Dathatri        except OSError as e:
125229b76a9SAnusha Dathatri            print(str(e))
126229b76a9SAnusha Dathatri            quit()
127229b76a9SAnusha Dathatri    else:
128229b76a9SAnusha Dathatri        print("Exiting....")
129229b76a9SAnusha Dathatri        quit()
130229b76a9SAnusha Dathatri
131229b76a9SAnusha Dathatri# Create log directory.
132229b76a9SAnusha Dathatrilog_dir = os.path.join(working_dir, "logs")
133229b76a9SAnusha Dathatritry:
134229b76a9SAnusha Dathatri    os.mkdir(log_dir)
135229b76a9SAnusha Dathatriexcept OSError as e:
136229b76a9SAnusha Dathatri    print("Unable to create log directory: " + log_dir)
137229b76a9SAnusha Dathatri    print(str(e))
138229b76a9SAnusha Dathatri    quit()
139229b76a9SAnusha Dathatri
140229b76a9SAnusha Dathatri
141229b76a9SAnusha Dathatri# Log files
142229b76a9SAnusha Dathatridebug_file = os.path.join(log_dir, "debug.log")
143229b76a9SAnusha Dathatrioutput_file = os.path.join(log_dir, "output.log")
144*e08ffba8SPatrick Williamslogging.basicConfig(
145*e08ffba8SPatrick Williams    format="%(levelname)s - %(message)s",
146*e08ffba8SPatrick Williams    level=logging.DEBUG,
147*e08ffba8SPatrick Williams    filename=debug_file,
148*e08ffba8SPatrick Williams)
149229b76a9SAnusha Dathatrilogger = logging.getLogger(__name__)
150229b76a9SAnusha Dathatri
151229b76a9SAnusha Dathatri# Create handlers
152229b76a9SAnusha Dathatriconsole_handler = logging.StreamHandler()
153229b76a9SAnusha Dathatrifile_handler = logging.FileHandler(output_file)
154229b76a9SAnusha Dathatriconsole_handler.setLevel(logging.INFO)
155229b76a9SAnusha Dathatrifile_handler.setLevel(logging.INFO)
156229b76a9SAnusha Dathatri
157229b76a9SAnusha Dathatri# Create formatters and add it to handlers
158*e08ffba8SPatrick Williamslog_format = logging.Formatter("%(message)s")
159229b76a9SAnusha Dathatriconsole_handler.setFormatter(log_format)
160229b76a9SAnusha Dathatrifile_handler.setFormatter(log_format)
161229b76a9SAnusha Dathatri
162229b76a9SAnusha Dathatri# Add handlers to the logger
163229b76a9SAnusha Dathatrilogger.addHandler(console_handler)
164229b76a9SAnusha Dathatrilogger.addHandler(file_handler)
165229b76a9SAnusha Dathatri
166229b76a9SAnusha Dathatri
167229b76a9SAnusha Dathatri# Create report directory.
168229b76a9SAnusha Dathatrireport_dir = os.path.join(working_dir, "reports")
169229b76a9SAnusha Dathatritry:
170229b76a9SAnusha Dathatri    os.mkdir(report_dir)
171229b76a9SAnusha Dathatriexcept OSError as e:
172229b76a9SAnusha Dathatri    logger.error("Unable to create report directory: " + report_dir)
173229b76a9SAnusha Dathatri    logger.error(str(e))
174229b76a9SAnusha Dathatri    quit()
175229b76a9SAnusha Dathatri
176229b76a9SAnusha Dathatri# Clone OpenBmc build scripts.
177229b76a9SAnusha Dathatritry:
178*e08ffba8SPatrick Williams    output = subprocess.check_output(
179*e08ffba8SPatrick Williams        "git clone https://github.com/openbmc/openbmc-build-scripts.git",
180*e08ffba8SPatrick Williams        shell=True,
181*e08ffba8SPatrick Williams        cwd=working_dir,
182*e08ffba8SPatrick Williams        stderr=subprocess.STDOUT,
183*e08ffba8SPatrick Williams    )
184229b76a9SAnusha Dathatri    logger.debug(output)
185229b76a9SAnusha Dathatriexcept subprocess.CalledProcessError as e:
18658cbe5fbSAnusha Dathatri    logger.error(e.output)
18758cbe5fbSAnusha Dathatri    logger.error(e.cmd)
18858cbe5fbSAnusha Dathatri    logger.error("Unable to clone openbmc-build-scripts")
189229b76a9SAnusha Dathatri    quit()
190229b76a9SAnusha Dathatri
19158cbe5fbSAnusha Dathatrirepo_data = []
19258cbe5fbSAnusha Dathatriif input_urls:
19358cbe5fbSAnusha Dathatri    api_url = "https://api.github.com/repos/openbmc/"
19458cbe5fbSAnusha Dathatri    for url in input_urls:
19558cbe5fbSAnusha Dathatri        try:
196*e08ffba8SPatrick Williams            repo_name = url.strip().split("/")[-1].split(";")[0].split(".")[0]
19758cbe5fbSAnusha Dathatri        except IndexError as e:
19858cbe5fbSAnusha Dathatri            logger.error("ERROR: Unable to get sandbox name for url " + url)
19958cbe5fbSAnusha Dathatri            logger.error("Reason: " + str(e))
20058cbe5fbSAnusha Dathatri            continue
20158cbe5fbSAnusha Dathatri
20258cbe5fbSAnusha Dathatri        try:
20358cbe5fbSAnusha Dathatri            resp = requests.get(api_url + repo_name)
20458cbe5fbSAnusha Dathatri            if resp.status_code != 200:
20558cbe5fbSAnusha Dathatri                logger.info(api_url + repo_name + " ==> " + resp.reason)
20658cbe5fbSAnusha Dathatri                continue
20758cbe5fbSAnusha Dathatri            repo_data.extend([resp.json()])
208*e08ffba8SPatrick Williams        except ValueError:
20958cbe5fbSAnusha Dathatri            logger.error("ERROR: Failed to get response for " + repo_name)
21058cbe5fbSAnusha Dathatri            logger.error(resp)
21158cbe5fbSAnusha Dathatri            continue
21258cbe5fbSAnusha Dathatri
21358cbe5fbSAnusha Dathatrielse:
214185d5b59SAnusha Dathatri    # Get number of pages.
215*e08ffba8SPatrick Williams    resp = requests.head("https://api.github.com/users/openbmc/repos")
216185d5b59SAnusha Dathatri    if resp.status_code != 200:
217185d5b59SAnusha Dathatri        logger.error("Error! Unable to get repositories")
21858cbe5fbSAnusha Dathatri        logger.error(resp.status_code)
21958cbe5fbSAnusha Dathatri        logger.error(resp.reason)
220185d5b59SAnusha Dathatri        quit()
221*e08ffba8SPatrick Williams    num_of_pages = int(resp.links["last"]["url"].split("page=")[-1])
222185d5b59SAnusha Dathatri    logger.debug("No. of pages: " + str(num_of_pages))
223185d5b59SAnusha Dathatri
224185d5b59SAnusha Dathatri    # Fetch data from all pages.
225185d5b59SAnusha Dathatri    for page in range(1, num_of_pages + 1):
226*e08ffba8SPatrick Williams        resp = requests.get(
227*e08ffba8SPatrick Williams            "https://api.github.com/users/openbmc/repos?page=" + str(page)
228*e08ffba8SPatrick Williams        )
229185d5b59SAnusha Dathatri        data = resp.json()
230185d5b59SAnusha Dathatri        repo_data.extend(data)
231185d5b59SAnusha Dathatri
23258cbe5fbSAnusha Dathatri
233185d5b59SAnusha Dathatri# Get URLs and their archive status from response.
234185d5b59SAnusha Dathatriurl_info = {}
235185d5b59SAnusha Dathatrifor repo in repo_data:
23658cbe5fbSAnusha Dathatri    try:
237185d5b59SAnusha Dathatri        url_info[repo["clone_url"]] = repo["archived"]
238*e08ffba8SPatrick Williams    except KeyError:
23958cbe5fbSAnusha Dathatri        logger.error("Failed to get archived status of {}".format(repo))
24058cbe5fbSAnusha Dathatri        url_info[repo["clone_url"]] = False
24158cbe5fbSAnusha Dathatri        continue
242185d5b59SAnusha Dathatrilogger.debug(url_info)
243185d5b59SAnusha Dathatrirepo_count = len(url_info)
244185d5b59SAnusha Dathatrilogger.info("Number of repositories (Including archived): " + str(repo_count))
245229b76a9SAnusha Dathatri
246229b76a9SAnusha Dathatri# Clone repository and run unit test.
247229b76a9SAnusha Dathatricoverage_report = []
248229b76a9SAnusha Dathatricounter = 0
249185d5b59SAnusha Dathatritested_report_count = 0
250229b76a9SAnusha Dathatricoverage_count = 0
251229b76a9SAnusha Dathatriunit_test_count = 0
252229b76a9SAnusha Dathatrino_report_count = 0
253229b76a9SAnusha Dathatrierror_count = 0
254a756e8a0SAnusha Dathatriskip_count = 0
255185d5b59SAnusha Dathatriarchive_count = 0
256185d5b59SAnusha Dathatriurl_list = sorted(url_info)
257229b76a9SAnusha Dathatrifor url in url_list:
258185d5b59SAnusha Dathatri    ut_status = "NO"
259229b76a9SAnusha Dathatri    skip = False
260185d5b59SAnusha Dathatri    if url_info[url]:
261185d5b59SAnusha Dathatri        ut_status = "ARCHIVED"
262a756e8a0SAnusha Dathatri        skip = True
263a756e8a0SAnusha Dathatri    else:
264229b76a9SAnusha Dathatri        try:
265185d5b59SAnusha Dathatri            # Eg: url = "https://github.com/openbmc/u-boot.git"
266185d5b59SAnusha Dathatri            #     sandbox_name = "u-boot"
267*e08ffba8SPatrick Williams            sandbox_name = (
268*e08ffba8SPatrick Williams                url.strip().split("/")[-1].split(";")[0].split(".")[0]
269*e08ffba8SPatrick Williams            )
270185d5b59SAnusha Dathatri        except IndexError as e:
27158cbe5fbSAnusha Dathatri            logger.error("ERROR: Unable to get sandbox name for url " + url)
27258cbe5fbSAnusha Dathatri            logger.error("Reason: " + str(e))
27358cbe5fbSAnusha Dathatri            continue
274185d5b59SAnusha Dathatri
275*e08ffba8SPatrick Williams        if sandbox_name in skip_list or re.match(r"meta-", sandbox_name):
276185d5b59SAnusha Dathatri            logger.debug("SKIPPING: " + sandbox_name)
277185d5b59SAnusha Dathatri            skip = True
278185d5b59SAnusha Dathatri            ut_status = "SKIPPED"
279185d5b59SAnusha Dathatri        else:
280185d5b59SAnusha Dathatri            checkout_cmd = "rm -rf " + sandbox_name + ";git clone " + url
281185d5b59SAnusha Dathatri            try:
282*e08ffba8SPatrick Williams                subprocess.check_output(
283*e08ffba8SPatrick Williams                    checkout_cmd,
284*e08ffba8SPatrick Williams                    shell=True,
285*e08ffba8SPatrick Williams                    cwd=working_dir,
286*e08ffba8SPatrick Williams                    stderr=subprocess.STDOUT,
287*e08ffba8SPatrick Williams                )
288229b76a9SAnusha Dathatri            except subprocess.CalledProcessError as e:
289229b76a9SAnusha Dathatri                logger.debug(e.output)
290229b76a9SAnusha Dathatri                logger.debug(e.cmd)
291229b76a9SAnusha Dathatri                logger.debug("Failed to clone " + sandbox_name)
292185d5b59SAnusha Dathatri                ut_status = "ERROR"
293229b76a9SAnusha Dathatri                skip = True
294229b76a9SAnusha Dathatri    if not (skip):
295*e08ffba8SPatrick Williams        docker_cmd = (
296*e08ffba8SPatrick Williams            "WORKSPACE=$(pwd) UNIT_TEST_PKG="
297*e08ffba8SPatrick Williams            + sandbox_name
298*e08ffba8SPatrick Williams            + " "
299*e08ffba8SPatrick Williams            + "./openbmc-build-scripts/run-unit-test-docker.sh"
300*e08ffba8SPatrick Williams        )
301229b76a9SAnusha Dathatri        try:
302*e08ffba8SPatrick Williams            result = subprocess.check_output(
303*e08ffba8SPatrick Williams                docker_cmd,
304*e08ffba8SPatrick Williams                cwd=working_dir,
305*e08ffba8SPatrick Williams                shell=True,
306*e08ffba8SPatrick Williams                stderr=subprocess.STDOUT,
307*e08ffba8SPatrick Williams            )
308229b76a9SAnusha Dathatri            logger.debug(result)
309229b76a9SAnusha Dathatri            logger.debug("UT BUILD COMPLETED FOR: " + sandbox_name)
310229b76a9SAnusha Dathatri
311229b76a9SAnusha Dathatri        except subprocess.CalledProcessError as e:
312229b76a9SAnusha Dathatri            logger.debug(e.output)
313229b76a9SAnusha Dathatri            logger.debug(e.cmd)
314229b76a9SAnusha Dathatri            logger.debug("UT BUILD EXITED FOR: " + sandbox_name)
315185d5b59SAnusha Dathatri            ut_status = "ERROR"
316229b76a9SAnusha Dathatri
317229b76a9SAnusha Dathatri        folder_name = os.path.join(working_dir, sandbox_name)
318229b76a9SAnusha Dathatri        repo_report_dir = os.path.join(report_dir, sandbox_name)
319229b76a9SAnusha Dathatri
320544d83afSAnusha Dathatri        report_names = ("coveragereport", "test-suite.log", "LastTest.log")
321*e08ffba8SPatrick Williams        find_cmd = "".join(
322*e08ffba8SPatrick Williams            "find " + folder_name + " -name " + report + ";"
323*e08ffba8SPatrick Williams            for report in report_names
324*e08ffba8SPatrick Williams        )
325185d5b59SAnusha Dathatri        try:
326229b76a9SAnusha Dathatri            result = subprocess.check_output(find_cmd, shell=True)
3275ef836e0SAnusha Dathatri            result = result.decode("utf-8")
328185d5b59SAnusha Dathatri        except subprocess.CalledProcessError as e:
329185d5b59SAnusha Dathatri            logger.debug(e.output)
330185d5b59SAnusha Dathatri            logger.debug(e.cmd)
331185d5b59SAnusha Dathatri            logger.debug("CMD TO FIND REPORT FAILED FOR: " + sandbox_name)
332185d5b59SAnusha Dathatri            ut_status = "ERROR"
333185d5b59SAnusha Dathatri
334185d5b59SAnusha Dathatri        if ut_status != "ERROR":
335229b76a9SAnusha Dathatri            if result:
336229b76a9SAnusha Dathatri                if result.__contains__("coveragereport"):
337185d5b59SAnusha Dathatri                    ut_status = "YES, COVERAGE"
338229b76a9SAnusha Dathatri                    coverage_count += 1
339544d83afSAnusha Dathatri                elif "test-suite.log" in result:
340185d5b59SAnusha Dathatri                    ut_status = "YES, UNIT TEST"
341544d83afSAnusha Dathatri                    unit_test_count += 1
342544d83afSAnusha Dathatri                elif "LastTest.log" in result:
343544d83afSAnusha Dathatri                    file_names = result.splitlines()
344544d83afSAnusha Dathatri                    for file in file_names:
345*e08ffba8SPatrick Williams                        pattern_count_cmd = (
346*e08ffba8SPatrick Williams                            "sed -n '/Start testing/,/End testing/p;' "
347*e08ffba8SPatrick Williams                            + file
348*e08ffba8SPatrick Williams                            + "|wc -l"
349*e08ffba8SPatrick Williams                        )
350185d5b59SAnusha Dathatri                        try:
351*e08ffba8SPatrick Williams                            num_of_lines = subprocess.check_output(
352*e08ffba8SPatrick Williams                                pattern_count_cmd, shell=True
353*e08ffba8SPatrick Williams                            )
354185d5b59SAnusha Dathatri                        except subprocess.CalledProcessError as e:
355185d5b59SAnusha Dathatri                            logger.debug(e.output)
356185d5b59SAnusha Dathatri                            logger.debug(e.cmd)
357*e08ffba8SPatrick Williams                            logger.debug(
358*e08ffba8SPatrick Williams                                "CONTENT CHECK FAILED FOR: " + sandbox_name
359*e08ffba8SPatrick Williams                            )
360185d5b59SAnusha Dathatri                            ut_status = "ERROR"
361185d5b59SAnusha Dathatri
362544d83afSAnusha Dathatri                        if int(num_of_lines.strip()) > 5:
363185d5b59SAnusha Dathatri                            ut_status = "YES, UNIT TEST"
364229b76a9SAnusha Dathatri                            unit_test_count += 1
365229b76a9SAnusha Dathatri
366185d5b59SAnusha Dathatri        if "YES" in ut_status:
367185d5b59SAnusha Dathatri            tested_report_count += 1
368229b76a9SAnusha Dathatri            result = result.splitlines()
369229b76a9SAnusha Dathatri            for file_path in result:
370*e08ffba8SPatrick Williams                destination = os.path.dirname(
371*e08ffba8SPatrick Williams                    os.path.join(
372*e08ffba8SPatrick Williams                        report_dir, os.path.relpath(file_path, working_dir)
373*e08ffba8SPatrick Williams                    )
374*e08ffba8SPatrick Williams                )
375*e08ffba8SPatrick Williams                copy_cmd = (
376*e08ffba8SPatrick Williams                    "mkdir -p "
377*e08ffba8SPatrick Williams                    + destination
378*e08ffba8SPatrick Williams                    + ";cp -rf "
379*e08ffba8SPatrick Williams                    + file_path.strip()
380*e08ffba8SPatrick Williams                    + " "
381*e08ffba8SPatrick Williams                    + destination
382*e08ffba8SPatrick Williams                )
383185d5b59SAnusha Dathatri                try:
384229b76a9SAnusha Dathatri                    subprocess.check_output(copy_cmd, shell=True)
385185d5b59SAnusha Dathatri                except subprocess.CalledProcessError as e:
386185d5b59SAnusha Dathatri                    logger.debug(e.output)
387185d5b59SAnusha Dathatri                    logger.debug(e.cmd)
388185d5b59SAnusha Dathatri                    logger.info("FAILED TO COPY REPORTS FOR: " + sandbox_name)
389229b76a9SAnusha Dathatri
390185d5b59SAnusha Dathatri    if ut_status == "ERROR":
391185d5b59SAnusha Dathatri        error_count += 1
392185d5b59SAnusha Dathatri    elif ut_status == "NO":
393185d5b59SAnusha Dathatri        no_report_count += 1
394185d5b59SAnusha Dathatri    elif ut_status == "SKIPPED":
395185d5b59SAnusha Dathatri        skip_count += 1
396185d5b59SAnusha Dathatri    elif ut_status == "ARCHIVED":
397185d5b59SAnusha Dathatri        archive_count += 1
398185d5b59SAnusha Dathatri
399185d5b59SAnusha Dathatri    coverage_report.append("{:<65}{:<10}".format(url.strip(), ut_status))
400229b76a9SAnusha Dathatri    counter += 1
401229b76a9SAnusha Dathatri    logger.info(str(counter) + " in " + str(repo_count) + " completed")
402229b76a9SAnusha Dathatri
403229b76a9SAnusha Dathatrilogger.info("*" * 30 + "UNIT TEST COVERAGE REPORT" + "*" * 30)
404229b76a9SAnusha Dathatrifor res in coverage_report:
405229b76a9SAnusha Dathatri    logger.info(res)
406229b76a9SAnusha Dathatrilogger.info("*" * 30 + "UNIT TEST COVERAGE REPORT" + "*" * 30)
407229b76a9SAnusha Dathatri
408229b76a9SAnusha Dathatrilogger.info("REPORTS: " + report_dir)
409229b76a9SAnusha Dathatrilogger.info("LOGS: " + log_dir)
410229b76a9SAnusha Dathatrilogger.info("*" * 85)
411229b76a9SAnusha Dathatrilogger.info("SUMMARY: ")
412229b76a9SAnusha Dathatrilogger.info("TOTAL REPOSITORIES     : " + str(repo_count))
413185d5b59SAnusha Dathatrilogger.info("TESTED REPOSITORIES    : " + str(tested_report_count))
414229b76a9SAnusha Dathatrilogger.info("ERROR                  : " + str(error_count))
415229b76a9SAnusha Dathatrilogger.info("COVERAGE REPORT        : " + str(coverage_count))
416229b76a9SAnusha Dathatrilogger.info("UNIT TEST REPORT       : " + str(unit_test_count))
417229b76a9SAnusha Dathatrilogger.info("NO REPORT              : " + str(no_report_count))
418a756e8a0SAnusha Dathatrilogger.info("SKIPPED                : " + str(skip_count))
419185d5b59SAnusha Dathatrilogger.info("ARCHIVED               : " + str(archive_count))
420229b76a9SAnusha Dathatrilogger.info("*" * 85)
421