Skip to content

Commit

Permalink
Merge branch 'release/v0.2.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
rucciva committed Nov 6, 2020
2 parents ccd7e00 + 26aa733 commit 5c336a9
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 110 deletions.
19 changes: 13 additions & 6 deletions linux/script-resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@ func (h handlerScriptResource) read(ctx context.Context, rd *schema.ResourceData
if err != nil {
return
}
if res == "" {
rd.SetId("")
return
}
if err = rd.Set(attrScriptOutput, res); err != nil {
return
}
Expand All @@ -146,11 +142,17 @@ func (h handlerScriptResource) Read(ctx context.Context, rd *schema.ResourceData
return
}

_ = rd.Set(attrScriptReadFailed, false)
new := cast.ToString(rd.Get(attrScriptOutput))
if new == "" {
rd.SetId("")
return
}
if err := rd.Set(attrScriptDirty, old != new); err != nil {
return diag.FromErr(err)
}
if err := rd.Set(attrScriptReadFailed, false); err != nil {
return diag.FromErr(err)
}
return
}

Expand Down Expand Up @@ -263,13 +265,18 @@ func (h handlerScriptResource) CustomizeDiff(c context.Context, rd *schema.Resou
return
}

if n, _ := rd.GetChange(attrScriptReadFailed); cast.ToBool(n) && !rd.HasChange(attrScriptLifecycleCommands+".0."+attrScriptLifecycleCommandRead) {
if f, _ := rd.GetChange(attrScriptReadFailed); cast.ToBool(f) &&
!rd.HasChange(attrScriptLifecycleCommands+".0."+attrScriptLifecycleCommandRead) {
_ = rd.ForceNew(attrScriptReadFailed)
}
if _, ok := rd.GetOk(attrScriptLifecycleCommands + ".0." + attrScriptLifecycleCommandUpdate); ok {
return
}
for _, key := range rd.GetChangedKeysPrefix("") {
if key == attrScriptLifecycleCommands+".0."+attrScriptLifecycleCommandCreate ||
key == attrScriptLifecycleCommands+".0."+attrScriptLifecycleCommandDelete {
continue // should not trigger force new
}
if strings.HasPrefix(key, attrScriptTriggers) {
continue // already force new
}
Expand Down
216 changes: 112 additions & 104 deletions linux/script-resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,118 @@ func testAccLinuxScriptNoUpdateConfig(t *testing.T, conf tfConf) (s string) {
return
}

func TestAccLinuxScriptFailedRead(t *testing.T) {
// TODO: a proper provisioner to check
createFile := tfConf{
Provider: testAccProvider,
Script: tfScript{
LifecycleCommands: tfmap{
attrScriptLifecycleCommandCreate: `"echo -n $CONTENT > $FILE"`,
attrScriptLifecycleCommandRead: `"cat $FILE"`,
attrScriptLifecycleCommandUpdate: `"echo -n $CONTENT.updated > $FILE"`,
attrScriptLifecycleCommandDelete: `"rm $FILE || true"`,
},
Environment: tfmap{
"FILE": `"/tmp/linux-test"`,
"CONTENT": `"test"`,
},
},
Extra: tfmap{
"ShouldDelete": "true",
},
}
recreateFile := tfConf{
Provider: testAccProvider,
Script: createFile.Script.Copy(),
}
fixedReadUpdatedContentScript := tfConf{
Provider: testAccProvider,
Script: createFile.Script.Copy(
func(sc *tfScript) {
sc.LifecycleCommands.
With(attrScriptLifecycleCommandRead, `"cat $FILE || echo"`).
With(attrScriptLifecycleCommandDelete, `"rm $FILE"`)
},
func(sc *tfScript) {
sc.Environment.With("CONTENT", `"test2"`)
},
),
}

resource.Test(t, resource.TestCase{
ExternalProviders: map[string]resource.ExternalProvider{"null": {}},
PreCheck: testAccPreCheckConnection(t),
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccLinuxScriptFailedReadConfig(t, createFile),
ExpectNonEmptyPlan: true,
},
{
Config: testAccLinuxScriptFailedReadConfig(t, recreateFile),
Check: resource.TestCheckResourceAttr("linux_script.create_file", "output", "test"),
},
},
})
resource.Test(t, resource.TestCase{
ExternalProviders: map[string]resource.ExternalProvider{"null": {}},
PreCheck: testAccPreCheckConnection(t),
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccLinuxScriptFailedReadConfig(t, createFile),
ExpectNonEmptyPlan: true,
},
{
Config: testAccLinuxScriptFailedReadConfig(t, fixedReadUpdatedContentScript),
ExpectNonEmptyPlan: true,
},
{
Config: testAccLinuxScriptFailedReadConfig(t, fixedReadUpdatedContentScript),
Check: resource.TestCheckResourceAttr("linux_script.create_file", "output", "test2.updated"),
},
},
})
}

