예제 #1
0
 def setUp(self, mock_parent_open_file_handle):
     nevra_in_repo = set([('pulp-test-package', '0', '0.3.1', '1.fc22',
                           'x86_64')])
     self.context = UpdateinfoXMLFileContext('/foo',
                                             nevra_in_repo,
                                             checksum_type='sha256')
     self.context.metadata_file_handle = StringIO()
     self.context._open_metadata_file_handle()
    def test_updateinfo_file_creation(self):

        path = os.path.join(self.metadata_file_dir, REPO_DATA_DIR_NAME, UPDATE_INFO_XML_FILE_NAME)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)

        context._open_metadata_file_handle()
        context._close_metadata_file_handle()

        self.assertTrue(os.path.exists(path))
예제 #3
0
    def test_updateinfo_unit_metadata(self):

        path = os.path.join(self.metadata_file_dir, REPO_DATA_DIR_NAME,
                            UPDATE_INFO_XML_FILE_NAME)

        handle = open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r')
        generator = packages.package_list_generator(
            handle, 'update', updateinfo.process_package_element)

        erratum_unit = next(generator)

        # just checking
        self.assertEqual(erratum_unit.unit_key['errata_id'], 'RHEA-2010:9999')

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)
        context._open_metadata_file_handle()
        context.add_unit_metadata(erratum_unit)
        context._close_metadata_file_handle()

        self.assertNotEqual(os.path.getsize(path), 0)

        updateinfo_handle = gzip.open(path, 'r')
        content = updateinfo_handle.read()
        updateinfo_handle.close()

        self.assertEqual(content.count('from="*****@*****.**"'), 1)
        self.assertEqual(content.count('status="final"'), 1)
        self.assertEqual(content.count('type="enhancements"'), 1)
        self.assertEqual(content.count('version="1"'), 1)
        self.assertEqual(content.count('<id>RHEA-2010:9999</id>'), 1)
        self.assertEqual(content.count('<collection short="F13PTP">'), 1)
        self.assertEqual(content.count('<package'), 2)
        self.assertEqual(
            content.count(
                '<sum type="md5">f3c197a29d9b66c5b65c5d62b25db5b4</sum>'), 1)
예제 #4
0
    def test_updateinfo_unit_metadata(self):

        path = os.path.join(self.metadata_file_dir,
                            REPO_DATA_DIR_NAME,
                            UPDATE_INFO_XML_FILE_NAME)

        handle = open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r')
        generator = packages.package_list_generator(handle, 'update',
                                                    updateinfo.process_package_element)

        erratum_unit = next(generator)

        # just checking
        self.assertEqual(erratum_unit.unit_key['id'], 'RHEA-2010:9999')

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)
        context._open_metadata_file_handle()
        context.add_unit_metadata(erratum_unit)
        context._close_metadata_file_handle()

        self.assertNotEqual(os.path.getsize(path), 0)

        updateinfo_handle = gzip.open(path, 'r')
        content = updateinfo_handle.read()
        updateinfo_handle.close()

        self.assertEqual(content.count('from="*****@*****.**"'), 1)
        self.assertEqual(content.count('status="final"'), 1)
        self.assertEqual(content.count('type="enhancements"'), 1)
        self.assertEqual(content.count('version="1"'), 1)
        self.assertEqual(content.count('<id>RHEA-2010:9999</id>'), 1)
        self.assertEqual(content.count('<collection short="F13PTP">'), 1)
        self.assertEqual(content.count('<package'), 2)
        self.assertEqual(content.count('<sum type="md5">f3c197a29d9b66c5b65c5d62b25db5b4</sum>'), 1)
예제 #5
0
    def test_updateinfo_get_repo_unit_nevra_return(self):
        nevra_fields = ('name', 'epoch', 'version', 'release', 'arch')
        unit1_nevra = ('n1', 'e1', 'v1', 'r1', 'a1')
        unit1_nevra_dict = dict(zip(nevra_fields, unit1_nevra))
        unit2_nevra = ('n2', 'e2', 'v2', 'r2', 'a2')
        unit2_nevra_dict = dict(zip(nevra_fields, unit2_nevra))

        erratum_unit = Mock()
        erratum_unit.pkglist = [{'packages': [
            unit1_nevra_dict,
            unit2_nevra_dict,
        ]}]

        context = UpdateinfoXMLFileContext(self.metadata_file_dir, set([unit1_nevra]))
        repo_unit_nevra = context._get_repo_unit_nevra(erratum_unit)

        self.assertEqual(len(repo_unit_nevra), 1)
        self.assertTrue(unit1_nevra_dict in repo_unit_nevra)
        self.assertTrue(unit2_nevra_dict not in repo_unit_nevra)
예제 #6
0
    def test_updateinfo_repo_unit_nevra_q_filter(self, mock_rpm):
        # A mongoengine "QCombination" object is used to efficiently search for units
        # by nevra. This checks that the QCombination object is properly created based
        # on the errata unit parsed from the test updateinfo XML.
        with open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r') as handle:
            generator = packages.package_list_generator(
                handle, 'update', updateinfo.process_package_element)
            erratum_unit = next(generator)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)
        context._repo_unit_nevra(erratum_unit, 'mock_repo')

        # Call 0 to mock_rpm's filter should have one arg, which should be the QCombination
        # object that is built with an OR operator, with two children (one for each package
        # in the errata unit that was passed to the method under test.
        qcombination = mock_rpm.objects.filter.call_args_list[0][0][0]
        self.assertTrue(isinstance(qcombination, QCombination))
        self.assertEqual(qcombination.operation, qcombination.OR)
        self.assertEqual(len(qcombination.children), 2)
