github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/assess_destroy_model.py (about) 1 #!/usr/bin/env python 2 """Assess if Juju tracks the model when the current model is destroyed.""" 3 4 from __future__ import print_function 5 6 import argparse 7 import logging 8 import sys 9 import subprocess 10 11 from deploy_stack import ( 12 BootstrapManager, 13 ) 14 from utility import ( 15 add_basic_testing_arguments, 16 configure_logging, 17 JujuAssertionError, 18 add_model, 19 get_current_model, 20 ) 21 22 23 __metaclass__ = type 24 25 26 log = logging.getLogger("assess_destroy_model") 27 28 TEST_MODEL = 'test-tmp-env' 29 30 31 def assess_destroy_model(client): 32 """Tests if Juju tracks the model properly through deletion. 33 34 In normal behavior Juju should drop the current model selection if that 35 model is destroyed. This will fail if Juju does not drop it's current 36 selection. 37 38 :param client: Jujupy ModelClient object 39 """ 40 41 current_model = get_current_model(client) 42 controller = get_current_controller(client) 43 log.info('Current model: {}'.format(current_model)) 44 45 new_client = add_model(client) 46 destroy_model(client, new_client) 47 48 log.info('Juju successfully dropped its current model. ' 49 'Switching to {} to complete test'.format(current_model)) 50 switch_model(client, current_model, controller) 51 52 log.info('SUCCESS') 53 54 55 def destroy_model(client, new_client): 56 log.info('Destroying model "{}"'.format(TEST_MODEL)) 57 new_client.destroy_model() 58 old_model = get_current_model(client) 59 if not old_model: 60 error = 'Juju unset model after it was destroyed' 61 raise JujuAssertionError(error) 62 try: 63 client.get_juju_output('status', include_e=False) 64 except subprocess.CalledProcessError as e: 65 if b'{} not found'.format(old_model) not in e.stderr: 66 error = 'unexpected error calling status\n{}'.format(e.stderr) 67 raise JujuAssertionError(error) 68 else: 69 error = 'model still valid after it was destroyed' 70 raise JujuAssertionError(error) 71 72 73 def switch_model(client, current_model, current_controller): 74 """Switches back to the old model. 75 76 :param client: Jujupy ModelClient object 77 :param current_model: String name of initial testing model 78 :param current_controller: String name of testing controller 79 """ 80 client.switch(model=current_model, controller=current_controller) 81 new_model = get_current_model(client) 82 if new_model == current_model: 83 log.info('Current model and switch target match') 84 else: 85 error = ('Juju failed to switch back to existing model. ' 86 'Expected {} got {}'.format(TEST_MODEL, new_model)) 87 raise JujuAssertionError(error) 88 89 90 def get_current_controller(client): 91 """Gets the current controller from Juju's list-models command. 92 93 :param client: Jujupy ModelClient object 94 :return: String name of current controller 95 """ 96 raw = client.get_juju_output('switch', include_e=False).decode('utf-8') 97 raw = raw.split(':')[0] 98 return raw 99 100 101 def parse_args(argv): 102 """Parse all arguments.""" 103 parser = argparse.ArgumentParser( 104 description='Test if juju drops selection of the current model ' 105 'when that model is destroyed.') 106 add_basic_testing_arguments(parser, existing=False) 107 return parser.parse_args(argv) 108 109 110 def main(argv=None): 111 args = parse_args(argv) 112 configure_logging(args.verbose) 113 bs_manager = BootstrapManager.from_args(args) 114 with bs_manager.booted_context(args.upload_tools): 115 assess_destroy_model(bs_manager.client) 116 return 0 117 118 119 if __name__ == '__main__': 120 sys.exit(main())