Skip to content

Commit

Permalink
use unique TF IDs for exec test resources (#136)
Browse files Browse the repository at this point in the history
Testing a theory that oci_exec_test reusing IDs causes problems when one
or another exec test fails, causing the other one for the same ID to run
indefinitely and not respect its timeout.

TF IDs uniquely identify resources and datasources, so reusing the
resolved digest for the ID might not be the best.

Instead, this hashes the script bytes and prepends it to the image
digest, so two different tests for the same digest doesn't have the same
TF ID.

Signed-off-by: Jason Hall <[email protected]>
  • Loading branch information
imjasonh authored May 13, 2024
1 parent fab0e04 commit f5e1054
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
22 changes: 21 additions & 1 deletion internal/provider/exec_test_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package provider

import (
"context"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"net"
Expand Down Expand Up @@ -185,13 +187,25 @@ func (d *ExecTestDataSource) Read(ctx context.Context, req datasource.ReadReques
}

cmd := exec.CommandContext(ctx, "sh", "-c", data.Script.ValueString())
go func() {
select {
case <-ctx.Done():
if err := cmd.Process.Kill(); err != nil {
tflog.Error(ctx, "failed to kill process", map[string]interface{}{"error": err})
}
case <-time.After(time.Duration(timeout) * time.Second):
if err := cmd.Process.Kill(); err != nil {
tflog.Error(ctx, "failed to kill process", map[string]interface{}{"error": err})
}
}
}()
cmd.Env = env
cmd.Dir = data.WorkingDir.ValueString()
fullout, err := cmd.CombinedOutput()
data.Output = types.StringValue("") // always empty.

data.TestedRef = data.Digest
data.Id = data.Digest
data.Id = types.StringValue(md5str(data.Script.ValueString()) + data.Digest.ValueString())
data.ExitCode = types.Int64Value(int64(cmd.ProcessState.ExitCode()))

if errors.Is(ctx.Err(), context.DeadlineExceeded) {
Expand All @@ -210,6 +224,12 @@ func (d *ExecTestDataSource) Read(ctx context.Context, req datasource.ReadReques
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func md5str(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}

type positiveIntValidator struct{}

func (positiveIntValidator) MarkdownDescription(context.Context) string { return "positive integer" }
Expand Down
8 changes: 4 additions & 4 deletions internal/provider/exec_test_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestAccExecTestDataSource(t *testing.T) {
}`, d.String()),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.oci_exec_test.test", "digest", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestCheckResourceAttr("data.oci_exec_test.test", "id", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestMatchResourceAttr("data.oci_exec_test.test", "id", regexp.MustCompile(".*cgr.dev/chainguard/wolfi-base@"+d.String())),
resource.TestCheckResourceAttr("data.oci_exec_test.test", "exit_code", "0"),
resource.TestCheckResourceAttr("data.oci_exec_test.test", "output", ""),
),
Expand All @@ -54,7 +54,7 @@ func TestAccExecTestDataSource(t *testing.T) {
}`, d.String()),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.oci_exec_test.env", "digest", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestCheckResourceAttr("data.oci_exec_test.env", "id", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestMatchResourceAttr("data.oci_exec_test.env", "id", regexp.MustCompile(".*cgr.dev/chainguard/wolfi-base@"+d.String())),
resource.TestCheckResourceAttr("data.oci_exec_test.env", "exit_code", "0"),
resource.TestCheckResourceAttr("data.oci_exec_test.env", "output", ""),
),
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestAccExecTestDataSource(t *testing.T) {
}`, d.String()),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.oci_exec_test.working_dir", "digest", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestCheckResourceAttr("data.oci_exec_test.working_dir", "id", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestMatchResourceAttr("data.oci_exec_test.working_dir", "id", regexp.MustCompile(".*cgr.dev/chainguard/wolfi-base@"+d.String())),
resource.TestCheckResourceAttr("data.oci_exec_test.working_dir", "exit_code", "0"),
resource.TestCheckResourceAttr("data.oci_exec_test.working_dir", "output", ""),
),
Expand Down Expand Up @@ -131,7 +131,7 @@ func TestAccExecTestDataSource_FreePort(t *testing.T) {
`, i, d.String())
checks = append(checks,
resource.TestCheckResourceAttr(fmt.Sprintf("data.oci_exec_test.freeport-%d", i), "digest", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestCheckResourceAttr(fmt.Sprintf("data.oci_exec_test.freeport-%d", i), "id", fmt.Sprintf("cgr.dev/chainguard/wolfi-base@%s", d.String())),
resource.TestMatchResourceAttr(fmt.Sprintf("data.oci_exec_test.freeport-%d", i), "id", regexp.MustCompile(".*cgr.dev/chainguard/wolfi-base@"+d.String())),
)
}

Expand Down

0 comments on commit f5e1054

Please sign in to comment.