예제 #1
0
 def test_dr_clone(self):
     setup_stack()
     dr_stack = aws_stack.Stack(CONF_CLONE_STACKNAME, REGION)
     clone_params = get_stack_params()
     next(param for param in clone_params if param['ParameterKey'] ==
          'DeployEnvironment')['ParameterValue'] = 'dr'
     clone_params.append({
         'ParameterKey': 'StackName',
         'ParameterValue': CONF_CLONE_STACKNAME
     })
     # setup mocks
     dr_stack.run_sql = MagicMock(return_value=False)
     dr_stack.validate_service_responding = MagicMock(return_value=True)
     dr_stack.wait_stack_action_complete = MagicMock(return_value=True)
     with app.app_context():
         outcome = dr_stack.clone(
             stack_params=clone_params,
             template_file=TEMPLATE_FILE_CLONE,
             app_type='confluence',
             clustered='true',
             creator='test-user',
             region=REGION,
             cloned_from=CONF_STACKNAME,
         )
         assert outcome
         dr_stack.run_sql.assert_not_called()
예제 #2
0
 def test_execute_changeset(self):
     setup_stack()
     cfn = boto3.client('cloudformation', REGION)
     stack = cfn.describe_stacks(StackName=CONF_STACKNAME)
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     params_for_update = stack['Stacks'][0]['Parameters']
     for param in params_for_update:
         if param['ParameterKey'] == 'TomcatConnectionTimeout':
             param['ParameterValue'] = '20001'
         # for other params, delete the value and set UsePreviousValue to true
         else:
             del param['ParameterValue']
             param['UsePreviousValue'] = True
     with app.app_context():
         change_set = mystack.create_change_set(params_for_update,
                                                TEMPLATE_FILE)
         change_set_name = change_set['Id']
         mystack.validate_service_responding = MagicMock(return_value=True)
         result = mystack.execute_change_set(change_set_name)
         assert result is True
         cfn = boto3.client('cloudformation', REGION)
         stacks = cfn.describe_stacks(StackName=CONF_STACKNAME)
         assert [
             param for param in stacks['Stacks'][0]['Parameters']
             if param['ParameterKey'] == 'TomcatConnectionTimeout'
         ][0]['ParameterValue'] == '20001'
예제 #3
0
 def test_clone(self):
     setup_stack()
     clone_stack = aws_stack.Stack(CONF_CLONE_STACKNAME, REGION)
     clone_params = get_stack_params()
     clone_params.append({
         'ParameterKey': 'StackName',
         'ParameterValue': CONF_CLONE_STACKNAME
     })
     # setup mocks
     clone_stack.full_restart = MagicMock(return_value=True)
     clone_stack.get_stacknodes = MagicMock(
         return_value=[{
             'i-0bcf57c789637b10f': '10.111.22.333'
         }, {
             'i-0fdacb1ab66016786': '10.111.22.444'
         }])
     clone_stack.get_sql = MagicMock(
         return_value='Select * from cwd_user limit 1;')
     clone_stack.validate_service_responding = MagicMock(return_value=True)
     clone_stack.wait_stack_action_complete = MagicMock(return_value=True)
     with app.app_context():
         outcome = clone_stack.clone(
             stack_params=clone_params,
             template_file=TEMPLATE_FILE_CLONE,
             app_type='confluence',
             clustered='true',
             creator='test-user',
             region=REGION,
             cloned_from=CONF_STACKNAME,
         )
         assert outcome
         stacks = boto3.client(
             'cloudformation',
             REGION).describe_stacks(StackName=CONF_CLONE_STACKNAME)
         assert stacks['Stacks'][0]['StackName'] == CONF_CLONE_STACKNAME