예제 #7
0
    def test_updateinfo_unit_metadata_with_repo(self,
                                                mock__get_repo_unit_nevra):

        path = os.path.join(self.metadata_file_dir, REPO_DATA_DIR_NAME,
                            UPDATE_INFO_XML_FILE_NAME)

        handle = open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r')
        generator = packages.package_list_generator(
            handle, 'update', updateinfo.process_package_element)

        # mock out the repo/unit nevra matcher so that only one unit in the referenced errata
        # is included in the output updateinfo XML
        mock__get_repo_unit_nevra.return_value = [
            {
                'name': 'patb',
                'epoch': '0',
                'version': '0.1',
                'release': '2',
                'arch': 'x86_64'
            },
        ]

        erratum_unit = next(generator)

        # just checking
        self.assertEqual(erratum_unit.unit_key['errata_id'], 'RHEA-2010:9999')

        mock_conduit = Mock()
        mock_conduit.repo_id = 'mock_conduit_repo'
        context = UpdateinfoXMLFileContext(self.metadata_file_dir,
                                           set(),
                                           conduit=mock_conduit,
                                           checksum_type='md5')
        context._open_metadata_file_handle()
        context.add_unit_metadata(erratum_unit)
        context._close_metadata_file_handle()

        self.assertNotEqual(os.path.getsize(path), 0)

        updateinfo_handle = gzip.open(path, 'r')
        content = updateinfo_handle.read()
        updateinfo_handle.close()

        self.assertEqual(content.count('from="*****@*****.**"'), 1)
        self.assertEqual(content.count('status="final"'), 1)
        self.assertEqual(content.count('type="enhancements"'), 1)
        self.assertEqual(content.count('version="1"'), 1)
        self.assertEqual(content.count('<id>RHEA-2010:9999</id>'), 1)
        self.assertEqual(content.count('<collection short="F13PTP">'), 1)
        self.assertEqual(content.count('<package'), 1)
        self.assertEqual(
            content.count(
                '<sum type="md5">f3c197a29d9b66c5b65c5d62b25db5b4</sum>'), 1)
    def test_updateinfo_repo_unit_nevra_q_filter(self, mock_rpm):
        # A mongoengine "QCombination" object is used to efficiently search for units
        # by nevra. This checks that the QCombination object is properly created based
        # on the errata unit parsed from the test updateinfo XML.
        with open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r') as handle:
            generator = packages.package_list_generator(
                handle, 'update', updateinfo.process_package_element)
            erratum_unit = next(generator)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)
        context._repo_unit_nevra(erratum_unit, 'mock_repo')

        # Call 0 to mock_rpm's filter should have one arg, which should be the QCombination
        # object that is built with an OR operator, with two children (one for each package
        # in the errata unit that was passed to the method under test.
        qcombination = mock_rpm.objects.filter.call_args_list[0][0][0]
        self.assertTrue(isinstance(qcombination, QCombination))
        self.assertEqual(qcombination.operation, qcombination.OR)
        self.assertEqual(len(qcombination.children), 2)
예제 #9
0
    def test_updateinfo_get_repo_unit_nevra_no_epoch(self):
        """
        Test that epoch defaults to 0 and corresponding erratum and RPM unit match
        """
        nevra_fields = ('name', 'epoch', 'version', 'release', 'arch')
        erratum_unit_nevra = ('n1', None, 'v1', 'r1', 'a1')
        erratum_unit_nevra_dict = dict(zip(nevra_fields, erratum_unit_nevra))
        rpm_unit_nevra = ('n1', '0', 'v1', 'r1', 'a1')
        rpm_unit_nevra_dict = dict(zip(nevra_fields, rpm_unit_nevra))

        erratum_unit = Mock()
        erratum_unit.pkglist = [{'packages': [
            erratum_unit_nevra_dict,
        ]}]

        context = UpdateinfoXMLFileContext(self.metadata_file_dir, set([rpm_unit_nevra]))
        repo_unit_nevra = context._get_repo_unit_nevra(erratum_unit)

        self.assertEqual(len(repo_unit_nevra), 1)
        self.assertTrue(rpm_unit_nevra_dict in repo_unit_nevra)
예제 #10
0
    def test_updateinfo_repo_unit_nevra_return(self, mock_rcu, mock_rpm):
        # Build up the mock data as well as the expected returns
        nevra_fields = ('name', 'epoch', 'version', 'release', 'arch')
        unit1_nevra = ('n1', 'e1', 'v1', 'r1', 'a1')
        unit1_nevra_dict = dict(zip(nevra_fields, unit1_nevra))
        unit2_nevra = ('n2', 'e2', 'v2', 'r2', 'a2')
        unit2_nevra_dict = dict(zip(nevra_fields, unit2_nevra))

        # This is the result to the query for all units with a given nevra
        # The expected value is a list of tuples containing unit ids and nevra fields;
        mock_rpm.objects.filter().scalar.return_value = [
            ('id1', ) + unit1_nevra,
            ('id2', ) + unit2_nevra,
        ]
        # The expected value here is a list of unit IDs from the previous query that are
        # associated with our mock repo.
        mock_rcu.objects.filter().scalar.return_value = ['id1']

        # Load the updateinfo XML to get an erratum unit to process
        with open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r') as handle:
            generator = packages.package_list_generator(
                handle, 'update', updateinfo.process_package_element)
            erratum_unit = next(generator)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)
        repo_unit_nevra = context._repo_unit_nevra(erratum_unit, 'mock_repo')

        # Call 0 created the scalar mock, so we're interested in call 1. In this case, check
        # that filter was called at least once with the expected filter kwargs and values.
        mock_rcu.objects.filter.assert_any_call(unit_id__in=['id2', 'id1'],
                                                repo_id='mock_repo')

        # And finally, make sure the return value is actually good!
        # We made the RPM mock simulate two units known to pulp with the nevra seen in our errata.
        # Then, we made the RepositoryContentUnit mock simulate that only one of those units is
        # associated with the passed-in repo. The return value should be a list with only the
        # single matching unit's nevra dict in it.
        self.assertEqual(len(repo_unit_nevra), 1)
        self.assertTrue(unit1_nevra_dict in repo_unit_nevra)
        self.assertTrue(unit2_nevra_dict not in repo_unit_nevra)
    def test_updateinfo_repo_unit_nevra_return(self, mock_rcu, mock_rpm):
        # Build up the mock data as well as the expected returns
        nevra_fields = ('name', 'epoch', 'version', 'release', 'arch')
        unit1_nevra = ('n1', 'e1', 'v1', 'r1', 'a1')
        unit1_nevra_dict = dict(zip(nevra_fields, unit1_nevra))
        unit2_nevra = ('n2', 'e2', 'v2', 'r2', 'a2')
        unit2_nevra_dict = dict(zip(nevra_fields, unit2_nevra))

        # This is the result to the query for all units with a given nevra
        # The expected value is a list of tuples containing unit ids and nevra fields;
        mock_rpm.objects.filter().scalar.return_value = [
            ('id1',) + unit1_nevra,
            ('id2',) + unit2_nevra,
        ]
        # The expected value here is a list of unit IDs from the previous query that are
        # associated with our mock repo.
        mock_rcu.objects.filter().scalar.return_value = ['id1']

        # Load the updateinfo XML to get an erratum unit to process
        with open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r') as handle:
            generator = packages.package_list_generator(
                handle, 'update', updateinfo.process_package_element)
            erratum_unit = next(generator)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)
        repo_unit_nevra = context._repo_unit_nevra(erratum_unit, 'mock_repo')

        # Call 0 created the scalar mock, so we're interested in call 1. In this case, check
        # that filter was called at least once with the expected filter kwargs and values.
        mock_rcu.objects.filter.assert_any_call(unit_id__in=['id2', 'id1'], repo_id='mock_repo')

        # And finally, make sure the return value is actually good!
        # We made the RPM mock simulate two units known to pulp with the nevra seen in our errata.
        # Then, we made the RepositoryContentUnit mock simulate that only one of those units is
        # associated with the passed-in repo. The return value should be a list with only the
        # single matching unit's nevra dict in it.
        self.assertEqual(len(repo_unit_nevra), 1)
        self.assertTrue(unit1_nevra_dict in repo_unit_nevra)
        self.assertTrue(unit2_nevra_dict not in repo_unit_nevra)
