From d9fb59c514d4391435b50624cdba40778ebea445 Mon Sep 17 00:00:00 2001 From: Jordan Caussat Date: Fri, 23 Mar 2018 16:32:02 +0100 Subject: [PATCH] TER-235: add unit tests for expanders and improve expanders' prototype --- ghost/resource_ghost_app.go | 53 ++-- ghost/resource_ghost_app_test.go | 418 +++++++++++++++++++++++++++++++ 2 files changed, 441 insertions(+), 30 deletions(-) diff --git a/ghost/resource_ghost_app.go b/ghost/resource_ghost_app.go index 81271e3..4df47aa 100644 --- a/ghost/resource_ghost_app.go +++ b/ghost/resource_ghost_app.go @@ -501,26 +501,25 @@ func expandGhostApp(d *schema.ResourceData) ghost.App { VpcID: d.Get("vpc_id").(string), InstanceMonitoring: d.Get("instance_monitoring").(bool), - Modules: expandGhostAppModules(d), - Features: expandGhostAppFeatures(d), - Autoscale: expandGhostAppAutoscale(d), - BuildInfos: expandGhostAppBuildInfos(d), - EnvironmentInfos: expandGhostAppEnvironmentInfos(d), - LifecycleHooks: expandGhostAppLifecycleHooks(d), + Modules: expandGhostAppModules(d.Get("modules").([]interface{})), + Features: expandGhostAppFeatures(d.Get("features").([]interface{})), + Autoscale: expandGhostAppAutoscale(d.Get("autoscale").([]interface{})), + BuildInfos: expandGhostAppBuildInfos(d.Get("build_infos").([]interface{})), + EnvironmentInfos: expandGhostAppEnvironmentInfos(d.Get("environment_infos").([]interface{})), + LifecycleHooks: expandGhostAppLifecycleHooks(d.Get("lifecycle_hooks").([]interface{})), LogNotifications: expandGhostAppStringList(d.Get("log_notifications").([]interface{})), - EnvironmentVariables: expandGhostAppEnvironmentVariables(d), + EnvironmentVariables: expandGhostAppEnvironmentVariables(d.Get("environment_variables").([]interface{})), } return app } // Get modules from TF configuration -func expandGhostAppModules(d *schema.ResourceData) *[]ghost.Module { - configs := d.Get("modules").([]interface{}) +func expandGhostAppModules(d []interface{}) *[]ghost.Module { modules := &[]ghost.Module{} // Add each module to modules list - for _, config := range configs { + for _, config := range d { data := config.(map[string]interface{}) module := ghost.Module{ Name: data["name"].(string), @@ -543,11 +542,10 @@ func expandGhostAppModules(d *schema.ResourceData) *[]ghost.Module { } // Get environment variables from TF configuration -func expandGhostAppEnvironmentVariables(d *schema.ResourceData) *[]ghost.EnvironmentVariable { - configs := d.Get("environment_variables").([]interface{}) +func expandGhostAppEnvironmentVariables(d []interface{}) *[]ghost.EnvironmentVariable { environmentVariables := &[]ghost.EnvironmentVariable{} - for _, config := range configs { + for _, config := range d { data := config.(map[string]interface{}) environmentVariable := ghost.EnvironmentVariable{ Key: data["key"].(string), @@ -561,12 +559,11 @@ func expandGhostAppEnvironmentVariables(d *schema.ResourceData) *[]ghost.Environ } // Get autoscale from TF configuration -func expandGhostAppAutoscale(d *schema.ResourceData) *ghost.Autoscale { - config := d.Get("autoscale").([]interface{}) - if len(config) == 0 { +func expandGhostAppAutoscale(d []interface{}) *ghost.Autoscale { + if len(d) == 0 { return nil } - data := config[0].(map[string]interface{}) + data := d[0].(map[string]interface{}) autoscale := &ghost.Autoscale{ Name: data["name"].(string), @@ -579,12 +576,11 @@ func expandGhostAppAutoscale(d *schema.ResourceData) *ghost.Autoscale { } // Get lifecycle_hooks from TF configuration -func expandGhostAppLifecycleHooks(d *schema.ResourceData) *ghost.LifecycleHooks { - config := d.Get("lifecycle_hooks").([]interface{}) - if len(config) == 0 { +func expandGhostAppLifecycleHooks(d []interface{}) *ghost.LifecycleHooks { + if len(d) == 0 { return nil } - data := config[0].(map[string]interface{}) + data := d[0].(map[string]interface{}) lifecycleHooks := &ghost.LifecycleHooks{ PreBuildimage: StrToB64(data["pre_buildimage"].(string)), @@ -597,11 +593,10 @@ func expandGhostAppLifecycleHooks(d *schema.ResourceData) *ghost.LifecycleHooks } // Get features from TF configuration -func expandGhostAppFeatures(d *schema.ResourceData) *[]ghost.Feature { - configs := d.Get("features").([]interface{}) +func expandGhostAppFeatures(d []interface{}) *[]ghost.Feature { features := &[]ghost.Feature{} - for _, config := range configs { + for _, config := range d { data := config.(map[string]interface{}) feature := ghost.Feature{ Name: data["name"].(string), @@ -616,9 +611,8 @@ func expandGhostAppFeatures(d *schema.ResourceData) *[]ghost.Feature { } // Get build_infos from TF configuration -func expandGhostAppBuildInfos(d *schema.ResourceData) *ghost.BuildInfos { - config := d.Get("build_infos").([]interface{}) - data := config[0].(map[string]interface{}) +func expandGhostAppBuildInfos(d []interface{}) *ghost.BuildInfos { + data := d[0].(map[string]interface{}) buildInfos := &ghost.BuildInfos{ SshUsername: data["ssh_username"].(string), @@ -631,9 +625,8 @@ func expandGhostAppBuildInfos(d *schema.ResourceData) *ghost.BuildInfos { } // Get environment_infos from TF configuration -func expandGhostAppEnvironmentInfos(d *schema.ResourceData) *ghost.EnvironmentInfos { - config := d.Get("environment_infos").([]interface{}) - data := config[0].(map[string]interface{}) +func expandGhostAppEnvironmentInfos(d []interface{}) *ghost.EnvironmentInfos { + data := d[0].(map[string]interface{}) environmentInfos := &ghost.EnvironmentInfos{ InstanceProfile: data["instance_profile"].(string), diff --git a/ghost/resource_ghost_app_test.go b/ghost/resource_ghost_app_test.go index 81c2bd3..3453a91 100644 --- a/ghost/resource_ghost_app_test.go +++ b/ghost/resource_ghost_app_test.go @@ -3,6 +3,7 @@ package ghost import ( "fmt" "log" + "reflect" "testing" "cloud-deploy.io/go-st" @@ -141,3 +142,420 @@ func testAccGhostAppConfig(name string) string { } `, name) } + +var ( + app = ghost.App{ + Name: "app_name", + Env: "test", + Role: "web", + Region: "us-west-1", + InstanceType: "t2.micro", + VpcID: "vpc-123456", + InstanceMonitoring: false, + + Modules: &[]ghost.Module{{ + Name: "my_module", + GitRepo: "https://github.com/test/test.git", + Scope: "system", + Path: "/", + BuildPack: StrToB64("#!/usr/bin/env bash"), + PreDeploy: StrToB64("#!/usr/bin/env bash"), + }}, + Features: &[]ghost.Feature{{ + Name: "feature", + Version: "1.0", + Provisioner: "ansible", + }}, + Autoscale: &ghost.Autoscale{ + Name: "autoscale", + EnableMetrics: false, + Min: 0, + Max: 3, + }, + BuildInfos: &ghost.BuildInfos{ + SshUsername: "admin", + SourceAmi: "ami-1", + SubnetID: "subnet-1", + }, + EnvironmentInfos: &ghost.EnvironmentInfos{ + InstanceProfile: "profile", + KeyName: "key", + PublicIpAddress: false, + SecurityGroups: []string{"sg-1", "sg-2"}, + SubnetIDs: []string{"subnet-1", "subnet-2"}, + InstanceTags: &[]ghost.InstanceTag{{ + TagName: "name", + TagValue: "val", + }}, + OptionalVolumes: &[]ghost.OptionalVolume{{ + DeviceName: "my_device", + VolumeType: "gp2", + VolumeSize: 20, + Iops: 3000, + }}, + RootBlockDevice: &ghost.RootBlockDevice{ + Name: "rootblock", + Size: 20, + }, + }, + LifecycleHooks: &ghost.LifecycleHooks{ + PreBuildimage: StrToB64("#!/usr/bin/env bash"), + PostBuildimage: StrToB64("#!/usr/bin/env bash"), + }, + LogNotifications: []string{"log_not@email.com"}, + EnvironmentVariables: &[]ghost.EnvironmentVariable{{ + Key: "env_var_key", + Value: "env_var_value", + }}, + } +) + +// Expanders Unit Tests +func TestExpandGhostAppStringList(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput []string + }{ + { + []interface{}{ + "1", "2", "3", + }, + []string{ + "1", "2", "3", + }, + }, + { + nil, + nil, + }, + } + + for _, tc := range cases { + output := expandGhostAppStringList(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppInstanceTags(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *[]ghost.InstanceTag + }{ + { + []interface{}{ + map[string]interface{}{ + "tag_name": "name", + "tag_value": "val", + }, + }, + app.EnvironmentInfos.InstanceTags, + }, + { + nil, + &[]ghost.InstanceTag{}, + }, + } + + for _, tc := range cases { + output := expandGhostAppInstanceTags(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppOptionalVolume(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *[]ghost.OptionalVolume + }{ + { + []interface{}{ + map[string]interface{}{ + "device_name": "my_device", + "volume_type": "gp2", + "volume_size": 20, + "iops": 3000, + "launch_block_device_mappings": false, + }, + }, + app.EnvironmentInfos.OptionalVolumes, + }, + { + nil, + &[]ghost.OptionalVolume{}, + }, + } + + for _, tc := range cases { + output := expandGhostAppOptionalVolumes(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppRootBlockDevice(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *ghost.RootBlockDevice + }{ + { + []interface{}{ + map[string]interface{}{ + "name": "rootblock", + "size": 20, + }, + }, + app.EnvironmentInfos.RootBlockDevice, + }, + { + nil, + nil, + }, + } + + for _, tc := range cases { + output := expandGhostAppRootBlockDevice(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppEnvironmentInfos(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *ghost.EnvironmentInfos + }{ + { + []interface{}{ + map[string]interface{}{ + "instance_profile": "profile", + "key_name": "key", + "public_ip_address": false, + "security_groups": []interface{}{"sg-1", "sg-2"}, + "subnet_ids": []interface{}{"subnet-1", "subnet-2"}, + "instance_tags": []interface{}{ + map[string]interface{}{ + "tag_name": "name", + "tag_value": "val", + }, + }, + "optional_volumes": []interface{}{ + map[string]interface{}{ + "device_name": "my_device", + "volume_type": "gp2", + "volume_size": 20, + "iops": 3000, + "launch_block_device_mappings": false, + }, + }, + "root_block_device": []interface{}{ + map[string]interface{}{ + "name": "rootblock", + "size": 20, + }, + }, + }, + }, + app.EnvironmentInfos, + }, + } + + for _, tc := range cases { + output := expandGhostAppEnvironmentInfos(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppBuildInfos(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *ghost.BuildInfos + }{ + { + []interface{}{ + map[string]interface{}{ + "ssh_username": "admin", + "source_ami": "ami-1", + "subnet_id": "subnet-1", + "ami_name": "", + }, + }, + app.BuildInfos, + }, + } + + for _, tc := range cases { + output := expandGhostAppBuildInfos(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppFeatures(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *[]ghost.Feature + }{ + { + []interface{}{ + map[string]interface{}{ + "name": "feature", + "version": "1.0", + "provisioner": "ansible", + }, + }, + app.Features, + }, + { + nil, + &[]ghost.Feature{}, + }, + } + + for _, tc := range cases { + output := expandGhostAppFeatures(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppLifecycleHooks(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *ghost.LifecycleHooks + }{ + { + []interface{}{ + map[string]interface{}{ + "pre_buildimage": "#!/usr/bin/env bash", + "post_buildimage": "#!/usr/bin/env bash", + "pre_bootstrap": "", + "post_bootstrap": "", + }, + }, + app.LifecycleHooks, + }, + { + nil, + nil, + }, + } + + for _, tc := range cases { + output := expandGhostAppLifecycleHooks(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppAutoscale(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *ghost.Autoscale + }{ + { + []interface{}{ + map[string]interface{}{ + "name": "autoscale", + "enable_metrics": false, + "min": 0, + "max": 3, + }, + }, + app.Autoscale, + }, + { + nil, + nil, + }, + } + + for _, tc := range cases { + output := expandGhostAppAutoscale(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppEnvironmentVariables(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *[]ghost.EnvironmentVariable + }{ + { + []interface{}{ + map[string]interface{}{ + "key": "env_var_key", + "value": "env_var_value", + }, + }, + app.EnvironmentVariables, + }, + { + nil, + &[]ghost.EnvironmentVariable{}, + }, + } + + for _, tc := range cases { + output := expandGhostAppEnvironmentVariables(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + +func TestExpandGhostAppModules(t *testing.T) { + cases := []struct { + Input []interface{} + ExpectedOutput *[]ghost.Module + }{ + { + []interface{}{ + map[string]interface{}{ + "name": "my_module", + "git_repo": "https://github.com/test/test.git", + "path": "/", + "scope": "system", + "build_pack": "#!/usr/bin/env bash", + "pre_deploy": "#!/usr/bin/env bash", + "post_deploy": "", + "after_all_deploy": "", + "uid": 0, + "gid": 0, + "last_deployment": "", + }, + }, + app.Modules, + }, + } + + for _, tc := range cases { + output := expandGhostAppModules(tc.Input) + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +}