Merge pull request #11686 from danfengliu/add-ctr-client-for-pull-artifacts

Add ctr command for pulling oci
This commit is contained in:
danfengliu 2020-04-28 15:42:11 +08:00 committed by GitHub
commit 97283cef79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 186 additions and 20 deletions

View File

@ -43,6 +43,7 @@ def cnab_push_bundle(bundle_file, target):
raise Exception(r"Fail to get sha256 in returned data: {}".format(ret)) raise Exception(r"Fail to get sha256 in returned data: {}".format(ret))
def push_cnab_bundle(harbor_server, user, password, service_image, invocation_image, target, auto_update_bundle = True): def push_cnab_bundle(harbor_server, user, password, service_image, invocation_image, target, auto_update_bundle = True):
docker_api.docker_info_display()
docker_api.docker_login_cmd(harbor_server, user, password, enable_manifest = False) docker_api.docker_login_cmd(harbor_server, user, password, enable_manifest = False)
bundle_file = load_bundle(service_image, invocation_image) bundle_file = load_bundle(service_image, invocation_image)
fixed_bundle_file = cnab_fixup_bundle(bundle_file, target, auto_update_bundle = auto_update_bundle) fixed_bundle_file = cnab_fixup_bundle(bundle_file, target, auto_update_bundle = auto_update_bundle)

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
import base
import json
import docker_api
def ctr_images_pull(username, password, oci):
command = ["sudo", "ctr", "images", "pull", "-u", username+":"+password, oci]
print "Command: ", command
ret = base.run_command(command)
print "Command return: ", ret
def ctr_images_list(oci_ref = None):
command = ["sudo", "ctr", "images", "list", "--q"]
print "Command: ", command
ret = base.run_command(command)
print "Command return: ", ret
if oci_ref is not None and oci_ref not in ret.split("\n"):
raise Exception(r" Get OCI ref failed, expected ref is [{}], but return ref list is [{}]".format (ret))

View File

@ -11,6 +11,12 @@ except ImportError:
pip.main(['install', 'docker']) pip.main(['install', 'docker'])
import docker import docker
def docker_info_display():
command = ["docker", "info", "-f", "'{{.OSType}}/{{.Architecture}}'"]
print "Docker Info: ", command
ret = base.run_command(command)
print "Command return: ", ret
def docker_login_cmd(harbor_host, user, password, enable_manifest = True): def docker_login_cmd(harbor_host, user, password, enable_manifest = True):
command = ["sudo", "docker", "login", harbor_host, "-u", user, "-p", password] command = ["sudo", "docker", "login", harbor_host, "-u", user, "-p", password]
print "Docker Login Command: ", command print "Docker Login Command: ", command

View File

@ -15,7 +15,7 @@ def pull_harbor_image(registry, username, password, image, tag, expected_login_e
ret = _docker_api.docker_image_pull(r'{}/{}'.format(registry, image), tag = tag, expected_error_message = expected_error_message) ret = _docker_api.docker_image_pull(r'{}/{}'.format(registry, image), tag = tag, expected_error_message = expected_error_message)
print ret print ret
def push_image_to_project(project_name, registry, username, password, image, tag, expected_login_error_message = None, expected_error_message = None): def push_image_to_project(project_name, registry, username, password, image, tag, expected_login_error_message = None, expected_error_message = None, profix_for_image = None):
_docker_api = DockerAPI() _docker_api = DockerAPI()
_docker_api.docker_login(registry, username, password, expected_error_message = expected_login_error_message) _docker_api.docker_login(registry, username, password, expected_error_message = expected_login_error_message)
time.sleep(2) time.sleep(2)
@ -24,7 +24,10 @@ def push_image_to_project(project_name, registry, username, password, image, tag
_docker_api.docker_image_pull(image, tag = tag) _docker_api.docker_image_pull(image, tag = tag)
time.sleep(2) time.sleep(2)
if profix_for_image == None:
new_harbor_registry, new_tag = _docker_api.docker_image_tag(r'{}:{}'.format(image, tag), r'{}/{}/{}'.format(registry, project_name, image)) new_harbor_registry, new_tag = _docker_api.docker_image_tag(r'{}:{}'.format(image, tag), r'{}/{}/{}'.format(registry, project_name, image))
else:
new_harbor_registry, new_tag = _docker_api.docker_image_tag(r'{}:{}'.format(image, tag), r'{}/{}/{}/{}'.format(registry, project_name, profix_for_image, image))
time.sleep(2) time.sleep(2)
_docker_api.docker_image_push(new_harbor_registry, new_tag, expected_error_message = expected_error_message) _docker_api.docker_image_push(new_harbor_registry, new_tag, expected_error_message = expected_error_message)

View File

@ -134,6 +134,7 @@ class Retention(base.Base):
{ {
"kind": "doublestar", "kind": "doublestar",
"decoration": "matches", "decoration": "matches",
"extras":'["untagged":True]',
"pattern": selector_tag "pattern": selector_tag
} }
] ]