예제 #12
0
    def test_updateinfo_get_repo_unit_nevra_return(self):
        nevra_fields = ('name', 'epoch', 'version', 'release', 'arch')
        unit1_nevra = ('n1', 'e1', 'v1', 'r1', 'a1')
        unit1_nevra_dict = dict(zip(nevra_fields, unit1_nevra))
        unit2_nevra = ('n2', 'e2', 'v2', 'r2', 'a2')
        unit2_nevra_dict = dict(zip(nevra_fields, unit2_nevra))

        erratum_unit = Mock()
        erratum_unit.pkglist = [{
            'packages': [
                unit1_nevra_dict,
                unit2_nevra_dict,
            ]
        }]

        context = UpdateinfoXMLFileContext(self.metadata_file_dir,
                                           set([unit1_nevra]))
        repo_unit_nevra = context._get_repo_unit_nevra(erratum_unit)

        self.assertEqual(len(repo_unit_nevra), 1)
        self.assertTrue(unit1_nevra_dict in repo_unit_nevra)
        self.assertTrue(unit2_nevra_dict not in repo_unit_nevra)
예제 #13
0
    def test_updateinfo_get_repo_unit_nevra_no_epoch(self):
        """
        Test that epoch defaults to 0 and corresponding erratum and RPM unit match
        """
        nevra_fields = ('name', 'epoch', 'version', 'release', 'arch')
        erratum_unit_nevra = ('n1', None, 'v1', 'r1', 'a1')
        erratum_unit_nevra_dict = dict(zip(nevra_fields, erratum_unit_nevra))
        rpm_unit_nevra = ('n1', '0', 'v1', 'r1', 'a1')
        rpm_unit_nevra_dict = dict(zip(nevra_fields, rpm_unit_nevra))

        erratum_unit = Mock()
        erratum_unit.pkglist = [{
            'packages': [
                erratum_unit_nevra_dict,
            ]
        }]

        context = UpdateinfoXMLFileContext(self.metadata_file_dir,
                                           set([rpm_unit_nevra]))
        repo_unit_nevra = context._get_repo_unit_nevra(erratum_unit)

        self.assertEqual(len(repo_unit_nevra), 1)
        self.assertTrue(rpm_unit_nevra_dict in repo_unit_nevra)
예제 #14
0
    def test_updateinfo_opening_closing_tags(self):

        path = os.path.join(self.metadata_file_dir, REPO_DATA_DIR_NAME,
                            UPDATE_INFO_XML_FILE_NAME)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)

        context._open_metadata_file_handle()

        self.assertRaises(NotImplementedError, context._write_root_tag_close)

        context._write_root_tag_open()

        try:
            context._write_root_tag_close()

        except Exception, e:
            self.fail(e.message)
예제 #15
0
    def test_updateinfo_file_creation(self):

        path = os.path.join(self.metadata_file_dir, REPO_DATA_DIR_NAME,
                            UPDATE_INFO_XML_FILE_NAME)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)

        context._open_metadata_file_handle()
        context._close_metadata_file_handle()

        self.assertTrue(os.path.exists(path))
    def test_updateinfo_opening_closing_tags(self):

        path = os.path.join(self.metadata_file_dir, REPO_DATA_DIR_NAME, UPDATE_INFO_XML_FILE_NAME)

        context = UpdateinfoXMLFileContext(self.metadata_file_dir)

        context._open_metadata_file_handle()

        self.assertRaises(NotImplementedError, context._write_root_tag_close)

        context._write_root_tag_open()

        try:
            context._write_root_tag_close()

        except Exception, e:
            self.fail(e.message)
예제 #17
0
    def test_updateinfo_unit_metadata_with_repo(self, mock__get_repo_unit_nevra):

        path = os.path.join(self.metadata_file_dir,
                            REPO_DATA_DIR_NAME,
                            UPDATE_INFO_XML_FILE_NAME)

        handle = open(os.path.join(DATA_DIR, 'updateinfo.xml'), 'r')
        generator = packages.package_list_generator(handle, 'update',
                                                    updateinfo.process_package_element)

        # mock out the repo/unit nevra matcher so that only one unit in the referenced errata
        # is included in the output updateinfo XML
        mock__get_repo_unit_nevra.return_value = [
            {'name': 'patb', 'epoch': '0', 'version': '0.1',
             'release': '2', 'arch': 'x86_64'},
        ]

        erratum_unit = next(generator)

        # just checking
        self.assertEqual(erratum_unit.unit_key['errata_id'], 'RHEA-2010:9999')

        mock_conduit = Mock()
        mock_conduit.repo_id = 'mock_conduit_repo'
        context = UpdateinfoXMLFileContext(self.metadata_file_dir, set(),
                                           conduit=mock_conduit, checksum_type='md5')
        context._open_metadata_file_handle()
        context.add_unit_metadata(erratum_unit)
        context._close_metadata_file_handle()

        self.assertNotEqual(os.path.getsize(path), 0)

        updateinfo_handle = gzip.open(path, 'r')
        content = updateinfo_handle.read()
        updateinfo_handle.close()

        self.assertEqual(content.count('from="*****@*****.**"'), 1)
        self.assertEqual(content.count('status="final"'), 1)
        self.assertEqual(content.count('type="enhancements"'), 1)
        self.assertEqual(content.count('version="1"'), 1)
        self.assertEqual(content.count('<id>RHEA-2010:9999</id>'), 1)
        self.assertEqual(content.count('<collection short="F13PTP">'), 1)
        self.assertEqual(content.count('<package'), 1)
        self.assertEqual(content.count('<sum type="md5">f3c197a29d9b66c5b65c5d62b25db5b4</sum>'), 1)
