go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/resultdb/sink/testutil_test.go (about)

     1  // Copyright 2020 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sink
    16  
    17  import (
    18  	"context"
    19  	"io/ioutil"
    20  	"net/http"
    21  	"os"
    22  	"time"
    23  
    24  	"google.golang.org/grpc"
    25  	"google.golang.org/grpc/metadata"
    26  	"google.golang.org/protobuf/types/known/durationpb"
    27  	"google.golang.org/protobuf/types/known/timestamppb"
    28  
    29  	"go.chromium.org/luci/common/clock/testclock"
    30  	"go.chromium.org/luci/grpc/prpc"
    31  
    32  	"go.chromium.org/luci/resultdb/pbutil"
    33  	pb "go.chromium.org/luci/resultdb/proto/v1"
    34  	sinkpb "go.chromium.org/luci/resultdb/sink/proto/v1"
    35  
    36  	. "github.com/smartystreets/goconvey/convey"
    37  )
    38  
    39  func reportTestResults(ctx context.Context, host, authToken string, in *sinkpb.ReportTestResultsRequest) (*sinkpb.ReportTestResultsResponse, error) {
    40  	sinkClient := sinkpb.NewSinkPRPCClient(&prpc.Client{
    41  		Host:    host,
    42  		Options: &prpc.Options{Insecure: true},
    43  	})
    44  	// install the auth token into the context, if present
    45  	if authToken != "" {
    46  		ctx = metadata.AppendToOutgoingContext(ctx, AuthTokenKey, authTokenValue(authToken))
    47  	}
    48  	return sinkClient.ReportTestResults(ctx, in)
    49  }
    50  
    51  func testServerConfig(addr, tk string) ServerConfig {
    52  	return ServerConfig{
    53  		Address:                  addr,
    54  		AuthToken:                tk,
    55  		ArtifactStreamClient:     &http.Client{},
    56  		ArtifactStreamHost:       "example.org",
    57  		Recorder:                 &mockRecorder{},
    58  		Invocation:               "invocations/u-foo-1587421194_893166206",
    59  		invocationID:             "u-foo-1587421194_893166206",
    60  		UpdateToken:              "UpdateToken-ABC",
    61  		MaxBatchableArtifactSize: 2 * 1024 * 1024,
    62  	}
    63  }
    64  
    65  func testArtifactWithFile(writer func(f *os.File)) *sinkpb.Artifact {
    66  	f, err := ioutil.TempFile("", "test-artifact")
    67  	So(err, ShouldBeNil)
    68  	defer f.Close()
    69  	writer(f)
    70  
    71  	return &sinkpb.Artifact{
    72  		Body:        &sinkpb.Artifact_FilePath{FilePath: f.Name()},
    73  		ContentType: "text/plain",
    74  	}
    75  }
    76  
    77  func testArtifactWithContents(contents []byte) *sinkpb.Artifact {
    78  	return &sinkpb.Artifact{
    79  		Body:        &sinkpb.Artifact_Contents{Contents: contents},
    80  		ContentType: "text/plain",
    81  	}
    82  }
    83  
    84  func testArtifactWithGcs(gcsURI string) *sinkpb.Artifact {
    85  	return &sinkpb.Artifact{
    86  		Body:        &sinkpb.Artifact_GcsUri{GcsUri: gcsURI},
    87  		ContentType: "text/plain",
    88  	}
    89  }
    90  
    91  // validTestResult returns a valid sinkpb.TestResult sample message.
    92  func validTestResult() (*sinkpb.TestResult, func()) {
    93  	now := testclock.TestRecentTimeUTC
    94  	st := timestamppb.New(now.Add(-2 * time.Minute))
    95  	artf := testArtifactWithFile(func(f *os.File) {
    96  		_, err := f.WriteString("a sample artifact")
    97  		So(err, ShouldBeNil)
    98  	})
    99  	cleanup := func() { os.Remove(artf.GetFilePath()) }
   100  
   101  	return &sinkpb.TestResult{
   102  		TestId:      "this is testID",
   103  		ResultId:    "result_id1",
   104  		Expected:    true,
   105  		Status:      pb.TestStatus_PASS,
   106  		SummaryHtml: "HTML summary",
   107  		StartTime:   st,
   108  		Duration:    durationpb.New(time.Minute),
   109  		Tags:        pbutil.StringPairs("k1", "v1"),
   110  		Variant:     pbutil.Variant(),
   111  		Artifacts: map[string]*sinkpb.Artifact{
   112  			"art1": artf,
   113  		},
   114  		TestMetadata: &pb.TestMetadata{
   115  			Name: "name",
   116  			Location: &pb.TestLocation{
   117  				Repo:     "https://chromium.googlesource.com/chromium/src",
   118  				FileName: "//artifact_dir/a_test.cc",
   119  				Line:     54,
   120  			},
   121  			BugComponent: &pb.BugComponent{
   122  				System: &pb.BugComponent_Monorail{
   123  					Monorail: &pb.MonorailComponent{
   124  						Project: "chromium",
   125  						Value:   "Component>Value",
   126  					},
   127  				},
   128  			},
   129  		},
   130  		FailureReason: &pb.FailureReason{
   131  			PrimaryErrorMessage: "This is a failure message.",
   132  			Errors: []*pb.FailureReason_Error{
   133  				{Message: "This is a failure message."},
   134  				{Message: "This is a failure message2."},
   135  			},
   136  			TruncatedErrorsCount: 0,
   137  		},
   138  	}, cleanup
   139  }
   140  
   141  type mockRecorder struct {
   142  	pb.RecorderClient
   143  	batchCreateTestResults      func(ctx context.Context, in *pb.BatchCreateTestResultsRequest) (*pb.BatchCreateTestResultsResponse, error)
   144  	batchCreateArtifacts        func(ctx context.Context, in *pb.BatchCreateArtifactsRequest) (*pb.BatchCreateArtifactsResponse, error)
   145  	batchCreateTestExonerations func(ctx context.Context, in *pb.BatchCreateTestExonerationsRequest) (*pb.BatchCreateTestExonerationsResponse, error)
   146  }
   147  
   148  func (m *mockRecorder) BatchCreateTestResults(ctx context.Context, in *pb.BatchCreateTestResultsRequest, opts ...grpc.CallOption) (*pb.BatchCreateTestResultsResponse, error) {
   149  	if m.batchCreateTestResults != nil {
   150  		return m.batchCreateTestResults(ctx, in)
   151  	}
   152  	return nil, nil
   153  }
   154  
   155  func (m *mockRecorder) BatchCreateArtifacts(ctx context.Context, in *pb.BatchCreateArtifactsRequest, opts ...grpc.CallOption) (*pb.BatchCreateArtifactsResponse, error) {
   156  	if m.batchCreateArtifacts != nil {
   157  		return m.batchCreateArtifacts(ctx, in)
   158  	}
   159  	return nil, nil
   160  }
   161  
   162  func (m *mockRecorder) BatchCreateTestExonerations(ctx context.Context, in *pb.BatchCreateTestExonerationsRequest, opts ...grpc.CallOption) (*pb.BatchCreateTestExonerationsResponse, error) {
   163  	if m.batchCreateTestExonerations != nil {
   164  		return m.batchCreateTestExonerations(ctx, in)
   165  	}
   166  	return nil, nil
   167  }