View File

@ -76,11 +76,16 @@ class TestProjects(unittest.TestCase):
self.assertEqual(artifacts[0].type, 'CHART') self.assertEqual(artifacts[0].type, 'CHART')
self.assertEqual(artifacts[0].tags[0].name, self.verion) self.assertEqual(artifacts[0].tags[0].name, self.verion)
#5. Get chart(CA) by reference successfully; #5.1 Get chart(CA) by reference successfully;
artifact = self.artifact.get_reference_info(TestProjects.project_push_chart_name, self.repo_name, self.verion, **TestProjects.USER_CLIENT) artifact = self.artifact.get_reference_info(TestProjects.project_push_chart_name, self.repo_name, self.verion, **TestProjects.USER_CLIENT)
self.assertEqual(artifact[0].type, 'CHART') self.assertEqual(artifact[0].type, 'CHART')
self.assertEqual(artifact[0].tags[0].name, self.verion) self.assertEqual(artifact[0].tags[0].name, self.verion)
#5.2 Chart bundle can be pulled by ctr successfully;
#oci_ref = harbor_server+"/"+TestProjects.project_push_chart_name+"/"+self.repo_name+":"+self.verion
#library.containerd.ctr_images_pull(user_name, self.user_push_chart_password, oci_ref)
#library.containerd.ctr_images_list(oci_ref = oci_ref)
#6. Get addtion successfully; #6. Get addtion successfully;
addition_r = self.artifact.get_addition(TestProjects.project_push_chart_name, self.repo_name, self.verion, "readme.md", **TestProjects.USER_CLIENT) addition_r = self.artifact.get_addition(TestProjects.project_push_chart_name, self.repo_name, self.verion, "readme.md", **TestProjects.USER_CLIENT)
self.assertIn("Helm Chart for Harbor", addition_r[0]) self.assertIn("Helm Chart for Harbor", addition_r[0])

View File