예제 #4
0
 def test_upgrade(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     assert mystack.get_param_value('ProductVersion') == '6.11.0'
     # mock status
     mystack.check_service_status = MagicMock(return_value='RUNNING')
     # upgrade
     with app.app_context():
         mystack.upgrade('6.11.1')
     assert mystack.get_param_value('ProductVersion') == '6.11.1'
예제 #5
0
 def test_thread_dump_links(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     # upload a dummy thread dump
     s3 = boto3.client('s3')
     s3.upload_file(os.path.relpath(DUMMY_FILE), app.config['S3_BUCKET'],
                    f'diagnostics/{mystack.stack_name}/threaddump.zip')
     with app.app_context():
         thread_dump_links = mystack.get_thread_dump_links()
         assert len(thread_dump_links) > 0
예제 #6
0
 def test_node_cpu(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     mystack.get_stacknodes = MagicMock(
         return_value=[{
             'i-0bcf57c789637b10f': '10.111.22.333'
         }, {
             'i-0fdacb1ab66016786': '10.111.22.444'
         }])
     result = mystack.get_node_cpu('10.111.22.333')
     # moto returns no metrics, but this proves that the function completed successfully
     assert result == {}
예제 #7
0
 def test_restarts(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     # setup mocks
     mystack.check_service_status = MagicMock(return_value='RUNNING')
     mystack.check_node_status = MagicMock(return_value='RUNNING')
     mystack.get_tag = MagicMock(return_value='Confluence')
     mystack.is_app_clustered = MagicMock(return_value=True)
     drain_target_states = [
         'healthy', 'draining', 'notregistered', 'initial', 'initial',
         'healthy', 'healthy', 'draining', 'notregistered', 'initial',
         'initial', 'healthy'
     ]
     no_drain_target_states = [
         'initial', 'initial', 'healthy', 'initial', 'initial', 'healthy'
     ]
     with app.app_context():
         # perform restarts
         # expect failures as node count is 0
         rolling_result = mystack.rolling_restart(False)
         assert rolling_result is False
         full_result = mystack.full_restart()
         assert full_result is False
         # mock nodes and target states
         mystack.get_stacknodes = MagicMock(
             return_value=[{
                 'i-0bcf57c789637b10f': '10.111.22.333'
             }, {
                 'i-0fdacb1ab66016786': '10.111.22.444'
             }])
         mystack.get_target_state = MagicMock(
             side_effect=no_drain_target_states)
         # test rolling restart with and without draining
         rolling_result = mystack.rolling_restart(False)
         assert rolling_result is True
         mystack.get_target_state = MagicMock(
             side_effect=drain_target_states)
         rolling_drain_result = mystack.rolling_restart(True)
         assert rolling_drain_result is True
         # test full restart
         full_result = mystack.full_restart()
         assert full_result is True
         # test node restart with and without draining
         mystack.get_target_state = MagicMock(
             side_effect=no_drain_target_states)
         restart_node_result = mystack.restart_node('10.111.22.333', False)
         assert restart_node_result is True
         mystack.get_target_state = MagicMock(
             side_effect=drain_target_states)
         restart_node_drain_result = mystack.restart_node(
             '10.111.22.444', True)
         assert restart_node_drain_result is True
예제 #8
0
 def test_tagging(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     tags_to_add = [{
         'Key': 'Tag1',
         'Value': 'Value1'
     }, {
         'Key': 'Tag2',
         'Value': 'Value2'
     }]
     tagged = mystack.tag(tags_to_add)
     assert tagged
     tags = mystack.get_tags()
     assert tags == tags_to_add
예제 #9
0
 def test_toggle_node(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     # setup mocks
     mystack.check_service_status = MagicMock(return_value='RUNNING')
     mystack.check_node_status = MagicMock(return_value='RUNNING')
     mystack.get_tag = MagicMock(return_value='Confluence')
     mystack.is_app_clustered = MagicMock(return_value=True)
     deregister_target_states = [
         'healthy', 'healthy', 'draining', 'draining', 'notregistered'
     ]
     register_target_states = [
         'notregistered', 'notregistered', 'initial', 'initial', 'healthy'
     ]
     with app.app_context():
         with app.test_request_context(''):
             session = {'saml': {'subject': 'UserA'}}
             # mock nodes
             mystack.get_stacknodes = MagicMock(
                 return_value=[{
                     'i-0bcf57c789637b10f': '10.111.22.333'
                 }, {
                     'i-0fdacb1ab66016786': '10.111.22.444'
                 }])
             # register node initially
             mystack.get_target_state = MagicMock(
                 side_effect=register_target_states)
             register_result = mystack.toggle_node_registration(
                 node='10.111.22.333')
             assert register_result is True
             # deregister node
             mystack.get_target_state = MagicMock(
                 side_effect=deregister_target_states)
             deregister_result = mystack.toggle_node_registration(
                 node='10.111.22.333')
             assert deregister_result is True
             # re-register node
             mystack.get_target_state = MagicMock(
                 side_effect=register_target_states)
             register_result = mystack.toggle_node_registration(
                 node='10.111.22.333')
             assert register_result is True
             # confirm a draining node re-registers
             mystack.get_target_state = MagicMock(side_effect=['draining'])
             mystack.wait_node_registered = MagicMock(return_value=True)
             mystack.toggle_node_registration(node='10.111.22.333')
             assert mystack.wait_node_registered.called
예제 #10
0
 def test_sns(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     action_msg = 'test msg'
     with app.test_request_context(''):
         session = {'saml': {'subject': 'UserA'}}
         topic_arn = mystack.get_sns_topic_arn()
         # confirm there is no topic for forge msgs
         assert topic_arn is None
         # send a msg
         published_msg = mystack.send_sns_msg(action_msg)
         topic_arn = mystack.get_sns_topic_arn()
         # confirm a topic has been created for forge msgs
         assert topic_arn is not None
         # confirm the message was sent successfully
         assert published_msg is not None
         assert published_msg['MessageId'] is not None
예제 #11
0
def setup_stack():
    # not using pytest.setup_class or a fixture here as the moto environment does not persist - it tears itself down
    # each test must call this at the start
    with app.app_context():
        setup_env_resources()
        mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
        # setup mocks
        mystack.validate_service_responding = MagicMock(return_value=True)
        mystack.wait_stack_action_complete = MagicMock(return_value=True)
        # create stack
        outcome = mystack.create(get_stack_params(),
                                 TEMPLATE_FILE,
                                 'confluence',
                                 'true',
                                 'test_user',
                                 REGION,
                                 cloned_from=False)
        assert outcome
예제 #12
0
 def test_thread_and_heap_dumps(self):
     setup_stack()
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     # setup mocks
     mystack.get_stacknodes = MagicMock(
         return_value=[{
             'i-0bcf57c789637b10f': '10.111.22.333'
         }, {
             'i-0fdacb1ab66016786': '10.111.22.444'
         }])
     with app.app_context():
         # test thread dumps
         thread_result = mystack.thread_dump(alsoHeaps=False)
         assert thread_result is True
         single_node_thread_result = mystack.thread_dump(
             node='10.111.22.333', alsoHeaps=False)
         assert single_node_thread_result is True
         # test heap dumps
         heap_result = mystack.heap_dump()
         assert heap_result is True
         single_node_heap_result = mystack.heap_dump(node='10.111.22.333')
         assert single_node_heap_result is True
예제 #13
0
 def test_destroy(self):
     setup_stack()
     s3_bucket = app.config['S3_BUCKET']
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     with app.app_context():
         # upload a changelog and thread dump
         s3 = boto3.client('s3')
         s3.upload_file(os.path.relpath(DUMMY_FILE), s3_bucket,
                        f'changelogs/{mystack.stack_name}')
         s3.upload_file(os.path.relpath(DUMMY_FILE), s3_bucket,
                        f'changelogs/{mystack.stack_name}/changelog.log')
         s3.upload_file(os.path.relpath(DUMMY_FILE), s3_bucket,
                        f'diagnostics/{mystack.stack_name}')
         s3.upload_file(os.path.relpath(DUMMY_FILE), s3_bucket,
                        f'diagnostics/{mystack.stack_name}/threaddump.zip')
         # confirm files exist
         changelogs = s3.list_objects_v2(
             Bucket=s3_bucket, Prefix=f'changelogs/{mystack.stack_name}/')
         assert len(changelogs['Contents']) == 1
         diagnostics = s3.list_objects_v2(
             Bucket=s3_bucket, Prefix=f'diagnostics/{mystack.stack_name}/')
         assert len(diagnostics['Contents']) == 1
         # confirm stack exists
         cfn = boto3.client('cloudformation', REGION)
         stacks = cfn.describe_stacks()
         assert len(stacks['Stacks']) == 1
         # confirm stack has been deleted
         mystack.destroy(delete_changelogs=True, delete_threaddumps=True)
         stacks = cfn.describe_stacks()
         assert len(stacks['Stacks']) == 0
         # confirm changelogs have been deleted
         changelogs = s3.list_objects_v2(
             Bucket=s3_bucket, Prefix=f'changelogs/{mystack.stack_name}/')
         assert 'Contents' not in changelogs
         # confirm threaddumps have been deleted
         diagnostics = s3.list_objects_v2(
             Bucket=s3_bucket, Prefix=f'diagnostics/{mystack.stack_name}/')
         assert 'Contents' not in diagnostics
예제 #14
0
 def test_clone_destroy_failed(self):
     setup_stack()
     clone_stack = aws_stack.Stack(CONF_CLONE_STACKNAME, REGION)
     clone_params = get_stack_params()
     clone_params.append({
         'ParameterKey': 'StackName',
         'ParameterValue': CONF_CLONE_STACKNAME
     })
     # setup mocks
     clone_stack.wait_stack_action_complete = MagicMock(return_value=False)
     clone_stack.create = MagicMock(return_value=True)
     with app.app_context():
         outcome = clone_stack.clone(
             stack_params=clone_params,
             template_file=TEMPLATE_FILE_CLONE,
             app_type='confluence',
             clustered='true',
             creator='test-user',
             region=REGION,
             cloned_from=CONF_STACKNAME,
         )
         assert not outcome
         clone_stack.create.assert_not_called()
예제 #15
0
 def test_create_changeset(self):
     setup_stack()
     cfn = boto3.client('cloudformation', REGION)
     stack = cfn.describe_stacks(StackName=CONF_STACKNAME)
     mystack = aws_stack.Stack(CONF_STACKNAME, REGION)
     params_for_update = stack['Stacks'][0]['Parameters']
     for param in params_for_update:
         if param['ParameterKey'] == 'TomcatConnectionTimeout':
             param['ParameterValue'] = '20001'
         # for other params, delete the value and set UsePreviousValue to true
         else:
             del param['ParameterValue']
             param['UsePreviousValue'] = True
     with app.app_context():
         result = mystack.create_change_set(params_for_update,
                                            TEMPLATE_FILE)
         assert result['ResponseMetadata']['HTTPStatusCode'] == 200
         cfn = boto3.client('cloudformation', REGION)
         change_set = cfn.describe_change_set(ChangeSetName=result['Id'],
                                              StackName=CONF_STACKNAME)
         assert [
             param for param in change_set['Parameters']
             if param['ParameterKey'] == 'TomcatConnectionTimeout'
         ][0]['ParameterValue'] == '20001'