from __future__ import absolute_import import time import unittest import v2_swagger_client from library import base from testutils import harbor_server, ADMIN_CLIENT, suppress_urllib3_warning from library.jobservice import Jobservice from library.gc import GC from library.purge import Purge from library.user import User from library.project import Project from library.retention import Retention from library.preheat import Preheat from library.replication import Replication from library.registry import Registry from library.scan_all import ScanAll from library.schedule import Schedule class TestJobServiceDashboard(unittest.TestCase, object): @suppress_urllib3_warning def setUp(self): self.jobservice = Jobservice() self.gc = GC() self.purge = Purge() self.user = User() self.project = Project() self.retention = Retention() self.preheat = Preheat() self.replication = Replication() self.registry = Registry() self.scan_all = ScanAll() self.schedule = Schedule() self.job_types = [ "GARBAGE_COLLECTION", "PURGE_AUDIT_LOG", "P2P_PREHEAT", "IMAGE_SCAN", "REPLICATION", "RETENTION", "SCAN_DATA_EXPORT", "SCHEDULER", "SLACK", "SYSTEM_ARTIFACT_CLEANUP", "WEBHOOK", "EXECUTION_SWEEP"] self.cron_type = "Custom" self.cron = "0 0 0 * * 0" def testJobQueues(self): """ Test case: Job Service Dashboard Job Queues Test step and expected result: 1. List job queue; 2. Pause GC Job and purge audit Job; 3. Verify that the Job status is Paused; 4. Run GC and purge audit; 5. Verify pending jobs of job queues; 6. Resume GC Job and purge audit Job; 7. Verify pending jobs of job queues; 8. Pause GC Job and purge audit Job; 9. Verify that the Job status is Paused; 10. Run GC and purge audit; 11. Verify pending jobs of job queues; 12. Stop GC Job and purge audit Job; 13. Verify pending jobs of job queues; 14. Run GC and purge audit; 15. Verify pending jobs of job queues; 16. Stop all Job; 17. Verify pending jobs of job queues; 18. Resume all Job; """ # 1. List job queue job_queues = self.jobservice.get_job_queues() self.assertSetEqual(set(self.job_types), set(job_queues.keys())) # 2. Pause GC Job and purge audit Job self.jobservice.action_pending_jobs(self.job_types[0], "pause") self.jobservice.action_pending_jobs(self.job_types[1], "pause") # 3. Verify that the Job status is Paused job_queues = self.jobservice.get_job_queues() self.assertTrue(job_queues[self.job_types[0]].paused) self.assertTrue(job_queues[self.job_types[1]].paused) # 4. Run GC and purge audit self.gc.gc_now() self.purge.create_purge_schedule(type="Manual", cron=None, dry_run=False) time.sleep(2) # 5. Verify pending jobs of job queues self.verifyPendingJobs([self.job_types[0], self.job_types[1]]) # 6. Resume GC Job and purge audit Job self.jobservice.action_pending_jobs(self.job_types[0], "resume") self.jobservice.action_pending_jobs(self.job_types[1], "resume") # 7. Verify pending jobs of job queues self.waitJobQueuesStopToComplete([self.job_types[0], self.job_types[1]]) # 8. Pause GC Job and purge audit Job; self.jobservice.action_pending_jobs(self.job_types[0], "pause") self.jobservice.action_pending_jobs(self.job_types[1], "pause") # 9. Verify that the Job status is Paused job_queues = self.jobservice.get_job_queues() self.assertTrue(job_queues[self.job_types[0]].paused) self.assertTrue(job_queues[self.job_types[1]].paused) # 10. Run GC and purge audit self.gc.gc_now() self.purge.create_purge_schedule(type="Manual", cron=None, dry_run=False) time.sleep(2) # 11. Verify pending jobs of job queues self.verifyPendingJobs([self.job_types[0], self.job_types[1]]) # 12. Stop GC Job and purge audit Job self.jobservice.action_pending_jobs(self.job_types[0], "stop") self.jobservice.action_pending_jobs(self.job_types[1], "stop") # 13. Verify pending jobs of job queues self.waitJobQueuesStopToComplete([self.job_types[0], self.job_types[1]]) # 14. Run GC and purge audit self.gc.gc_now() self.purge.create_purge_schedule(type="Manual", cron=None, dry_run=False) time.sleep(2) # 15. Verify pending jobs of job queues self.verifyPendingJobs([self.job_types[0], self.job_types[1]]) # 16. Stop all Job self.jobservice.action_pending_jobs("all", "stop") # 17. Verify pending jobs of job queues self.waitJobQueuesStopToComplete([self.job_types[0], self.job_types[1]]) # 18. Resume all Job self.jobservice.action_pending_jobs("all", "resume") job_queues = self.jobservice.get_job_queues() self.assertFalse(job_queues[self.job_types[0]].paused) self.assertFalse(job_queues[self.job_types[1]].paused) def verifyPendingJobs(self, job_types): job_queues = self.jobservice.get_job_queues() for job_type in job_types: self.assertTrue(job_queues[job_type].count > 0) self.assertTrue(job_queues[job_type].latency > 0) self.assertTrue(job_queues[job_type].count > 0) self.assertTrue(job_queues[job_type].latency > 0) def waitJobQueuesStopToComplete(self, job_types): is_success = False for i in range(10): print("Wait for queues to be consumed:", i) job_queues = self.jobservice.get_job_queues() for job_type in job_types: if job_queues[job_type].count is not None or job_queues[job_type].latency is not None: is_success = False break else: is_success = True break time.sleep(2) self.assertTrue(is_success) def testSchedules(self): """ Test case: Job Service Dashboard Schedules Test step and expected result: 1. Create a new project; 2. Create a retention policy triggered by schedule; 3. Create a new distribution; 4. Create a preheat policy triggered by schedule; 5. Create a new registry; 6. Create a replication policy triggered by schedule; 7. Set up a schedule to scan all; 8. Set up a schedule to GC; 9. Set up a schedule to log rotation; 10. Verify schedules; 11. Pause all schedules; 12. Verify schedules is Paused; 13. Resume all schedules; 14. Verify schedules is not Paused; 15. Reset the schedule for scan all, GC, and log rotation; 16. Verify schedules; """ # 1. Create a new project(PA) by user(UA) project_id, project_name = self.project.create_project(metadata = {"public": "false"}) # 2. Create a retention policy retention_id = self.retention.create_retention_policy(project_id, selector_repository="**", selector_tag="**") self.retention.update_retention_policy(retention_id, project_id, cron=self.cron) # 3. Create a new distribution _, distribution_name = self.preheat.create_instance(endpoint_url=base._random_name("https://")) # 4. Create a new preheat policy distribution = self.preheat.get_instance(distribution_name) _, preheat_policy_name = self.preheat.create_policy(project_name, project_id, distribution.id, trigger=r'{"type":"scheduled","trigger_setting":{"cron":"%s"}}' % (self.cron)) preheat_policy = self.preheat.get_policy(project_name, preheat_policy_name) # 5. Create a new registry registry_id, _ = self.registry.create_registry("https://" + harbor_server) # 6. Create a replication policy triggered by schedule replication_id, _ = self.replication.create_replication_policy(dest_registry=v2_swagger_client.Registry(id=int(registry_id)), trigger=v2_swagger_client.ReplicationTrigger(type="scheduled",trigger_settings=v2_swagger_client.ReplicationTriggerSettings(cron=self.cron))) # 7. Set up a schedule to scan all self.scan_all.create_scan_all_schedule(self.cron_type, cron=self.cron) # 8. Set up a schedule to GC self.gc.create_gc_schedule(self.cron_type, is_delete_untagged=True, cron=self.cron) # 9. Set up a schedule to Log Rotation self.purge.create_purge_schedule(self.cron_type, self.cron, True) # 10. Verify schedules schedules = self.schedule.list_schedules(page_size=50, page=1) # 10.1 Verify retention schedule retention_schedule = schedules["%s-%d" % (self.job_types[5], retention_id)] self.assertEqual(retention_schedule.cron, self.cron) # 10.2 Verify preheat schedule preheat_schedule = schedules["%s-%d" % (self.job_types[2], preheat_policy.id)] self.assertEqual(preheat_schedule.cron, self.cron) # 10.3 Verify replication schedule replication_schedule = schedules["%s-%d" % (self.job_types[4], replication_id)] self.assertEqual(replication_schedule.vendor_type, self.job_types[4]) self.assertEqual(replication_schedule.cron, self.cron) # 10.4 Verify scan all schedule scan_all_schedule = schedules["SCAN_ALL"] self.assertEqual(scan_all_schedule.cron, self.cron) # 10.5 Verify GC schedule gc_schedule = schedules[self.job_types[0]] self.assertEqual(gc_schedule.cron, self.cron) # 10.6 Verify log rotation log_rotation_schedule = schedules["PURGE_AUDIT_LOG"] self.assertEqual(log_rotation_schedule.cron, self.cron) # 11. Pause all schedules self.jobservice.action_pending_jobs("scheduler", "pause") # 12. Verify schedules is Paused; self.assertTrue(self.schedule.get_schedule_paused("all").paused) # 13. Resume all schedules self.jobservice.action_pending_jobs("scheduler", "resume") # 14. Verify schedules is not Paused self.assertFalse(self.schedule.get_schedule_paused("all").paused) # 15. Reset the schedule for scan all, GC, and log rotation self.scan_all.update_scan_all_schedule("None", cron="") self.gc.update_gc_schedule("None", cron="") self.purge.update_purge_schedule("None", "") # 16. Verify schedules schedules = self.schedule.list_schedules(page_size=50, page=1) # 16.1 Verify retention schedule retention_schedule = schedules["%s-%d" % (self.job_types[5], retention_id)] self.assertEqual(retention_schedule.cron, self.cron) # 16.2 Verify preheat schedule preheat_schedule = schedules["%s-%d" % (self.job_types[2], preheat_policy.id)] self.assertEqual(preheat_schedule.cron, self.cron) # 16.3 Verify replication schedule replication_schedule = schedules["%s-%d" % (self.job_types[4], replication_id)] self.assertEqual(replication_schedule.vendor_type, self.job_types[4]) self.assertEqual(replication_schedule.cron, self.cron) # 16.4 Verify scan all schedule self.assertNotIn("SCAN_ALL", schedules) # 16.5 Verify GC schedule self.assertNotIn(self.job_types[0], schedules) # 16.6 Verify log rotation self.assertNotIn("PURGE_AUDIT_LOG", schedules) def testWorkers(self): """ Test case: Job Service Dashboard Workers Test step and expected result: 1. Get worker pools; 2. Get workers in current pool; 3. Stop running job; """ # 1. Get worker pools worker_pools = self.jobservice.get_worker_pools() for worker_pool in worker_pools: self.assertIsNotNone(worker_pool.pid) self.assertIsNotNone(worker_pool.worker_pool_id) self.assertIsNotNone(worker_pool.concurrency) self.assertIsNotNone(worker_pool.start_at) self.assertIsNotNone(worker_pool.heartbeat_at) # 2. Get workers in current pool workers = self.jobservice.get_workers(worker_pool.worker_pool_id) self.assertEqual(len(workers), worker_pool.concurrency) for worker in workers: self.assertIsNotNone(worker.id) self.assertEqual(worker_pool.worker_pool_id, worker.pool_id) # 3. Stop running job self.jobservice.stop_running_job("966a49aa2278b67d743f8aca") def testJobServiceDashboardAPIPermission(self): """ Test case: Log Rotaion Permission API Test step and expected result: 1. Create a new user(UA); 2. User(UA) should not have permission to list job queue API; 3. User(UA) should not have permission to action_pending_jobs API; 4. User(UA) should not have permission to stop running job API; 5. User(UA) should not have permission to get worker pools API; 6. User(UA) should not have permission to get workers in current pool API; 7. User(UA) should not have permission to list schedules API; 8. User(UA) should have permission to get scheduler paused status API; 9. Verify that the get scheduler paused status API parameter job_type only support all; """ expect_status_code = 403 expect_response_body = "FORBIDDEN" # 1. Create a new user(UA) user_password = "Aa123456" _, user_name = self.user.create_user(user_password = user_password) USER_CLIENT = dict(endpoint = ADMIN_CLIENT["endpoint"], username = user_name, password = user_password) # 2. User(UA) should not have permission to list job queue API self.jobservice.get_job_queues(expect_status_code=expect_status_code, expect_response_body=expect_response_body, **USER_CLIENT) # 3. User(UA) should not have permission to action_pending_jobs API self.jobservice.action_pending_jobs(self.job_types[0], "pause", expect_status_code=expect_status_code, expect_response_body=expect_response_body, **USER_CLIENT) # 4. User(UA) should not have permission to stop running job API self.jobservice.stop_running_job("966a49aa2278b67d743f8aca", expect_status_code=expect_status_code, expect_response_body=expect_response_body, **USER_CLIENT) # 5. User(UA) should not have permission to get worker pools API self.jobservice.get_worker_pools(expect_status_code=expect_status_code, expect_response_body=expect_response_body, **USER_CLIENT) # 6. User(UA) should not have permission to get workers in current pool API self.jobservice.get_workers("13e0cfe999715102c47614ec", expect_status_code=expect_status_code, expect_response_body=expect_response_body, **USER_CLIENT) # 7. User(UA) should not have permission to list schedules API self.schedule.list_schedules(expect_status_code=expect_status_code, expect_response_body=expect_response_body, **USER_CLIENT) # 8. User(UA) should have permission to get scheduler paused status API self.schedule.get_schedule_paused("all") # 9. Verify that the get scheduler paused status API parameter job_type only support all self.schedule.get_schedule_paused(self.job_types[0], expect_status_code=400, expect_response_body="job_type can only be 'all'") if __name__ == '__main__': unittest.main()