Add proxy cache python test scipts and upgrade containerd

Containerd in e2e image was using native one in ubuntu, it should be updated to the latest release.
And add proxy cache py-tests including pull image/manifest list by docker and ctr CLI.

Signed-off-by: danfengliu <danfengl@vmware.com>
This commit is contained in:
danfengliu 2020-10-22 09:55:38 +08:00
parent b388078a3e
commit ab3e24a2e3
7 changed files with 166 additions and 5 deletions

View File

@ -101,3 +101,17 @@ class Artifact(base.Base, object):
return { return {
0: False, 0: False,
}.get(len(artifact), True) }.get(len(artifact), True)
def waiting_for_reference_exist(self, project_name, repo_name, reference, ignore_not_found = False, period = 60, loop_count = 8, **kwargs):
_loop_count = loop_count
while True:
print("Waiting for reference {} round...".format(_loop_count))
_loop_count = _loop_count - 1
if (_loop_count == 0):
break
artifact = self.get_reference_info(project_name, repo_name, reference, ignore_not_found=ignore_not_found, **kwargs)
print("Returned artifact by get reference info:", artifact)
if artifact and artifact !=[]:
return artifact
time.sleep(period)
raise Exception("Referencet is not exist {} {} {}.".format(project_name, repo_name, reference))

View File

@ -5,7 +5,7 @@ import json
import docker_api import docker_api
def ctr_images_pull(username, password, oci): def ctr_images_pull(username, password, oci):
command = ["sudo", "ctr", "images", "pull", "-u", username+":"+password, oci] command = ["sudo", "ctr", "images", "pull","--snapshotter", "native", "-u", username+":"+password, oci]
print("Command: ", command) print("Command: ", command)
ret = base.run_command(command) ret = base.run_command(command)
print("Command return: ", ret) print("Command return: ", ret)

View File

@ -30,15 +30,18 @@ class Project(base.Base):
kwargs["credential"] = base.Credential('basic_auth', username, password) kwargs["credential"] = base.Credential('basic_auth', username, password)
super(Project, self).__init__(**kwargs) super(Project, self).__init__(**kwargs)
def create_project(self, name=None, metadata=None, expect_status_code = 201, expect_response_body = None, **kwargs): def create_project(self, name=None, registry_id=None, metadata=None, expect_status_code = 201, expect_response_body = None, **kwargs):
if name is None: if name is None:
name = base._random_name("project") name = base._random_name("project")
if metadata is None: if metadata is None:
metadata = {} metadata = {}
if registry_id is None:
registry_id = registry_id
client = self._get_client(**kwargs) client = self._get_client(**kwargs)
try: try:
_, status_code, header = client.create_project_with_http_info(v2_swagger_client.ProjectReq(project_name=name, metadata=metadata)) _, status_code, header = client.create_project_with_http_info(v2_swagger_client.ProjectReq(project_name=name, registry_id = registry_id, metadata=metadata))
except ApiException as e: except ApiException as e:
base._assert_status_code(expect_status_code, e.status) base._assert_status_code(expect_status_code, e.status)
if expect_response_body is not None: if expect_response_body is not None:
@ -46,6 +49,7 @@ class Project(base.Base):
return return
base._assert_status_code(expect_status_code, status_code) base._assert_status_code(expect_status_code, status_code)
base._assert_status_code(201, status_code) base._assert_status_code(201, status_code)
print("==========header:", header)
return base._get_id_from_header(header), name return base._get_id_from_header(header), name
def get_projects(self, params, **kwargs): def get_projects(self, params, **kwargs):

View File

@ -14,7 +14,7 @@ class Registry(base.Base):
registry = swagger_client.Registry(name=name, url=url, registry = swagger_client.Registry(name=name, url=url,
description= description, type=registry_type, description= description, type=registry_type,
insecure=insecure, credential=registryCredential) insecure=insecure, credential=registryCredential)
print("registry:", registry)
_, status_code, header = client.registries_post_with_http_info(registry) _, status_code, header = client.registries_post_with_http_info(registry)
base._assert_status_code(expect_status_code, status_code) base._assert_status_code(expect_status_code, status_code)
return base._get_id_from_header(header), _ return base._get_id_from_header(header), _

