go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/run/pubsub/publisher_test.go (about)

     1  // Copyright 2021 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 pubsub
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	"google.golang.org/protobuf/encoding/protojson"
    23  
    24  	"go.chromium.org/luci/gae/service/datastore"
    25  
    26  	cvpb "go.chromium.org/luci/cv/api/v1"
    27  	"go.chromium.org/luci/cv/internal/common"
    28  	"go.chromium.org/luci/cv/internal/cvtesting"
    29  	"go.chromium.org/luci/cv/internal/run"
    30  
    31  	. "github.com/smartystreets/goconvey/convey"
    32  	. "go.chromium.org/luci/common/testing/assertions"
    33  )
    34  
    35  func TestExportRunToBQ(t *testing.T) {
    36  	t.Parallel()
    37  
    38  	Convey("Publisher", t, func() {
    39  		ct := cvtesting.Test{}
    40  		ctx, cancel := ct.SetUp(t)
    41  		defer cancel()
    42  
    43  		publisher := NewPublisher(ct.TQDispatcher, ct.Env)
    44  		epoch := ct.Clock.Now().UTC()
    45  		r := run.Run{
    46  			ID:            common.MakeRunID("lproject", epoch, 1, []byte("aaa")),
    47  			Status:        run.Status_SUCCEEDED,
    48  			ConfigGroupID: "sha256:deadbeefdeadbeef/cgroup",
    49  			CreateTime:    epoch,
    50  			StartTime:     epoch.Add(time.Minute * 2),
    51  			EndTime:       epoch.Add(time.Minute * 25),
    52  			CLs:           common.CLIDs{1},
    53  			Submission:    nil,
    54  			Mode:          run.DryRun,
    55  			EVersion:      123456,
    56  		}
    57  
    58  		Convey("RunEnded enqueues a task", func() {
    59  			// A RunEnded task must be scheduled in a transaction.
    60  			runEnded := func() error {
    61  				return datastore.RunInTransaction(ctx, func(tCtx context.Context) error {
    62  					return publisher.RunEnded(tCtx, r.ID, r.Status, r.EVersion)
    63  				}, nil)
    64  			}
    65  			So(runEnded(), ShouldBeNil)
    66  			t := ct.TQ.Tasks()[0]
    67  
    68  			Convey("with attributes", func() {
    69  				attrs := t.Message.GetAttributes()
    70  				So(attrs, ShouldContainKey, "luci_project")
    71  				So(attrs["luci_project"], ShouldEqual, r.ID.LUCIProject())
    72  				So(attrs, ShouldContainKey, "status")
    73  				So(attrs["status"], ShouldEqual, r.Status.String())
    74  			})
    75  
    76  			Convey("with JSONPB encoded message", func() {
    77  				var msg cvpb.PubSubRun
    78  				So(protojson.Unmarshal(t.Message.GetData(), &msg), ShouldBeNil)
    79  				So(&msg, ShouldResembleProto, &cvpb.PubSubRun{
    80  					Id:       r.ID.PublicID(),
    81  					Status:   cvpb.Run_SUCCEEDED,
    82  					Eversion: int64(r.EVersion),
    83  					Hostname: ct.Env.LogicalHostname,
    84  				})
    85  			})
    86  		})
    87  	})
    88  }