package digitalocean import ( "strconv" "testing" "time" packersdk "github.com/hashicorp/packer/packer-plugin-sdk/packer" ) func testConfig() map[string]interface{} { return map[string]interface{}{ "api_token": "bar", "region": "nyc2", "size": "512mb", "ssh_username": "root", "image": "foo", } } func TestBuilder_ImplementsBuilder(t *testing.T) { var raw interface{} raw = &Builder{} if _, ok := raw.(packersdk.Builder); !ok { t.Fatalf("Builder should be a builder") } } func TestBuilder_Prepare_BadType(t *testing.T) { b := &Builder{} c := map[string]interface{}{ "api_key": []string{}, } _, warnings, err := b.Prepare(c) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatalf("prepare should fail") } } func TestBuilderPrepare_InvalidKey(t *testing.T) { var b Builder config := testConfig() // Add a random key config["i_should_not_be_valid"] = true _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatal("should have error") } } func TestBuilderPrepare_Region(t *testing.T) { var b Builder config := testConfig() // Test default delete(config, "region") _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatalf("should error") } expected := "sfo1" // Test set config["region"] = expected b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.Region != expected { t.Errorf("found %s, expected %s", b.config.Region, expected) } } func TestBuilderPrepare_Size(t *testing.T) { var b Builder config := testConfig() // Test default delete(config, "size") _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatalf("should error") } expected := "1024mb" // Test set config["size"] = expected b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.Size != expected { t.Errorf("found %s, expected %s", b.config.Size, expected) } } func TestBuilderPrepare_Image(t *testing.T) { var b Builder config := testConfig() // Test default delete(config, "image") _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatal("should error") } expected := "ubuntu-14-04-x64" // Test set config["image"] = expected b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.Image != expected { t.Errorf("found %s, expected %s", b.config.Image, expected) } } func TestBuilderPrepare_StateTimeout(t *testing.T) { var b Builder config := testConfig() // Test default _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.StateTimeout != 6*time.Minute { t.Errorf("invalid: %s", b.config.StateTimeout) } // Test set config["state_timeout"] = "5m" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } // Test bad config["state_timeout"] = "tubes" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatal("should have error") } } func TestBuilderPrepare_SnapshotTimeout(t *testing.T) { var b Builder config := testConfig() // Test default _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.SnapshotTimeout != 60*time.Minute { t.Errorf("invalid: %s", b.config.SnapshotTimeout) } // Test set config["snapshot_timeout"] = "15m" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } // Test bad config["snapshot_timeout"] = "badstring" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatal("should have error") } } func TestBuilderPrepare_PrivateNetworking(t *testing.T) { var b Builder config := testConfig() // Test default _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.PrivateNetworking != false { t.Errorf("invalid: %t", b.config.PrivateNetworking) } // Test set config["private_networking"] = true b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.PrivateNetworking != true { t.Errorf("invalid: %t", b.config.PrivateNetworking) } } func TestBuilderPrepare_SnapshotName(t *testing.T) { var b Builder config := testConfig() // Test default _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.SnapshotName == "" { t.Errorf("invalid: %s", b.config.SnapshotName) } // Test set config["snapshot_name"] = "foobarbaz" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } // Test set with template config["snapshot_name"] = "{{timestamp}}" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } _, err = strconv.ParseInt(b.config.SnapshotName, 0, 0) if err != nil { t.Fatalf("failed to parse int in template: %s", err) } } func TestBuilderPrepare_DropletName(t *testing.T) { var b Builder config := testConfig() // Test default _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } if b.config.DropletName == "" { t.Errorf("invalid: %s", b.config.DropletName) } // Test normal set config["droplet_name"] = "foobar" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } // Test with template config["droplet_name"] = "foobar-{{timestamp}}" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatalf("should not have error: %s", err) } // Test with bad template config["droplet_name"] = "foobar-{{" b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatal("should have error") } } func TestBuilderPrepare_VPCUUID(t *testing.T) { var b Builder config := testConfig() // Test with the case vpc_uuid is defined but private_networking is not enabled config["vpc_uuid"] = "554c41b3-425f-5403-8860-7f24fb108098" _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatalf("should have error: 'private networking should be enabled to use vpc_uuid'") } // Test with the case both vpc_uuid and private_networking are defined/enabled config["private_networking"] = true b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatal("should not have error") } } func TestBuilderPrepare_ConnectWithPrivateIP(t *testing.T) { var b Builder config := testConfig() // Test with the case connect_with_private_ip is defined but private_networking is not enabled config["connect_with_private_ip"] = true _, warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err == nil { t.Fatalf("should have error: 'private networking should be enabled to use connect_with_private_ip'") } // Test with the case both connect_with_private_ip and private_networking are enabled config["private_networking"] = true b = Builder{} _, warnings, err = b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } if err != nil { t.Fatal("should not have error") } }