github.com/opentofu/opentofu@v1.7.1/internal/builtin/provisioners/file/resource_provisioner_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package file 7 8 import ( 9 "strings" 10 "testing" 11 12 "github.com/opentofu/opentofu/internal/provisioners" 13 "github.com/zclconf/go-cty/cty" 14 ) 15 16 func TestResourceProvider_Validate_good_source(t *testing.T) { 17 v := cty.ObjectVal(map[string]cty.Value{ 18 "source": cty.StringVal("/tmp/foo"), 19 "destination": cty.StringVal("/tmp/bar"), 20 }) 21 22 resp := New().ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{ 23 Config: v, 24 }) 25 26 if len(resp.Diagnostics) > 0 { 27 t.Fatal(resp.Diagnostics.ErrWithWarnings()) 28 } 29 } 30 31 func TestResourceProvider_Validate_good_content(t *testing.T) { 32 v := cty.ObjectVal(map[string]cty.Value{ 33 "content": cty.StringVal("value to copy"), 34 "destination": cty.StringVal("/tmp/bar"), 35 }) 36 37 resp := New().ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{ 38 Config: v, 39 }) 40 41 if len(resp.Diagnostics) > 0 { 42 t.Fatal(resp.Diagnostics.ErrWithWarnings()) 43 } 44 } 45 46 func TestResourceProvider_Validate_good_unknown_variable_value(t *testing.T) { 47 v := cty.ObjectVal(map[string]cty.Value{ 48 "content": cty.UnknownVal(cty.String), 49 "destination": cty.StringVal("/tmp/bar"), 50 }) 51 52 resp := New().ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{ 53 Config: v, 54 }) 55 56 if len(resp.Diagnostics) > 0 { 57 t.Fatal(resp.Diagnostics.ErrWithWarnings()) 58 } 59 } 60 61 func TestResourceProvider_Validate_bad_not_destination(t *testing.T) { 62 v := cty.ObjectVal(map[string]cty.Value{ 63 "source": cty.StringVal("nope"), 64 }) 65 66 resp := New().ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{ 67 Config: v, 68 }) 69 70 if !resp.Diagnostics.HasErrors() { 71 t.Fatal("Should have errors") 72 } 73 } 74 75 func TestResourceProvider_Validate_bad_no_source(t *testing.T) { 76 v := cty.ObjectVal(map[string]cty.Value{ 77 "destination": cty.StringVal("/tmp/bar"), 78 }) 79 80 resp := New().ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{ 81 Config: v, 82 }) 83 84 if !resp.Diagnostics.HasErrors() { 85 t.Fatal("Should have errors") 86 } 87 } 88 89 func TestResourceProvider_Validate_bad_to_many_src(t *testing.T) { 90 v := cty.ObjectVal(map[string]cty.Value{ 91 "source": cty.StringVal("nope"), 92 "content": cty.StringVal("vlue to copy"), 93 "destination": cty.StringVal("/tmp/bar"), 94 }) 95 96 resp := New().ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{ 97 Config: v, 98 }) 99 100 if !resp.Diagnostics.HasErrors() { 101 t.Fatal("Should have errors") 102 } 103 } 104 105 // Validate that Stop can Close can be called even when not provisioning. 106 func TestResourceProvisioner_StopClose(t *testing.T) { 107 p := New() 108 p.Stop() 109 p.Close() 110 } 111 112 func TestResourceProvisioner_connectionRequired(t *testing.T) { 113 p := New() 114 resp := p.ProvisionResource(provisioners.ProvisionResourceRequest{}) 115 if !resp.Diagnostics.HasErrors() { 116 t.Fatal("expected error") 117 } 118 119 got := resp.Diagnostics.Err().Error() 120 if !strings.Contains(got, "Missing connection") { 121 t.Fatalf("expected 'Missing connection' error: got %q", got) 122 } 123 } 124 125 func TestResourceProvisioner_nullSrcVars(t *testing.T) { 126 conn := cty.ObjectVal(map[string]cty.Value{ 127 "type": cty.StringVal(""), 128 "host": cty.StringVal("localhost"), 129 }) 130 config := cty.ObjectVal(map[string]cty.Value{ 131 "source": cty.NilVal, 132 "content": cty.NilVal, 133 "destination": cty.StringVal("/tmp/bar"), 134 }) 135 p := New() 136 resp := p.ProvisionResource(provisioners.ProvisionResourceRequest{ 137 Connection: conn, 138 Config: config, 139 }) 140 if !resp.Diagnostics.HasErrors() { 141 t.Fatal("expected error") 142 } 143 144 got := resp.Diagnostics.Err().Error() 145 if !strings.Contains(got, "file provisioner error: source and content cannot both be null") { 146 t.Fatalf("file provisioner error: source and content cannot both be null' error: got %q", got) 147 } 148 }