| OLD | NEW |
| (Empty) |
| 1 // Copyright 2017 The LUCI Authors. All rights reserved. | |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | |
| 3 // that can be found in the LICENSE file. | |
| 4 | |
| 5 package swarming | |
| 6 | |
| 7 import ( | |
| 8 "fmt" | |
| 9 "testing" | |
| 10 | |
| 11 swarming "github.com/luci/luci-go/common/api/swarming/swarming/v1" | |
| 12 miloProto "github.com/luci/luci-go/common/proto/milo" | |
| 13 "github.com/luci/luci-go/grpc/grpcutil" | |
| 14 "github.com/luci/luci-go/logdog/api/endpoints/coordinator/logs/v1" | |
| 15 "github.com/luci/luci-go/logdog/client/coordinator" | |
| 16 milo "github.com/luci/luci-go/milo/api/proto" | |
| 17 | |
| 18 "github.com/luci/gae/impl/memory" | |
| 19 | |
| 20 "golang.org/x/net/context" | |
| 21 | |
| 22 . "github.com/luci/luci-go/common/testing/assertions" | |
| 23 . "github.com/smartystreets/goconvey/convey" | |
| 24 ) | |
| 25 | |
| 26 type testSwarmingService struct { | |
| 27 swarmingService | |
| 28 | |
| 29 host string | |
| 30 req swarming.SwarmingRpcsTaskRequest | |
| 31 res swarming.SwarmingRpcsTaskResult | |
| 32 out string | |
| 33 } | |
| 34 | |
| 35 func (sf *testSwarmingService) getHost() string { return sf.host } | |
| 36 | |
| 37 func (sf *testSwarmingService) getSwarmingResult(c context.Context, taskID strin
g) ( | |
| 38 *swarming.SwarmingRpcsTaskResult, error) { | |
| 39 | |
| 40 return &sf.res, nil | |
| 41 } | |
| 42 | |
| 43 func (sf *testSwarmingService) getSwarmingRequest(c context.Context, taskID stri
ng) ( | |
| 44 *swarming.SwarmingRpcsTaskRequest, error) { | |
| 45 | |
| 46 return &sf.req, nil | |
| 47 } | |
| 48 | |
| 49 func (sf *testSwarmingService) getTaskOutput(c context.Context, taskID string) (
string, error) { | |
| 50 return sf.out, nil | |
| 51 } | |
| 52 | |
| 53 func TestBuildInfo(t *testing.T) { | |
| 54 t.Parallel() | |
| 55 | |
| 56 Convey("A testing BuildInfoProvider", t, func() { | |
| 57 c := context.Background() | |
| 58 c = memory.Use(c) | |
| 59 | |
| 60 testClient := testLogDogClient{} | |
| 61 testSvc := testSwarmingService{ | |
| 62 host: "swarming.example.com", | |
| 63 req: swarming.SwarmingRpcsTaskRequest{ | |
| 64 Properties: &swarming.SwarmingRpcsTaskProperties
{ | |
| 65 Command: []string{"kitchen", "foo", "bar
", "-logdog-project", "testproject", "baz"}, | |
| 66 }, | |
| 67 Tags: []string{ | |
| 68 "allow_milo:1", | |
| 69 }, | |
| 70 }, | |
| 71 res: swarming.SwarmingRpcsTaskResult{ | |
| 72 TaskId: "12340", | |
| 73 State: TaskRunning, | |
| 74 Tags: []string{ | |
| 75 "allow_milo:1", | |
| 76 "foo:1", | |
| 77 "bar:2", | |
| 78 }, | |
| 79 TryNumber: 1, | |
| 80 }, | |
| 81 } | |
| 82 bip := BuildInfoProvider{ | |
| 83 bl: buildLoader{ | |
| 84 logDogClientFunc: func(c context.Context, host s
tring) (*coordinator.Client, error) { | |
| 85 if host == "" { | |
| 86 host = "example.com" | |
| 87 } | |
| 88 return &coordinator.Client{ | |
| 89 C: &testClient, | |
| 90 Host: host, | |
| 91 }, nil | |
| 92 }, | |
| 93 }, | |
| 94 swarmingServiceFunc: func(context.Context, string) (swar
mingService, error) { | |
| 95 return &testSvc, nil | |
| 96 }, | |
| 97 } | |
| 98 | |
| 99 logdogStep := miloProto.Step{ | |
| 100 Command: &miloProto.Step_Command{ | |
| 101 CommandLine: []string{"foo", "bar", "baz"}, | |
| 102 }, | |
| 103 Text: []string{"test step"}, | |
| 104 Property: []*miloProto.Step_Property{ | |
| 105 {Name: "bar", Value: "log-bar"}, | |
| 106 }, | |
| 107 } | |
| 108 | |
| 109 biReq := milo.BuildInfoRequest{ | |
| 110 Build: &milo.BuildInfoRequest_Swarming_{ | |
| 111 Swarming: &milo.BuildInfoRequest_Swarming{ | |
| 112 Task: "12340", | |
| 113 }, | |
| 114 }, | |
| 115 } | |
| 116 | |
| 117 Convey("Will fail to load a non-Kitchen build.", func() { | |
| 118 testSvc.req.Properties.Command = []string{"not", "kitche
n"} | |
| 119 | |
| 120 _, err := bip.GetBuildInfo(c, biReq.GetSwarming(), "") | |
| 121 So(err, ShouldBeRPCNotFound) | |
| 122 }) | |
| 123 | |
| 124 Convey("Can load a build, inferring project from Kitchen CLI.",
func() { | |
| 125 testClient.resp = datagramGetResponse("testproject", "sw
arm/swarming.example.com/12341", &logdogStep) | |
| 126 | |
| 127 resp, err := bip.GetBuildInfo(c, biReq.GetSwarming(), ""
) | |
| 128 So(err, ShouldBeNil) | |
| 129 So(testClient.req, ShouldResemble, &logdog.TailRequest{ | |
| 130 Project: "testproject", | |
| 131 Path: "swarm/swarming.example.com/12341/+/ann
otations", | |
| 132 State: true, | |
| 133 }) | |
| 134 So(resp, ShouldResemble, &milo.BuildInfoResponse{ | |
| 135 Project: "testproject", | |
| 136 Step: &miloProto.Step{ | |
| 137 Command: &miloProto.Step_Command{ | |
| 138 CommandLine: []string{"foo", "ba
r", "baz"}, | |
| 139 }, | |
| 140 Text: []string{"test step"}, | |
| 141 Link: &miloProto.Link{ | |
| 142 Label: "Task 12340", | |
| 143 Value: &miloProto.Link_Url{ | |
| 144 Url: "https://swarming.e
xample.com/task?id=12340&show_raw=1&wide_logs=true", | |
| 145 }, | |
| 146 }, | |
| 147 Property: []*miloProto.Step_Property{ | |
| 148 {Name: "bar", Value: "log-bar"}, | |
| 149 }, | |
| 150 }, | |
| 151 AnnotationStream: &miloProto.LogdogStream{ | |
| 152 Server: "example.com", | |
| 153 Prefix: "swarm/swarming.example.com/1234
1", | |
| 154 Name: "annotations", | |
| 155 }, | |
| 156 }) | |
| 157 }) | |
| 158 | |
| 159 Convey("Will fail to load Kitchen without LogDog and no project
hint.", func() { | |
| 160 testSvc.req.Properties.Command = []string{"kitchen"} | |
| 161 | |
| 162 _, err := bip.GetBuildInfo(c, biReq.GetSwarming(), "") | |
| 163 So(err, ShouldBeRPCNotFound) | |
| 164 }) | |
| 165 | |
| 166 Convey("Will load Kitchen without LogDog if there is a project h
int.", func() { | |
| 167 biReq.ProjectHint = "testproject" | |
| 168 testSvc.req.Properties.Command = []string{"kitchen"} | |
| 169 testClient.resp = datagramGetResponse("testproject", "sw
arm/swarming.example.com/12341", &logdogStep) | |
| 170 | |
| 171 resp, err := bip.GetBuildInfo(c, biReq.GetSwarming(), "t
estproject") | |
| 172 So(err, ShouldBeNil) | |
| 173 So(testClient.req, ShouldResemble, &logdog.TailRequest{ | |
| 174 Project: "testproject", | |
| 175 Path: "swarm/swarming.example.com/12341/+/ann
otations", | |
| 176 State: true, | |
| 177 }) | |
| 178 So(resp, ShouldResemble, &milo.BuildInfoResponse{ | |
| 179 Project: "testproject", | |
| 180 Step: &miloProto.Step{ | |
| 181 Command: &miloProto.Step_Command{ | |
| 182 CommandLine: []string{"foo", "ba
r", "baz"}, | |
| 183 }, | |
| 184 Text: []string{"test step"}, | |
| 185 Link: &miloProto.Link{ | |
| 186 Label: "Task 12340", | |
| 187 Value: &miloProto.Link_Url{ | |
| 188 Url: "https://swarming.e
xample.com/task?id=12340&show_raw=1&wide_logs=true", | |
| 189 }, | |
| 190 }, | |
| 191 Property: []*miloProto.Step_Property{ | |
| 192 {Name: "bar", Value: "log-bar"}, | |
| 193 }, | |
| 194 }, | |
| 195 AnnotationStream: &miloProto.LogdogStream{ | |
| 196 Server: "example.com", | |
| 197 Prefix: "swarm/swarming.example.com/1234
1", | |
| 198 Name: "annotations", | |
| 199 }, | |
| 200 }) | |
| 201 | |
| 202 Convey("Will return NotFound if the build is internal",
func() { | |
| 203 testSvc.res.Tags = testSvc.res.Tags[1:] | |
| 204 testSvc.req.Tags = testSvc.req.Tags[1:] | |
| 205 _, err := bip.GetBuildInfo(c, biReq.GetSwarming(
), "testproject") | |
| 206 So(err, ShouldResemble, grpcutil.NotFound) | |
| 207 }) | |
| 208 }) | |
| 209 }) | |
| 210 } | |
| 211 | |
| 212 func TestGetRunID(t *testing.T) { | |
| 213 t.Parallel() | |
| 214 | |
| 215 successes := []struct { | |
| 216 taskID string | |
| 217 tryNumber int64 | |
| 218 runID string | |
| 219 }{ | |
| 220 {"3442825749e6e110", 1, "3442825749e6e111"}, | |
| 221 } | |
| 222 | |
| 223 failures := []struct { | |
| 224 taskID string | |
| 225 tryNumber int64 | |
| 226 err string | |
| 227 }{ | |
| 228 {"", 1, "swarming task ID is empty"}, | |
| 229 {"3442825749e6e110", 16, "exceeds 4 bits"}, | |
| 230 {"3442825749e6e11M", 1, "failed to parse hex from rune"}, | |
| 231 } | |
| 232 | |
| 233 Convey("Testing BuildInfo's getRunID", t, func() { | |
| 234 for _, tc := range successes { | |
| 235 Convey(fmt.Sprintf("Successfully processes %q / %q => %q
", tc.taskID, tc.tryNumber, tc.runID), func() { | |
| 236 v, err := getRunID(tc.taskID, tc.tryNumber) | |
| 237 So(err, ShouldBeNil) | |
| 238 So(v, ShouldEqual, tc.runID) | |
| 239 }) | |
| 240 } | |
| 241 | |
| 242 for _, tc := range failures { | |
| 243 Convey(fmt.Sprintf("Failes to parse %q / %q (%s)", tc.ta
skID, tc.tryNumber, tc.err), func() { | |
| 244 _, err := getRunID(tc.taskID, tc.tryNumber) | |
| 245 So(err, ShouldErrLike, tc.err) | |
| 246 }) | |
| 247 } | |
| 248 }) | |
| 249 } | |
| OLD | NEW |