예제 #18
0
 def setUp(self, mock_parent_open_file_handle):
     nevra_in_repo = set([('pulp-test-package', '0', '0.3.1', '1.fc22', 'x86_64')])
     self.context = UpdateinfoXMLFileContext('/foo', nevra_in_repo, checksum_type='sha256')
     self.context.metadata_file_handle = StringIO()
     self.context._open_metadata_file_handle()
예제 #19
0
 def setUp(self, mock_parent_open_file_handle):
     self.context = UpdateinfoXMLFileContext('/foo')
     self.context.metadata_file_handle = StringIO()
     self.context._open_metadata_file_handle()
예제 #20
0
class UpdateinfoXMLFileContextTests(unittest.TestCase):
    """
    Test correct generation of comps.xml file
    """
    @mock.patch(
        'pulp.plugins.util.metadata_writer.MetadataFileContext._open_metadata_file_handle'
    )
    def setUp(self, mock_parent_open_file_handle):
        self.context = UpdateinfoXMLFileContext('/foo')
        self.context.metadata_file_handle = StringIO()
        self.context._open_metadata_file_handle()

    def _generate_erratum_unit(self):
        """
        Generate erratum unit.
        """
        packages = [{
            'src': 'pulp-test-package-0.3.1-1.fc22.src.rpm',
            'name': 'pulp-test-package',
            'arch': 'x86_64',
            'sums': 'sums',
            'filename': 'pulp-test-package-0.3.1-1.fc22.x86_64.rpm',
            'epoch': '0',
            'version': '0.3.1',
            'release': '1.fc22',
            'type': 'sha256'
        }]
        unit_data = {
            'errata_id':
            'RHSA-2014:0042',
            'title':
            'Some Title',
            'release':
            '2',
            'rights':
            'You have the right to remain silent.',
            'solution':
            'Open Source is the solution to your problems.',
            'severity':
            'High',
            'summary':
            'A Summary',
            # Note that pushcount is an int. This should be OK (no exceptions).
            'pushcount':
            1,
            'status':
            'symbol',
            'type':
            'security',
            'version':
            '2.4.1',
            'issued':
            '2014-05-27 00:00:00',
            'references': [{
                'href': 'https://bugzilla.hostname/bug.cgi?id=XXXXX',
                'type': 'bugzilla',
                'id': 'XXXXX',
                'title': 'some title'
            }],
            'updated':
            '2014-05-28 00:00:00',
            'pkglist': [{
                'packages': packages,
                'name': 'test-name',
                'short': ''
            }, {
                'packages': packages,
                'name': 'test-name',
                'short': ''
            }]
        }
        return models.Errata(**unit_data)

    def test_handles_integer_pushcount(self):
        """
        Test that the pushcount of type integer handled well.

        We had a bug[0] wherein uploaded errata couldn't be published because the pushcount would
        be represented as an int. Synchronized errata would have this field represented as a
        basestring. The descrepancy between these has been filed as a separate issue[1].

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1100848
        [1] https://bugzilla.redhat.com/show_bug.cgi?id=1101728
        """
        erratum = self._generate_erratum_unit()
        erratum.description = 'A Description'

        self.context.add_unit_metadata(erratum)

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('<pushcount>1</pushcount>' in generated_xml)

    def test_no_description(self):
        """
        Test that if the erratum has no description, the empty description element should be
        generated.

        We had a bug[0] wherein an empty or missing description would result in
        XML that did not include a description element. The corresponding upstream
        repo (epel5) did have a description element that was merely empty, so the
        distributor was modified to always include the description element.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1138475
        """
        erratum = self._generate_erratum_unit()

        self.context.add_unit_metadata(erratum)

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue(
            re.search('<description */>', generated_xml) is not None)

    def test_no_duplicated_pkglists(self):
        """
        Test that no duplicated pkglists are generated.
        """
        erratum = self._generate_erratum_unit()
        print erratum.pkglist
        expected_pkg_str = '<package src="pulp-test-package-0.3.1-1.fc22.src.rpm" ' \
                           'name="pulp-test-package" epoch="0" version="0.3.1" '\
                           'release="1.fc22" arch="x86_64">'
        self.context.add_unit_metadata(erratum)

        generated_xml = self.context.metadata_file_handle.getvalue()
        print generated_xml
        self.assertEqual(generated_xml.count(expected_pkg_str), 1)

    def test_add_errata_unit_metadata(self):
        """
        Test the generation of erratum unit.
        """
        erratum = self._generate_erratum_unit()
        self.context.add_unit_metadata(erratum)
        generated_xml = self.context.metadata_file_handle.getvalue()
        expected_xml = '<update status="symbol" from="" version="2.4.1" type="security">\n' \
                       '  <id>RHSA-2014:0042</id>\n' \
                       '  <issued date="2014-05-27 00:00:00" />\n' \
                       '  <reboot_suggested>False</reboot_suggested>\n' \
                       '  <title>Some Title</title>\n' \
                       '  <release>2</release>\n' \
                       '  <rights>You have the right to remain silent.</rights>\n' \
                       '  <solution>Open Source is the solution to your problems.</solution>\n' \
                       '  <severity>High</severity>\n' \
                       '  <summary>A Summary</summary>\n' \
                       '  <pushcount>1</pushcount>\n' \
                       '  <description />\n' \
                       '  <updated date="2014-05-28 00:00:00" />\n' \
                       '  <references>\n' \
                       '    <reference href="https://bugzilla.hostname/bug.cgi?id=XXXXX" ' \
                       'type="bugzilla" id="XXXXX" title="some title" />\n' \
                       '  </references>\n' \
                       '  <pkglist>\n' \
                       '    <collection short="">\n' \
                       '      <name>test-name</name>\n' \
                       '      <package src="pulp-test-package-0.3.1-1.fc22.src.rpm" ' \
                       'name="pulp-test-package" epoch="0" version="0.3.1" release="1.fc22" ' \
                       'arch="x86_64">\n' \
                       '        <filename>pulp-test-package-0.3.1-1.fc22.x86_64.rpm</filename>\n' \
                       '        <reboot_suggested>False</reboot_suggested>\n' \
                       '      </package>\n' \
                       '    </collection>\n' \
                       '  </pkglist>\n' \
                       '</update>\n'
        self.assertEqual(generated_xml, expected_xml)