@ -5,6 +5,7 @@ import unittest
import library.repository import library.repository
import library.cnab import library.cnab
from testutils import ADMIN_CLIENT from testutils import ADMIN_CLIENT
from testutils import harbor_server from testutils import harbor_server
@ -23,8 +24,9 @@ class TestProjects(unittest.TestCase):
self.artifact = Artifact() self.artifact = Artifact()
self.repo= Repository() self.repo= Repository()
self.url = ADMIN_CLIENT["endpoint"] self.url = ADMIN_CLIENT["endpoint"]
self.user_push_chart_password = "Aa123456" self.user_push_cnab_password = "Aa123456"
self.cnab_repo_name = "test_cnab" self.cnab_repo_name = "test_cnab"
self.cnab_tag = "test_cnab_tag"
@classmethod @classmethod
def tearDownClass(self): def tearDownClass(self):
@ -60,8 +62,8 @@ class TestProjects(unittest.TestCase):
3. Delete user(UA). 3. Delete user(UA).
""" """
#1. Create a new user(UA); #1. Create a new user(UA);
TestProjects.user_id, user_name = self.user.create_user(user_password = self.user_push_chart_password, **ADMIN_CLIENT) TestProjects.user_id, user_name = self.user.create_user(user_password = self.user_push_cnab_password, **ADMIN_CLIENT)
TestProjects.USER_CLIENT=dict(endpoint = self.url, username = user_name, password = self.user_push_chart_password) TestProjects.USER_CLIENT=dict(endpoint = self.url, username = user_name, password = self.user_push_cnab_password)
#2. Create a new project(PA) by user(UA); #2. Create a new project(PA) by user(UA);
@ -69,17 +71,23 @@ class TestProjects(unittest.TestCase):
#3. Pull images for bundle; #3. Pull images for bundle;
_docker_api = DockerAPI() _docker_api = DockerAPI()
_docker_api.docker_image_pull("hello-world", tag = "latest") _docker_api.docker_image_pull("alpine", tag = "latest")
_docker_api.docker_image_pull("busybox", tag = "latest") _docker_api.docker_image_pull("haproxy", tag = "latest")
#4. Push bundle to harbor as repository(RA); #4. Push bundle to harbor as repository(RA);
target = harbor_server + "/" + TestProjects.project_push_bundle_name + "/" + self.cnab_repo_name target = harbor_server + "/" + TestProjects.project_push_bundle_name + "/" + self.cnab_repo_name + ":" + self.cnab_tag
reference_sha256 = library.cnab.push_cnab_bundle(harbor_server, user_name, self.user_push_chart_password, "hello-world:latest", "busybox:latest", target) reference_sha256 = library.cnab.push_cnab_bundle(harbor_server, user_name, self.user_push_cnab_password, "alpine:latest", "haproxy:latest", target)
#5. Get repository from Harbor successfully; #5. Get repository from Harbor successfully;
index_data = self.repo.get_repository(TestProjects.project_push_bundle_name, self.cnab_repo_name, **TestProjects.USER_CLIENT) index_data = self.repo.get_repository(TestProjects.project_push_bundle_name, self.cnab_repo_name, **TestProjects.USER_CLIENT)
print "index_data:", index_data print "index_data:", index_data
#5.2 Cnab bundle can be pulled by ctr successfully;
# This step might not successful since ctr does't support cnab fully, it might be uncomment sometime in future.
# Please keep them in comment!
#library.containerd.ctr_images_pull(user_name, self.user_push_cnab_password, target)
#library.containerd.ctr_images_list(oci_ref = target)
#6. Verfiy bundle name; #6. Verfiy bundle name;
self.assertEqual(index_data.name, TestProjects.project_push_bundle_name + "/" + self.cnab_repo_name) self.assertEqual(index_data.name, TestProjects.project_push_bundle_name + "/" + self.cnab_repo_name)

View File

@ -0,0 +1,87 @@
from __future__ import absolute_import
import unittest
import urllib
from library.sign import sign_image
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.artifact import Artifact
from library.project import Project
from library.user import User
from library.repository import Repository
from library.repository import push_image_to_project
class TestProjects(unittest.TestCase):
@classmethod
def setUp(self):
self.project = Project()
self.user = User()
self.artifact = Artifact()
self.repo = Repository()
@classmethod
def tearDown(self):
print "Case completed"
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
# remove the deletion as the signed image cannot be deleted.
#1. Delete repository(RA) by user(UA);
#self.repo.delete_repoitory(TestProjects.project_sign_image_name, TestProjects.repo_name.split('/')[1], **TestProjects.USER_sign_image_CLIENT)
#2. Delete project(PA);
#self.project.delete_project(TestProjects.project_sign_image_id, **TestProjects.USER_sign_image_CLIENT)
#3. Delete user(UA);
self.user.delete_user(TestProjects.user_sign_image_id, **ADMIN_CLIENT)
def testSignImage(self):
"""
Test case:
Push Image With Special Name
Test step and expected result:
1. Create a new user(UA);
2. Create a new private project(PA) by user(UA);
3. Add user(UA) as a member of project(PA) with project-admin role;
4. Get private project of user(UA), user(UA) can see only one private project which is project(PA);
5. Create a new repository(RA) and tag(TA) in project(PA) by user(UA);
6. Sign image with tag(TA) which was tagged by step #5;
7. Get signature of image with tag(TA), it should be exist.
Tear down:
NA
"""
url = ADMIN_CLIENT["endpoint"]
user_001_password = "Aa123456"
#1. Create user-001
TestProjects.user_sign_image_id, user_sign_image_name = self.user.create_user(user_password = user_001_password, **ADMIN_CLIENT)
TestProjects.USER_sign_image_CLIENT=dict(with_signature = True, endpoint = url, username = user_sign_image_name, password = user_001_password)
#2. Create a new private project(PA) by user(UA);
TestProjects.project_sign_image_id, TestProjects.project_sign_image_name = self.project.create_project(metadata = {"public": "false"}, **ADMIN_CLIENT)
#3. Add user(UA) as a member of project(PA) with project-admin role;
self.project.add_project_members(TestProjects.project_sign_image_id, TestProjects.user_sign_image_id, **ADMIN_CLIENT)
#4. Get private project of user(UA), user(UA) can see only one private project which is project(PA);
self.project.projects_should_exist(dict(public=False), expected_count = 1,
expected_project_id = TestProjects.project_sign_image_id, **TestProjects.USER_sign_image_CLIENT)
image = "hello-world"
src_tag = "latest"
profix = "aaa/bbb"
#5. Create a new repository(RA) and tag(TA) in project(PA) by user(UA);
TestProjects.repo_name, tag = push_image_to_project(TestProjects.project_sign_image_name, harbor_server, user_sign_image_name, user_001_password, image, src_tag, profix_for_image=profix)
#7. Get signature of image with tag(TA), it should be exist.
full_name = urllib.quote(profix+"/"+image,'utf-8')
artifact = self.artifact.get_reference_info(TestProjects.project_sign_image_name, (str(full_name)).encode(), tag, **TestProjects.USER_sign_image_CLIENT)
print artifact
self.assertEqual(artifact[0].type, 'IMAGE')
if __name__ == '__main__':
unittest.main()

