Skip to content

Commit

Permalink
Merge pull request #33 from sclorg/helm_chart_refactor
Browse files Browse the repository at this point in the history
Refactor Helm chart for s2i
  • Loading branch information
phracek authored Dec 8, 2023
2 parents 4c3be67 + 35e18fa commit ade13c9
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 37 deletions.
53 changes: 41 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,55 @@ from container_ci_suite.openshift import OpenShiftAPI

test_dir = os.path.abspath(os.path.dirname(__file__))

RAW_URL = "https://raw.githubusercontent.com/sclorg/{container}/master/{dir}/{filename}.json"
IS_RUBY = OpenShiftAPI.get_raw_url_for_json(container="s2i-ruby-container", dir="imagestreams", filename="ruby-rhel.json")
IS_POSTGRESQL = OpenShiftAPI.get_raw_url_for_json(container="postgresql-container", dir="imagestreams", filename="postgresql-rhel.json")
TEMPLATE_RAILS_POSTGRESQL = OpenShiftAPI.get_raw_url_for_json(container="s2i-ruby-container", dir="examples", filename="rails-postgresql-persistent.json")

class TestRubyEx:
def setup_method(self):
self.oc_api = OpenShiftAPI(namespace="test-ruby-ex")

def test_ruby_is(self):
self.oc_api.create(RAW_URL.format(container="s2i-ruby-container", dir="imagestreams", filename="ruby-rhel.json"))
self.oc_api.check_is_version("ruby:2.5-ubi8")

def test_postgresql_is(self):
self.oc_api.create(RAW_URL.format(container="postgresql-container", dir="imagestreams", filename="postgresql-rhel.json"))
self.oc_api.check_is_version("postgresql:10-el8")
# Reference https://github.com/sclorg/s2i-nodejs-container/blob/master/test/test-lib-nodejs.sh#L561 (ct_os_test_template_app_func)
def test_deployment_template(self):
self.oc_api.create(IS_RUBY)
self.oc_api.create(IS_POSTGRESQL)
assert self.oc_api.check_is_exists(is_name="ruby", version_to_check="2.5-ubi8")
assert self.oc_api.check_is_exists(is_name="postgresql", version_to_check="10-el8")
self.oc_api.process_file(TEMPLATE_RAILS_POSTGRESQL)
self.oc_api.new_app(image_name="ruby:2.5-ubi8", github_repo="https://github.com/sclorg/ruby-ex")
self.oc_api.is_pod_ready(pod_name="")
self.oc_api.ct_os_check_service_image_info()
#oc process -f rails-postgresql.json -p NAMESPACE=$(oc project -q) | oc create -f -

def test_deployment(self):
self.oc_api.create(RAW_URL.format(container="s2i-ruby-container", dir="imagestreams", filename="ruby-rhel.json"))
self.oc_api.create(RAW_URL.format(container="postgresql-container", dir="imagestreams", filename="postgresql-rhel.json"))
self.oc_api.process_file(RAW_URL.format(container="s2i-ruby-container", dir="examples", filename="rails-postgresql-persistent.json"))
# Reference https://github.com/sclorg/s2i-nodejs-container/blob/master/test/test-lib-nodejs.sh#L554 (ct_os_test_s2i_app_func)
# ct_os_deploy_s2i_image
def test_s2i_app_func(self):
self.oc_api.create(IS_RUBY)
self.oc_api.create(IS_POSTGRESQL)
assert self.oc_api.check_is_exists(is_name="ruby", version_to_check="2.5-ubi8")
assert self.oc_api.check_is_exists(is_name="postgresql", version_to_check="10-el8")
self.oc_api.process_file(TEMPLATE_RAILS_POSTGRESQL)
self.oc_api.new_app("ruby-ex-tests/ruby:2.5-ubi8~https://github.com/sclorg/ruby-ex")
self.oc_api.start-build() # service-name, --from-dir
self.oc_api.is_pod_ready()
self.oc_api.ct_os_check_service_image_info()
#oc process -f rails-postgresql.json -p NAMESPACE=$(oc project -q) | oc create -f -