예제 #21
0
 def setUp(self, mock_parent_open_file_handle):
     self.context = UpdateinfoXMLFileContext('/foo', checksum_type='sha256')
     self.context.metadata_file_handle = StringIO()
     self.context._open_metadata_file_handle()
예제 #22
0
class UpdateinfoXMLFileContextTests(unittest.TestCase):
    """
    Test correct generation of updateinfo.xml file
    """
    @mock.patch('pulp.plugins.util.metadata_writer.MetadataFileContext._open_metadata_file_handle')
    def setUp(self, mock_parent_open_file_handle):
        self.context = UpdateinfoXMLFileContext('/foo', checksum_type='sha256')
        self.context.metadata_file_handle = StringIO()
        self.context._open_metadata_file_handle()

    def _generate_erratum_unit(self):
        """
        Generate erratum unit.
        """
        packages = [{'src': 'pulp-test-package-0.3.1-1.fc22.src.rpm',
                     'name': 'pulp-test-package',
                     'arch': 'x86_64',
                     'sums': 'sums',
                     'filename': 'pulp-test-package-0.3.1-1.fc22.x86_64.rpm',
                     'epoch': '0',
                     'version': '0.3.1',
                     'release': '1.fc22',
                     'type': 'sha256'},
                    {'src': 'another-test-package-3.2-1.fc22.src.rpm',
                     'name': 'another-test-package',
                     'arch': 'x86_64',
                     'filename': 'another-test-package-0.3.1-1.fc22.x86_64.rpm',
                     'epoch': '0',
                     'version': '3.2',
                     'release': '1.fc22',
                     'sum': ['md5', 'md5_checksum', 'sha256', 'sha256_checksum']}]
        unit_data = {'errata_id': 'RHSA-2014:0042',
                     'title': 'Some Title',
                     'release': '2',
                     'rights': 'You have the right to remain silent.',
                     'solution': 'Open Source is the solution to your problems.',
                     'severity': 'High',
                     'summary': 'A Summary',
                     # Note that pushcount is an int. This should be OK (no exceptions).
                     'pushcount': 1,
                     'status': 'symbol',
                     'type': 'security',
                     'version': '2.4.1',
                     'issued': '2014-05-27 00:00:00',
                     'references': [{'href': 'https://bugzilla.hostname/bug.cgi?id=XXXXX',
                                     'type': 'bugzilla',
                                     'id': 'XXXXX',
                                     'title': 'some title'}],
                     'updated': '2014-05-28 00:00:00',
                     'pkglist': [{'packages': packages, 'name': 'test-name', 'short': ''},
                                 {'packages': packages, 'name': 'test-name', 'short': ''}]}
        return models.Errata(**unit_data)

    def _filtered_pkglist(self, erratum_unit):
        # Return a "filtered" pkglist. Since the test unit generated in _generate_erratum_unit
        # contains two identical pkglists, return one of them to simulate it having been filtered.
        return erratum_unit.pkglist[0]

    def test_handles_integer_pushcount(self):
        """
        Test that the pushcount of type integer handled well.

        We had a bug[0] wherein uploaded errata couldn't be published because the pushcount would
        be represented as an int. Synchronized errata would have this field represented as a
        basestring. The descrepancy between these has been filed as a separate issue[1].

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1100848
        [1] https://bugzilla.redhat.com/show_bug.cgi?id=1101728
        """
        erratum = self._generate_erratum_unit()
        erratum.description = 'A Description'

        self.context.add_unit_metadata(erratum, self._filtered_pkglist(erratum))

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('<pushcount>1</pushcount>' in generated_xml)

    def test_no_description(self):
        """
        Test that if the erratum has no description, the empty description element should be
        generated.

        We had a bug[0] wherein an empty or missing description would result in
        XML that did not include a description element. The corresponding upstream
        repo (epel5) did have a description element that was merely empty, so the
        distributor was modified to always include the description element.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1138475
        """
        erratum = self._generate_erratum_unit()

        self.context.add_unit_metadata(erratum, self._filtered_pkglist(erratum))

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue(re.search('<description */>', generated_xml) is not None)

    def test_reboot_suggested(self):
        """
        Test that when reboot_suggested is True, the element is present in the XML
        """
        erratum = self._generate_erratum_unit()
        erratum.reboot_suggested = True

        self.context.add_unit_metadata(erratum, self._filtered_pkglist(erratum))

        xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('reboot_suggested' in xml)

    def test_no_reboot_suggested(self):
        """
        Test that when reboot_suggested is False, the element is not present in the XML
        """
        erratum = self._generate_erratum_unit()
        erratum.reboot_suggested = False

        self.context.add_unit_metadata(erratum, self._filtered_pkglist(erratum))

        xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('reboot_suggested' not in xml)

    def test__get_package_checksum_tuple_sums_field(self):
        """
        Test that the `sums` package field is handled correctly.
        """
        erratum = self._generate_erratum_unit()
        package_with_sums_field = self._filtered_pkglist(erratum)['packages'][0]
        result = self.context._get_package_checksum_tuple(package_with_sums_field)
        expected_checksum_tuple = ('sha256', 'sums')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_dist_type(self):
        """
        Test that the package checksum of the distributor checksum type is published if available.
        """
        erratum = self._generate_erratum_unit()
        package_with_multiple_checksums = self._filtered_pkglist(erratum)['packages'][1]
        result = self.context._get_package_checksum_tuple(package_with_multiple_checksums)
        expected_checksum_tuple = ('sha256', 'sha256_checksum')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_unknown_type(self):
        """
        Test that the longest package checksum is published if the distributor checksum type is not
        available.
        """
        erratum = self._generate_erratum_unit()
        self.context.checksum_type = 'unknown type #1'
        package_with_multiple_checksums = self._filtered_pkglist(erratum)['packages'][1]
        result = self.context._get_package_checksum_tuple(package_with_multiple_checksums)
        expected_checksum_tuple = ('sha256', 'sha256_checksum')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_updateinfo_type(self):
        """
        Test that the package checksum of requested checksum type for updateinfo.xml is
        published if available.
        """
        erratum = self._generate_erratum_unit()
        self.context.checksum_type = 'sha256'
        self.context.updateinfo_checksum_type = 'md5'
        package_with_multiple_checksums = self._filtered_pkglist(erratum)['packages'][1]
        result = self.context._get_package_checksum_tuple(package_with_multiple_checksums)
        expected_checksum_tuple = ('md5', 'md5_checksum')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_updateinfo_unknown_type(self):
        """
        Test that the proper exception is raised if the updateinfo checksum type is unavailable.
        """
        erratum = self._generate_erratum_unit()
        self.context.checksum_type = 'sha256'
        self.context.updateinfo_checksum_type = 'unknown type'
        package_with_multiple_checksums = self._filtered_pkglist(erratum)['packages'][1]
        with self.assertRaises(PulpCodedException) as e:
            self.context._get_package_checksum_tuple(package_with_multiple_checksums)
        self.assertEqual(e.exception.error_code.code, 'RPM1012')

    def test_add_errata_unit_metadata(self):
        """
        Test the generation of erratum unit.
        """
        erratum = self._generate_erratum_unit()
        self.context.add_unit_metadata(erratum, self._filtered_pkglist(erratum))
        generated_xml = self.context.metadata_file_handle.getvalue()
        expected_xml = '<update status="symbol" from="" version="2.4.1" type="security">\n' \
                       '  <id>RHSA-2014:0042</id>\n' \
                       '  <issued date="2014-05-27 00:00:00" />\n' \
                       '  <title>Some Title</title>\n' \
                       '  <release>2</release>\n' \
                       '  <rights>You have the right to remain silent.</rights>\n' \
                       '  <solution>Open Source is the solution to your problems.</solution>\n' \
                       '  <severity>High</severity>\n' \
                       '  <summary>A Summary</summary>\n' \
                       '  <pushcount>1</pushcount>\n' \
                       '  <description />\n' \
                       '  <updated date="2014-05-28 00:00:00" />\n' \
                       '  <references>\n' \
                       '    <reference href="https://bugzilla.hostname/bug.cgi?id=XXXXX" ' \
                       'type="bugzilla" id="XXXXX" title="some title" />\n' \
                       '  </references>\n' \
                       '  <pkglist>\n' \
                       '    <collection short="">\n' \
                       '      <name>test-name</name>\n' \
                       '      <package src="pulp-test-package-0.3.1-1.fc22.src.rpm" ' \
                       'name="pulp-test-package" epoch="0" version="0.3.1" release="1.fc22" ' \
                       'arch="x86_64">\n' \
                       '        <filename>pulp-test-package-0.3.1-1.fc22.x86_64.rpm</filename>\n' \
                       '        <sum type="sha256">sums</sum>\n' \
                       '      </package>\n' \
                       '      <package src="another-test-package-3.2-1.fc22.src.rpm" ' \
                       'name="another-test-package" epoch="0" version="3.2" release="1.fc22" ' \
                       'arch="x86_64">\n' \
                       '        <filename>another-test-package-0.3.1-1.fc22.x86_64.rpm' \
                       '</filename>\n' \
                       '        <sum type="sha256">sha256_checksum</sum>\n' \
                       '      </package>\n' \
                       '    </collection>\n' \
                       '  </pkglist>\n' \
                       '</update>\n'
        self.assertEqual(generated_xml, expected_xml)
