package rpc import ( "context" "errors" "reflect" "testing" packersdk "github.com/hashicorp/packer/packer-plugin-sdk/packer" ) var testBuildArtifact = &packersdk.MockArtifact{} type testBuild struct { nameCalled bool prepareCalled bool prepareWarnings []string runFn func(context.Context) runCalled bool runUi packersdk.Ui setDebugCalled bool setForceCalled bool setOnErrorCalled bool errRunResult bool } func (b *testBuild) Name() string { b.nameCalled = true return "name" } func (b *testBuild) Prepare() ([]string, error) { b.prepareCalled = true return b.prepareWarnings, nil } func (b *testBuild) Run(ctx context.Context, ui packersdk.Ui) ([]packersdk.Artifact, error) { b.runCalled = true b.runUi = ui if b.runFn != nil { b.runFn(ctx) } if b.errRunResult { return nil, errors.New("foo") } else { return []packersdk.Artifact{testBuildArtifact}, nil } } func (b *testBuild) SetDebug(bool) { b.setDebugCalled = true } func (b *testBuild) SetForce(bool) { b.setForceCalled = true } func (b *testBuild) SetOnError(string) { b.setOnErrorCalled = true } func TestBuild(t *testing.T) { b := new(testBuild) client, server := testClientServer(t) defer client.Close() defer server.Close() server.RegisterBuild(b) bClient := client.Build() ctx := context.Background() // Test Name bClient.Name() if !b.nameCalled { t.Fatal("name should be called") } // Test Prepare bClient.Prepare() if !b.prepareCalled { t.Fatal("prepare should be called") } // Test Run ui := new(packersdk.MockUi) artifacts, err := bClient.Run(ctx, ui) if !b.runCalled { t.Fatal("run should be called") } if err != nil { t.Fatalf("err: %s", err) } if len(artifacts) != 1 { t.Fatalf("bad: %#v", artifacts) } if artifacts[0].BuilderId() != "bid" { t.Fatalf("bad: %#v", artifacts) } // Test run with an error b.errRunResult = true _, err = bClient.Run(ctx, ui) if err == nil { t.Fatal("should error") } // Test SetDebug bClient.SetDebug(true) if !b.setDebugCalled { t.Fatal("should be called") } // Test SetForce bClient.SetForce(true) if !b.setForceCalled { t.Fatal("should be called") } // Test SetOnError bClient.SetOnError("ask") if !b.setOnErrorCalled { t.Fatal("should be called") } } func TestBuild_cancel(t *testing.T) { topCtx, cancelTopCtx := context.WithCancel(context.Background()) b := new(testBuild) done := make(chan interface{}) b.runFn = func(ctx context.Context) { cancelTopCtx() <-ctx.Done() close(done) } client, server := testClientServer(t) defer client.Close() defer server.Close() server.RegisterBuild(b) bClient := client.Build() bClient.Prepare() ui := new(packersdk.MockUi) bClient.Run(topCtx, ui) // if context cancellation is not propagated, this will timeout <-done } func TestBuildPrepare_Warnings(t *testing.T) { b := new(testBuild) client, server := testClientServer(t) defer client.Close() defer server.Close() server.RegisterBuild(b) bClient := client.Build() expected := []string{"foo"} b.prepareWarnings = expected warnings, err := bClient.Prepare() if err != nil { t.Fatalf("err: %s", err) } if !reflect.DeepEqual(warnings, expected) { t.Fatalf("bad: %#v", warnings) } } func TestBuild_ImplementsBuild(t *testing.T) { var _ packersdk.Build = new(build) }