View File

@ -0,0 +1,139 @@
from __future__ import absolute_import
import unittest
import urllib
import sys
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.base import _random_name
from library.base import _assert_status_code
from library.project import Project
from library.user import User
from library.repository import Repository
from library.repository import push_image_to_project
from library.registry import Registry
from library.repository import pull_harbor_image
from library.artifact import Artifact
import library.containerd
class TestProxyCache(unittest.TestCase):
@classmethod
def setUpClass(self):
self.url = ADMIN_CLIENT["endpoint"]
self.user_password = "Aa123456"
self.project= Project()
self.user= User()
self.repo= Repository()
self.registry = Registry()
self.artifact = Artifact()
@classmethod
def tearDownClass(self):
print("Case completed")
def do_validate(self, registry_type):
"""
Test case:
Proxy Cache Image From Harbor
Test step and expected result:
1. Create a new registry;
2. Create a new project;
3. Add a new user as a member of project;
4. Pull image from this project by docker CLI;
5. Pull image from this project by ctr CLI;
6. Pull manifest index from this project by docker CLI;
7. Pull manifest from this project by ctr CLI;
8. Image pulled by docker CLI should be cached;
9. Image pulled by ctr CLI should be cached;
10. Manifest index pulled by docker CLI should be cached;
11. Manifest index pulled by ctr CLI should be cached;
Tear down:
1. Delete project(PA);
2. Delete user(UA).
"""
user_id, user_name = self.user.create_user(user_password = self.user_password, **ADMIN_CLIENT)
USER_CLIENT=dict(with_signature = True, endpoint = self.url, username = user_name, password = self.user_password)
image_for_docker = dict(image = "for_proxy", tag = "1.0")
image_for_ctr = dict(image = "redis", tag = "latest")
index_for_docker = dict(image = "index081597864867", tag = "index_tag081597864867")
access_key = ""
access_secret = ""
#1. Create a new registry;
if registry_type == "docker-hub":
user_namespace = "danfengliu"
access_key = user_namespace
access_secret = "Aa123456"
registry = "https://hub.docker.com"
# Memo: ctr will not send image pull request if manifest list already exist, so we pull different manifest list for different registry;
index_for_ctr = dict(image = "alpine", tag = "3.12.0")
else:
user_namespace = "nightly"
registry = "https://cicd.harbor.vmwarecna.net"
index_for_ctr = dict(image = "busybox", tag = "1.32.0")
registry_id, _ = self.registry.create_registry(registry, name=_random_name(registry_type), registry_type=registry_type, access_key = access_key, access_secret = access_secret, insecure=False, **ADMIN_CLIENT)
print("registry_id:", registry_id)
#2. Create a new project;
project_id, project_name = self.project.create_project(registry_id = registry_id, metadata = {"public": "false"}, **ADMIN_CLIENT)
print("project_id:",project_id)
print("project_name:",project_name)
#3. Add a new user as a member of project;
self.project.add_project_members(project_id, user_id=user_id, **ADMIN_CLIENT)
#4. Pull image from this project by docker CLI;
pull_harbor_image(harbor_server, USER_CLIENT["username"], USER_CLIENT["password"], project_name + "/" + user_namespace + "/" + image_for_docker["image"], image_for_docker["tag"])
#5. Pull image from this project by ctr CLI;
oci_ref = harbor_server + "/" + project_name + "/" + user_namespace + "/" + image_for_ctr["image"] + ":" + image_for_ctr["tag"]
library.containerd.ctr_images_pull(user_name, self.user_password, oci_ref)
library.containerd.ctr_images_list(oci_ref = oci_ref)
#6. Pull manifest index from this project by docker CLI;
index_repo_name = user_namespace + "/" + index_for_docker["image"]
pull_harbor_image(harbor_server, user_name, self.user_password, project_name + "/" + index_repo_name, index_for_docker["tag"])
#7. Pull manifest from this project by ctr CLI;
index_repo_name_for_ctr = user_namespace + "/" + index_for_ctr["image"]
oci_ref = harbor_server + "/" + project_name + "/" + index_repo_name_for_ctr + ":" + index_for_ctr["tag"]
library.containerd.ctr_images_pull(user_name, self.user_password, oci_ref)
library.containerd.ctr_images_list(oci_ref = oci_ref)
#8. Image pulled by docker CLI should be cached;
self.artifact.waiting_for_reference_exist(project_name, urllib.parse.quote(user_namespace + "/" + image_for_docker["image"],'utf-8'), image_for_docker["tag"], **USER_CLIENT)
#9. Image pulled by ctr CLI should be cached;
self.artifact.waiting_for_reference_exist(project_name, urllib.parse.quote(user_namespace + "/" + image_for_ctr["image"],'utf-8'), image_for_ctr["tag"], **USER_CLIENT)
#10. Manifest index pulled by docker CLI should be cached;
ret_index_by_d = self.artifact.waiting_for_reference_exist(project_name, urllib.parse.quote(index_repo_name,'utf-8'), index_for_docker["tag"], **USER_CLIENT)
print("Index's reference by docker CLI:",ret_index_by_d[0].references)
self.assertTrue(len(ret_index_by_d[0].references) == 1)
#11. Manifest index pulled by ctr CLI should be cached;
ret_index_by_c = self.artifact.waiting_for_reference_exist(project_name, urllib.parse.quote(index_repo_name_for_ctr,'utf-8'), index_for_ctr["tag"], **USER_CLIENT)
print("Index's reference by ctr CLI:",ret_index_by_c[0].references)
self.assertTrue(len(ret_index_by_c[0].references) == 1)
def test_proxy_cache_from_harbor(self):
self.do_validate("harbor")
def test_proxy_cache_from_dockerhub(self):
self.do_validate("docker-hub")
def suite():
suite = unittest.TestSuite(unittest.makeSuite(TestProxyCache))
return suite
if __name__ == '__main__':
result = unittest.TextTestRunner(sys.stdout, verbosity=2, failfast=True).run(TestProxyCache.suite())
if not result.wasSuccessful():
raise Exception(r"Proxy cache test failed: ".format(result))