예제 #23
0
class UpdateinfoXMLFileContextTests(unittest.TestCase):
    """
    Test correct generation of comps.xml file
    """
    @mock.patch('pulp.plugins.util.metadata_writer.MetadataFileContext._open_metadata_file_handle')
    def setUp(self, mock_parent_open_file_handle):
        self.context = UpdateinfoXMLFileContext('/foo')
        self.context.metadata_file_handle = StringIO()
        self.context._open_metadata_file_handle()

    def _generate_erratum_unit(self):
        """
        Generate erratum unit.
        """
        packages = [{'src': 'pulp-test-package-0.3.1-1.fc22.src.rpm',
                     'name': 'pulp-test-package',
                     'arch': 'x86_64',
                     'sums': 'sums',
                     'filename': 'pulp-test-package-0.3.1-1.fc22.x86_64.rpm',
                     'epoch': '0',
                     'version': '0.3.1',
                     'release': '1.fc22',
                     'type': 'sha256'}]
        unit_data = {'errata_id': 'RHSA-2014:0042',
                     'title': 'Some Title',
                     'release': '2',
                     'rights': 'You have the right to remain silent.',
                     'solution': 'Open Source is the solution to your problems.',
                     'severity': 'High',
                     'summary': 'A Summary',
                     # Note that pushcount is an int. This should be OK (no exceptions).
                     'pushcount': 1,
                     'status': 'symbol',
                     'type': 'security',
                     'version': '2.4.1',
                     'issued': '2014-05-27 00:00:00',
                     'references': [{'href': 'https://bugzilla.hostname/bug.cgi?id=XXXXX',
                                     'type': 'bugzilla',
                                     'id': 'XXXXX',
                                     'title': 'some title'}],
                     'updated': '2014-05-28 00:00:00',
                     'pkglist': [{'packages': packages, 'name': 'test-name', 'short': ''},
                                 {'packages': packages, 'name': 'test-name', 'short': ''}]}
        return models.Errata(**unit_data)

    def test_handles_integer_pushcount(self):
        """
        Test that the pushcount of type integer handled well.

        We had a bug[0] wherein uploaded errata couldn't be published because the pushcount would
        be represented as an int. Synchronized errata would have this field represented as a
        basestring. The descrepancy between these has been filed as a separate issue[1].

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1100848
        [1] https://bugzilla.redhat.com/show_bug.cgi?id=1101728
        """
        erratum = self._generate_erratum_unit()
        erratum.description = 'A Description'

        self.context.add_unit_metadata(erratum)

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('<pushcount>1</pushcount>' in generated_xml)

    def test_no_description(self):
        """
        Test that if the erratum has no description, the empty description element should be
        generated.

        We had a bug[0] wherein an empty or missing description would result in
        XML that did not include a description element. The corresponding upstream
        repo (epel5) did have a description element that was merely empty, so the
        distributor was modified to always include the description element.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1138475
        """
        erratum = self._generate_erratum_unit()

        self.context.add_unit_metadata(erratum)

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue(re.search('<description */>', generated_xml) is not None)

    def test_no_duplicated_pkglists(self):
        """
        Test that no duplicated pkglists are generated.
        """
        erratum = self._generate_erratum_unit()
        print erratum.pkglist
        expected_pkg_str = '<package src="pulp-test-package-0.3.1-1.fc22.src.rpm" ' \
                           'name="pulp-test-package" epoch="0" version="0.3.1" '\
                           'release="1.fc22" arch="x86_64">'
        self.context.add_unit_metadata(erratum)

        generated_xml = self.context.metadata_file_handle.getvalue()
        print generated_xml
        self.assertEqual(generated_xml.count(expected_pkg_str), 1)

    def test_add_errata_unit_metadata(self):
        """
        Test the generation of erratum unit.
        """
        erratum = self._generate_erratum_unit()
        self.context.add_unit_metadata(erratum)
        generated_xml = self.context.metadata_file_handle.getvalue()
        expected_xml = '<update status="symbol" from="" version="2.4.1" type="security">\n' \
                       '  <id>RHSA-2014:0042</id>\n' \
                       '  <issued date="2014-05-27 00:00:00" />\n' \
                       '  <reboot_suggested>False</reboot_suggested>\n' \
                       '  <title>Some Title</title>\n' \
                       '  <release>2</release>\n' \
                       '  <rights>You have the right to remain silent.</rights>\n' \
                       '  <solution>Open Source is the solution to your problems.</solution>\n' \
                       '  <severity>High</severity>\n' \
                       '  <summary>A Summary</summary>\n' \
                       '  <pushcount>1</pushcount>\n' \
                       '  <description />\n' \
                       '  <updated date="2014-05-28 00:00:00" />\n' \
                       '  <references>\n' \
                       '    <reference href="https://bugzilla.hostname/bug.cgi?id=XXXXX" ' \
                       'type="bugzilla" id="XXXXX" title="some title" />\n' \
                       '  </references>\n' \
                       '  <pkglist>\n' \
                       '    <collection short="">\n' \
                       '      <name>test-name</name>\n' \
                       '      <package src="pulp-test-package-0.3.1-1.fc22.src.rpm" ' \
                       'name="pulp-test-package" epoch="0" version="0.3.1" release="1.fc22" ' \
                       'arch="x86_64">\n' \
                       '        <filename>pulp-test-package-0.3.1-1.fc22.x86_64.rpm</filename>\n' \
                       '        <reboot_suggested>False</reboot_suggested>\n' \
                       '      </package>\n' \
                       '    </collection>\n' \
                       '  </pkglist>\n' \
                       '</update>\n'
        self.assertEqual(generated_xml, expected_xml)
