| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package service |
| |
| import ( |
| "context" |
| "reflect" |
| "testing" |
| "time" |
| |
| mocks "fuchsia.googlesource.com/infra/infra/tilo/resultstore/service/mocks" |
| "github.com/golang/mock/gomock" |
| api "google.golang.org/genproto/googleapis/devtools/resultstore/v2" |
| "google.golang.org/genproto/protobuf/field_mask" |
| ) |
| |
| // Public testing values. |
| var ( |
| // The value of entity start times and durations is not important for these tests, |
| // so we use the same value everywhere. |
| TestTimestamp = time.Date(1, 2, 3, 4, 5, 6, 7, time.UTC) |
| |
| // The specific values of the UUIDs are not important for these tests. We just want to |
| // verify that the service sets some value other than the empty string, so we just use |
| // the same UUID everywhere. |
| TestUUIDValue = "uuid" |
| ) |
| |
| // TestBed manages the setup and teardown phases of individual test cases. |
| type TestBed struct { |
| MockRPCClient *mocks.MockResultStoreUploadClient |
| ctrl *gomock.Controller |
| } |
| |
| // Setup creates the service-under-test and should be run before every test case. |
| func (bed *TestBed) Setup(t *testing.T, authToken string) (Service, context.Context) { |
| // Cache the mock controller so we can Finish() it during test teardown. |
| bed.ctrl = gomock.NewController(t) |
| bed.MockRPCClient = mocks.NewMockResultStoreUploadClient(bed.ctrl) |
| |
| // Force Service to re-use a fake UUID for testing by embedding the UUID in the |
| // context object. |
| ctx, err := SetTestUUID(context.Background(), TestUUIDValue) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| ctx, err = SetAuthToken(ctx, authToken) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| return New(bed.MockRPCClient), ctx |
| } |
| |
| // Teardown is used to clean up after every test-case. |
| func (bed *TestBed) Teardown() { |
| bed.ctrl.Finish() |
| } |
| |
| // ExpectRPC is used to expect that a specific RPC message is recieved by the test bed. |
| // If an invalid message or no message is received, the test will fail. |
| func (bed *TestBed) ExpectRPC() *mocks.MockResultStoreUploadClientMockRecorder { |
| return bed.MockRPCClient.EXPECT() |
| } |
| |
| func expectEqual(t *testing.T, expected interface{}, actual interface{}) { |
| if !reflect.DeepEqual(expected, actual) { |
| t.Errorf("Objects do not match:\n") |
| t.Errorf("Expected: %+v\n", expected) |
| t.Errorf("Actual: %+v\n", actual) |
| } |
| } |
| |
| func TestService_CreateInvocation(t *testing.T) { |
| t.Run("should return an InvocationKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &Invocation{ |
| ProjectID: "123456789", |
| Users: []string{"user"}, |
| Labels: []string{"label"}, |
| Properties: map[string]string{"key": "value"}, |
| LogURL: "http://test.log", |
| StartTime: TestTimestamp, |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| CreateInvocation(ctx, &api.CreateInvocationRequest{ |
| AuthorizationToken: "auth_token", |
| RequestId: TestUUIDValue, |
| InvocationId: TestUUIDValue, |
| Invocation: input.ToResultStoreInvocation(), |
| }). |
| Return(input.ToResultStoreInvocation(), nil) |
| |
| output, err := service.CreateInvocation(ctx, input) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_UpdateInvocation(t *testing.T) { |
| t.Run("should return an InvocationKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &Invocation{ |
| ID: "invocation_id", |
| Properties: map[string]string{"key": "value"}, |
| ProjectID: "project_id", |
| StartTime: TestTimestamp, |
| Duration: time.Duration(0), |
| Users: []string{"users"}, |
| Labels: []string{"label"}, |
| LogURL: "url", |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| UpdateInvocation(ctx, &api.UpdateInvocationRequest{ |
| AuthorizationToken: "auth_token", |
| Invocation: input.ToResultStoreInvocation(), |
| UpdateMask: &field_mask.FieldMask{ |
| Paths: []string{"timing.duration", "status_attributes"}, |
| }, |
| }). |
| Return(input.ToResultStoreInvocation(), nil) |
| |
| output, err := service.UpdateInvocation(ctx, input) |
| if err != nil { |
| t.Fatal(err) |
| } |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_FinishInvocation(t *testing.T) { |
| t.Run("should return an InvocationKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| testBed.ExpectRPC(). |
| FinishInvocation(ctx, &api.FinishInvocationRequest{ |
| AuthorizationToken: "auth_token", |
| Name: "invocation_name", |
| }). |
| Return(&api.FinishInvocationResponse{}, nil) |
| |
| if err := service.FinishInvocation(ctx, "invocation_name"); err != nil { |
| t.Fatal(err) |
| } |
| }) |
| } |
| |
| func TestService_CreateConfiguration(t *testing.T) { |
| t.Run("should return a ConfigurationKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &Configuration{ |
| ID: "configuration_id", |
| InvocationID: "invocation_id", |
| Properties: map[string]string{"key": "value"}, |
| } |
| |
| testBed.ExpectRPC(). |
| CreateConfiguration(ctx, &api.CreateConfigurationRequest{ |
| RequestId: TestUUIDValue, |
| AuthorizationToken: "auth_token", |
| Parent: "invocation_name", |
| ConfigId: "configuration_id", |
| Configuration: input.ToResultStoreConfiguration(), |
| }). |
| Return(input.ToResultStoreConfiguration(), nil) |
| |
| output, err := service.CreateConfiguration(ctx, input, "invocation_name") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_CreateTarget(t *testing.T) { |
| t.Run("should return a TargetKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &Target{ |
| ID: "target_id", |
| Properties: map[string]string{"key": "value"}, |
| StartTime: TestTimestamp, |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| CreateTarget(ctx, &api.CreateTargetRequest{ |
| RequestId: TestUUIDValue, |
| AuthorizationToken: "auth_token", |
| Parent: "invocation_name", |
| TargetId: input.ID, |
| Target: input.ToResultStoreTarget(), |
| }). |
| Return(input.ToResultStoreTarget(), nil) |
| |
| output, err := service.CreateTarget(ctx, input, "invocation_name") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_UpdateTarget(t *testing.T) { |
| t.Run("should return a TargetKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &Target{ |
| ID: "target_id", |
| InvocationID: "invocation_id", |
| Properties: map[string]string{"key": "value"}, |
| StartTime: TestTimestamp, |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| UpdateTarget(ctx, &api.UpdateTargetRequest{ |
| AuthorizationToken: "auth_token", |
| Target: input.ToResultStoreTarget(), |
| UpdateMask: &field_mask.FieldMask{ |
| Paths: []string{"timing.duration", "status_attributes"}, |
| }, |
| }). |
| Return(input.ToResultStoreTarget(), nil) |
| |
| output, err := service.UpdateTarget(ctx, input) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_FinishTarget(t *testing.T) { |
| t.Run("should return a TargetKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| testBed.ExpectRPC(). |
| FinishTarget(ctx, &api.FinishTargetRequest{ |
| AuthorizationToken: "auth_token", |
| Name: "target_name", |
| }). |
| Return(&api.FinishTargetResponse{}, nil) |
| |
| if err := service.FinishTarget(ctx, "target_name"); err != nil { |
| t.Fatal(err) |
| } |
| }) |
| } |
| |
| func TestService_CreateConfiguredTarget(t *testing.T) { |
| t.Run("should return a ConfiguredTargetKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &ConfiguredTarget{ |
| InvocationID: "invocation_id", |
| TargetID: "target_id", |
| ConfigID: "configuration_id", |
| Properties: map[string]string{"key": "value"}, |
| StartTime: TestTimestamp, |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| CreateConfiguredTarget(ctx, &api.CreateConfiguredTargetRequest{ |
| AuthorizationToken: "auth_token", |
| RequestId: TestUUIDValue, |
| Parent: "target_name", |
| ConfigId: "configuration_id", |
| ConfiguredTarget: input.ToResultStoreConfiguredTarget(), |
| }). |
| Return(input.ToResultStoreConfiguredTarget(), nil) |
| |
| output, err := service.CreateConfiguredTarget(ctx, input, "target_name") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_UpdateConfiguredTarget(t *testing.T) { |
| t.Run("should return a ConfiguredTargetKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &ConfiguredTarget{ |
| ConfigID: "configuration_id", |
| Properties: map[string]string{"key": "value"}, |
| Status: Passed, |
| StartTime: TestTimestamp, |
| } |
| |
| testBed.ExpectRPC(). |
| UpdateConfiguredTarget(ctx, &api.UpdateConfiguredTargetRequest{ |
| AuthorizationToken: "auth_token", |
| ConfiguredTarget: input.ToResultStoreConfiguredTarget(), |
| UpdateMask: &field_mask.FieldMask{ |
| Paths: []string{"timing.duration", "status_attributes"}, |
| }, |
| }). |
| Return(input.ToResultStoreConfiguredTarget(), nil) |
| |
| output, err := service.UpdateConfiguredTarget(ctx, input) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_FinishConfiguredTarget(t *testing.T) { |
| t.Run("should return a ConfiguredTargetKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| testBed.ExpectRPC(). |
| FinishConfiguredTarget(ctx, &api.FinishConfiguredTargetRequest{ |
| AuthorizationToken: "auth_token", |
| Name: "configured_target_name", |
| }). |
| Return(&api.FinishConfiguredTargetResponse{}, nil) |
| |
| if err := service.FinishConfiguredTarget(ctx, "configured_target_name"); err != nil { |
| t.Fatal(err) |
| } |
| }) |
| } |
| |
| func TestService_CreateTestAction(t *testing.T) { |
| t.Run("should return an ActionKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &TestAction{ |
| ID: "test", |
| InvocationID: "invocation_id", |
| TargetID: "target_id", |
| ConfigID: "configuration_id", |
| TestSuite: "test_suite", |
| TestLogURI: "http://test.log", |
| StartTime: TestTimestamp, |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| CreateAction(ctx, &api.CreateActionRequest{ |
| RequestId: TestUUIDValue, |
| AuthorizationToken: "auth_token", |
| Parent: "configured_target_name", |
| ActionId: input.ID, |
| Action: input.ToResultStoreAction(), |
| }). |
| Return(input.ToResultStoreAction(), nil) |
| |
| output, err := service.CreateTestAction(ctx, input, "configured_target_name") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |
| |
| func TestService_UpdateTestAction(t *testing.T) { |
| t.Run("should return an ActionKey from an RPC response", func(t *testing.T) { |
| testBed := new(TestBed) |
| service, ctx := testBed.Setup(t, "auth_token") |
| defer testBed.Teardown() |
| |
| input := &TestAction{ |
| ID: "test", |
| InvocationID: "invocation_id", |
| TargetID: "target_id", |
| ConfigID: "configuration_id", |
| TestSuite: "test_suite", |
| TestLogURI: "http://test.log", |
| StartTime: TestTimestamp, |
| Status: Passed, |
| } |
| |
| testBed.ExpectRPC(). |
| UpdateAction(ctx, &api.UpdateActionRequest{ |
| AuthorizationToken: "auth_token", |
| Action: input.ToResultStoreAction(), |
| UpdateMask: &field_mask.FieldMask{ |
| Paths: []string{"timing.duration", "status_attributes"}, |
| }, |
| }). |
| Return(input.ToResultStoreAction(), nil) |
| |
| output, err := service.UpdateTestAction(ctx, input) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| expectEqual(t, input, output) |
| }) |
| } |