Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#34: Added validation for results of tests and security_scan #36

Merged
merged 11 commits into from
Jun 14, 2023
12 changes: 8 additions & 4 deletions exasol_script_languages_container_ci/lib/ci_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@
from exasol_script_languages_container_tool.lib.api import build
from exasol_script_languages_container_tool.lib.tasks.test.test_container_content import build_test_container_content

from exasol_script_languages_container_ci.lib.common import print_docker_images
from exasol_script_languages_container_ci.lib.ci_step_output_printer import CIStepOutputPrinterProtocol, \
CIStepOutputPrinter


class CIBuild:

def __init__(self, printer: CIStepOutputPrinterProtocol = CIStepOutputPrinter(logging.info)):
self._printer = printer
tkilias marked this conversation as resolved.
Show resolved Hide resolved

def build(self,
flavor_path: Tuple[str, ...],
rebuild: bool,
build_docker_repository: Optional[str],
commit_sha: str,
docker_user: str,
docker_password: str,
test_container_folder: str) -> Tuple[Dict[str, Dict[str, ImageInfo]], ImageInfo]:
test_container_folder: str):
"""
Build the script-language container for given flavor. And also build the test container
"""
Expand Down Expand Up @@ -47,5 +52,4 @@ def build(self,
source_docker_repository_name=build_docker_repository,
source_docker_tag_prefix=commit_sha
)
print_docker_images(logging.info)
return slc_image_infos, test_container_image_infos
self._printer.print_exasol_docker_images()
12 changes: 8 additions & 4 deletions exasol_script_languages_container_ci/lib/ci_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
from exasol_script_languages_container_tool.lib.api import export
from exasol_script_languages_container_tool.lib.tasks.export.export_containers import ExportContainerResult

from exasol_script_languages_container_ci.lib.common import print_docker_images
from exasol_script_languages_container_ci.lib.ci_step_output_printer import CIStepOutputPrinterProtocol, \
CIStepOutputPrinter


class CIExport:

def __init__(self, printer: CIStepOutputPrinterProtocol = CIStepOutputPrinter(logging.info)):
self._printer = printer

