示例#1
0
class TestSyncRepo(unittest.TestCase):
    def setUp(self):
        super(TestSyncRepo, self).setUp()
        self.repo = Repository('repo1', working_dir='/a/b/c')
        self.repo.repo_obj = model.Repository(repo_id=self.repo.id)
        self.sync_conduit = mock.MagicMock()
        self.config = mock.MagicMock()
        self.importer = DockerImporter()

    @mock.patch('pulp_docker.plugins.importers.sync.SyncStep')
    @mock.patch(
        'pulp.plugins.util.publish_step.common_utils.get_working_directory',
        mock.MagicMock(return_value='/a/b/c'))
    def test_calls_sync_step(self, mock_sync_step, mock_rmtree, mock_mkdtemp):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.assert_called_once_with(repo=self.repo,
                                               conduit=self.sync_conduit,
                                               config=self.config)

    @mock.patch('pulp_docker.plugins.importers.sync.SyncStep')
    @mock.patch(
        'pulp.plugins.util.publish_step.common_utils.get_working_directory',
        mock.MagicMock(return_value='/a/b/c'))
    def test_calls_sync(self, mock_sync_step, mock_rmtree, mock_mkdtemp):
        """
        Assert that the sync_repo() method calls sync() on the SyncStep.
        """
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.return_value.process_lifecycle.assert_called_once_with()
示例#2
0
    def test_import_all_manifests(self):
        units = [
            mock.Mock(
                type_id=constants.MANIFEST_TYPE_ID,
                unit_key={'digest': 'A1234'},
                metadata={'fs_layers': []}),
            mock.Mock(
                type_id=constants.MANIFEST_TYPE_ID,
                unit_key={'digest': 'B1234'},
                metadata={'fs_layers': []}),
        ]
        conduit = mock.Mock()
        conduit.get_source_units.side_effect = [units, []]

        # test
        importer = DockerImporter()
        importer._import_manifests(conduit, None)

        # validation
        self.assertEqual(
            conduit.associate_unit.call_args_list,
            [
                mock.call(units[0]),
                mock.call(units[1]),
            ])
示例#3
0
 def setUp(self):
     super(TestSyncRepo, self).setUp()
     self.repo = Repository('repo1', working_dir='/a/b/c')
     self.repo.repo_obj = model.Repository(repo_id=self.repo.id)
     self.sync_conduit = mock.MagicMock()
     self.config = mock.MagicMock()
     self.importer = DockerImporter()
示例#4
0
class TestSyncRepo(unittest.TestCase):
    def setUp(self):
        super(TestSyncRepo, self).setUp()
        self.repo = Repository('repo1', working_dir='/a/b/c')
        self.repo.repo_obj = model.Repository(repo_id=self.repo.id)
        self.sync_conduit = mock.MagicMock()
        self.config = mock.MagicMock()
        self.importer = DockerImporter()

    @mock.patch('pulp_docker.plugins.importers.sync.SyncStep')
    @mock.patch('pulp.plugins.util.publish_step.common_utils.get_working_directory',
                mock.MagicMock(return_value='/a/b/c'))
    def test_calls_sync_step(self, mock_sync_step, mock_rmtree, mock_mkdtemp):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.assert_called_once_with(
            repo=self.repo, conduit=self.sync_conduit,
            config=self.config)

    @mock.patch('pulp_docker.plugins.importers.sync.SyncStep')
    @mock.patch('pulp.plugins.util.publish_step.common_utils.get_working_directory',
                mock.MagicMock(return_value='/a/b/c'))
    def test_calls_sync(self, mock_sync_step, mock_rmtree, mock_mkdtemp):
        """
        Assert that the sync_repo() method calls sync() on the SyncStep.
        """
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.return_value.process_lifecycle.assert_called_once_with()
示例#5
0
    def test_import_manifests(self, criteria):
        layers = [
            {'blobSum': 'b2244'},
            {'blobSum': 'b2245'},
            {'blobSum': 'b2246'}
        ]
        units = [
            # ignored
            mock.Mock(type_id=constants.IMAGE_TYPE_ID),
            # manifests
            mock.Mock(
                type_id=constants.MANIFEST_TYPE_ID,
                unit_key={'digest': 'A1234'},
                metadata={'fs_layers': []}
            ),
            mock.Mock(
                type_id=constants.MANIFEST_TYPE_ID,
                unit_key={'digest': 'B1234'},
                metadata={'fs_layers': layers}
            ),
            mock.Mock(
                type_id=constants.MANIFEST_TYPE_ID,
                unit_key={'digest': 'C1234'},
                metadata={'fs_layers': layers}
            ),
        ]

        conduit = mock.Mock()
        blobs = [dict(digest=l.values()[0]) for l in layers]
        conduit.get_source_units.return_value = blobs

        # test
        importer = DockerImporter()
        units_added = importer._import_manifests(conduit, units)

        # validation
        blob_filter = {
            'digest': {
                '$in': [l.values()[0] for l in layers]
            }
        }
        self.assertEqual(units_added, units[1:] + blobs)
        self.assertEqual(
            criteria.call_args_list,
            [
                mock.call(type_ids=[constants.BLOB_TYPE_ID], unit_filters=blob_filter),
            ])
        self.assertEqual(
            conduit.associate_unit.call_args_list,
            [
                mock.call(units[1]),
                mock.call(units[2]),
                mock.call(units[3]),
                mock.call(blobs[0]),
                mock.call(blobs[1]),
                mock.call(blobs[2]),
            ])
