2022-10-14 23:36:37 +00:00
import argparse
import dataclasses
2022-10-04 13:29:16 +00:00
import json
2022-10-14 23:36:37 +00:00
import logging
2022-10-04 13:29:16 +00:00
import os
import platform
2022-10-14 23:36:37 +00:00
import sys
2022-10-04 13:29:16 +00:00
import time
import traceback
2022-10-14 23:36:37 +00:00
import uuid
from concurrent import futures
from pathlib import Path
from typing import Any , Dict , Generator , List , Optional , Tuple , Set
2022-10-04 13:29:16 +00:00
import docker
2022-10-14 23:36:37 +00:00
import docker . errors
import requests
2022-12-06 18:53:16 +00:00
from docker . client import DockerClient
from docker . models . containers import Container
2022-12-13 23:42:35 +00:00
from docker . models . images import Image
2022-12-06 18:53:16 +00:00
2022-10-04 13:29:16 +00:00
from simple_report import Result , Report
root = logging . getLogger ( )
root . setLevel ( logging . DEBUG )
handler = logging . StreamHandler ( sys . stdout )
handler . setLevel ( logging . DEBUG )
formatter = logging . Formatter ( ' [ %(asctime)s ] %(levelname)s : %(message)s ' )
handler . setFormatter ( formatter )
root . addHandler ( handler )
2022-10-14 23:36:37 +00:00
PACKAGE_MANAGER_COMMANDS = {
" apt " : {
2022-12-13 23:42:35 +00:00
" update " : " export DEBIAN_FRONTEND=noninteractive && apt-get update -y " ,
" install " : " export DEBIAN_FRONTEND=noninteractive && apt-get install -y {} " ,
2022-10-14 23:36:37 +00:00
} ,
" yum " : {
" update " : " yum update -y " ,
" install " : " yum install -y {} " ,
} ,
" zypper " : {
" update " : " zypper -n update " ,
" install " : " zypper -n install {} " ,
} ,
}
# Lookup table used when building and running containers
# os_name, Optional[(base_image, package_manager, frozenset(base_packages), python_command)]
2022-10-04 13:29:16 +00:00
OS_DOCKER_LOOKUP = {
' amazon ' : None ,
' amzn64 ' : None ,
2022-12-28 21:47:03 +00:00
' amazon2 ' : ( ' amazonlinux:2 ' , " yum " ,
2023-01-05 22:07:10 +00:00
frozenset ( [ " python " , " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) ,
" python3 " ) ,
2022-12-28 21:47:03 +00:00
' amazon2022 ' : ( ' amazonlinux:2022 ' , " yum " ,
2023-01-05 22:07:10 +00:00
frozenset (
[ " python " , " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) ,
" python3 " ) ,
2022-12-28 21:47:03 +00:00
' debian10 ' : ( ' debian:10-slim ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [ " python " , " python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file " ] ) , " python3 " ) ,
2022-12-28 21:47:03 +00:00
' debian11 ' : ( ' debian:11-slim ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [
" python3 " , " python-is-python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file "
] ) , " python3 " ) ,
2022-12-28 21:47:03 +00:00
' debian71 ' : ( ' debian:7-slim ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [ " python " , " python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file " ] ) , " python3 " ) ,
2022-12-28 21:47:03 +00:00
' debian81 ' : ( ' debian:8-slim ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [ " python " , " python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file " ] ) , " python3 " ) ,
2022-12-28 21:47:03 +00:00
' debian92 ' : ( ' debian:9-slim ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [ " python " , " python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file " ] ) , " python3 " ) ,
2022-10-04 13:29:16 +00:00
' linux_i686 ' : None ,
' linux_x86_64 ' : None ,
' macos ' : None ,
' osx ' : None ,
' osx-ssl ' : None ,
' rhel55 ' : None ,
' rhel57 ' : None ,
' rhel62 ' : None ,
2023-01-05 22:07:10 +00:00
' rhel70 ' : ( ' centos:7 ' , " yum " ,
frozenset ( [ " rh-python38.x86_64 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) ,
2022-10-14 23:36:37 +00:00
" /opt/rh/rh-python38/root/usr/bin/python3 " ) ,
2023-01-05 22:07:10 +00:00
' rhel71 ' : ( ' centos:7 ' , " yum " ,
frozenset ( [ " rh-python38.x86_64 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) ,
2022-10-14 23:36:37 +00:00
" /opt/rh/rh-python38/root/usr/bin/python3 " ) ,
2023-01-05 22:07:10 +00:00
' rhel72 ' : ( ' centos:7 ' , " yum " ,
frozenset ( [ " rh-python38.x86_64 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) ,
2022-10-14 23:36:37 +00:00
" /opt/rh/rh-python38/root/usr/bin/python3 " ) ,
2023-01-05 22:07:10 +00:00
' rhel80 ' : ( ' almalinux:8 ' , " yum " ,
frozenset ( [ " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) , " python3 " ) ,
' rhel81 ' : ( ' almalinux:8 ' , " yum " ,
frozenset ( [ " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) , " python3 " ) ,
' rhel82 ' : ( ' almalinux:8 ' , " yum " ,
frozenset ( [ " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) , " python3 " ) ,
' rhel83 ' : ( ' almalinux:8 ' , " yum " ,
frozenset ( [ " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) , " python3 " ) ,
' rhel90 ' : ( ' almalinux:9 ' , " yum " ,
frozenset ( [ " python3 " , " wget " , " pkgconfig " , " systemd " , " procps " , " file " ] ) , " python3 " ) ,
2022-10-04 13:29:16 +00:00
' sunos5 ' : None ,
' suse11 ' : None ,
' suse12 ' : None ,
2022-12-28 21:47:03 +00:00
' suse15 ' : ( ' registry.suse.com/suse/sle15:latest ' , " zypper " ,
2023-01-05 22:07:10 +00:00
frozenset ( [ " python3 " , " wget " , " pkg-config " , " systemd " , " procps " , " file " ] ) ,
" python3 " ) ,
2022-10-04 13:29:16 +00:00
# Has the same error as above
' ubuntu1204 ' : None ,
' ubuntu1404 ' : None ,
2022-12-28 21:47:03 +00:00
' ubuntu1604 ' : ( ' ubuntu:16.04 ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset (
[ " python " , " python3 " , " wget " , " pkg-config " , " systemd " , " procps " , " file " ] ) ,
" python3 " ) ,
2022-12-28 21:47:03 +00:00
' ubuntu1804 ' : ( ' ubuntu:18.04 ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset (
[ " python " , " python3 " , " wget " , " pkg-config " , " systemd " , " procps " , " file " ] ) ,
" python3 " ) ,
2022-12-28 21:47:03 +00:00
' ubuntu2004 ' : ( ' ubuntu:20.04 ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [
" python3 " , " python-is-python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file "
] ) , " python3 " ) ,
2022-12-28 21:47:03 +00:00
' ubuntu2204 ' : ( ' ubuntu:22.04 ' , " apt " ,
2023-01-05 22:07:10 +00:00
frozenset ( [
" python3 " , " python-is-python3 " , " wget " , " pkg-config " , " systemd " , " procps " ,
" file "
] ) , " python3 " ) ,
2022-10-04 13:29:16 +00:00
' windows ' : None ,
' windows_i686 ' : None ,
' windows_x86_64 ' : None ,
' windows_x86_64-2008plus ' : None ,
' windows_x86_64-2008plus-ssl ' : None ,
' windows_x86_64-2012plus ' : None ,
}
VERSIONS_TO_SKIP = set ( [ ' 3.0.15 ' , ' 3.2.22 ' , ' 3.4.24 ' , ' 3.6.23 ' , ' 4.0.28 ' ] )
# TODO(SERVER-70016) These can be deleted once these versions are no longer is current.json
2022-10-14 23:36:37 +00:00
DISABLED_TESTS = [ ( " amazon2 " , " 4.4.16 " ) , ( " amazon2 " , " 4.4.17-rc2 " ) , ( " amazon2 " , " 4.2.23-rc0 " ) ,
( " amazon2 " , " 4.2.23-rc1 " ) , ( " amazon2 " , " 4.2.22 " ) ]
2022-10-04 13:29:16 +00:00
@dataclasses.dataclass
class Test :
""" Class to track a single test. """
2022-10-14 23:36:37 +00:00
os_name : str
2022-10-04 13:29:16 +00:00
version : str
2022-10-14 23:36:37 +00:00
base_image : str = dataclasses . field ( default = " " , repr = False )
package_manager : str = dataclasses . field ( default = " " , repr = False )
update_command : str = dataclasses . field ( default = " " , repr = False )
install_command : str = dataclasses . field ( default = " " , repr = False )
2022-12-06 18:53:16 +00:00
base_packages : List [ str ] = dataclasses . field ( default_factory = list )
2022-10-14 23:36:37 +00:00
python_command : str = dataclasses . field ( default = " " , repr = False )
2022-10-04 13:29:16 +00:00
packages_urls : List [ str ] = dataclasses . field ( default_factory = list )
packages_paths : List [ Path ] = dataclasses . field ( default_factory = list )
2022-10-14 23:36:37 +00:00
def __post_init__ ( self ) - > None :
assert OS_DOCKER_LOOKUP [ self . os_name ] is not None
self . base_image = OS_DOCKER_LOOKUP [ self . os_name ] [ 0 ]
self . package_manager = OS_DOCKER_LOOKUP [ self . os_name ] [ 1 ]
2022-12-06 18:53:16 +00:00
self . base_packages = list ( OS_DOCKER_LOOKUP [ self . os_name ] [ 2 ] )
2022-10-14 23:36:37 +00:00
self . python_command = OS_DOCKER_LOOKUP [ self . os_name ] [ 3 ]
self . update_command = PACKAGE_MANAGER_COMMANDS [ self . package_manager ] [ " update " ]
self . install_command = PACKAGE_MANAGER_COMMANDS [ self . package_manager ] [ " install " ]
2022-10-04 13:29:16 +00:00
def __repr__ ( self ) - > str :
2022-10-14 23:36:37 +00:00
ret = f " \n Test: \n \t os: { self . os_name } \n "
ret + = f " image: { self . base_image } \n "
2022-10-04 13:29:16 +00:00
ret + = f " \t version: { self . version } \n "
ret + = f " \t packages_urls: { self . packages_urls } \n "
ret + = f " \t packages_paths: { self . packages_paths } \n "
return ret
def name ( self ) - > str :
2022-10-14 23:36:37 +00:00
return self . os_name + " - " + self . version
2022-12-13 23:42:35 +00:00
def get_image ( test : Test , client : DockerClient ) - > Image :
2022-12-06 18:53:16 +00:00
tries = 1
while True :
try :
logging . info ( " Pulling base image for %s : %s , try %s " , test . os_name , test . base_image ,
tries )
base_image = client . images . pull ( test . base_image )
except docker . errors . ImageNotFound as exc :
if tries > = 5 :
logging . error ( " Base image %s not found after %s tries " , test . base_image , tries )
raise exc
else :
2022-12-13 23:42:35 +00:00
return base_image
2022-12-06 18:53:16 +00:00
finally :
tries + = 1
time . sleep ( 1 )
2022-10-14 23:36:37 +00:00
2022-12-13 23:42:35 +00:00
def join_commands ( commands : List [ str ] , sep : str = ' && ' ) - > str :
return sep . join ( commands )
2022-10-04 13:29:16 +00:00
2022-12-06 18:53:16 +00:00
def run_test ( test : Test , client : DockerClient ) - > Result :
2022-10-04 13:29:16 +00:00
result = Result ( status = " pass " , test_file = test . name ( ) , start = time . time ( ) , log_raw = " " )
2022-10-14 23:36:37 +00:00
log_name = f " logs/ { test . os_name } _ { test . version } _ { uuid . uuid4 ( ) . hex } .log "
test_docker_root = Path ( " /mnt/package_test " ) . resolve ( )
2022-10-04 13:29:16 +00:00
log_docker_path = Path . joinpath ( test_docker_root , log_name )
2022-10-14 23:36:37 +00:00
test_external_root = Path ( __file__ ) . parent . resolve ( )
logging . debug ( test_external_root )
2022-10-04 13:29:16 +00:00
log_external_path = Path . joinpath ( test_external_root , log_name )
2023-01-05 22:07:10 +00:00
commands : List [ str ] = [ ]
if test . os_name . startswith ( ' rhel ' ) :
if test . os_name . startswith ( ' rhel7 ' ) :
# RHEL 7 needs the SCL installed for Python 3
commands + = [
" yum -y install centos-release-scl " ,
" yum-config-manager --enable centos-sclo-rh " ,
]
# RHEL distros need EPEL for Compass dependencies
commands + = [
" yum -y install yum-utils epel-release " ,
" yum-config-manager --enable epel " ,
]
commands + = [
2022-12-13 23:42:35 +00:00
test . update_command ,
test . install_command . format ( " " . join ( test . base_packages ) ) ,
]
2022-10-04 13:29:16 +00:00
2022-12-13 23:42:35 +00:00
if test . python_command != ' python3 ' :
commands . append ( f " ln -s { test . python_command } /usr/bin/python3 " )
os . makedirs ( log_external_path . parent , exist_ok = True )
commands . append (
f " python3 /mnt/package_test/package_test_internal.py { log_docker_path } { ' ' . join ( test . packages_urls ) } "
)
logging . debug ( " Attempting to run the following docker commands: \n \t %s " ,
join_commands ( commands , sep = ' \n \t ' ) )
image : Image | None = None
container : Container | None = None
2022-10-04 13:29:16 +00:00
try :
2022-12-13 23:42:35 +00:00
image = get_image ( test , client )
container = client . containers . run ( image , command = f " bash -c \" { join_commands ( commands ) } \" " ,
auto_remove = True , detach = True ,
volumes = [ f ' { test_external_root } : { test_docker_root } ' ] )
2022-10-04 13:29:16 +00:00
for log in container . logs ( stream = True ) :
result [ " log_raw " ] + = log . decode ( ' UTF-8 ' )
# This is pretty verbose, lets run this way for a while and we can delete this if it ends up being too much
logging . debug ( log . decode ( ' UTF-8 ' ) . strip ( ) )
exit_code = container . wait ( )
result [ " exit_code " ] = exit_code [ ' StatusCode ' ]
2022-10-14 23:36:37 +00:00
except docker . errors . APIError as exc :
traceback . print_exception ( type ( exc ) , exc , exc . __traceback__ )
2022-12-13 23:42:35 +00:00
logging . error ( " Failed to start test " )
2022-10-04 13:29:16 +00:00
result [ " end " ] = time . time ( )
result [ ' status ' ] = ' fail '
result [ " exit_code " ] = 1
return result
try :
with open ( log_external_path , ' r ' ) as log_raw :
result [ " log_raw " ] + = log_raw . read ( )
except OSError as oserror :
logging . error ( " Failed to open %s with error %s " , log_external_path , oserror )
if exit_code [ ' StatusCode ' ] != 0 :
logging . error ( " Failed test %s with exit code %s " , test , exit_code )
result [ ' status ' ] = ' fail '
result [ " end " ] = time . time ( )
return result
2022-11-29 18:52:20 +00:00
logging . info ( " Attempting to download current mongo releases json " )
2022-10-04 13:29:16 +00:00
r = requests . get ( ' https://downloads.mongodb.org/current.json ' )
current_releases = r . json ( )
2022-11-29 18:52:20 +00:00
logging . info ( " Attempting to download current mongo tools releases json " )
2022-10-04 13:29:16 +00:00
r = requests . get ( ' https://downloads.mongodb.org/tools/db/release.json ' )
current_tools_releases = r . json ( )
2022-11-29 18:52:20 +00:00
logging . info ( " Attempting to download current mongosh releases json " )
2022-10-04 13:29:16 +00:00
r = requests . get ( ' https://s3.amazonaws.com/info-mongodb-com/com-download-center/mongosh.json ' )
mongosh_releases = r . json ( )
def iterate_over_downloads ( ) - > Generator [ Dict [ str , Any ] , None , None ] :
2022-11-29 18:52:20 +00:00
# TODO: TOOLS-3204 - we need to sub the arch alias until package
# rchitectures are named consistently with the server packages
2022-10-04 13:29:16 +00:00
for version in current_releases [ " versions " ] :
for download in version [ " downloads " ] :
if download [ " edition " ] == " source " :
continue
if version [ " version " ] in VERSIONS_TO_SKIP :
continue
download [ " version " ] = version [ " version " ]
yield download
def get_tools_package ( arch_name : str , os_name : str ) - > Optional [ str ] :
2022-11-29 18:52:20 +00:00
# TODO: MONGOSH-1308 - we need to sub the arch alias until package
# architectures are named consistently with the server packages
if arch_name == " aarch64 " and os_name != " amazon2 " :
arch_name = " arm64 "
2022-10-04 13:29:16 +00:00
for download in current_tools_releases [ " versions " ] [ 0 ] [ " downloads " ] :
if download [ " name " ] == os_name and download [ " arch " ] == arch_name :
return download [ " package " ] [ " url " ]
return None
def get_mongosh_package ( arch_name : str , os_name : str ) - > Optional [ str ] :
2022-11-29 18:52:20 +00:00
if arch_name == " aarch64 " :
arch_name = " arm64 "
if arch_name in ( " x86_64 " , " amd64 " ) :
2022-10-04 13:29:16 +00:00
arch_name = " x64 "
pkg_ext = " rpm "
if " debian " in os_name or " ubuntu " in os_name :
pkg_ext = " deb "
for platform_type in mongosh_releases [ " versions " ] [ 0 ] [ " platform " ] :
if platform_type [ " os " ] == pkg_ext and platform_type [ " arch " ] == arch_name :
return platform_type [ " download_link " ]
return None
2022-11-29 18:52:20 +00:00
def get_arch_aliases ( arch_name : str ) - > List [ str ] :
if arch_name in ( ' amd64 ' , ' x86_64 ' ) :
return [ ' amd64 ' , ' x86_64 ' ]
if arch_name in ( ' ppc64le ' , ' ppc64el ' ) :
return [ ' ppc64le ' , ' ppc64el ' ]
return [ arch_name ]
2022-10-04 13:29:16 +00:00
arches : Set [ str ] = set ( )
oses : Set [ str ] = set ( )
editions : Set [ str ] = set ( )
versions : Set [ str ] = set ( )
for dl in iterate_over_downloads ( ) :
editions . add ( dl [ " edition " ] )
arches . add ( dl [ " arch " ] )
oses . add ( dl [ " target " ] )
versions . add ( dl [ " version " ] )
2022-10-04 21:21:07 +00:00
parser = argparse . ArgumentParser (
description =
' Test packages on various hosts. This will spin up docker containers and test the installs. ' )
2022-10-04 13:29:16 +00:00
parser . add_argument ( " --arch " , type = str , help = " Arch of host machine to use " ,
choices = [ " auto " ] + list ( arches ) , default = " auto " )
parser . add_argument (
" --os " , type = str , help =
" OS of docker image to run test(s) on. All means run all os tests on this arch. None means run no os test on this arch (except for one specified in extra-packages. " ,
choices = [ " all " , " none " ] + list ( oses ) , default = " all " )
parser . add_argument (
" -e " , " --extra-test " , type = str , help =
2022-10-14 23:36:37 +00:00
" Space-separated tuple of (test_os, package_archive_path). For example ubuntu2004,https://s3.amazonaws.com/mciuploads/$ {project} /$ {build_variant} /$ {revision} /artifacts/$ {build_id} -packages.tgz. " ,
action = ' append ' , nargs = 2 , default = [ ] )
2022-10-04 13:29:16 +00:00
args = parser . parse_args ( )
mongo_os : str = args . os
2022-10-14 23:36:37 +00:00
extra_tests : List [ Tuple [ str , str ] ] = args . extra_test
2022-10-04 13:29:16 +00:00
arch : str = args . arch
if arch == " auto " :
arch = platform . machine ( )
tests : List [ Test ] = [ ]
for extra_test in extra_tests :
test_os = extra_test [ 0 ]
2022-10-14 23:36:37 +00:00
logging . info ( extra_test [ 1 ] )
urls : List [ str ] = [ extra_test [ 1 ] ]
2022-10-04 13:29:16 +00:00
if test_os not in OS_DOCKER_LOOKUP :
logging . error ( " We have not seen this OS %s before, please add it to OS_DOCKER_LOOKUP " ,
test_os )
sys . exit ( 1 )
2022-10-14 23:36:37 +00:00
if not OS_DOCKER_LOOKUP [ test_os ] :
logging . info ( " Skipping test on target because the OS has no associated container %s ->??? " ,
test_os )
continue
2022-10-04 13:29:16 +00:00
tools_package = get_tools_package ( arch , test_os )
mongosh_package = get_mongosh_package ( arch , test_os )
if tools_package :
urls . append ( tools_package )
else :
2022-11-29 18:52:20 +00:00
logging . error ( " Could not find tools package for %s and %s " , arch , test_os )
sys . exit ( 1 )
2022-10-04 13:29:16 +00:00
if mongosh_package :
urls . append ( mongosh_package )
else :
2022-11-29 18:52:20 +00:00
logging . error ( " Could not find mongosh package for %s and %s " , arch , test_os )
sys . exit ( 1 )
2022-10-04 13:29:16 +00:00
2022-10-14 23:36:37 +00:00
tests . append ( Test ( os_name = test_os , version = " custom " , packages_urls = urls ) )
2022-10-04 13:29:16 +00:00
# If os is None we only want to do the tests specified in the arguments
if mongo_os != " none " :
for dl in iterate_over_downloads ( ) :
if mongo_os not in [ " all " , dl [ " target " ] ] :
continue
2022-11-29 18:52:20 +00:00
# amd64 and x86_64 should be treated as aliases of each other
2022-12-13 23:42:35 +00:00
if dl [ " arch " ] not in get_arch_aliases ( arch ) :
2022-10-04 13:29:16 +00:00
continue
if not OS_DOCKER_LOOKUP [ dl [ " target " ] ] :
logging . info (
" Skipping test on target because the OS has no associated container %s ->??? on mongo version %s " ,
dl [ ' target ' ] , dl [ ' version ' ] )
continue
2022-11-29 18:52:20 +00:00
if " packages " not in dl :
2022-10-04 13:29:16 +00:00
logging . info (
" Skipping test on target because there are no packages %s ->??? on mongo version %s " ,
dl [ ' target ' ] , dl [ ' version ' ] )
continue
2022-10-14 23:36:37 +00:00
if ( dl [ " target " ] , dl [ " version " ] ) in DISABLED_TESTS :
2022-10-04 13:29:16 +00:00
continue
tests . append (
2022-10-14 23:36:37 +00:00
Test ( os_name = dl [ " target " ] , packages_urls = dl [ " packages " ] , version = dl [ " version " ] ) )
2022-10-04 13:29:16 +00:00
2022-12-06 18:53:16 +00:00
docker_client = docker . client . from_env ( )
docker_username = os . environ . get ( ' docker_username ' )
docker_password = os . environ . get ( ' docker_password ' )
if all ( ( docker_username , docker_password ) ) :
logging . info ( " Logging into docker.io " )
response = docker_client . login ( username = docker_username , password = docker_password )
logging . debug ( " Login response: %s " , response )
else :
2022-12-13 23:42:35 +00:00
logging . warning ( " Skipping docker login " )
2022-12-06 18:53:16 +00:00
2022-10-04 13:29:16 +00:00
report = Report ( results = [ ] , failures = 0 )
with futures . ThreadPoolExecutor ( ) as tpe :
2022-12-06 18:53:16 +00:00
test_futures = [ tpe . submit ( run_test , test , docker_client ) for test in tests ]
2022-10-04 13:29:16 +00:00
completed_tests = 0 # pylint: disable=invalid-name
for f in futures . as_completed ( test_futures ) :
completed_tests + = 1
test_result = f . result ( )
if test_result [ " exit_code " ] != 0 :
report [ " failures " ] + = 1
report [ " results " ] . append ( test_result )
logging . info ( " Completed %s / %s tests " , completed_tests , len ( test_futures ) )
with open ( " report.json " , " w " ) as fh :
json . dump ( report , fh )
if report [ " failures " ] == 0 :
logging . info ( " All %s tests passed :) " , len ( report [ ' results ' ] ) )
sys . exit ( 0 )
else :
success_count = sum ( [ 1 for test_result in report [ " results " ] if test_result [ " exit_code " ] == 0 ] )
logging . info ( " %s / %s tests passed " , success_count , len ( report [ ' results ' ] ) )
sys . exit ( 1 )