def export(self,
flavor_path: Tuple[str, ...],
export_path: str) -> ExportContainerResult:
export_path: str):
"""
Export the flavor as tar.gz file
"""
Expand All @@ -19,5 +24,4 @@ def export(self,
export_result = export(flavor_path=flavor_path,
export_path=export_path,
workers=7)
print_docker_images(logging.info)
return export_result
self._printer.print_exasol_docker_images()
10 changes: 7 additions & 3 deletions exasol_script_languages_container_ci/lib/ci_push.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import logging
from typing import Tuple

import click
from exasol_script_languages_container_tool.lib.api.push import push

from exasol_script_languages_container_ci.lib.common import print_docker_images
from exasol_script_languages_container_ci.lib.ci_step_output_printer import CIStepOutputPrinterProtocol, \
CIStepOutputPrinter


class CIPush:

def __init__(self, printer: CIStepOutputPrinterProtocol = CIStepOutputPrinter(logging.info)):
self._printer = printer

def push(self,
flavor_path: Tuple[str, ...],
target_docker_repository: str,
Expand All @@ -27,4 +31,4 @@ def push(self,
target_docker_tag_prefix=target_docker_tag_prefix,
target_docker_username=docker_user,
target_docker_password=docker_password)
print_docker_images(logging.info)
self._printer.print_exasol_docker_images()
21 changes: 12 additions & 9 deletions exasol_script_languages_container_ci/lib/ci_security_scan.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import logging
from pathlib import Path
from typing import Tuple
from typing import Tuple, Callable

from exasol_script_languages_container_tool.lib.api import security_scan
from exasol_script_languages_container_tool.lib.tasks.security_scan.security_scan import AllScanResult

import exasol_script_languages_container_ci.lib.common
from exasol_script_languages_container_ci.lib.ci_step_output_printer import CIStepOutputPrinterProtocol, \
CIStepOutputPrinter

tkilias marked this conversation as resolved.
Show resolved Hide resolved

class CISecurityScan:

def run_security_scan(self, flavor_path: Tuple[str, ...]) -> AllScanResult:
def __init__(self, printer: CIStepOutputPrinterProtocol = CIStepOutputPrinter(logging.info)):
self._printer = printer

def run_security_scan(self,
flavor_path: Tuple[str, ...]):
"""
Run security scan and print result
"""

logging.info(f"Running command 'security_scan' with parameters {locals()}")
security_scan_result = security_scan(flavor_path=flavor_path, workers=7)
exasol_script_languages_container_ci.lib.common.print_docker_images(logging.info)
logging.info("============= SECURITY REPORT ===========")
# Important: Call print_file over the global module name, otherwise the patch in the unit-test does not work!
exasol_script_languages_container_ci.lib.common.print_file(
Path() / ".build_output" / "security_scan" / "security_report", logging.info)
return security_scan_result
self._printer.print_file(Path(security_scan_result.report_path))
self._printer.print_exasol_docker_images()
if not security_scan_result.scans_are_ok:
raise AssertionError("Some security scans not successful.")
51 changes: 51 additions & 0 deletions exasol_script_languages_container_ci/lib/ci_step_output_printer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from inspect import cleandoc
from pathlib import Path
from typing import Callable, Protocol

import docker


class CIStepOutputPrinterProtocol(Protocol):

def print_exasol_docker_images(self):
tkilias marked this conversation as resolved.
Show resolved Hide resolved
raise NotImplementedError()

def print_file(self, filename: Path):
raise NotImplementedError()


def _get_exasol_docker_images():
docker_client = docker.from_env()
try:
exa_images = [str(img) for img in docker_client.images.list() if "exasol" in str(img)]
return exa_images
finally:
docker_client.close()
return []


class CIStepOutputPrinter(CIStepOutputPrinterProtocol):

def __init__(self, writer: Callable[[str], None]):
self._writer = writer

def print_exasol_docker_images(self):
"""
Prints all docker images with "exasol" in it's name to stdout.
:return: None
"""

self._writer(cleandoc("""
{seperator}
Printing docker images
{seperator}
{images}""").format(
seperator=20 * "=", images="\n".join(_get_exasol_docker_images())
))

def print_file(self, filename: Path):
"""
Print the file's content to the writer.
"""
with open(filename, "r") as f:
self._writer(f.read())
104 changes: 84 additions & 20 deletions exasol_script_languages_container_ci/lib/ci_test.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,102 @@
import logging
from typing import Tuple
from typing import Tuple, Protocol

import click
from exasol_script_languages_container_tool.lib.api.run_db_tests import run_db_test
from exasol_script_languages_container_tool.lib.tasks.test.test_container import AllTestsResult

from exasol_script_languages_container_ci.lib.common import print_docker_images
from exasol_script_languages_container_ci.lib.ci_step_output_printer import CIStepOutputPrinterProtocol, \
CIStepOutputPrinter


class DBTestRunnerProtocol(Protocol):
def run(self,
flavor_path: Tuple[str, ...],
release_goal: Tuple[str, ...],
test_folder: Tuple[str, ...],
test_container_folder: str,
workers: int,
docker_username: str,
docker_password: str) -> AllTestsResult:
raise NotImplementedError()

from exasol_script_languages_container_tool.lib.tasks.test.test_container import AllTestsResult

class DBTestRunner(DBTestRunnerProtocol):
def run(self,
flavor_path: Tuple[str, ...],
release_goal: Tuple[str, ...],
test_folder: Tuple[str, ...],
test_container_folder: str,
workers: int,
docker_username: str,
docker_password: str) -> AllTestsResult:
return run_db_test(
flavor_path=flavor_path,
release_goal=release_goal,
test_folder=test_folder,
test_container_folder=test_container_folder,
workers=workers,
source_docker_username=docker_username,
source_docker_password=docker_password
)


class CIExecuteTest:
tkilias marked this conversation as resolved.
Show resolved Hide resolved

def __init__(self,
db_test_runner: DBTestRunnerProtocol = DBTestRunner(),
printer: CIStepOutputPrinterProtocol = CIStepOutputPrinter(logging.info)):
self._db_test_runner = db_test_runner
self._printer = printer

def execute_tests(self,
flavor_path: Tuple[str, ...],
docker_user: str,
docker_password: str,
test_container_folder: str) -> Tuple[AllTestsResult, AllTestsResult]:
test_container_folder: str):
"""
Run db tests
"""
db_tests_are_ok = self.run_db_tests(flavor_path=flavor_path,
docker_user=docker_user,
docker_password=docker_password,
test_container_folder=test_container_folder)
linker_namespace_tests_are_ok = self.run_linker_namespace_tests(flavor_path=flavor_path,
tkilias marked this conversation as resolved.
Show resolved Hide resolved
docker_user=docker_user,
docker_password=docker_password,
test_container_folder=test_container_folder)
self._printer.print_exasol_docker_images()
tests_are_ok = db_tests_are_ok and linker_namespace_tests_are_ok
if not tests_are_ok:
raise AssertionError("Not all tests are ok!")

def run_db_tests(self, flavor_path: Tuple[str, ...],
docker_user: str,
docker_password: str,
test_container_folder: str) -> bool:
logging.info(f"Running command 'run_db_test' for flavor-path {flavor_path}")
run_db_test_flavor_result = \
run_db_test(flavor_path=flavor_path,
workers=7,
source_docker_username=docker_user,
source_docker_password=docker_password,
test_container_folder=test_container_folder)
db_test_result = \
self._db_test_runner.run(flavor_path=flavor_path,
test_folder=tuple(),
release_goal=('release',),
workers=7,
docker_username=docker_user,
docker_password=docker_password,
test_container_folder=test_container_folder)
self._printer.print_file(db_test_result.command_line_output_path)
return db_test_result.tests_are_ok

def run_linker_namespace_tests(self,
flavor_path: Tuple[str, ...],
docker_user: str,
docker_password: str,
test_container_folder: str) -> bool:
logging.info(f"Running command 'run_db_test' for linker_namespace_sanity for flavor-path {flavor_path}")
run_db_test_linkernamespace = \
run_db_test(flavor_path=flavor_path, workers=7,
test_folder=("test/linker_namespace_sanity",),
release_goal=("base_test_build_run",),
source_docker_username=docker_user,
source_docker_password=docker_password,
test_container_folder=test_container_folder)
print_docker_images(logging.info)
return run_db_test_flavor_result, run_db_test_linkernamespace
linker_namespace_test_result = \
self._db_test_runner.run(flavor_path=flavor_path, workers=7,
test_folder=("test/linker_namespace_sanity",),
release_goal=("base_test_build_run",),
docker_username=docker_user,
docker_password=docker_password,
test_container_folder=test_container_folder)
self._printer.print_file(linker_namespace_test_result.command_line_output_path)
return linker_namespace_test_result.tests_are_ok
33 changes: 0 additions & 33 deletions exasol_script_languages_container_ci/lib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,6 @@
import docker


def _get_docker_images():
docker_client = docker.from_env()
exa_images = []
try:
exa_images = [str(img) for img in docker_client.images.list() if "exasol" in str(img)]
finally:
docker_client.close()
return exa_images


def print_docker_images(writer: Callable[[str], None]):
"""
Prints all docker images whith "exa" in it's name to stdout.
:return: None
"""

writer(cleandoc("""
{seperator}
Printing docker images
{seperator}
{images}""").format(
seperator=20 * "=", images="\n".join(_get_docker_images())
))


def print_file(filename: Path, writer: Callable[[str], None]):
"""
Opens file readonly, reads it content and prints to writer.
"""
with open(filename, "r") as f:
writer(f.read())


@contextmanager
def get_config(config_file: str):
"""
Expand Down
11 changes: 11 additions & 0 deletions test/asserts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from contextlib import contextmanager

import pytest


@contextmanager
def not_raises(exception):
try:
yield
except exception:
raise pytest.fail("DID RAISE {0}".format(exception))
Loading