示例#6
0
    def test_call(self, purge_blobs, purge_tags, mock_repo_qs):
        repo = mock.Mock()
        config = mock.Mock()
        units = mock.Mock()
        importer = DockerImporter()

        importer.remove_units(repo, units, config)

        purge_tags.assert_called_once_with(repo, units)
        purge_blobs.assert_called_once_with(repo, units)
示例#7
0
    def test_call(self, purge_blobs, purge_tags, mock_repo_qs):
        repo = mock.Mock()
        config = mock.Mock()
        units = mock.Mock()
        importer = DockerImporter()

        importer.remove_units(repo, units, config)

        purge_tags.assert_called_once_with(repo, units)
        purge_blobs.assert_called_once_with(repo, units)
示例#8
0
class TestSyncRepo(unittest.TestCase):
    def setUp(self):
        super(TestSyncRepo, self).setUp()
        self.repo = Repository('repo1', working_dir='/a/b/c')
        self.sync_conduit = mock.MagicMock()
        self.config = mock.MagicMock()
        self.importer = DockerImporter()

    def test_calls_sync_step(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.assert_called_once_with(repo=self.repo, conduit=self.sync_conduit,
                                               config=self.config,
                                               working_dir=mock_mkdtemp.return_value)

    def test_calls_sync(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.return_value.sync.assert_called_once_with()

    @mock.patch('pulp_docker.plugins.importers.v1_sync.SyncStep')
    def test_fall_back_to_v1(self, v1_sync_step, mock_rmtree, mock_mkdtemp, mock_sync_step):
        """
        Ensure that the sync_repo() method falls back to Docker v1 if Docker v2 isn't available.
        """
        # Simulate the v2 API being unavailable
        mock_sync_step.side_effect = NotImplementedError()

        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        v1_sync_step.assert_called_once_with(
            repo=self.repo, conduit=self.sync_conduit, config=self.config,
            working_dir=mock_mkdtemp.return_value)
        v1_sync_step.return_value.sync.assert_called_once_with()

    def test_makes_temp_dir(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_mkdtemp.assert_called_once_with(dir=self.repo.working_dir)

    def test_removes_temp_dir(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_rmtree.assert_called_once_with(mock_mkdtemp.return_value, ignore_errors=True)

    def test_removes_temp_dir_after_exception(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        class MyError(Exception):
            pass
        mock_sync_step.return_value.sync.side_effect = MyError
        self.assertRaises(MyError, self.importer.sync_repo, self.repo,
                          self.sync_conduit, self.config)

        mock_rmtree.assert_called_once_with(mock_mkdtemp.return_value, ignore_errors=True)
示例#9
0
class TestCancel(unittest.TestCase):
    def setUp(self):
        super(TestCancel, self).setUp()
        self.importer = DockerImporter()

    def test_calls_cancel(self):
        self.importer.sync_step = mock.MagicMock()

        self.importer.cancel_sync_repo()

        # make sure the step's cancel method was called
        self.importer.sync_step.cancel.assert_called_once_with()
示例#10
0
class TestCancel(unittest.TestCase):
    def setUp(self):
        super(TestCancel, self).setUp()
        self.importer = DockerImporter()

    def test_calls_cancel(self):
        self.importer.sync_step = mock.MagicMock()

        self.importer.cancel_sync_repo()

        # make sure the step's cancel method was called
        self.importer.sync_step.cancel.assert_called_once_with()
示例#11
0
    def test_calls_process_lifecycle(self, m_repo_objects, m_step):
        repo = mock.Mock(id='repo1')
        conduit = mock.MagicMock()
        config = mock.MagicMock()
        importer = DockerImporter()
        repo_instance = Repository()
        m_repo_objects.get_repo_or_missing_resource.return_value = repo_instance

        importer.upload_unit(repo, constants.IMAGE_TYPE_ID, {}, {}, 'foo/path', conduit, config)
        m_step.assert_called_once_with(repo=repo_instance,
                                       file_path='foo/path',
                                       config=config)
        m_step.return_value.process_lifecycle.assert_called_once_with()
示例#12
0
    def test_purge_orphaned(self, query_manager, association_manager, criteria):
        repo = mock.Mock()
        blobs = [
            {'blobSum': 'blob-0'},  # manifest => 1
            {'blobSum': 'blob-1'},  # manifest => 1
            {'blobSum': 'blob-2'},  # manifest => 1
            {'blobSum': 'blob-3'},  # manifest => 1, 2, 3  (not orphaned)
            {'blobSum': 'blob-4'},  # manifest => 1, 2
            {'blobSum': 'blob-5'},  # manifest => 2, 4     (not orphaned)
            {'blobSum': 'blob-6'},  # manifest => 2
        ]
        removed = [
            mock.Mock(
                id='manifest-1',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs[0:4]}),
            mock.Mock(
                id='manifest-2',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs[2:8]})
        ]
        others = [
            mock.Mock(
                id='manifest-3',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs[3:4]}),
            mock.Mock(
                id='manifest-4',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs[5:6]})
        ]

        query_manager.return_value.get_units_by_type.return_value = others

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        criteria.assert_called_once_with(
            type_ids=[constants.BLOB_TYPE_ID],
            unit_filters={'digest': {'$in': ['blob-0', 'blob-1', 'blob-2', 'blob-4', 'blob-6']}})

        query_manager.return_value.get_units_by_type.assert_called_once_with(
            repo.id, constants.MANIFEST_TYPE_ID)
        association_manager.return_value.unassociate_by_criteria(
            repo_id=repo.id,
            criteria=criteria.return_value,
            owner_type='',  # unused
            owner_id='',    # unused
            notify_plugins=False)
示例#13
0
 def test_import(self, import_manifests, import_images):
     import_images.return_value = [1, 2]
     import_manifests.return_value = [3, 4]
     units = mock.Mock()
     importer = DockerImporter()
     imported = importer.import_units(
         source_repo=self.source_repo,
         dest_repo=self.dest_repo,
         import_conduit=self.conduit,
         config=self.config,
         units=units)
     import_images.assert_called_once_with(self.conduit, units)
     import_manifests.assert_called_once_with(self.conduit, units)
     self.assertEqual(imported, import_images.return_value + import_manifests.return_value)
示例#14
0
    def test_calls_process_lifecycle(self, m_repo_objects, mock_sync_step):
        repo = mock.Mock(id='repo1')
        sync_conduit = mock.MagicMock()
        config = mock.MagicMock()
        importer = DockerImporter()
        repo_instance = Repository()
        m_repo_objects.get_repo_or_missing_resource.return_value = repo_instance

        importer.sync_repo(repo, sync_conduit, config)

        mock_sync_step.assert_called_once_with(repo=repo_instance,
                                               conduit=sync_conduit,
                                               config=config)
        mock_sync_step.return_value.process_lifecycle.assert_called_once_with()
示例#15
0
    def test_purge_orphaned_all_adopted(self, query_manager,
                                        association_manager, criteria):
        repo = mock.Mock()
        blobs = [
            {
                'blobSum': 'blob-0'
            },  # manifest => 1, 3     (not orphaned)
            {
                'blobSum': 'blob-1'
            },  # manifest => 1, 3     (not orphaned)
            {
                'blobSum': 'blob-2'
            },  # manifest => 1, 3     (not orphaned)
            {
                'blobSum': 'blob-3'
            },  # manifest => 1, 2, 3  (not orphaned)
            {
                'blobSum': 'blob-4'
            },  # manifest => 1, 2, 3  (not orphaned)
            {
                'blobSum': 'blob-5'
            },  # manifest => 2, 4, 3  (not orphaned)
            {
                'blobSum': 'blob-6'
            },  # manifest => 2, 3     (not orphaned)
        ]
        removed = [
            mock.Mock(id='manifest-1',
                      type_id=constants.MANIFEST_TYPE_ID,
                      metadata={'fs_layers': blobs[0:4]}),
            mock.Mock(id='manifest-2',
                      type_id=constants.MANIFEST_TYPE_ID,
                      metadata={'fs_layers': blobs[2:8]})
        ]
        others = [
            mock.Mock(id='manifest-3',
                      type_id=constants.MANIFEST_TYPE_ID,
                      metadata={'fs_layers': blobs}),
        ]

        query_manager.return_value.get_units_by_type.return_value = others

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        self.assertFalse(criteria.called)
        self.assertFalse(association_manager.called)
示例#16
0
    def test_purge_not_manifests(self, query_manager, association_manager, criteria):
        repo = mock.Mock()
        removed = [
            mock.Mock(type_id=constants.IMAGE_TYPE_ID),
            mock.Mock(type_id=constants.IMAGE_TYPE_ID),
        ]

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        self.assertFalse(query_manager.called)
        self.assertFalse(criteria.called)
        self.assertFalse(association_manager.called)
示例#17
0
 def test_import(self, import_manifests, import_images):
     import_images.return_value = [1, 2]
     import_manifests.return_value = [3, 4]
     units = mock.Mock()
     importer = DockerImporter()
     imported = importer.import_units(source_repo=self.source_repo,
                                      dest_repo=self.dest_repo,
                                      import_conduit=self.conduit,
                                      config=self.config,
                                      units=units)
     import_images.assert_called_once_with(self.conduit, units)
     import_manifests.assert_called_once_with(self.conduit, units)
     self.assertEqual(
         imported,
         import_images.return_value + import_manifests.return_value)
示例#18
0
    def test_purge_not_manifests(self, query_manager, association_manager,
                                 criteria):
        repo = mock.Mock()
        removed = [
            mock.Mock(type_id=constants.IMAGE_TYPE_ID),
            mock.Mock(type_id=constants.IMAGE_TYPE_ID),
        ]

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        self.assertFalse(query_manager.called)
        self.assertFalse(criteria.called)
        self.assertFalse(association_manager.called)
示例#19
0
 def setUp(self):
     super(TestSyncRepo, self).setUp()
     self.repo = Repository('repo1', working_dir='/a/b/c')
     self.repo.repo_obj = model.Repository(repo_id=self.repo.id)
     self.sync_conduit = mock.MagicMock()
     self.config = mock.MagicMock()
     self.importer = DockerImporter()
示例#20
0
    def test_added_tags(self, mock_save, mock_update_tags):
        DockerImporter().upload_unit(self.repo, constants.IMAGE_TYPE_ID,
                                     self.unit_key, {}, data.busybox_tar_path,
                                     self.conduit, self.config)

        mock_update_tags.assert_called_once_with(self.repo.id,
                                                 data.busybox_tar_path)
示例#21
0
 def test_remove_with_tag(self, mock_repo_manager):
     mock_repo_manager.return_value.get_repo_scratchpad.return_value = \
         {u'tags': [{constants.IMAGE_TAG_KEY: 'apple',
                     constants.IMAGE_ID_KEY: 'foo'}]}
     DockerImporter().remove_units(self.repo, [self.mock_unit], self.config)
     mock_repo_manager.return_value.set_repo_scratchpad.assert_called_once_with(
         self.repo.id, {u'tags': []})
示例#22
0
    def test_save_conduit(self, mock_save, mock_update_tags):
        DockerImporter().upload_unit(self.repo, constants.IMAGE_TYPE_ID,
                                     self.unit_key, {}, data.busybox_tar_path,
                                     self.conduit, self.config)

        conduit = mock_save.call_args[0][0]

        self.assertTrue(conduit is self.conduit)
示例#23
0
    def test_saved_ancestry(self, mock_save, mock_update_tags):
        DockerImporter().upload_unit(self.repo, constants.IMAGE_TYPE_ID,
                                     self.unit_key, {}, data.busybox_tar_path,
                                     self.conduit, self.config)

        ancestry = mock_save.call_args[0][2]

        self.assertEqual(tuple(ancestry), data.busybox_ids)
示例#24
0
    def test_saved_filepath(self, mock_save, mock_update_tags):
        DockerImporter().upload_unit(self.repo, constants.IMAGE_TYPE_ID,
                                     self.unit_key, {}, data.busybox_tar_path,
                                     self.conduit, self.config)

        path = mock_save.call_args[0][3]

        self.assertEqual(path, data.busybox_tar_path)
示例#25
0
    def test_import_manifests(self, criteria):
        layers = [{
            'blobSum': 'b2244'
        }, {
            'blobSum': 'b2245'
        }, {
            'blobSum': 'b2246'
        }]
        units = [
            # ignored
            mock.Mock(type_id=constants.IMAGE_TYPE_ID),
            # manifests
            mock.Mock(type_id=constants.MANIFEST_TYPE_ID,
                      unit_key={'digest': 'A1234'},
                      metadata={'fs_layers': []}),
            mock.Mock(type_id=constants.MANIFEST_TYPE_ID,
                      unit_key={'digest': 'B1234'},
                      metadata={'fs_layers': layers}),
            mock.Mock(type_id=constants.MANIFEST_TYPE_ID,
                      unit_key={'digest': 'C1234'},
                      metadata={'fs_layers': layers}),
        ]

        conduit = mock.Mock()
        blobs = [dict(digest=l.values()[0]) for l in layers]
        conduit.get_source_units.return_value = blobs

        # test
        importer = DockerImporter()
        units_added = importer._import_manifests(conduit, units)

        # validation
        blob_filter = {'digest': {'$in': [l.values()[0] for l in layers]}}
        self.assertEqual(units_added, units[1:] + blobs)
        self.assertEqual(criteria.call_args_list, [
            mock.call(type_ids=[constants.BLOB_TYPE_ID],
                      unit_filters=blob_filter),
        ])
        self.assertEqual(conduit.associate_unit.call_args_list, [
            mock.call(units[1]),
            mock.call(units[2]),
            mock.call(units[3]),
            mock.call(blobs[0]),
            mock.call(blobs[1]),
            mock.call(blobs[2]),
        ])
示例#26
0
 def test_always_true(self):
     for repo, config in [['a', 'b'], [1, 2], [mock.Mock(), {}],
                          ['abc', {
                              'a': 2
                          }]]:
         # make sure all attempts are validated
         self.assertEqual(DockerImporter().validate_config(repo, config),
                          (True, ''))
示例#27
0
 def test_import_all(self):
     mock_unit = mock.Mock(unit_key={'image_id': 'foo'}, metadata={})
     self.conduit.get_source_units.return_value = [mock_unit]
     result = DockerImporter().import_units(self.source_repo,
                                            self.dest_repo, self.conduit,
                                            self.config)
     self.assertEquals(result, [mock_unit])
     self.conduit.associate_unit.assert_called_once_with(mock_unit)
示例#28
0
    def test_metadata(self):
        metadata = DockerImporter.metadata()

        self.assertEqual(metadata['id'], constants.IMPORTER_TYPE_ID)
        self.assertEqual(
            set(metadata['types']),
            set([constants.BLOB_TYPE_ID, constants.IMAGE_TYPE_ID, constants.MANIFEST_TYPE_ID,
                 constants.TAG_TYPE_ID]))
        self.assertTrue(len(metadata['display_name']) > 0)
示例#29
0
 def test_import_no_parent(self):
     mock_unit = mock.Mock(unit_key={'image_id': 'foo'}, metadata={})
     result = DockerImporter().import_units(self.source_repo,
                                            self.dest_repo,
                                            self.conduit,
                                            self.config,
                                            units=[mock_unit])
     self.assertEquals(result, [mock_unit])
     self.conduit.associate_unit.assert_called_once_with(mock_unit)
示例#30
0
 def test_import_images_no_parent(self):
     units = [
         mock.Mock(type_id=constants.IMAGE_TYPE_ID,
                   unit_key={'image_id': 'foo'},
                   metadata={}),
     ]
     result = DockerImporter()._import_images(self.conduit, units)
     self.assertEquals(result, units[0:1])
     self.conduit.associate_unit.assert_called_once_with(units[0])
     self.assertFalse(self.conduit.get_source_units.called)
示例#31
0
    def test_metadata(self):
        metadata = DockerImporter.metadata()

        self.assertEqual(metadata['id'], constants.IMPORTER_TYPE_ID)
        self.assertEqual(
            set(metadata['types']),
            set([
                constants.BLOB_TYPE_ID, constants.IMAGE_TYPE_ID,
                constants.MANIFEST_TYPE_ID, constants.TAG_TYPE_ID
            ]))
        self.assertTrue(len(metadata['display_name']) > 0)
示例#32
0
 def test_uploadstep_failure(self, UploadStep):
     """Assert that upload_unit() reports the failure of the UploadStep."""
     expected_msg = 'UploadStep failure message'
     UploadStep.side_effect = Exception(expected_msg)
     report = DockerImporter().upload_unit(self.repo,
                                           constants.IMAGE_TYPE_ID,
                                           self.unit_key, {},
                                           data.busybox_tar_path,
                                           self.conduit, self.config)
     self.assertFalse(report['success_flag'])
     self.assertEqual(report['summary'], expected_msg)
示例#33
0
    def test_purge_orphaned_nothing_orphaned(self, query_manager,
                                             association_manager, criteria):
        repo = mock.Mock()
        removed = [
            mock.Mock(id='manifest-1',
                      type_id=constants.MANIFEST_TYPE_ID,
                      metadata={'fs_layers': []}),
            mock.Mock(id='manifest-2',
                      type_id=constants.MANIFEST_TYPE_ID,
                      metadata={'fs_layers': []})
        ]

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        self.assertFalse(query_manager.called)
        self.assertFalse(criteria.called)
        self.assertFalse(association_manager.called)
示例#34
0
    def test_purge_orphaned_nothing_orphaned(self, query_manager, association_manager, criteria):
        repo = mock.Mock()
        removed = [
            mock.Mock(
                id='manifest-1',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': []}),
            mock.Mock(
                id='manifest-2',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': []})
        ]

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        self.assertFalse(query_manager.called)
        self.assertFalse(criteria.called)
        self.assertFalse(association_manager.called)
示例#35
0
    def test_metadata(self):
        metadata = DockerImporter.metadata()

        self.assertEqual(metadata['id'], constants.IMPORTER_TYPE_ID)
        self.assertEqual(
            metadata['types'],
            [
                models.Image.TYPE_ID,
                models.Manifest.TYPE_ID,
                models.Blob.TYPE_ID
            ])
        self.assertTrue(len(metadata['display_name']) > 0)
示例#36
0
    def test_remove_without_tag(self, mock_repo_manager):
        expected_tags = {
            u'tags': [{
                constants.IMAGE_TAG_KEY: 'apple',
                constants.IMAGE_ID_KEY: 'bar'
            }]
        }
        mock_repo_manager.return_value.get_repo_scratchpad.return_value = expected_tags

        DockerImporter().remove_units(self.repo, [self.mock_unit], self.config)
        mock_repo_manager.return_value.set_repo_scratchpad.assert_called_once_with(
            self.repo.id, expected_tags)
示例#37
0
    def test_import_all_manifests(self):
        units = [
            mock.Mock(type_id=constants.MANIFEST_TYPE_ID,
                      unit_key={'digest': 'A1234'},
                      metadata={'fs_layers': []}),
            mock.Mock(type_id=constants.MANIFEST_TYPE_ID,
                      unit_key={'digest': 'B1234'},
                      metadata={'fs_layers': []}),
        ]
        conduit = mock.Mock()
        conduit.get_source_units.side_effect = [units, []]

        # test
        importer = DockerImporter()
        importer._import_manifests(conduit, None)

        # validation
        self.assertEqual(conduit.associate_unit.call_args_list, [
            mock.call(units[0]),
            mock.call(units[1]),
        ])
示例#38
0
 def test_import_with_parent(self):
     mock_unit1 = mock.Mock(unit_key={'image_id': 'foo'},
                            metadata={'parent_id': 'bar'})
     mock_unit2 = mock.Mock(unit_key={'image_id': 'bar'}, metadata={})
     self.conduit.get_source_units.return_value = [mock_unit2]
     result = DockerImporter().import_units(self.source_repo,
                                            self.dest_repo,
                                            self.conduit,
                                            self.config,
                                            units=[mock_unit1])
     self.assertEquals(result, [mock_unit1, mock_unit2])
     calls = [mock.call(mock_unit1), mock.call(mock_unit2)]
     self.conduit.associate_unit.assert_has_calls(calls)
示例#39
0
 def test_import_all_images(self):
     units = [
         mock.Mock(type_id=constants.IMAGE_TYPE_ID,
                   unit_key={'image_id': 'foo'},
                   metadata={}),
         mock.Mock(type_id='not-an-image',
                   unit_key={'image_id': 'foo'},
                   metadata={}),
     ]
     self.conduit.get_source_units.return_value = units
     result = DockerImporter()._import_images(self.conduit, None)
     self.assertEquals(result, units[0:1])
     self.conduit.associate_unit.assert_called_once_with(units[0])
示例#40
0
    def test_saved_models(self, mock_save, mock_update_tags):
        DockerImporter().upload_unit(self.repo, constants.IMAGE_TYPE_ID,
                                     self.unit_key, {}, data.busybox_tar_path,
                                     self.conduit, self.config)

        models = mock_save.call_args[0][1]

        for model in models:
            self.assertTrue(isinstance(model, DockerImage))

        ids = [m.image_id for m in models]

        self.assertEqual(tuple(ids), data.busybox_ids)
示例#41
0
    def test_remove_without_tag(self, mock_repo_qs):
        expected_tags = {
            u'tags': [{
                constants.IMAGE_TAG_KEY: 'apple',
                constants.IMAGE_ID_KEY: 'bar'
            }]
        }
        mock_repo = mock_repo_qs.get_repo_or_missing_resource.return_value
        mock_repo.scratchpad = expected_tags

        DockerImporter()._purge_unreferenced_tags(self.repo, [self.mock_unit])

        self.assertEqual(mock_repo.scratchpad['tags'], expected_tags['tags'])
        mock_repo.save.assert_called_once_with()
示例#42
0
    def test_purge_orphaned_all_adopted(self, query_manager, association_manager, criteria):
        repo = mock.Mock()
        blobs = [
            {'blobSum': 'blob-0'},  # manifest => 1, 3     (not orphaned)
            {'blobSum': 'blob-1'},  # manifest => 1, 3     (not orphaned)
            {'blobSum': 'blob-2'},  # manifest => 1, 3     (not orphaned)
            {'blobSum': 'blob-3'},  # manifest => 1, 2, 3  (not orphaned)
            {'blobSum': 'blob-4'},  # manifest => 1, 2, 3  (not orphaned)
            {'blobSum': 'blob-5'},  # manifest => 2, 4, 3  (not orphaned)
            {'blobSum': 'blob-6'},  # manifest => 2, 3     (not orphaned)
        ]
        removed = [
            mock.Mock(
                id='manifest-1',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs[0:4]}),
            mock.Mock(
                id='manifest-2',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs[2:8]})
        ]
        others = [
            mock.Mock(
                id='manifest-3',
                type_id=constants.MANIFEST_TYPE_ID,
                metadata={'fs_layers': blobs}),
        ]

        query_manager.return_value.get_units_by_type.return_value = others

        # test
        importer = DockerImporter()
        importer._purge_orphaned_blobs(repo, removed)

        # validation
        self.assertFalse(criteria.called)
        self.assertFalse(association_manager.called)
示例#43
0
 def test_correct_calls(self, UploadStep):
     """
     Assert that upload_unit() builds the UploadStep correctly and calls its process_lifecycle()
     method.
     """
     report = DockerImporter().upload_unit(self.repo,
                                           constants.IMAGE_TYPE_ID,
                                           self.unit_key, {},
                                           data.busybox_tar_path,
                                           self.conduit, self.config)
     UploadStep.assert_called_once_with(repo=self.repo,
                                        file_path=data.busybox_tar_path,
                                        config=self.config)
     UploadStep.return_value.process_lifecycle.assert_called_once_with()
     self.assertTrue(report['success_flag'])
示例#44
0
class TestSyncRepo(unittest.TestCase):
    def setUp(self):
        super(TestSyncRepo, self).setUp()
        self.repo = Repository('repo1', working_dir='/a/b/c')
        self.sync_conduit = mock.MagicMock()
        self.config = mock.MagicMock()
        self.importer = DockerImporter()

    def test_calls_sync_step(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.assert_called_once_with(
            repo=self.repo,
            conduit=self.sync_conduit,
            config=self.config,
            working_dir=mock_mkdtemp.return_value)

    def test_calls_sync(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.return_value.sync.assert_called_once_with()

    def test_makes_temp_dir(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_mkdtemp.assert_called_once_with(dir=self.repo.working_dir)

    def test_removes_temp_dir(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_rmtree.assert_called_once_with(mock_mkdtemp.return_value,
                                            ignore_errors=True)

    def test_removes_temp_dir_after_exception(self, mock_rmtree, mock_mkdtemp,
                                              mock_sync_step):
        class MyError(Exception):
            pass

        mock_sync_step.return_value.sync.side_effect = MyError
        self.assertRaises(MyError, self.importer.sync_repo, self.repo,
                          self.sync_conduit, self.config)

        mock_rmtree.assert_called_once_with(mock_mkdtemp.return_value,
                                            ignore_errors=True)
示例#45
0
    def test_remove_with_tag(self, mock_repo_qs):
        units = [
            mock.MagicMock(type_id=constants.MANIFEST_TYPE_ID),
            mock.MagicMock(type_id=constants.IMAGE_TYPE_ID,
                           unit_key={'image_id': 'foo'},
                           metadata={})
        ]
        mock_repo = mock_repo_qs.get_repo_or_missing_resource.return_value
        mock_repo.scratchpad = {
            u'tags': [{
                constants.IMAGE_TAG_KEY: 'apple',
                constants.IMAGE_ID_KEY: 'foo'
            }]
        }

        DockerImporter().remove_units(mock_repo, units, mock.MagicMock())

        self.assertEqual(mock_repo.scratchpad['tags'], [])
示例#46
0
    def test_correct_calls(self, UploadStep):
        """
        Assert that upload_unit() builds the UploadStep correctly and calls its process_lifecycle()
        method.
        """
        unit_key = {'image_id': data.busybox_ids[0]}
        repo = Repository('repo1')
        conduit = mock.MagicMock()
        config = PluginCallConfiguration({}, {})

        DockerImporter().upload_unit(repo, constants.IMAGE_TYPE_ID, unit_key,
                                     {}, data.busybox_tar_path, conduit,
                                     config)

        UploadStep.assert_called_once_with(repo=repo,
                                           file_path=data.busybox_tar_path,
                                           config=config)
        UploadStep.return_value.process_lifecycle.assert_called_once_with()
示例#47
0
class TestSyncRepo(unittest.TestCase):
    def setUp(self):
        super(TestSyncRepo, self).setUp()
        self.repo = Repository('repo1', working_dir='/a/b/c')
        self.sync_conduit = mock.MagicMock()
        self.config = mock.MagicMock()
        self.importer = DockerImporter()

    def test_calls_sync_step(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.assert_called_once_with(repo=self.repo, conduit=self.sync_conduit,
                                               config=self.config,
                                               working_dir=mock_mkdtemp.return_value)

    def test_calls_sync(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_sync_step.return_value.sync.assert_called_once_with()

    def test_makes_temp_dir(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_mkdtemp.assert_called_once_with(dir=self.repo.working_dir)

    def test_removes_temp_dir(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        mock_rmtree.assert_called_once_with(mock_mkdtemp.return_value, ignore_errors=True)

    def test_removes_temp_dir_after_exception(self, mock_rmtree, mock_mkdtemp, mock_sync_step):
        class MyError(Exception):
            pass
        mock_sync_step.return_value.sync.side_effect = MyError
        self.assertRaises(MyError, self.importer.sync_repo, self.repo,
                          self.sync_conduit, self.config)

        mock_rmtree.assert_called_once_with(mock_mkdtemp.return_value, ignore_errors=True)
示例#48
0
class TestSyncRepo(unittest.TestCase):
    def setUp(self):
        super(TestSyncRepo, self).setUp()
        self.repo = Repository('repo1', working_dir='/a/b/c')
        self.sync_conduit = mock.MagicMock()
        self.config = mock.MagicMock()
        self.importer = DockerImporter()

    @mock.patch('pulp.plugins.util.publish_step.common_utils.get_working_directory',
                mock.MagicMock(return_value='/a/b/c'))
    def test_calls_sync_step(self, objects, mock_rmtree, mock_mkdtemp, v1_sync_step):
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        v1_sync_step.assert_called_once_with(
            repo=objects.get_repo_or_missing_resource.return_value, conduit=self.sync_conduit,
            config=self.config)
        objects.get_repo_or_missing_resource.assert_called_once_with(self.repo.id)

    @mock.patch('pulp.plugins.util.publish_step.common_utils.get_working_directory',
                mock.MagicMock(return_value='/a/b/c'))
    def test_calls_sync(self, objects, mock_rmtree, mock_mkdtemp, v1_sync_step):
        """
        Assert that the sync_repo() method calls sync() on the SyncStep.
        """
        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        objects.get_repo_or_missing_resource.assert_called_once_with(self.repo.id)
        v1_sync_step.return_value.process_lifecycle.assert_called_once_with()

    @mock.patch('pulp_docker.plugins.importers.sync.SyncStep')
    def test_fall_back_to_v1(self, sync_step, objects, mock_rmtree, mock_mkdtemp, v1_sync_step):
        """
        Ensure that the sync_repo() method falls back to Docker v1 if Docker v2 isn't available.
        """
        # Simulate the v2 API being unavailable
        sync_step.side_effect = NotImplementedError()

        self.importer.sync_repo(self.repo, self.sync_conduit, self.config)

        objects.get_repo_or_missing_resource.assert_called_once_with(self.repo.id)
        v1_sync_step.assert_called_once_with(
            repo=objects.get_repo_or_missing_resource.return_value, conduit=self.sync_conduit,
            config=self.config)
        v1_sync_step.return_value.process_lifecycle.assert_called_once_with()
示例#49
0
    def test_metadata(self):
        metadata = DockerImporter.metadata()

        self.assertEqual(metadata['id'], constants.IMPORTER_TYPE_ID)
        self.assertEqual(metadata['types'], [constants.IMAGE_TYPE_ID])
        self.assertTrue(len(metadata['display_name']) > 0)
示例#50
0
 def setUp(self):
     super(TestCancel, self).setUp()
     self.importer = DockerImporter()