def test_assign_certified_key_info_expiration(self):
        """Test assignment of key expiration date in
    gpg.common._assign_certified_key_info using real gpg data (with ambiguity
    resolution / prioritization).

    # FIXME: Below tests are missing proper assertions for which User ID
    self-certificate is considered for the expiration date. Reasons are:
    - gpg does not let you (easily) modify individual expiration dates of User
      IDs (changing one changes all), hence we cannot assert the chosen packet
      by the particular date
    -  _assign_certified_key_info first verifies all self-certificates and then
       only considers successfully verified ones, hence we cannot modify the
       certificate data, before passing it to _assign_certified_key_info

    IMO the best solution is a better separation of concerns, e.g. separate
    self-certificate verification and packet prioritization.

    """
        # Test ambiguity resolution scheme with 3 User IDs
        #   :user ID packet: "Test Expiration I <*****@*****.**>"
        #   :user ID packet: "Test Expiration II <*****@*****.**>"
        #   :user ID packet: "Test Expiration III <*****@*****.**>"
        # User ID packets are ordered by their creation time in ascending order.
        # "Test Expiration II" has the primary user ID flag set and therefor has
        # the highest priority.
        key = _assign_certified_key_info(self.raw_expired_key_bundle)
        self.assertTrue(key["validity_period"] == 87901)  # ~ 1 day

        # Test ambiguity resolution scheme with 2 User IDs
        #   :user ID packet: "Test Expiration III <*****@*****.**>"
        #   :user ID packet: "Test Expiration I <*****@*****.**>"
        # User ID packets are ordered by their creation time in descending order.
        # Neither packet has the primary user ID flag set.
        # "Test Expiration III" has the highest priority.
        raw_key_bundle = deepcopy(self.raw_expired_key_bundle)
        user_id_items = list(
            reversed(raw_key_bundle[PACKET_TYPE_USER_ID].items()))
        del user_id_items[1]
        raw_key_bundle[PACKET_TYPE_USER_ID] = OrderedDict(user_id_items)
        key = _assign_certified_key_info(raw_key_bundle)
        self.assertTrue(key["validity_period"] == 87901)  # ~ 1 day
    def test_assign_certified_key_info_errors(self):
        """Test _assign_certified_key_info errors with manually crafted data
    based on real gpg key data (see self.raw_key_bundle). """

        # Replace legitimate user certifacte with a bogus packet
        wrong_cert_bundle = deepcopy(self.raw_key_bundle)
        packet, packet_data = wrong_cert_bundle[PACKET_TYPE_USER_ID].popitem()
        packet_data["signatures"] = [bytearray([0b01111111, 0])]
        wrong_cert_bundle[PACKET_TYPE_USER_ID][packet] = packet_data

        # Replace primary key id with a non-associated keyid
        wrong_keyid_bundle = deepcopy(self.raw_key_bundle)
        wrong_keyid_bundle[PACKET_TYPE_PRIMARY_KEY]["key"]["keyid"] = \
            "8465A1E2E0FB2B40ADB2478E18FB3F537E0C8A17"

        # Remove a byte in user id packet to make signature verification fail
        invalid_cert_bundle = deepcopy(self.raw_key_bundle)
        packet, packet_data = invalid_cert_bundle[PACKET_TYPE_USER_ID].popitem(
        )
        packet = packet[:-1]
        invalid_cert_bundle[PACKET_TYPE_USER_ID][packet] = packet_data

        test_data = [
            # Skip and log parse_signature_packet error
            (wrong_cert_bundle, "Expected packet 2, but got 63 instead"),
            # Skip and log signature packet that doesn't match primary key id
            (wrong_keyid_bundle, "Ignoring User ID certificate issued by"),
            # Skip and log invalid signature
            (invalid_cert_bundle, "Ignoring invalid User ID self-certificate")
        ]

        for bundle, expected_msg in test_data:
            with patch("securesystemslib.gpg.common.log") as mock_log:
                _assign_certified_key_info(bundle)
                msg = str(mock_log.info.call_args[0][0])
                self.assertTrue(expected_msg in msg,
                                "'{}' not in '{}'".format(expected_msg, msg))