# Reference https://github.com/sclorg/s2i-nodejs-container/blob/master/test/test-lib-nodejs.sh#L533 (ct_os_test_image_stream_quickstart)
# ct_os_deploy_s2i_image
def test_iamgestream_quicstart(self):
self.oc_api.create(IS_RUBY)
self.oc_api.create(IS_POSTGRESQL)
assert self.oc_api.check_is_exists(is_name="ruby", version_to_check="2.5-ubi8")
assert self.oc_api.check_is_exists(is_name="postgresql", version_to_check="10-el8")
self.oc_api.process_file(TEMPLATE_RAILS_POSTGRESQL)
self.oc_api.create()
self.oc_api.ct_os_test_template_app("ruby-ex-tests/ruby:2.5-ubi8~https://github.com/sclorg/ruby-ex")
self.oc_api.start-build() # service-name, --from-dir
self.oc_api.is_pod_ready()
self.oc_api.ct_os_check_service_image_info()
#oc process -f rails-postgresql.json -p NAMESPACE=$(oc project -q) | oc create -f -

```

## Run a test with Container-CI-Suite for Helm charts
Expand Down
73 changes: 54 additions & 19 deletions container_ci_suite/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(
self.create_prj = False
self.oc_api = OpenShiftAPI(namespace=self.namespace, create_prj=self.create_prj, delete_prj=self.delete_prj)
self.oc_api.create_project()
self.pod_json_data: dict = {}

@staticmethod
def run_helm_command(
Expand Down Expand Up @@ -110,10 +111,20 @@ def helm_package(self) -> bool:

def get_helm_json_output(self, command: str) -> Dict:
output = HelmChartsAPI.run_helm_command(cmd=command)
return json.loads(output)
print(output)
# Remove debug wrong output
new_output = []
for line in output.split('\n'):
print(line)
if line.startswith("W"):
continue
new_output.append(line)
# output = [x for x in output.split('\n') if not x.startswith("W")]
# print(output)
return json.loads(''.join(new_output))

def is_pod_finished(self, json_data: Dict, pod_suffix_name: str = "deploy") -> bool:
for item in json_data["items"]:
def is_pod_finished(self, pod_suffix_name: str = "deploy") -> bool:
for item in self.pod_json_data["items"]:
pod_name = item["metadata"]["name"]
status = item["status"]["phase"]
print(f"is_pod_finished for {pod_suffix_name}: {pod_name} and status: {status}.")
Expand All @@ -124,31 +135,45 @@ def is_pod_finished(self, json_data: Dict, pod_suffix_name: str = "deploy") -> b
return True
return False

def is_build_pod_present(self, json_data) -> bool:
for item in json_data["items"]:
def is_build_pod_present(self) -> bool:
for item in self.pod_json_data["items"]:
pod_name = item["metadata"]["name"]
print(f"is_build_pod_present: {pod_name}.")
if "build" in pod_name:
return True
return False

def is_pod_running(self):
def is_s2i_pod_running(self) -> bool:
build_pod_finished = False
for count in range(60):
print(f"Cycle for checking pod status: {count}.")
json_data = self.oc_api.oc_get_pod_status()
output = OpenShiftAPI.run_oc_command("status --suggest", json_output=False)
print(output)
if len(json_data["items"]) == 0:
print(f"Cycle for checking s2i build pod status: {count}.")
self.pod_json_data = self.oc_api.oc_get_pod_status()
if len(self.pod_json_data["items"]) == 0:
time.sleep(3)
continue
if self.is_build_pod_present(json_data) and \
not self.is_pod_finished(json_data=json_data, pod_suffix_name="build"):
if not self.is_build_pod_present():
print("Build pod is not present.")
time.sleep(3)
continue
if not self.is_pod_finished(json_data=json_data):
if not self.is_pod_finished(pod_suffix_name="build"):
print("Build pod is not yet finished")
time.sleep(3)
continue
for item in json_data["items"]:
if not self.is_pod_running():
print("Running pod is not yet finished")
time.sleep(3)
continue
build_pod_finished = True
return build_pod_finished

def is_pod_running(self):
for count in range(60):
print(f"Cycle for checking pod status: {count}.")
output = OpenShiftAPI.run_oc_command("status --suggest", json_output=False)
# if not self.is_pod_finished(json_data=json_data):
# time.sleep(3
# continue
for item in self.pod_json_data["items"]:
pod_name = item["metadata"]["name"]
status = item["status"]["phase"]
print(f"Pod Name: {pod_name} and status: {status}.")
Expand All @@ -161,7 +186,7 @@ def is_pod_running(self):
)
print(output)
# Wait couple seconds for sure
time.sleep(10)
time.sleep(3)
return True
time.sleep(3)

Expand Down Expand Up @@ -296,12 +321,22 @@ def check_imagestreams(self, version: str, registry: str) -> bool:
break
return tag_found

def test_helm_curl_output(self, route_name: str, expected_str=str, schema: str = "http://") -> bool:
def test_helm_curl_output(
self, route_name: str, expected_str: str, port: int = None, schema: str = "http://"
) -> bool:
host_name = self.get_route_name(route_name=route_name)
print(f"Route name is: {host_name}")
print(f"test_helm_curl_output: : Route name is: {host_name}")
if not host_name:
return False
resp = requests.get(f"{schema}{host_name}")
url_address = f"{schema}{host_name}"
if port:
url_address = f"{url_address}:{port}"
resp = requests.get(url_address, verify=False)
resp.raise_for_status()
if resp.status_code != 200:
print(f"test_helm_curl_output: {resp.text}, {resp.status_code}")
return False
print(f"test_helm_curl_output: {resp.text}")
if expected_str not in resp.text:
return False
return True
108 changes: 103 additions & 5 deletions container_ci_suite/openshift.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
# SOFTWARE.
import json
import logging
import time


from subprocess import CalledProcessError
from typing import Dict


Expand Down Expand Up @@ -76,25 +77,56 @@ def is_project_exits(self) -> bool:
return True
return False

@staticmethod
def get_raw_url_for_json(container: str, dir: str, filename: str) -> str:
RAW_SCL_JSON_URL: str = "https://raw.githubusercontent.com/sclorg/{container}/master/{dir}/{filename}"
return RAW_SCL_JSON_URL.format(container=container, dir=dir, filename=filename)

def oc_get_pod_status(self) -> Dict:
output = OpenShiftAPI.run_oc_command("get all", json_output=False)
# print(f"oc get all: {output}")
output = OpenShiftAPI.run_oc_command("get pods", json_output=True, namespace=self.namespace)
# print(f" oc get pods: {output}")
return json.loads(output)

def create(self, path):
def import_is(self, path: str, name: str):
try:
json_output = self.oc_get_is(name=name)
if json_output["kind"] == "ImageStream" and json_output["metadata"]["name"] == name:
return json_output
except CalledProcessError:
pass
output = OpenShiftAPI.run_oc_command(f"create -f {path}", namespace=self.namespace)
# Let's wait 3 seconds till imagestreams are not uploaded
time.sleep(3)
return json.loads(output)

def process_file(self, path):
def process_file(self, path: str):
output = OpenShiftAPI.run_oc_command(f"process -f {path}", namespace=self.namespace)
return json.loads(output)
json_output = json.loads(output)
print(json_output)
return json_output

def oc_get_is(self, name: str):
output = OpenShiftAPI.run_oc_command(f"get is/{name}", namespace=self.namespace)
return json.loads(output)

def start_build(self, name: str):
output = OpenShiftAPI.run_oc_command(f"start-build {name}", json_output=False)
return output

def is_pod_finished(self, json_data: Dict, pod_suffix_name: str = "deploy") -> bool:
for item in json_data["items"]:
pod_name = item["metadata"]["name"]
status = item["status"]["phase"]
print(f"is_pod_finished for {pod_suffix_name}: {pod_name} and status: {status}.")
if pod_suffix_name in pod_name and status != "Succeeded":
continue
if pod_suffix_name in pod_name and status == "Succeeded":
print(f"Pod with suffix {pod_suffix_name} is finished")
return True
return False

def check_is_exists(self, is_name, version_to_check: str) -> bool:
"""
Function checks if it exists in OpenShift 4 environment
Expand All @@ -107,13 +139,79 @@ def check_is_exists(self, is_name, version_to_check: str) -> bool:
return False
tag_found: bool = False
for tag in json_output["spec"]["tags"]:
print(tag)
if "name" not in tag:
continue
if version_to_check not in tag["name"]:
continue
tag_found = True
return tag_found

def create_new_app_with_template(self, name: str, template_json: str, template_args: Dict = None):
"""
Function creates a new application in OpenShift 4 environment
:param name: str - Template name
:param template_json: str - Template path to file
:param template_args: Dict - Arguments that will be passed to oc new-app
:return json toutput
"""

# Let's wait couple seconds till is fully loaded
time.sleep(3)
args = [""]
if template_args:
args = [f"-p {key}={val}" for key, val in template_args]
print(args)
output = OpenShiftAPI.run_oc_command(
f"new-app {template_json} --name {name} -p NAMESPACE={self.namespace} {args}",
json_output=False
)
print(output)
return output

def get_service_ip(self, service_name: str) -> dict:
output = OpenShiftAPI.run_oc_command(f"get svc/{service_name}")
return output

def get_route_url(self, routes_name: str) -> str:
output = OpenShiftAPI.run_oc_command(f"get routes/{routes_name}")
json_output = json.loads(output)
if not json_output["spec"]["host"]:
return None
if routes_name != json_output["specs"]["to"]["name"]:
return None
return json_output["spec"]["host"]

def is_pod_ready(self) -> bool:
"""
Function checks if pod with specific name is really ready
"""

for count in range(60):
print(f"Cycle for checking pod status: {count}.")
json_data = self.oc_get_pod_status()
if len(json_data["items"]) == 0:
time.sleep(3)
continue
if not self.is_pod_finished(json_data=json_data):
time.sleep(3)
continue
for item in json_data["items"]:
pod_name = item["metadata"]["name"]
status = item["status"]["phase"]
print(f"Pod Name: {pod_name} and status: {status}.")
if "deploy" in pod_name:
continue
if item["status"]["phase"] == "Running":
print(f"Pod with name {pod_name} is running {status}.")
output = OpenShiftAPI.run_oc_command(
f"logs {pod_name}", namespace=self.namespace, json_output=False
)
print(output)
# Wait couple seconds for sure
time.sleep(10)
return True
time.sleep(3)
return False

def new_app(self):
pass
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def get_requirements():
description='A python3 container CI tool for testing images.',
long_description=long_description,
long_description_content_type='text/markdown',
version="0.0.3",
version="0.0.4",
keywords='tool,containers,images,tests',
packages=find_packages(exclude=["tests"]),
url="https://github.com/phracek/container-ci-suite",
Expand Down
45 changes: 45 additions & 0 deletions tests/data/oc_get_routes_cakephp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"apiVersion": "route.openshift.io/v1",
"kind": "Route",
"metadata": {
"annotations": {
"openshift.io/generated-by": "OpenShiftNewApp",
"openshift.io/host.generated": "true"
},
"creationTimestamp": "2023-11-06T16:15:09Z",
"labels": {
"app": "cakephp-example",
"template": "cakephp-example"
},
"name": "cakephp-example",
"namespace": "cake-php-ex-tests",
"resourceVersion": "4074673",
"uid": "c84f663b-90ef-46fc-b667-fcab3868f6d2"
},
"spec": {
"host": "cakephp-example-cake-php-ex-tests.apps.core-serv-ocp.hosted.psi.rdu2.redhat.com",
"to": {
"kind": "Service",
"name": "cakephp-example",
"weight": 100
},
"wildcardPolicy": "None"
},
"status": {
"ingress": [
{
"conditions": [
{
"lastTransitionTime": "2023-11-06T16:15:29Z",
"status": "True",
"type": "Admitted"
}
],
"host": "cakephp-example-cake-php-ex-tests.apps.core-serv-ocp.hosted.psi.rdu2.redhat.com",
"routerCanonicalHostname": "router-default.apps.core-serv-ocp.hosted.psi.rdu2.redhat.com",
"routerName": "default",
"wildcardPolicy": "None"
}
]
}
}

0 comments on commit ade13c9

Please sign in to comment.