From 0e85f88f8eaf44f50655fbe0d89fa2818807b756 Mon Sep 17 00:00:00 2001 From: Tom Melendez Date: Wed, 21 Sep 2016 14:48:09 -0700 Subject: [PATCH] test_gce_mig integration test playbook (#17249) Includes: * Tests to create, delete, resize, recreate and configure an Autoscaler * Tests for parameters only. Use TEST_FLAGS="--tags 'param-check'" to execute only these tests. Requires: * An instance template to be configured in your project. --- test/integration/gce.yml | 1 + test/integration/gce_credentials.py | 29 +-- .../roles/test_gce_mig/defaults/main.yml | 8 + .../roles/test_gce_mig/tasks/main.yml | 232 ++++++++++++++++++ 4 files changed, 256 insertions(+), 14 deletions(-) create mode 100644 test/integration/roles/test_gce_mig/defaults/main.yml create mode 100644 test/integration/roles/test_gce_mig/tasks/main.yml diff --git a/test/integration/gce.yml b/test/integration/gce.yml index 6e314315c52..7fde28d8f87 100644 --- a/test/integration/gce.yml +++ b/test/integration/gce.yml @@ -3,4 +3,5 @@ roles: - { role: test_gce, tags: test_gce } - { role: test_gce_pd, tags: test_gce_pd } + - { role: test_gce_mig, tags: test_gce_mig } # TODO: tests for gce_lb, gce_net, gc_storage diff --git a/test/integration/gce_credentials.py b/test/integration/gce_credentials.py index e474bf0307e..805c66fa992 100644 --- a/test/integration/gce_credentials.py +++ b/test/integration/gce_credentials.py @@ -14,27 +14,28 @@ except ImportError: def add_credentials_options(parser): - default_service_account_email=None - default_pem_file=None - default_project_id=None + default_service_account_email = None + default_pem_file = None + default_project_id = None # Load details from credentials.yml if os.path.isfile('credentials.yml'): credentials = yaml.load(open('credentials.yml', 'r')) - default_service_account_email = credentials['gce_service_account_email'] - default_pem_file = credentials['gce_pem_file'] + default_service_account_email = credentials[ + 'gce_service_account_email'] + default_pem_file = credentials['gce_credentials_file'] default_project_id = credentials['gce_project_id'] - parser.add_option("--service_account_email", - action="store", dest="service_account_email", - default=default_service_account_email, + parser.add_option( + "--service_account_email", action="store", + dest="service_account_email", default=default_service_account_email, help="GCE service account email. Default is loaded from credentials.yml.") - parser.add_option("--pem_file", - action="store", dest="pem_file", + parser.add_option( + "--pem_file", action="store", dest="pem_file", default=default_pem_file, help="GCE client key. Default is loaded from credentials.yml.") - parser.add_option("--project_id", - action="store", dest="project_id", + parser.add_option( + "--project_id", action="store", dest="project_id", default=default_project_id, help="Google Cloud project ID. Default is loaded from credentials.yml.") @@ -48,5 +49,5 @@ def check_required(opts, parser): def get_gce_driver(opts): # Connect to GCE gce_cls = get_driver(Provider.GCE) - return gce_cls( - opts.service_account_email, opts.pem_file, project=opts.project_id) + return gce_cls(opts.service_account_email, opts.pem_file, + project=opts.project_id) diff --git a/test/integration/roles/test_gce_mig/defaults/main.yml b/test/integration/roles/test_gce_mig/defaults/main.yml new file mode 100644 index 00000000000..1fa8050435e --- /dev/null +++ b/test/integration/roles/test_gce_mig/defaults/main.yml @@ -0,0 +1,8 @@ +--- +# defaults file for test_gce_mig +mig_name: "{{ resource_prefix|lower }}" +service_account_email: "{{ gce_service_account_email }}" +pem_file: "{{ gce_credentials_file }}" +project_id: "{{ gce_project_id }}" +zone: "us-central1-c" +instance_template_name: "my-instance-template-1" diff --git a/test/integration/roles/test_gce_mig/tasks/main.yml b/test/integration/roles/test_gce_mig/tasks/main.yml new file mode 100644 index 00000000000..ea54aebce8c --- /dev/null +++ b/test/integration/roles/test_gce_mig/tasks/main.yml @@ -0,0 +1,232 @@ +# GCE Managed Instance Group Integration Tests. +# Note: 'pause' is used to ensure the instances are available +# and the status checks are correct. MIGs and their respective VMs +# will still be created/updated/deleted without the use of the pause module. + +## Parameter checking tests ## +# ============================================================ +- name: "test missing name" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + register: result + ignore_errors: true + tags: + - param-check + +- name: "assert failure when called without required params" + assert: + that: + - 'result.failed' + - 'result.msg == "missing required arguments: name,zone"' + + +# ============================================================ +- name: "test missing param: size on creation" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: my-mig + zone: "{{ zone }}" + template: "{{ instance_template_name }}" + register: result + ignore_errors: true + tags: + - param-check + +- name: "assert failure when param: size not specified" + assert: + that: + - 'result.failed' + - 'result.msg == "size must be of type: "' + +# ============================================================ +- name: "test missing param: template on creation" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: my-mig + zone: "{{ zone }}" + size: 1 + register: result + ignore_errors: true + tags: + - param-check + +- name: "assert failure when param: template not specified" + assert: + that: + - 'result.failed' + - 'result.msg == "template must be of type: "' + +# ============================================================ +- name: "test missing param: autoscaling.policy.max_instances" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: my-mig + zone: "{{ zone }}" + size: 1 + autoscaling: + name: my-test-autoscaler + enabled: yes + policy: + min_instances: 7 + register: result + ignore_errors: true + tags: + - param-check + +- name: "assert failure when param: max_instances not specified" + assert: + that: + - 'result.failed' + - 'result.msg == "max_instances is required and must be of type: "' + +# ============================================================ +- name: "test missing param: autoscaling.policy" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: my-mig + zone: "{{ zone }}" + size: 1 + autoscaling: + name: my-test-autoscaler + enabled: yes + register: result + ignore_errors: true + tags: + - param-check + +- name: "assert failure when param: policy not specified" + assert: + that: + - 'result.failed' + - 'result.msg == "policy is required and must be of type: "' + +## MIG allocation tests ## +# ============================================================ +- name: "test create MIG (state==present)" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: "{{ mig_name }}" + zone: "{{ zone }}" + state: present + size: 1 + template: "{{ instance_template_name }}" + register: result + +- name: "assert MIG creation successful" + assert: + that: + - 'result.changed == True' + - 'result.created_instances|length == 1' + - 'result.size == 1' + +# ============================================================ +- name: "test create Autoscaler" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: "{{ mig_name }}" + zone: "{{ zone }}" + state: present + autoscaling: + enabled: yes + name: "{{ mig_name }}" + policy: + min_instances: 1 + max_instances: 3 + cool_down_period: 17 + cpu_utilization: + target: .19 + load_balancing_utilization: + target: 0.2 + register: result + +- name: "assert Autoscaler created" + assert: + that: + - 'result.changed == True' + - 'result.created_autoscaler == True' + - 'result.size == 1' + - 'result.autoscaling.policy.max_instances == 3' + - 'result.autoscaling.policy.cpu_utilization.target == 0.19' + - 'result.autoscaling.policy.load_balancing_utilization.target == 0.2' + +# ============================================================ +- pause: seconds=30 +# ============================================================ +- name: "test resize MIG (state==present)" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: "{{ mig_name }}" + zone: "{{ zone }}" + state: present + size: 3 + template: "{{ instance_template_name }}" + register: result + +- name: "assert MIG resize successful" + assert: + that: + - 'result.changed == True' + - 'result.resize_created_instances|length == 2' + - 'result.size == 3' +# ============================================================ +- pause: seconds=30 +# ============================================================ +- name: "test recreate instances in MIG (state==present)" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: "{{ mig_name }}" + zone: "{{ zone }}" + state: present + size: 3 + recreate_instances: yes + template: "{{ instance_template_name }}" + register: result + +- name: "assert MIG recreate successful" + assert: + that: + - 'result.changed == True' + - 'result.recreated_instances|length == 3' + - 'result.size == 3' +# ============================================================ +- pause: seconds=60 +# ============================================================ +- name: "test delete MIG and Autoscaler" + gce_mig: + service_account_email: "{{ service_account_email }}" + pem_file: "{{ pem_file }}" + project_id: "{{ project_id }}" + name: "{{ mig_name }}" + zone: "{{ zone }}" + state: absent + autoscaling: + enabled: yes + name: "{{ mig_name }}" + policy: + max_instances: 3 + register: result + +- name: "assert MIG and Autoscaler deleted" + assert: + that: + - 'result.changed == True' + - 'result.deleted_autoscaler == True' + - 'result.deleted_instances|length == 3'