View File

@ -237,7 +237,7 @@ Retry Keyword N Times When Error
Log To Console Trying ${keyword} elements @{elements} ${n} times ... Log To Console Trying ${keyword} elements @{elements} ${n} times ...
${out} Run Keyword And Ignore Error ${keyword} @{elements} ${out} Run Keyword And Ignore Error ${keyword} @{elements}
Log To Console Return value is ${out} and ${out[0]} Log To Console Return value is ${out} and ${out[0]}
Capture Page Screenshot record.png Capture Page Screenshot
Run Keyword If '${keyword}'=='Make Swagger Client' Exit For Loop If '${out[0]}'=='PASS' and '${out[1]}'=='0' Run Keyword If '${keyword}'=='Make Swagger Client' Exit For Loop If '${out[0]}'=='PASS' and '${out[1]}'=='0'
... ELSE Exit For Loop If '${out[0]}'=='PASS' ... ELSE Exit For Loop If '${out[0]}'=='PASS'
Sleep 10 Sleep 10

View File

@ -144,3 +144,7 @@ Test Case - Push Chart File To Chart Repository By Helm V2 With Robot Account
Test Case - Replication From Dockerhub Test Case - Replication From Dockerhub
[Tags] replic_dockerhub [Tags] replic_dockerhub
Harbor API Test ./tests/apitests/python/test_replication_from_dockerhub.py Harbor API Test ./tests/apitests/python/test_replication_from_dockerhub.py
Test Case - Proxy Cache
[Tags] proxy_cache
Harbor API Test ./tests/apitests/python/test_proxy_cache.py