func testAccLinuxScriptFailedReadConfig(t *testing.T, conf tfConf) (s string) {
tf := heredoc.Doc(`
provider "linux" {
{{- .Provider.Serialize | nindent 4 }}
}
resource "linux_script" "create_file" {
{{- .Script.Serialize | nindent 4 }}
connection {
type = "ssh"
{{- .Provider.Serialize | nindent 8 }}
}
{{ if .Extra.ShouldDelete -}}
provisioner "remote-exec" {
inline = [
<<-EOF
rm ${self.environment.FILE}
EOF
]
}
{{- else -}}
provisioner "remote-exec" {
inline = [
<<-EOF
[ "$(cat ${self.environment.FILE})" == "${self.environment.CONTENT}" ] || exit 100
EOF
]
}
{{- end }}
}
`)
s, err := conf.compile(tf)
t.Log(s)
require.NoError(t, err, "compile template failed")
return
}

func TestAccLinuxScriptUpdatedScript(t *testing.T) {
failedCreateDueToReadError := tfConf{
Provider: testAccProvider,
Expand Down Expand Up @@ -404,107 +516,3 @@ func testAccLinuxScriptUpdatedScriptConfig(t *testing.T, conf tfConf) (s string)
require.NoError(t, err, "compile template failed")
return
}

func TestAccLinuxScriptFailedRead(t *testing.T) {
// TODO: a proper provisioner to check
createFile := tfConf{
Provider: testAccProvider,
Script: tfScript{
LifecycleCommands: tfmap{
attrScriptLifecycleCommandCreate: `"echo $CONTENT > $FILE"`,
attrScriptLifecycleCommandRead: `"cat $FILE"`,
attrScriptLifecycleCommandUpdate: `"echo $CONTENT > $FILE"`,
attrScriptLifecycleCommandDelete: `"rm $FILE || true"`,
},
Environment: tfmap{
"FILE": `"/tmp/linux-test"`,
"CONTENT": `"test"`,
},
},
Extra: tfmap{
"ShouldDelete": "true",
},
}
recreateFile := tfConf{
Provider: testAccProvider,
Script: createFile.Script.Copy(),
}
fixedReadUpdatedContentScript := tfConf{
Provider: testAccProvider,
Script: createFile.Script.Copy(
func(sc *tfScript) {
sc.LifecycleCommands.
With(attrScriptLifecycleCommandRead, `"cat $FILE || echo"`).
With(attrScriptLifecycleCommandDelete, `"rm $FILE"`)
},
func(sc *tfScript) {
sc.Environment.With("CONTENT", `"test2"`)
},
),
}

resource.Test(t, resource.TestCase{
ExternalProviders: map[string]resource.ExternalProvider{"null": {}},
PreCheck: testAccPreCheckConnection(t),
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccLinuxScriptFailedReadConfig(t, createFile),
ExpectNonEmptyPlan: true,
},
{
Config: testAccLinuxScriptFailedReadConfig(t, recreateFile),
Check: resource.TestCheckResourceAttr("linux_script.create_file", "read_failed", "false"),
},
},
})
resource.Test(t, resource.TestCase{
ExternalProviders: map[string]resource.ExternalProvider{"null": {}},
PreCheck: testAccPreCheckConnection(t),
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccLinuxScriptFailedReadConfig(t, createFile),
ExpectNonEmptyPlan: true,
},
{
Config: testAccLinuxScriptFailedReadConfig(t, fixedReadUpdatedContentScript),
Check: resource.TestCheckResourceAttr("linux_script.create_file", "read_failed", "false"),
ExpectNonEmptyPlan: true,
},
{
Config: testAccLinuxScriptFailedReadConfig(t, fixedReadUpdatedContentScript),
Check: resource.TestCheckResourceAttr("linux_script.create_file", "read_failed", "false"),
},
},
})
}

func testAccLinuxScriptFailedReadConfig(t *testing.T, conf tfConf) (s string) {
tf := heredoc.Doc(`
provider "linux" {
{{- .Provider.Serialize | nindent 4 }}
}
resource "linux_script" "create_file" {
{{- .Script.Serialize | nindent 4 }}
{{ if .Extra.ShouldDelete -}}
connection {
type = "ssh"
{{- .Provider.Serialize | nindent 8 }}
}
provisioner "remote-exec" {
inline = [
<<-EOF
rm ${self.environment.FILE}
EOF
]
}
{{- end }}
}
`)
s, err := conf.compile(tf)
t.Log(s)
require.NoError(t, err, "compile template failed")
return
}

0 comments on commit 5c336a9

Please sign in to comment.