View File

@ -5,6 +5,7 @@ import unittest
import library.repository import library.repository
import library.docker_api import library.docker_api
import library.containerd
from library.base import _assert_status_code from library.base import _assert_status_code
from testutils import ADMIN_CLIENT from testutils import ADMIN_CLIENT
from testutils import harbor_server from testutils import harbor_server
@ -60,7 +61,8 @@ class TestProjects(unittest.TestCase):
5. Get Artifacts successfully; 5. Get Artifacts successfully;
6. Get index(IA) by reference successfully; 6. Get index(IA) by reference successfully;
7. Verify harbor index is index(IA) pushed by docker manifest CLI; 7. Verify harbor index is index(IA) pushed by docker manifest CLI;
8. Verify harbor index(IA) can be pulled by docker CLI successfully; 8.1 Verify harbor index(IA) can be pulled by docker CLI successfully;
8.2 Verify harbor index(IA) can be pulled by docker CLI successfully;
9. Get addition successfully; 9. Get addition successfully;
10. Unable to Delete artifact in manifest list; 10. Unable to Delete artifact in manifest list;
11. Delete index successfully. 11. Delete index successfully.
@ -101,9 +103,14 @@ class TestProjects(unittest.TestCase):
self.assertEqual(manifests_sha256_harbor_ret.count(manifests_sha256_cli_ret[0]), 1) self.assertEqual(manifests_sha256_harbor_ret.count(manifests_sha256_cli_ret[0]), 1)
self.assertEqual(manifests_sha256_harbor_ret.count(manifests_sha256_cli_ret[1]), 1) self.assertEqual(manifests_sha256_harbor_ret.count(manifests_sha256_cli_ret[1]), 1)
#8. Verify harbor index(IA) can be pulled by docker CLI successfully; #8.1 Verify harbor index(IA) can be pulled by docker CLI successfully;
pull_harbor_image(harbor_server, user_name, self.user_push_index_password, TestProjects.project_push_index_name+"/"+self.index_name, self.index_tag) pull_harbor_image(harbor_server, user_name, self.user_push_index_password, TestProjects.project_push_index_name+"/"+self.index_name, self.index_tag)
#8.2 Verify harbor index(IA) can be pulled by ctr successfully;
oci_ref = harbor_server+"/"+TestProjects.project_push_index_name+"/"+self.index_name+":"+self.index_tag
library.containerd.ctr_images_pull(user_name, self.user_push_index_password, oci_ref)
library.containerd.ctr_images_list(oci_ref = oci_ref)
#9. Get addition successfully; #9. Get addition successfully;
addition_v = self.artifact.get_addition(TestProjects.project_push_index_name, self.index_name, self.index_tag, "vulnerabilities", **TestProjects.USER_CLIENT) addition_v = self.artifact.get_addition(TestProjects.project_push_index_name, self.index_name, self.index_tag, "vulnerabilities", **TestProjects.USER_CLIENT)
self.assertEqual(addition_v[0], '{}') self.assertEqual(addition_v[0], '{}')

