github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/assess_resolve.py (about) 1 #!/usr/bin/env python 2 """ Ensure resolve command resolves hook issues. 3 4 This test covers the resolve command (and the option --no-retry) 5 6 The test: 7 - Uses a simple custom charm that instruments failure in the install hook 8 - Ensures that 'resolve' retries the failed install hook and that the 9 followup 'start' hook is fired. 10 - Ensures that 'resolve --no-retry' does NOT re-run the failed install hook 11 and instead goes ahead and runs the follow up 'started' hook. 12 """ 13 14 from __future__ import print_function 15 16 import argparse 17 import logging 18 import sys 19 20 from deploy_stack import ( 21 BootstrapManager, 22 ) 23 from jujupy.models import ( 24 temporary_model, 25 ) 26 from jujupy.wait_condition import ( 27 UnitInstallCondition, 28 ) 29 from jujucharm import local_charm_path 30 from utility import ( 31 add_basic_testing_arguments, 32 configure_logging, 33 ) 34 35 36 __metaclass__ = type 37 38 39 log = logging.getLogger('assess_resolve') 40 41 42 class ResolveCharmMessage: 43 """Workload active message differs if the install hook completed.""" 44 ACTIVE_NO_INSTALL_HOOK = 'No install hook' 45 ACTIVE_INSTALL_HOOK = 'Install hook succeeded' 46 INSTALL_FAIL = 'hook failed: "install"' 47 48 49 def assess_resolve(client, local_charm='simple-resolve'): 50 local_resolve_charm = local_charm_path( 51 charm=local_charm, juju_ver=client.version) 52 ensure_retry_does_not_rerun_failed_hook(client, local_resolve_charm) 53 54 55 def ensure_retry_does_not_rerun_failed_hook(client, resolve_charm): 56 with temporary_model(client, "no-retry") as temp_client: 57 unit_name = 'simple-resolve/0' 58 temp_client.deploy(resolve_charm) 59 temp_client.wait_for(UnitInstallError(unit_name)) 60 temp_client.juju('resolve', ('--no-retry', unit_name)) 61 # simple-resolve start hook sets a message when active to indicate 62 # it ran and if the install hook ran successfully or not. 63 # Here we make sure it's active and no install hook success. 64 temp_client.wait_for( 65 UnitInstallActive( 66 unit_name, ResolveCharmMessage.ACTIVE_NO_INSTALL_HOOK)) 67 68 69 class UnitInstallError(UnitInstallCondition): 70 """Wait until `unit` is in error state with message status `message`. 71 72 Useful to determine when a unit is in an expected error state (the message 73 check allows further confirmation the error reason is the one we're looking 74 for) 75 """ 76 def __init__(self, unit, *args, **kwargs): 77 super(UnitInstallError, self).__init__( 78 unit, 'error', ResolveCharmMessage.INSTALL_FAIL, *args, **kwargs) 79 80 81 class UnitInstallActive(UnitInstallCondition): 82 """Wait until `unit` is in active state with message status `message` 83 84 Useful to determine when a unit is active for a specific reason. 85 """ 86 87 def __init__(self, unit, message, *args, **kwargs): 88 super(UnitInstallActive, self).__init__( 89 unit, 'active', message, *args, **kwargs) 90 91 92 def parse_args(argv): 93 """Parse all arguments.""" 94 parser = argparse.ArgumentParser( 95 description='Ensure the resolve command operates to spec.') 96 add_basic_testing_arguments(parser) 97 return parser.parse_args(argv) 98 99 100 def main(argv=None): 101 args = parse_args(argv) 102 configure_logging(args.verbose) 103 bs_manager = BootstrapManager.from_args(args) 104 with bs_manager.booted_context(args.upload_tools): 105 assess_resolve(bs_manager.client) 106 return 0 107 108 109 if __name__ == '__main__': 110 sys.exit(main())