def test_can_enable_false_on_unsupported_min_kernel_version( self, _m_is_container, kernel_version, meets_min_version, capsys, entitlement, ): """"When on an unsupported kernel version, can_enable returns False.""" unsupported_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_kernel["kernel"] = kernel_version with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_kernel entitlement = LivepatchEntitlement(entitlement.cfg) if meets_min_version: assert entitlement.can_enable() else: assert not entitlement.can_enable() if meets_min_version: msg = "" else: msg = ( "Livepatch is not available for kernel {}.\n" "Minimum kernel version required: 4.4\n".format(kernel_version) ) assert (msg, "") == capsys.readouterr()
def static_affordances(self) -> "Tuple[StaticAffordance, ...]": # Use a lambda so we can mock util.is_container in tests from uaclient.entitlements.livepatch import LivepatchEntitlement livepatch_ent = LivepatchEntitlement(self.cfg) enabled_status = status.ApplicationStatus.ENABLED is_livepatch_enabled = bool( livepatch_ent.application_status()[0] == enabled_status ) return ( ( "Cannot install {} on a container".format(self.title), lambda: util.is_container(), False, ), ( "Cannot enable {} when Livepatch is enabled".format( self.title ), lambda: is_livepatch_enabled, False, ), )
def test_can_enable_false_on_unsupported_min_kernel_version( self, _m_is_container, _m_livepatch_status, _m_fips_status, kernel_version, meets_min_version, entitlement, ): """When on an unsupported kernel version, can_enable returns False.""" unsupported_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_kernel["kernel"] = kernel_version with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_kernel entitlement = LivepatchEntitlement(entitlement.cfg) if meets_min_version: assert (True, None) == entitlement.can_enable() else: result, reason = entitlement.can_enable() assert False is result assert CanEnableFailureReason.INAPPLICABLE == reason.reason msg = ("Livepatch is not available for kernel {}.\n" "Minimum kernel version required: 4.4.".format( kernel_version)) assert msg == reason.message.msg
def test_contract_status_entitled(self, tmpdir): """The contract_status returns ENTITLED when entitled is True.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) assert status.ENTITLED == entitlement.contract_status()
def test_can_enable_false_on_containers(self, capsys, entitlement): """When is_container is True, can_enable returns False.""" with mock.patch("uaclient.util.get_platform_info") as m_platform: with mock.patch("uaclient.util.is_container") as m_container: m_platform.return_value = PLATFORM_INFO_SUPPORTED m_container.return_value = True entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = "Cannot install Livepatch on a container\n" assert (msg, "") == capsys.readouterr()
def test_contract_status_unentitled(self, tmpdir): """The contract_status returns NONE when entitled is False.""" livepatch_unentitled = copy.deepcopy(dict(LIVEPATCH_RESOURCE_ENTITLED)) # Make livepatch resource access report not entitled livepatch_unentitled['entitlement']['entitled'] = False cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', livepatch_unentitled) entitlement = LivepatchEntitlement(cfg) assert status.NONE == entitlement.contract_status()
def test_can_enable_false_on_containers(self, entitlement): """When is_container is True, can_enable returns False.""" with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: with mock.patch('uaclient.util.get_platform_info') as m_platform: with mock.patch('uaclient.util.is_container') as m_container: m_platform.return_value = PLATFORM_INFO_SUPPORTED m_container.return_value = True entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = 'Cannot install Livepatch on a container\n' assert msg == m_stdout.getvalue()
def test_can_enable_false_on_containers(self, m_is_container, capsys, entitlement): """When is_container is True, can_enable returns False.""" unsupported_min_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_min_kernel["kernel"] = "4.2.9-00-generic" with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_min_kernel m_is_container.return_value = True entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = "Cannot install Livepatch on a container\n" assert (msg, "") == capsys.readouterr()
def test_can_enable_false_on_unsupported_kernel_flavor( self, _m_is_container, capsys, entitlement): """"When on an unsupported kernel, can_enable returns False.""" unsupported_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_kernel["kernel"] = "4.4.0-140-notgeneric" with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_kernel entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = ("Livepatch is not available for kernel 4.4.0-140-notgeneric.\n" "Supported flavors are: generic, lowlatency\n") assert (msg, "") == capsys.readouterr()
def test_can_enable_false_on_unsupported_kernel_min_version( self, _m_is_container, capsys, entitlement): """"False when on a kernel less or equal to minKernelVersion.""" unsupported_min_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_min_kernel["kernel"] = "4.2.9-00-generic" with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_min_kernel entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = ("Livepatch is not available for kernel 4.2.9-00-generic.\n" "Minimum kernel version required: 4.4\n") assert (msg, "") == capsys.readouterr()
def test_can_enable_false_on_unsupported_kernel_flavor(self, entitlement): """"When on an unsupported kernel, can_enable returns False.""" unsupported_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_kernel['kernel'] = '4.4.0-140-notgeneric' with mock.patch('uaclient.util.get_platform_info') as m_platform: with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: m_platform.return_value = unsupported_kernel entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = ('Livepatch is not available for kernel 4.4.0-140-notgeneric.\n' 'Supported flavors are: generic, lowlatency\n') assert msg == m_stdout.getvalue()
def test_enable_does_not_install_livepatch_snap_when_present( self, m_can_enable, m_which, m_subp, tmpdir): """Do not attempt to install livepatch snap when it is present.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: assert entitlement.enable() assert self.mocks_config == m_subp.call_args_list assert 'Canonical livepatch enabled.\n' == m_stdout.getvalue()
def test_can_enable_false_on_unsupported_kernel_min_version( self, entitlement): """"False when on a kernel less or equal to minKernelVersion.""" unsupported_min_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_min_kernel['kernel'] = '4.2.9-00-generic' with mock.patch('uaclient.util.get_platform_info') as m_platform: with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: m_platform.return_value = unsupported_min_kernel entitlement = LivepatchEntitlement(entitlement.cfg) assert not entitlement.can_enable() msg = ('Livepatch is not available for kernel 4.2.9-00-generic.\n' 'Minimum kernel version required: 4.3\n') assert msg == m_stdout.getvalue()
def test_can_enable_false_on_containers(self, m_is_container, _m_livepatch_status, _m_fips_status, entitlement): """When is_container is True, can_enable returns False.""" unsupported_min_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_min_kernel["kernel"] = "4.2.9-00-generic" with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_min_kernel m_is_container.return_value = True entitlement = LivepatchEntitlement(entitlement.cfg) result, reason = entitlement.can_enable() assert False is result assert CanEnableFailureReason.INAPPLICABLE == reason.reason msg = "Cannot install Livepatch on a container." assert msg == reason.message.msg
def test_can_enable_false_on_unsupported_kernel_min_version( self, _m_is_container, _m_livepatch_status, _m_fips_status, entitlement): """False when on a kernel less or equal to minKernelVersion.""" unsupported_min_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_min_kernel["kernel"] = "4.2.9-00-generic" with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_min_kernel entitlement = LivepatchEntitlement(entitlement.cfg) result, reason = entitlement.can_enable() assert False is result assert CanEnableFailureReason.INAPPLICABLE == reason.reason msg = ("Livepatch is not available for kernel 4.2.9-00-generic.\n" "Minimum kernel version required: 4.4.") assert msg == reason.message.msg
def test_can_enable_false_on_unsupported_kernel_flavor( self, _m_is_container, _m_livepatch_status, _m_fips_status, entitlement): """When on an unsupported kernel, can_enable returns False.""" unsupported_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_kernel["kernel"] = "4.4.0-140-notgeneric" with mock.patch("uaclient.util.get_platform_info") as m_platform: m_platform.return_value = unsupported_kernel entitlement = LivepatchEntitlement(entitlement.cfg) result, reason = entitlement.can_enable() assert False is result assert CanEnableFailureReason.INAPPLICABLE == reason.reason msg = ( "Livepatch is not available for kernel 4.4.0-140-notgeneric.\n" "Supported flavors are: generic, lowlatency.") assert msg == reason.message.msg
def test_enable_false_when_can_enable_false( self, m_can_enable, caplog_text, tmpdir): """When can_enable returns False enable returns False.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: assert not entitlement.enable() info_level_logs = [ # see uaclient/conftest.py line for line in caplog_text().splitlines() if 'DEBUG' not in line] assert [] == info_level_logs assert '' == m_stdout.getvalue() # No additional prints assert [mock.call()] == m_can_enable.call_args_list
def test_can_enable_true_on_entitlement_inactive(self, tmpdir): """When operational status is INACTIVE, can_enable returns True.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) with mock.patch('uaclient.util.get_platform_info') as m_platform: with mock.patch('sys.stderr', new_callable=StringIO) as m_stdout: with mock.patch('uaclient.util.is_container') as m_container: with mock.patch(M_GETUID, return_value=0): m_platform.return_value = PLATFORM_INFO_SUPPORTED m_container.return_value = False assert entitlement.can_enable() assert '' == m_stdout.getvalue() assert [mock.call()] == m_container.call_args_list
def test_operational_status_inapplicable_on_checked_affordances( self, tmpdir): """The operational_status details failed check_affordances.""" livepatch_bionic = copy.deepcopy(dict(LIVEPATCH_RESOURCE_ENTITLED)) livepatch_bionic['entitlement']['affordances']['series'] = ['bionic'] cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) entitlement.cfg.write_cache( 'machine-access-livepatch', livepatch_bionic) with mock.patch('uaclient.util.get_platform_info') as m_platform_info: m_platform_info.return_value = PLATFORM_INFO_SUPPORTED op_status, details = entitlement.operational_status() assert op_status == status.INAPPLICABLE assert 'Livepatch is not available for Ubuntu xenial.' == details
def test_enable_installs_livepatch_snap_when_absent( self, m_can_enable, m_which, m_subp, tmpdir): """Install canonical-livepatch snap when not present on the system.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: assert entitlement.enable() assert self.mocks_install + self.mocks_config in m_subp.call_args_list msg = ('Installing snapd...\n' 'Installing canonical-livepatch snap...\n' 'Canonical livepatch enabled.\n') assert msg == m_stdout.getvalue() expected_calls = [mock.call('/snap/bin/canonical-livepatch'), mock.call('snap')] assert expected_calls == m_which.call_args_list
def test_can_enable_false_on_containers(self, tmpdir): """When is_container is True, can_enable returns False.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: with mock.patch('uaclient.util.get_platform_info') as m_platform: with mock.patch('uaclient.util.is_container') as m_container: with mock.patch(M_GETUID, return_value=0): m_platform.return_value = PLATFORM_INFO_SUPPORTED m_container.return_value = True entitlement = LivepatchEntitlement( entitlement.cfg) assert not entitlement.can_enable() msg = 'Cannot install Livepatch on a container\n' assert msg == m_stdout.getvalue()
def entitlement(tmpdir): """ A pytest fixture to create a LivepatchEntitlement with some default config (Uses the tmpdir fixture for the underlying config cache.) """ cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) return LivepatchEntitlement(cfg)
def test_can_enable_false_on_unsupported_architecture(self, tmpdir): """"When on an unsupported architecture, can_enable returns False.""" cfg = config.UAConfig(cfg={'data_dir': tmpdir.strpath}) cfg.write_cache('machine-token', dict(LIVEPATCH_MACHINE_TOKEN)) cfg.write_cache('machine-access-livepatch', dict(LIVEPATCH_RESOURCE_ENTITLED)) entitlement = LivepatchEntitlement(cfg) unsupported_kernel = copy.deepcopy(dict(PLATFORM_INFO_SUPPORTED)) unsupported_kernel['arch'] = 'ppc64le' with mock.patch('uaclient.util.get_platform_info') as m_platform: with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout: with mock.patch(M_GETUID, return_value=0): m_platform.return_value = unsupported_kernel entitlement = LivepatchEntitlement( entitlement.cfg) assert not entitlement.can_enable() msg = ('Livepatch is not available for platform ppc64le.\n' 'Supported platforms are: x86_64\n\n') assert msg == m_stdout.getvalue()