View File

@ -7,13 +7,14 @@ from testutils import ADMIN_CLIENT
from testutils import TEARDOWN from testutils import TEARDOWN
from testutils import harbor_server from testutils import harbor_server
from library.repository import push_special_image_to_project from library.repository import push_special_image_to_project
from library.docker_api import list_image_tags
from library.retention import Retention from library.retention import Retention
from library.project import Project from library.project import Project
from library.repository import Repository from library.repository import Repository
from library.user import User from library.user import User
from library.system import System from library.system import System
from library.artifact import Artifact
class TestProjects(unittest.TestCase): class TestProjects(unittest.TestCase):
""" """
@ -38,6 +39,8 @@ class TestProjects(unittest.TestCase):
self.repo = Repository() self.repo = Repository()
self.project = Project() self.project = Project()
self.retention = Retention() self.retention = Retention()
self.artifact = Artifact()
self.repo_name_1 = "test1"
def testTagRetention(self): def testTagRetention(self):
user_ra_password = "Aa123456" user_ra_password = "Aa123456"
@ -51,14 +54,20 @@ class TestProjects(unittest.TestCase):
TestProjects.project_src_repo_id, TestProjects.project_src_repo_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_RA_CLIENT) TestProjects.project_src_repo_id, TestProjects.project_src_repo_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_RA_CLIENT)
# Push image test1:1.0, test1:2.0, test1:3.0,latest, test2:1.0, test2:latest, test3:1.0 # Push image test1:1.0, test1:2.0, test1:3.0,latest, test2:1.0, test2:latest, test3:1.0
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test1", ['1.0']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, self.repo_name_1, ['1.0'])
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test1", ['2.0']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, self.repo_name_1, ['2.0'])
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test1", ['3.0','latest']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, self.repo_name_1, ['3.0','latest'])
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test2", ['1.0']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test2", ['1.0'])
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test2", ['latest']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test2", ['latest'])
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test3", ['1.0']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test3", ['1.0'])
push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test4", ['1.0']) push_special_image_to_project(TestProjects.project_src_repo_name, harbor_server, user_ra_name, user_ra_password, "test4", ['1.0'])
tags = list_image_tags(harbor_server, TestProjects.project_src_repo_name+"/"+self.repo_name_1, user_ra_name, user_ra_password)
#Delete all tags of "artifact3" in repostory "image1";
self.artifact.delete_tag(TestProjects.project_src_repo_name, self.repo_name_1, "3.0", "latest",**TestProjects.USER_RA_CLIENT)
self.artifact.delete_tag(TestProjects.project_src_repo_name, self.repo_name_1, "3.0", "3.0",**TestProjects.USER_RA_CLIENT)
tags = list_image_tags(harbor_server, TestProjects.project_src_repo_name+"/"+self.repo_name_1, user_ra_name, user_ra_password)
resp=self.repo.list_repositories(TestProjects.project_src_repo_name, **TestProjects.USER_RA_CLIENT) resp=self.repo.list_repositories(TestProjects.project_src_repo_name, **TestProjects.USER_RA_CLIENT)
self.assertEqual(len(resp), 4) self.assertEqual(len(resp), 4)
@ -77,7 +86,13 @@ class TestProjects(unittest.TestCase):
resp=self.retention.get_retention_exec_tasks(retention_id,execution.id, **TestProjects.USER_RA_CLIENT) resp=self.retention.get_retention_exec_tasks(retention_id,execution.id, **TestProjects.USER_RA_CLIENT)
self.assertEqual(len(resp), 4) self.assertEqual(len(resp), 4)
resp=self.retention.get_retention_exec_task_log(retention_id,execution.id,resp[0].id, **TestProjects.USER_RA_CLIENT) resp=self.retention.get_retention_exec_task_log(retention_id,execution.id,resp[0].id, **TestProjects.USER_RA_CLIENT)
print(resp) #For Debug:
print("Task 0 log begin:-----------------------------")
i=0
for line in resp.split("\n"):
print("Line"+str(i)+": "+line)
i=i+1
print("Task 0 log end:-----------------------------")
# Real run # Real run
self.retention.trigger_retention_policy(retention_id, dry_run=False, **TestProjects.USER_RA_CLIENT) self.retention.trigger_retention_policy(retention_id, dry_run=False, **TestProjects.USER_RA_CLIENT)
@ -94,6 +109,13 @@ class TestProjects(unittest.TestCase):
# resp=self.repo.list_repositories(TestProjects.project_src_repo_id, **TestProjects.USER_RA_CLIENT) # resp=self.repo.list_repositories(TestProjects.project_src_repo_id, **TestProjects.USER_RA_CLIENT)
# self.assertEqual(len(resp), 3) # self.assertEqual(len(resp), 3)
#List artifacts successfully;
artifacts = self.artifact.list_artifacts(TestProjects.project_src_repo_name, self.repo_name_1, **TestProjects.USER_RA_CLIENT)
print artifacts
# 'test1' has 3 artifacts, artifact1 with tag '1.0' and artifact2 with tag '2.0' should be deleted because they doesn't match 'latest'
# artifact3 should be retained because it has no tag, so count of artifacts should be 1.
# TODO: This verfication should be enhanced by verify sha256 at the same time;
self.assertTrue(len(artifacts)==1)
@classmethod @classmethod
def tearDownClass(self): def tearDownClass(self):