예제 #24
0
class UpdateinfoXMLFileContextTests(unittest.TestCase):
    """
    Test correct generation of updateinfo.xml file
    """
    @mock.patch(
        'pulp.plugins.util.metadata_writer.MetadataFileContext._open_metadata_file_handle'
    )
    def setUp(self, mock_parent_open_file_handle):
        self.context = UpdateinfoXMLFileContext('/foo', checksum_type='sha256')
        self.context.metadata_file_handle = StringIO()
        self.context._open_metadata_file_handle()

    def _generate_erratum_unit(self):
        """
        Generate erratum unit.
        """
        packages = [{
            'src': 'pulp-test-package-0.3.1-1.fc22.src.rpm',
            'name': 'pulp-test-package',
            'arch': 'x86_64',
            'sums': 'sums',
            'filename': 'pulp-test-package-0.3.1-1.fc22.x86_64.rpm',
            'epoch': '0',
            'version': '0.3.1',
            'release': '1.fc22',
            'type': 'sha256'
        }, {
            'src': 'another-test-package-3.2-1.fc22.src.rpm',
            'name': 'another-test-package',
            'arch': 'x86_64',
            'filename': 'another-test-package-0.3.1-1.fc22.x86_64.rpm',
            'epoch': '0',
            'version': '3.2',
            'release': '1.fc22',
            'sum': ['md5', 'md5_checksum', 'sha256', 'sha256_checksum']
        }]
        unit_data = {
            'errata_id':
            'RHSA-2014:0042',
            'title':
            'Some Title',
            'release':
            '2',
            'rights':
            'You have the right to remain silent.',
            'solution':
            'Open Source is the solution to your problems.',
            'severity':
            'High',
            'summary':
            'A Summary',
            # Note that pushcount is an int. This should be OK (no exceptions).
            'pushcount':
            1,
            'status':
            'symbol',
            'type':
            'security',
            'version':
            '2.4.1',
            'issued':
            '2014-05-27 00:00:00',
            'references': [{
                'href': 'https://bugzilla.hostname/bug.cgi?id=XXXXX',
                'type': 'bugzilla',
                'id': 'XXXXX',
                'title': 'some title'
            }],
            'updated':
            '2014-05-28 00:00:00',
            'pkglist': [{
                'packages': packages,
                'name': 'test-name',
                'short': ''
            }, {
                'packages': packages,
                'name': 'test-name',
                'short': ''
            }]
        }
        return models.Errata(**unit_data)

    def _filtered_pkglist(self, erratum_unit):
        # Return a "filtered" pkglist. Since the test unit generated in _generate_erratum_unit
        # contains two identical pkglists, return one of them to simulate it having been filtered.
        return erratum_unit.pkglist[0]

    def test_handles_integer_pushcount(self):
        """
        Test that the pushcount of type integer handled well.

        We had a bug[0] wherein uploaded errata couldn't be published because the pushcount would
        be represented as an int. Synchronized errata would have this field represented as a
        basestring. The descrepancy between these has been filed as a separate issue[1].

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1100848
        [1] https://bugzilla.redhat.com/show_bug.cgi?id=1101728
        """
        erratum = self._generate_erratum_unit()
        erratum.description = 'A Description'

        self.context.add_unit_metadata(erratum,
                                       self._filtered_pkglist(erratum))

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('<pushcount>1</pushcount>' in generated_xml)

    def test_no_description(self):
        """
        Test that if the erratum has no description, the empty description element should be
        generated.

        We had a bug[0] wherein an empty or missing description would result in
        XML that did not include a description element. The corresponding upstream
        repo (epel5) did have a description element that was merely empty, so the
        distributor was modified to always include the description element.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=1138475
        """
        erratum = self._generate_erratum_unit()

        self.context.add_unit_metadata(erratum,
                                       self._filtered_pkglist(erratum))

        generated_xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue(
            re.search('<description */>', generated_xml) is not None)

    def test_reboot_suggested(self):
        """
        Test that when reboot_suggested is True, the element is present in the XML
        """
        erratum = self._generate_erratum_unit()
        erratum.reboot_suggested = True

        self.context.add_unit_metadata(erratum,
                                       self._filtered_pkglist(erratum))

        xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('reboot_suggested' in xml)

    def test_no_reboot_suggested(self):
        """
        Test that when reboot_suggested is False, the element is not present in the XML
        """
        erratum = self._generate_erratum_unit()
        erratum.reboot_suggested = False

        self.context.add_unit_metadata(erratum,
                                       self._filtered_pkglist(erratum))

        xml = self.context.metadata_file_handle.getvalue()
        self.assertTrue('reboot_suggested' not in xml)

    def test__get_package_checksum_tuple_sums_field(self):
        """
        Test that the `sums` package field is handled correctly.
        """
        erratum = self._generate_erratum_unit()
        package_with_sums_field = self._filtered_pkglist(
            erratum)['packages'][0]
        result = self.context._get_package_checksum_tuple(
            package_with_sums_field)
        expected_checksum_tuple = ('sha256', 'sums')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_dist_type(self):
        """
        Test that the package checksum of the distributor checksum type is published if available.
        """
        erratum = self._generate_erratum_unit()
        package_with_multiple_checksums = self._filtered_pkglist(
            erratum)['packages'][1]
        result = self.context._get_package_checksum_tuple(
            package_with_multiple_checksums)
        expected_checksum_tuple = ('sha256', 'sha256_checksum')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_unknown_type(self):
        """
        Test that the longest package checksum is published if the distributor checksum type is not
        available.
        """
        erratum = self._generate_erratum_unit()
        self.context.checksum_type = 'unknown type #1'
        package_with_multiple_checksums = self._filtered_pkglist(
            erratum)['packages'][1]
        result = self.context._get_package_checksum_tuple(
            package_with_multiple_checksums)
        expected_checksum_tuple = ('sha256', 'sha256_checksum')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_updateinfo_type(self):
        """
        Test that the package checksum of requested checksum type for updateinfo.xml is
        published if available.
        """
        erratum = self._generate_erratum_unit()
        self.context.checksum_type = 'sha256'
        self.context.updateinfo_checksum_type = 'md5'
        package_with_multiple_checksums = self._filtered_pkglist(
            erratum)['packages'][1]
        result = self.context._get_package_checksum_tuple(
            package_with_multiple_checksums)
        expected_checksum_tuple = ('md5', 'md5_checksum')
        self.assertEqual(result, expected_checksum_tuple)

    def test__get_package_checksum_tuple_updateinfo_unknown_type(self):
        """
        Test that the proper exception is raised if the updateinfo checksum type is unavailable.
        """
        erratum = self._generate_erratum_unit()
        self.context.checksum_type = 'sha256'
        self.context.updateinfo_checksum_type = 'unknown type'
        package_with_multiple_checksums = self._filtered_pkglist(
            erratum)['packages'][1]
        with self.assertRaises(PulpCodedException) as e:
            self.context._get_package_checksum_tuple(
                package_with_multiple_checksums)
        self.assertEqual(e.exception.error_code.code, 'RPM1012')

    def test_add_errata_unit_metadata(self):
        """
        Test the generation of erratum unit.
        """
        erratum = self._generate_erratum_unit()
        self.context.add_unit_metadata(erratum,
                                       self._filtered_pkglist(erratum))
        generated_xml = self.context.metadata_file_handle.getvalue()
        expected_xml = '<update status="symbol" from="" version="2.4.1" type="security">\n' \
                       '  <id>RHSA-2014:0042</id>\n' \
                       '  <issued date="2014-05-27 00:00:00" />\n' \
                       '  <title>Some Title</title>\n' \
                       '  <release>2</release>\n' \
                       '  <rights>You have the right to remain silent.</rights>\n' \
                       '  <solution>Open Source is the solution to your problems.</solution>\n' \
                       '  <severity>High</severity>\n' \
                       '  <summary>A Summary</summary>\n' \
                       '  <pushcount>1</pushcount>\n' \
                       '  <description />\n' \
                       '  <updated date="2014-05-28 00:00:00" />\n' \
                       '  <references>\n' \
                       '    <reference href="https://bugzilla.hostname/bug.cgi?id=XXXXX" ' \
                       'type="bugzilla" id="XXXXX" title="some title" />\n' \
                       '  </references>\n' \
                       '  <pkglist>\n' \
                       '    <collection short="">\n' \
                       '      <name>test-name</name>\n' \
                       '      <package src="pulp-test-package-0.3.1-1.fc22.src.rpm" ' \
                       'name="pulp-test-package" epoch="0" version="0.3.1" release="1.fc22" ' \
                       'arch="x86_64">\n' \
                       '        <filename>pulp-test-package-0.3.1-1.fc22.x86_64.rpm</filename>\n' \
                       '        <sum type="sha256">sums</sum>\n' \
                       '      </package>\n' \
                       '      <package src="another-test-package-3.2-1.fc22.src.rpm" ' \
                       'name="another-test-package" epoch="0" version="3.2" release="1.fc22" ' \
                       'arch="x86_64">\n' \
                       '        <filename>another-test-package-0.3.1-1.fc22.x86_64.rpm' \
                       '</filename>\n' \
                       '        <sum type="sha256">sha256_checksum</sum>\n' \
                       '      </package>\n' \
                       '    </collection>\n' \
                       '  </pkglist>\n' \
                       '</update>\n'
        self.assertEqual(generated_xml, expected_xml)