go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/swarming/server/rpcs/tasks_get_request_test.go (about)

     1  // Copyright 2023 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 rpcs
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	"google.golang.org/protobuf/types/known/timestamppb"
    23  
    24  	"go.chromium.org/luci/gae/impl/memory"
    25  	"go.chromium.org/luci/gae/service/datastore"
    26  
    27  	apipb "go.chromium.org/luci/swarming/proto/api_v2"
    28  	configpb "go.chromium.org/luci/swarming/proto/config"
    29  	"go.chromium.org/luci/swarming/server/model"
    30  
    31  	. "github.com/smartystreets/goconvey/convey"
    32  	. "go.chromium.org/luci/common/testing/assertions"
    33  )
    34  
    35  func TestTaskRequestToResponse(t *testing.T) {
    36  	t.Parallel()
    37  
    38  	Convey("TestTaskRequestToResponse", t, func() {
    39  		ctx := memory.Use(context.Background())
    40  		testTime := time.Date(2023, time.January, 1, 2, 3, 4, 0, time.UTC)
    41  
    42  		key, err := model.TaskIDToRequestKey(ctx, "65aba3a3e6b99310")
    43  		So(err, ShouldBeNil)
    44  
    45  		tr := &model.TaskRequest{
    46  			Key:     key,
    47  			TxnUUID: "txn-uuid",
    48  			TaskSlices: []model.TaskSlice{
    49  				model.TaskSlice{
    50  					Properties: model.TaskProperties{
    51  						Idempotent: true,
    52  						Dimensions: model.TaskDimensions{
    53  							"d1": {"v1", "v2"},
    54  							"d2": {"v1"},
    55  						},
    56  						ExecutionTimeoutSecs: 123,
    57  						GracePeriodSecs:      456,
    58  						IOTimeoutSecs:        789,
    59  						Command:              []string{"run"},
    60  						RelativeCwd:          "./rel/cwd",
    61  						Env: model.Env{
    62  							"k1": "v1",
    63  							"k2": "val",
    64  						},
    65  						EnvPrefixes: model.EnvPrefixes{
    66  							"p1": {"v1", "v2"},
    67  							"p2": {"val"},
    68  						},
    69  						Caches: []model.CacheEntry{
    70  							{Name: "n1", Path: "p1"},
    71  							{Name: "n2", Path: "p2"},
    72  						},
    73  						CASInputRoot: model.CASReference{
    74  							CASInstance: "cas-inst",
    75  							Digest: model.CASDigest{
    76  								Hash:      "cas-hash",
    77  								SizeBytes: 1234,
    78  							},
    79  						},
    80  						CIPDInput: model.CIPDInput{
    81  							Server: "server",
    82  							ClientPackage: model.CIPDPackage{
    83  								PackageName: "client-package",
    84  								Version:     "client-version",
    85  							},
    86  							Packages: []model.CIPDPackage{
    87  								{
    88  									PackageName: "pkg1",
    89  									Version:     "ver1",
    90  									Path:        "path1",
    91  								},
    92  								{
    93  									PackageName: "pkg2",
    94  									Version:     "ver2",
    95  									Path:        "path2",
    96  								},
    97  							},
    98  						},
    99  						Outputs:        []string{"o1", "o2"},
   100  						HasSecretBytes: true,
   101  						Containment: model.Containment{
   102  							LowerPriority:             true,
   103  							ContainmentType:           123,
   104  							LimitProcesses:            456,
   105  							LimitTotalCommittedMemory: 789,
   106  						},
   107  					},
   108  					ExpirationSecs:  int64(testTime.Add(10 * time.Minute).Sub(testTime).Seconds()),
   109  					WaitForCapacity: true,
   110  				},
   111  			},
   112  			Created:              testTime,
   113  			Expiration:           testTime.Add(20 * time.Minute),
   114  			Name:                 "name",
   115  			ParentTaskID:         datastore.NewIndexedNullable("parent-task-id"),
   116  			Authenticated:        "user:authenticated",
   117  			User:                 "user",
   118  			Tags:                 []string{"tag1", "tag2"},
   119  			ManualTags:           []string{"tag1"},
   120  			ServiceAccount:       "service-account",
   121  			Realm:                "realm",
   122  			RealmsEnabled:        true,
   123  			SchedulingAlgorithm:  configpb.Pool_SCHEDULING_ALGORITHM_FIFO,
   124  			Priority:             123,
   125  			BotPingToleranceSecs: 456,
   126  			RBEInstance:          "rbe-instance",
   127  			PubSubTopic:          "pubsub-topic",
   128  			PubSubAuthToken:      "pubsub-auth-token",
   129  			PubSubUserData:       "pubsub-user-data",
   130  			ResultDBUpdateToken:  "resultdb-update-token",
   131  			ResultDB:             model.ResultDBConfig{Enable: true},
   132  			HasBuildTask:         true,
   133  		}
   134  		apiReq := &apipb.TaskIdRequest{
   135  			TaskId: "65aba3a3e6b99310",
   136  		}
   137  		Convey("ok", func() {
   138  			So(datastore.Put(ctx, tr), ShouldBeNil)
   139  			resp, err := taskRequestToResponse(ctx, apiReq, tr)
   140  			So(err, ShouldBeNil)
   141  			expectedProperties := &apipb.TaskProperties{
   142  				Caches: []*apipb.CacheEntry{
   143  					{Name: "n1", Path: "p1"},
   144  					{Name: "n2", Path: "p2"},
   145  				},
   146  				CasInputRoot: &apipb.CASReference{
   147  					CasInstance: "cas-inst",
   148  					Digest: &apipb.Digest{
   149  						Hash:      "cas-hash",
   150  						SizeBytes: 1234,
   151  					},
   152  				},
   153  				CipdInput: &apipb.CipdInput{
   154  					Server: "server",
   155  					ClientPackage: &apipb.CipdPackage{
   156  						PackageName: "client-package",
   157  						Version:     "client-version",
   158  					},
   159  					Packages: []*apipb.CipdPackage{
   160  						{
   161  							PackageName: "pkg1",
   162  							Version:     "ver1",
   163  							Path:        "path1",
   164  						},
   165  						{
   166  							PackageName: "pkg2",
   167  							Version:     "ver2",
   168  							Path:        "path2",
   169  						},
   170  					},
   171  				},
   172  				Command:     []string{"run"},
   173  				Containment: &apipb.Containment{ContainmentType: 123},
   174  				Dimensions: []*apipb.StringPair{
   175  					{Key: "d1", Value: "v1"},
   176  					{Key: "d1", Value: "v2"},
   177  					{Key: "d2", Value: "v1"},
   178  				},
   179  				Env: []*apipb.StringPair{
   180  					{Key: "k1", Value: "v1"},
   181  					{Key: "k2", Value: "val"},
   182  				},
   183  				EnvPrefixes: []*apipb.StringListPair{
   184  					{Key: "p1", Value: []string{"v1", "v2"}},
   185  					{Key: "p2", Value: []string{"val"}},
   186  				},
   187  				ExecutionTimeoutSecs: 123,
   188  				GracePeriodSecs:      456,
   189  				Idempotent:           true,
   190  				IoTimeoutSecs:        789,
   191  				Outputs:              []string{"o1", "o2"},
   192  				RelativeCwd:          "./rel/cwd",
   193  				SecretBytes:          []byte("<REDACTED>"),
   194  			}
   195  			So(resp, ShouldResembleProto, &apipb.TaskRequestResponse{
   196  				Authenticated:        "user:authenticated",
   197  				BotPingToleranceSecs: 456,
   198  				CreatedTs:            timestamppb.New(time.Date(2023, time.January, 1, 2, 3, 4, 0, time.UTC)),
   199  				ExpirationSecs:       4,
   200  				Name:                 "name",
   201  				ParentTaskId:         "parent-task-id",
   202  				Priority:             123,
   203  				Properties:           expectedProperties,
   204  				PubsubTopic:          "pubsub-topic",
   205  				PubsubUserdata:       "pubsub-user-data",
   206  				RbeInstance:          "rbe-instance",
   207  				Realm:                "realm",
   208  				Resultdb:             &apipb.ResultDBCfg{Enable: true},
   209  				ServiceAccount:       "service-account",
   210  				Tags:                 []string{"tag1", "tag2"},
   211  				TaskId:               "65aba3a3e6b99310",
   212  				TaskSlices: []*apipb.TaskSlice{
   213  					{
   214  						ExpirationSecs:  600,
   215  						Properties:      expectedProperties,
   216  						WaitForCapacity: true,
   217  					},
   218  				},
   219  				User: "user",
   220  			})
   221  		})
   222  	})
   223  }