View File

@ -56,5 +56,5 @@ Add A New User
Retry Text Input xpath=${newPassword_xpath} ${newPassword} Retry Text Input xpath=${newPassword_xpath} ${newPassword}
Retry Text Input xpath=${confirmPassword_xpath} ${newPassword} Retry Text Input xpath=${confirmPassword_xpath} ${newPassword}
Retry Text Input xpath=${comment_xpath} ${comment} Retry Text Input xpath=${comment_xpath} ${comment}
Retry Element Click xpath=${save_new_user_button} Retry Double Keywords When Error Retry Element Click xpath=${save_new_user_button} Retry Wait Until Page Not Contains Element xpath=${save_new_user_button}
Retry Wait Until Page Contains Element xpath=//harbor-user//clr-dg-row//clr-dg-cell[contains(., '${username}')] Retry Wait Until Page Contains Element xpath=//harbor-user//clr-dg-row//clr-dg-cell[contains(., '${username}')]

View File

@ -19,7 +19,7 @@ Resource ../../resources/Util.robot
*** Keywords *** *** Keywords ***
View Repo Scan Details View Repo Scan Details
Retry Element Click xpath=${first_repo_xpath} Retry Element Click xpath=${first_repo_xpath}
Capture Page Screenshot viewcve1.png Capture Page Screenshot
Retry Wait Until Page Contains unknown Retry Wait Until Page Contains unknown
Retry Wait Until Page Contains high Retry Wait Until Page Contains high
Retry Wait Until Page Contains medium Retry Wait Until Page Contains medium

View File

@ -95,3 +95,6 @@ Test Case - Scan All Images
Test Case - Registry API Test Case - Registry API
[Tags] reg_api [Tags] reg_api
Harbor API Test ./tests/apitests/python/test_registry_api.py Harbor API Test ./tests/apitests/python/test_registry_api.py
Test Case - Push Image With Special Name
[Tags] special_repo_name
Harbor API Test ./tests/apitests/python/test_push_image_with_special_name.py

View File

@ -105,6 +105,7 @@ Test Case - Scan Image On Push
Go Into Project library Go Into Project library
Go Into Repo memcached Go Into Repo memcached
Summary Chart Should Display latest Summary Chart Should Display latest
View Repo Scan Details
Close Browser Close Browser
Test Case - View Scan Results Test Case - View Scan Results

View File

@ -107,6 +107,7 @@ Test Case - Scan Image On Push
Go Into Project library Go Into Project library
Go Into Repo memcached Go Into Repo memcached
Summary Chart Should Display latest Summary Chart Should Display latest
View Repo Scan Details
Close Browser Close Browser
Test Case - View Scan Results Test Case - View Scan Results