TensorFlow Serving C++ API Documentation
resource_util_test.cc
1 /* Copyright 2016 Google Inc. All Rights Reserved.
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 
16 #include "tensorflow_serving/resources/resource_util.h"
17 
18 #include <vector>
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include "tensorflow/core/lib/core/status_test_util.h"
23 #include "tensorflow/core/platform/types.h"
24 #include "tensorflow_serving/test_util/test_util.h"
25 
26 using ::tensorflow::serving::test_util::CreateProto;
27 using ::tensorflow::serving::test_util::EqualsProto;
28 
29 namespace tensorflow {
30 namespace serving {
31 namespace {
32 
33 class ResourceUtilTest : public ::testing::Test {
34  protected:
35  ResourceUtilTest() : util_({{{"main", 1}, {"gpu", 2}}}) {}
36 
37  // The object under testing.
38  ResourceUtil util_;
39 };
40 
41 TEST_F(ResourceUtilTest, VerifyValidity) {
42  // Empty.
43  TF_EXPECT_OK(util_.VerifyValidity(CreateProto<ResourceAllocation>("")));
44 
45  // Unbound.
46  TF_EXPECT_OK(util_.VerifyValidity(
47  CreateProto<ResourceAllocation>("resource_quantities { "
48  " resource { "
49  " device: 'main' "
50  " kind: 'processing' "
51  " } "
52  " quantity: 100 "
53  "} ")));
54  TF_EXPECT_OK(util_.VerifyValidity(
55  CreateProto<ResourceAllocation>("resource_quantities { "
56  " resource { "
57  " device: 'main' "
58  " kind: 'processing' "
59  " } "
60  " quantity: 100 "
61  "} "
62  "resource_quantities { "
63  " resource { "
64  " device: 'gpu' "
65  " kind: 'ram' "
66  " } "
67  " quantity: 4 "
68  "} ")));
69 
70  // Bound to a valid instance.
71  TF_EXPECT_OK(util_.VerifyValidity(
72  CreateProto<ResourceAllocation>("resource_quantities { "
73  " resource { "
74  " device: 'gpu' "
75  " device_instance { value: 0 } "
76  " kind: 'ram' "
77  " } "
78  " quantity: 4 "
79  "} ")));
80  TF_EXPECT_OK(util_.VerifyValidity(
81  CreateProto<ResourceAllocation>("resource_quantities { "
82  " resource { "
83  " device: 'gpu' "
84  " device_instance { value: 1 } "
85  " kind: 'ram' "
86  " } "
87  " quantity: 4 "
88  "} ")));
89 
90  // Non-existent device.
91  EXPECT_FALSE(util_
92  .VerifyValidity(CreateProto<ResourceAllocation>(
93  "resource_quantities { "
94  " resource { "
95  " device: 'nonexistent_device' "
96  " kind: 'processing' "
97  " } "
98  " quantity: 100 "
99  "} "))
100  .ok());
101  EXPECT_FALSE(util_
102  .VerifyValidity(CreateProto<ResourceAllocation>(
103  "resource_quantities { "
104  " resource { "
105  " device: 'main' "
106  " kind: 'processing' "
107  " } "
108  " quantity: 100 "
109  "} "
110  "resource_quantities { "
111  " resource { "
112  " device: 'nonexistent_device' "
113  " kind: 'ram' "
114  " } "
115  " quantity: 4 "
116  "} "))
117  .ok());
118 
119  // Bound to an invalid instance.
120  EXPECT_FALSE(util_
121  .VerifyValidity(CreateProto<ResourceAllocation>(
122  "resource_quantities { "
123  " resource { "
124  " device: 'gpu' "
125  " device_instance { value: 2 } "
126  " kind: 'ram' "
127  " } "
128  " quantity: 4 "
129  "} "))
130  .ok());
131 
132  // Repeated entries for the same resource.
133  EXPECT_FALSE(util_
134  .VerifyValidity(
135  CreateProto<ResourceAllocation>("resource_quantities { "
136  " resource { "
137  " device: 'gpu' "
138  " kind: 'ram' "
139  " } "
140  " quantity: 2 "
141  "} "
142  "resource_quantities { "
143  " resource { "
144  " device: 'gpu' "
145  " kind: 'ram' "
146  " } "
147  " quantity: 4 "
148  "} "))
149  .ok());
150  EXPECT_FALSE(util_
151  .VerifyValidity(CreateProto<ResourceAllocation>(
152  "resource_quantities { "
153  " resource { "
154  " device: 'gpu' "
155  " device_instance { value: 0 } "
156  " kind: 'ram' "
157  " } "
158  " quantity: 2 "
159  "} "
160  "resource_quantities { "
161  " resource { "
162  " device: 'gpu' "
163  " device_instance { value: 0 } "
164  " kind: 'ram' "
165  " } "
166  " quantity: 4 "
167  "} "))
168  .ok());
169 }
170 
171 TEST_F(ResourceUtilTest, VerifyResourceValidity) {
172  // Unbound.
173  TF_EXPECT_OK(util_.VerifyResourceValidity(
174  CreateProto<Resource>("device: 'main' "
175  "kind: 'processing' ")));
176 
177  // Bound to a valid instance.
178  TF_EXPECT_OK(util_.VerifyResourceValidity(
179  CreateProto<Resource>("device: 'gpu' "
180  "device_instance { value: 0 } "
181  "kind: 'ram' ")));
182  TF_EXPECT_OK(util_.VerifyResourceValidity(
183  CreateProto<Resource>("device: 'gpu' "
184  "device_instance { value: 1 } "
185  "kind: 'ram' ")));
186 
187  // Non-existent device.
188  EXPECT_FALSE(util_
189  .VerifyResourceValidity(
190  CreateProto<Resource>("device: 'nonexistent_device' "
191  "kind: 'processing' "))
192  .ok());
193 
194  // Bound to an invalid instance.
195  EXPECT_FALSE(util_
196  .VerifyResourceValidity(
197  CreateProto<Resource>("device: 'gpu' "
198  "device_instance { value: 2 } "
199  "kind: 'ram' "))
200  .ok());
201 }
202 
203 TEST_F(ResourceUtilTest, Normalize) {
204  EXPECT_THAT(util_.Normalize(CreateProto<ResourceAllocation>("")),
205  EqualsProto(""));
206  EXPECT_THAT(
207  util_.Normalize(CreateProto<ResourceAllocation>("resource_quantities { "
208  " resource { "
209  " device: 'gpu' "
210  " kind: 'processing' "
211  " } "
212  " quantity: 100 "
213  "} "
214  "resource_quantities { "
215  " resource { "
216  " device: 'gpu' "
217  " kind: 'ram' "
218  " } "
219  " quantity: 0 "
220  "} ")),
221  EqualsProto("resource_quantities { "
222  " resource { "
223  " device: 'gpu' "
224  " kind: 'processing' "
225  " } "
226  " quantity: 100 "
227  "} "));
228  EXPECT_THAT(
229  util_.Normalize(CreateProto<ResourceAllocation>("resource_quantities { "
230  " resource { "
231  " device: 'main' "
232  " kind: 'ram' "
233  " } "
234  " quantity: 2 "
235  "} ")),
236  EqualsProto("resource_quantities { "
237  " resource { "
238  " device: 'main' "
239  " device_instance { value: 0 } "
240  " kind: 'ram' "
241  " } "
242  " quantity: 2 "
243  "} "));
244  // No-op.
245  EXPECT_THAT(util_.Normalize(CreateProto<ResourceAllocation>(
246  "resource_quantities { "
247  " resource { "
248  " device: 'main' "
249  " device_instance { value: 0 } "
250  " kind: 'ram' "
251  " } "
252  " quantity: 2 "
253  "} ")),
254  EqualsProto("resource_quantities { "
255  " resource { "
256  " device: 'main' "
257  " device_instance { value: 0 } "
258  " kind: 'ram' "
259  " } "
260  " quantity: 2 "
261  "} "));
262 }
263 
264 TEST_F(ResourceUtilTest, IsNormalized) {
265  EXPECT_TRUE(util_.IsNormalized(CreateProto<ResourceAllocation>("")));
266  EXPECT_TRUE(util_.IsNormalized(
267  CreateProto<ResourceAllocation>("resource_quantities { "
268  " resource { "
269  " device: 'gpu' "
270  " kind: 'processing' "
271  " } "
272  " quantity: 100 "
273  "} ")));
274  EXPECT_TRUE(util_.IsNormalized(
275  CreateProto<ResourceAllocation>("resource_quantities { "
276  " resource { "
277  " device: 'gpu' "
278  " device_instance { value: 0 } "
279  " kind: 'processing' "
280  " } "
281  " quantity: 100 "
282  "} ")));
283  EXPECT_TRUE(util_.IsNormalized(
284  CreateProto<ResourceAllocation>("resource_quantities { "
285  " resource { "
286  " device: 'main' "
287  " device_instance { value: 0 } "
288  " kind: 'processing' "
289  " } "
290  " quantity: 100 "
291  "} ")));
292 
293  EXPECT_FALSE(util_.IsNormalized(
294  CreateProto<ResourceAllocation>("resource_quantities { "
295  " resource { "
296  " device: 'gpu' "
297  " device_instance { value: 0 } "
298  " kind: 'processing' "
299  " } "
300  " quantity: 100 "
301  "} "
302  "resource_quantities { "
303  " resource { "
304  " device: 'main' "
305  " device_instance { value: 0 } "
306  " kind: 'processing' "
307  " } "
308  " quantity: 0 "
309  "} ")));
310  EXPECT_FALSE(util_.IsNormalized(
311  CreateProto<ResourceAllocation>("resource_quantities { "
312  " resource { "
313  " device: 'main' "
314  " kind: 'processing' "
315  " } "
316  " quantity: 100 "
317  "} ")));
318 }
319 
320 TEST_F(ResourceUtilTest, IsBound) {
321  EXPECT_TRUE(util_.IsBound(CreateProto<ResourceAllocation>("")));
322  EXPECT_TRUE(util_.IsBound(
323  CreateProto<ResourceAllocation>("resource_quantities { "
324  " resource { "
325  " device: 'gpu' "
326  " device_instance { value: 0 } "
327  " kind: 'processing' "
328  " } "
329  " quantity: 100 "
330  "} ")));
331  EXPECT_TRUE(util_.IsBound(
332  CreateProto<ResourceAllocation>("resource_quantities { "
333  " resource { "
334  " device: 'main' "
335  " device_instance { value: 0 } "
336  " kind: 'ram' "
337  " } "
338  " quantity: 4 "
339  "} "
340  "resource_quantities { "
341  " resource { "
342  " device: 'gpu' "
343  " device_instance { value: 1 } "
344  " kind: 'processing' "
345  " } "
346  " quantity: 100 "
347  "} ")));
348 
349  EXPECT_FALSE(
350  util_.IsBound(CreateProto<ResourceAllocation>("resource_quantities { "
351  " resource { "
352  " device: 'gpu' "
353  " kind: 'processing' "
354  " } "
355  " quantity: 100 "
356  "} ")));
357  EXPECT_FALSE(util_.IsBound(
358  CreateProto<ResourceAllocation>("resource_quantities { "
359  " resource { "
360  " device: 'main' "
361  " device_instance { value: 0 } "
362  " kind: 'ram' "
363  " } "
364  " quantity: 100 "
365  "} "
366  "resource_quantities { "
367  " resource { "
368  " device: 'gpu' "
369  " kind: 'processing' "
370  " } "
371  " quantity: 100 "
372  "} ")));
373 }
374 
375 TEST_F(ResourceUtilTest, CreateBoundResource) {
376  EXPECT_THAT(util_.CreateBoundResource("gpu", "ram", 2),
377  EqualsProto("device: 'gpu' "
378  "device_instance { value: 2 } "
379  "kind: 'ram' "));
380  EXPECT_THAT(
381  util_.CreateBoundResource("gpu", "ram" /* , implicit instance = 0 */),
382  EqualsProto("device: 'gpu' "
383  "device_instance { value: 0 } "
384  "kind: 'ram' "));
385 }
386 
387 TEST_F(ResourceUtilTest, GetQuantity) {
388  const auto allocation = CreateProto<ResourceAllocation>(
389  "resource_quantities { "
390  " resource { "
391  " device: 'main' "
392  " device_instance { value: 0 } "
393  " kind: 'ram' "
394  " } "
395  " quantity: 32 "
396  "} "
397  "resource_quantities { "
398  " resource { "
399  " device: 'gpu' "
400  " device_instance { value: 1 } "
401  " kind: 'processing' "
402  " } "
403  " quantity: 100 "
404  "} ");
405  EXPECT_EQ(32, util_.GetQuantity(CreateProto<Resource>("device: 'main' "
406  "kind: 'ram' "),
407  allocation));
408  EXPECT_EQ(32, util_.GetQuantity(
409  CreateProto<Resource>("device: 'main' "
410  "device_instance { value: 0 } "
411  "kind: 'ram' "),
412  allocation));
413  EXPECT_EQ(100, util_.GetQuantity(
414  CreateProto<Resource>("device: 'gpu' "
415  "device_instance { value: 1 } "
416  "kind: 'processing' "),
417  allocation));
418  EXPECT_EQ(
419  0, util_.GetQuantity(CreateProto<Resource>("device: 'gpu' "
420  "device_instance { value: 1 } "
421  "kind: 'ram' "),
422  allocation));
423 }
424 
425 TEST_F(ResourceUtilTest, SetQuantity) {
426  const auto initial_allocation = CreateProto<ResourceAllocation>(
427  "resource_quantities { "
428  " resource { "
429  " device: 'main' "
430  " kind: 'ram' "
431  " } "
432  " quantity: 32 "
433  "} "
434  "resource_quantities { "
435  " resource { "
436  " device: 'gpu' "
437  " device_instance { value: 1 } "
438  " kind: 'processing' "
439  " } "
440  " quantity: 100 "
441  "} ");
442 
443  {
444  ResourceAllocation allocation = initial_allocation;
445  util_.SetQuantity(CreateProto<Resource>("device: 'main' "
446  "device_instance { value: 0 } "
447  "kind: 'ram' "),
448  64, &allocation);
449  EXPECT_THAT(allocation, EqualsProto("resource_quantities { "
450  " resource { "
451  " device: 'main' "
452  " kind: 'ram' "
453  " } "
454  " quantity: 64 "
455  "} "
456  "resource_quantities { "
457  " resource { "
458  " device: 'gpu' "
459  " device_instance { value: 1 } "
460  " kind: 'processing' "
461  " } "
462  " quantity: 100 "
463  "} "));
464  }
465 
466  {
467  ResourceAllocation allocation = initial_allocation;
468  util_.SetQuantity(CreateProto<Resource>("device: 'main' "
469  "kind: 'ram' "),
470  64, &allocation);
471  EXPECT_THAT(allocation, EqualsProto("resource_quantities { "
472  " resource { "
473  " device: 'main' "
474  " kind: 'ram' "
475  " } "
476  " quantity: 64 "
477  "} "
478  "resource_quantities { "
479  " resource { "
480  " device: 'gpu' "
481  " device_instance { value: 1 } "
482  " kind: 'processing' "
483  " } "
484  " quantity: 100 "
485  "} "));
486  }
487 
488  {
489  ResourceAllocation allocation = initial_allocation;
490  util_.SetQuantity(CreateProto<Resource>("device: 'gpu' "
491  "device_instance { value: 1 } "
492  "kind: 'processing' "),
493  200, &allocation);
494  EXPECT_THAT(allocation, EqualsProto("resource_quantities { "
495  " resource { "
496  " device: 'main' "
497  " kind: 'ram' "
498  " } "
499  " quantity: 32 "
500  "} "
501  "resource_quantities { "
502  " resource { "
503  " device: 'gpu' "
504  " device_instance { value: 1 } "
505  " kind: 'processing' "
506  " } "
507  " quantity: 200 "
508  "} "));
509  }
510 
511  {
512  ResourceAllocation allocation = initial_allocation;
513  util_.SetQuantity(CreateProto<Resource>("device: 'gpu' "
514  "device_instance { value: 1 } "
515  "kind: 'ram' "),
516  128, &allocation);
517  EXPECT_THAT(allocation, EqualsProto("resource_quantities { "
518  " resource { "
519  " device: 'main' "
520  " kind: 'ram' "
521  " } "
522  " quantity: 32 "
523  "} "
524  "resource_quantities { "
525  " resource { "
526  " device: 'gpu' "
527  " device_instance { value: 1 } "
528  " kind: 'processing' "
529  " } "
530  " quantity: 100 "
531  "} "
532  "resource_quantities { "
533  " resource { "
534  " device: 'gpu' "
535  " device_instance { value: 1 } "
536  " kind: 'ram' "
537  " } "
538  " quantity: 128 "
539  "} "));
540  }
541 }
542 
543 TEST_F(ResourceUtilTest, AddEmpty) {
544  auto base = CreateProto<ResourceAllocation>("");
545  const auto to_add = CreateProto<ResourceAllocation>("");
546  util_.Add(to_add, &base);
547  EXPECT_THAT(base, EqualsProto(""));
548 }
549 
550 TEST_F(ResourceUtilTest, AddBasic) {
551  auto base = CreateProto<ResourceAllocation>(
552  "resource_quantities { "
553  " resource { "
554  " device: 'main' "
555  " device_instance { value: 0 } "
556  " kind: 'processing' "
557  " } "
558  " quantity: 100 "
559  "} "
560  "resource_quantities { "
561  " resource { "
562  " device: 'main' "
563  " device_instance { value: 0 } "
564  " kind: 'ram' "
565  " } "
566  " quantity: 8 "
567  "} ");
568  const auto to_add = CreateProto<ResourceAllocation>(
569  "resource_quantities { "
570  " resource { "
571  " device: 'main' "
572  " device_instance { value: 0 } "
573  " kind: 'processing' "
574  " } "
575  " quantity: 300 "
576  "} "
577  "resource_quantities { "
578  " resource { "
579  " device: 'gpu' "
580  " kind: 'ram' "
581  " } "
582  " quantity: 4 "
583  "} ");
584  util_.Add(to_add, &base);
585  EXPECT_THAT(base, EqualsProto("resource_quantities { "
586  " resource { "
587  " device: 'main' "
588  " device_instance { value: 0 } "
589  " kind: 'processing' "
590  " } "
591  " quantity: 400 "
592  "} "
593  "resource_quantities { "
594  " resource { "
595  " device: 'main' "
596  " device_instance { value: 0 } "
597  " kind: 'ram' "
598  " } "
599  " quantity: 8 "
600  "} "
601  "resource_quantities { "
602  " resource { "
603  " device: 'gpu' "
604  " kind: 'ram' "
605  " } "
606  " quantity: 4 "
607  "} "));
608 }
609 
610 TEST_F(ResourceUtilTest, AddBoundAndUnbound) {
611  auto base = CreateProto<ResourceAllocation>(
612  "resource_quantities { "
613  " resource { "
614  " device: 'gpu' "
615  " kind: 'ram' "
616  " } "
617  " quantity: 8 "
618  "} "
619  "resource_quantities { "
620  " resource { "
621  " device: 'gpu' "
622  " device_instance { value: 0 } "
623  " kind: 'ram' "
624  " } "
625  " quantity: 4 "
626  "} ");
627  const auto to_add = CreateProto<ResourceAllocation>(
628  "resource_quantities { "
629  " resource { "
630  " device: 'gpu' "
631  " kind: 'ram' "
632  " } "
633  " quantity: 16 "
634  "} "
635  "resource_quantities { "
636  " resource { "
637  " device: 'gpu' "
638  " device_instance { value: 0 } "
639  " kind: 'ram' "
640  " } "
641  " quantity: 2 "
642  "} "
643  "resource_quantities { "
644  " resource { "
645  " device: 'gpu' "
646  " device_instance { value: 1 } "
647  " kind: 'ram' "
648  " } "
649  " quantity: 12 "
650  "} ");
651  util_.Add(to_add, &base);
652  EXPECT_THAT(base, EqualsProto("resource_quantities { "
653  " resource { "
654  " device: 'gpu' "
655  " kind: 'ram' "
656  " } "
657  " quantity: 24 "
658  "} "
659  "resource_quantities { "
660  " resource { "
661  " device: 'gpu' "
662  " device_instance { value: 0 } "
663  " kind: 'ram' "
664  " } "
665  " quantity: 6 "
666  "} "
667  "resource_quantities { "
668  " resource { "
669  " device: 'gpu' "
670  " device_instance { value: 1 } "
671  " kind: 'ram' "
672  " } "
673  " quantity: 12 "
674  "} "));
675 }
676 
677 TEST_F(ResourceUtilTest, SubtractEmpty) {
678  auto base = CreateProto<ResourceAllocation>("");
679  const auto to_subtract = CreateProto<ResourceAllocation>("");
680  EXPECT_TRUE(util_.Subtract(to_subtract, &base));
681  EXPECT_THAT(base, EqualsProto(""));
682 }
683 
684 TEST_F(ResourceUtilTest, SubtractBasic) {
685  auto base = CreateProto<ResourceAllocation>(
686  "resource_quantities { "
687  " resource { "
688  " device: 'main' "
689  " device_instance { value: 0 } "
690  " kind: 'processing' "
691  " } "
692  " quantity: 300 "
693  "} "
694  "resource_quantities { "
695  " resource { "
696  " device: 'main' "
697  " device_instance { value: 0 } "
698  " kind: 'ram' "
699  " } "
700  " quantity: 8 "
701  "} "
702  "resource_quantities { "
703  " resource { "
704  " device: 'gpu' "
705  " kind: 'ram' "
706  " } "
707  " quantity: 16 "
708  "} ");
709  const auto to_subtract = CreateProto<ResourceAllocation>(
710  "resource_quantities { "
711  " resource { "
712  " device: 'main' "
713  " device_instance { value: 0 } "
714  " kind: 'processing' "
715  " } "
716  " quantity: 100 "
717  "} "
718  "resource_quantities { "
719  " resource { "
720  " device: 'main' "
721  " device_instance { value: 0 } "
722  " kind: 'ram' "
723  " } "
724  " quantity: 4 "
725  "} ");
726  EXPECT_TRUE(util_.Subtract(to_subtract, &base));
727  EXPECT_THAT(base, EqualsProto("resource_quantities { "
728  " resource { "
729  " device: 'main' "
730  " device_instance { value: 0 } "
731  " kind: 'processing' "
732  " } "
733  " quantity: 200 "
734  "} "
735  "resource_quantities { "
736  " resource { "
737  " device: 'main' "
738  " device_instance { value: 0 } "
739  " kind: 'ram' "
740  " } "
741  " quantity: 4 "
742  "} "
743  "resource_quantities { "
744  " resource { "
745  " device: 'gpu' "
746  " kind: 'ram' "
747  " } "
748  " quantity: 16 "
749  "} "));
750 }
751 
752 TEST_F(ResourceUtilTest, SubtractNegativeResult) {
753  const auto original_base = CreateProto<ResourceAllocation>(
754  "resource_quantities { "
755  " resource { "
756  " device: 'main' "
757  " device_instance { value: 0 } "
758  " kind: 'processing' "
759  " } "
760  " quantity: 100 "
761  "} "
762  "resource_quantities { "
763  " resource { "
764  " device: 'main' "
765  " device_instance { value: 0 } "
766  " kind: 'ram' "
767  " } "
768  " quantity: 4 "
769  "} "
770  "resource_quantities { "
771  " resource { "
772  " device: 'gpu' "
773  " kind: 'ram' "
774  " } "
775  " quantity: 16 "
776  "} ");
777  ResourceAllocation base = original_base;
778  const auto to_subtract = CreateProto<ResourceAllocation>(
779  "resource_quantities { "
780  " resource { "
781  " device: 'main' "
782  " device_instance { value: 0 } "
783  " kind: 'processing' "
784  " } "
785  " quantity: 50 "
786  "} "
787  "resource_quantities { "
788  " resource { "
789  " device: 'main' "
790  " device_instance { value: 0 } "
791  " kind: 'ram' "
792  " } "
793  " quantity: 6 "
794  "} ");
795  EXPECT_FALSE(util_.Subtract(to_subtract, &base));
796  // Upon detecting a negative result, it should leave 'base' unchanged.
797  EXPECT_THAT(base, EqualsProto(original_base));
798 }
799 
800 TEST_F(ResourceUtilTest, SubtractNormalizeOutput) {
801  auto base = CreateProto<ResourceAllocation>(
802  "resource_quantities { "
803  " resource { "
804  " device: 'main' "
805  " device_instance { value: 0 } "
806  " kind: 'processing' "
807  " } "
808  " quantity: 10 "
809  "} ");
810  const auto to_subtract = CreateProto<ResourceAllocation>(
811  "resource_quantities { "
812  " resource { "
813  " device: 'main' "
814  " device_instance { value: 0 } "
815  " kind: 'processing' "
816  " } "
817  " quantity: 10 "
818  "} ");
819  EXPECT_TRUE(util_.Subtract(to_subtract, &base));
820  EXPECT_THAT(base, EqualsProto(""));
821 }
822 
823 TEST_F(ResourceUtilTest, SubtractBoundAndUnbound) {
824  auto base = CreateProto<ResourceAllocation>(
825  "resource_quantities { "
826  " resource { "
827  " device: 'gpu' "
828  " kind: 'ram' "
829  " } "
830  " quantity: 16 "
831  "} "
832  "resource_quantities { "
833  " resource { "
834  " device: 'gpu' "
835  " device_instance { value: 0 } "
836  " kind: 'ram' "
837  " } "
838  " quantity: 4 "
839  "} "
840  "resource_quantities { "
841  " resource { "
842  " device: 'gpu' "
843  " device_instance { value: 1 } "
844  " kind: 'ram' "
845  " } "
846  " quantity: 12 "
847  "} ");
848  const auto to_subtract = CreateProto<ResourceAllocation>(
849  "resource_quantities { "
850  " resource { "
851  " device: 'gpu' "
852  " kind: 'ram' "
853  " } "
854  " quantity: 8 "
855  "} "
856  "resource_quantities { "
857  " resource { "
858  " device: 'gpu' "
859  " device_instance { value: 0 } "
860  " kind: 'ram' "
861  " } "
862  " quantity: 2 "
863  "} ");
864  EXPECT_TRUE(util_.Subtract(to_subtract, &base));
865  EXPECT_THAT(base, EqualsProto("resource_quantities { "
866  " resource { "
867  " device: 'gpu' "
868  " kind: 'ram' "
869  " } "
870  " quantity: 8 "
871  "} "
872  "resource_quantities { "
873  " resource { "
874  " device: 'gpu' "
875  " device_instance { value: 0 } "
876  " kind: 'ram' "
877  " } "
878  " quantity: 2 "
879  "} "
880  "resource_quantities { "
881  " resource { "
882  " device: 'gpu' "
883  " device_instance { value: 1 } "
884  " kind: 'ram' "
885  " } "
886  " quantity: 12 "
887  "} "));
888 }
889 
890 TEST_F(ResourceUtilTest, MultiplyEmpty) {
891  auto base = CreateProto<ResourceAllocation>("");
892  util_.Multiply(2, &base);
893  EXPECT_THAT(base, EqualsProto(""));
894 }
895 
896 TEST_F(ResourceUtilTest, MultiplyBasic) {
897  auto base = CreateProto<ResourceAllocation>(
898  "resource_quantities { "
899  " resource { "
900  " device: 'main' "
901  " device_instance { value: 0 } "
902  " kind: 'processing' "
903  " } "
904  " quantity: 300 "
905  "} "
906  "resource_quantities { "
907  " resource { "
908  " device: 'main' "
909  " device_instance { value: 0 } "
910  " kind: 'ram' "
911  " } "
912  " quantity: 8 "
913  "} "
914  "resource_quantities { "
915  " resource { "
916  " device: 'gpu' "
917  " kind: 'ram' "
918  " } "
919  " quantity: 16 "
920  "} ");
921  util_.Multiply(2, &base);
922  EXPECT_THAT(base, EqualsProto("resource_quantities { "
923  " resource { "
924  " device: 'main' "
925  " device_instance { value: 0 } "
926  " kind: 'processing' "
927  " } "
928  " quantity: 600 "
929  "} "
930  "resource_quantities { "
931  " resource { "
932  " device: 'main' "
933  " device_instance { value: 0 } "
934  " kind: 'ram' "
935  " } "
936  " quantity: 16 "
937  "} "
938  "resource_quantities { "
939  " resource { "
940  " device: 'gpu' "
941  " kind: 'ram' "
942  " } "
943  " quantity: 32 "
944  "} "));
945 }
946 
947 TEST_F(ResourceUtilTest, Equal) {
948  const std::vector<ResourceAllocation> values = {
949  CreateProto<ResourceAllocation>(""),
950  CreateProto<ResourceAllocation>("resource_quantities { "
951  " resource { "
952  " device: 'gpu' "
953  " device_instance { value: 1 } "
954  " kind: 'processing' "
955  " } "
956  " quantity: 10 "
957  "} "),
958  CreateProto<ResourceAllocation>("resource_quantities { "
959  " resource { "
960  " device: 'gpu' "
961  " device_instance { value: 0 } "
962  " kind: 'processing' "
963  " } "
964  " quantity: 20 "
965  "} "),
966  CreateProto<ResourceAllocation>("resource_quantities { "
967  " resource { "
968  " device: 'gpu' "
969  " device_instance { value: 1 } "
970  " kind: 'processing' "
971  " } "
972  " quantity: 20 "
973  "} "),
974  CreateProto<ResourceAllocation>("resource_quantities { "
975  " resource { "
976  " device: 'main' "
977  " device_instance { value: 0 } "
978  " kind: 'ram' "
979  " } "
980  " quantity: 32 "
981  "} "),
982  CreateProto<ResourceAllocation>("resource_quantities { "
983  " resource { "
984  " device: 'gpu' "
985  " device_instance { value: 1 } "
986  " kind: 'processing' "
987  " } "
988  " quantity: 20 "
989  "} "
990  "resource_quantities { "
991  " resource { "
992  " device: 'main' "
993  " device_instance { value: 0 } "
994  " kind: 'ram' "
995  " } "
996  " quantity: 32 "
997  "} ")};
998 
999  for (int i = 0; i < values.size(); ++i) {
1000  for (int j = 0; j < values.size(); ++j) {
1001  EXPECT_EQ(i == j, util_.Equal(values[i], values[j])) << i << " vs. " << j;
1002  EXPECT_EQ(j == i, util_.Equal(values[j], values[i])) << j << " vs. " << i;
1003  }
1004  }
1005 }
1006 
1007 TEST_F(ResourceUtilTest, EqualOrderInsensitive) {
1008  const auto a = CreateProto<ResourceAllocation>(
1009  "resource_quantities { "
1010  " resource { "
1011  " device: 'main' "
1012  " device_instance { value: 0 } "
1013  " kind: 'ram' "
1014  " } "
1015  " quantity: 32 "
1016  "} "
1017  "resource_quantities { "
1018  " resource { "
1019  " device: 'gpu' "
1020  " device_instance { value: 1 } "
1021  " kind: 'processing' "
1022  " } "
1023  " quantity: 20 "
1024  "} ");
1025  const auto b = CreateProto<ResourceAllocation>(
1026  "resource_quantities { "
1027  " resource { "
1028  " device: 'gpu' "
1029  " device_instance { value: 1 } "
1030  " kind: 'processing' "
1031  " } "
1032  " quantity: 20 "
1033  "} "
1034  "resource_quantities { "
1035  " resource { "
1036  " device: 'main' "
1037  " device_instance { value: 0 } "
1038  " kind: 'ram' "
1039  " } "
1040  " quantity: 32 "
1041  "} ");
1042  EXPECT_TRUE(util_.Equal(a, b));
1043  EXPECT_TRUE(util_.Equal(b, a));
1044 }
1045 
1046 TEST_F(ResourceUtilTest, ResourcesEqual) {
1047  EXPECT_TRUE(util_.ResourcesEqual(CreateProto<Resource>("device: 'gpu' "
1048  "kind: 'ram' "),
1049  CreateProto<Resource>("device: 'gpu' "
1050  "kind: 'ram' ")));
1051  EXPECT_TRUE(
1052  util_.ResourcesEqual(CreateProto<Resource>("device: 'gpu' "
1053  "device_instance { value: 1 } "
1054  "kind: 'ram' "),
1055  CreateProto<Resource>("device: 'gpu' "
1056  "device_instance { value: 1 } "
1057  "kind: 'ram' ")));
1058  EXPECT_TRUE(
1059  util_.ResourcesEqual(CreateProto<Resource>("device: 'main' "
1060  "kind: 'ram' "),
1061  CreateProto<Resource>("device: 'main' "
1062  "device_instance { value: 0 } "
1063  "kind: 'ram' ")));
1064  EXPECT_FALSE(util_.ResourcesEqual(CreateProto<Resource>("device: 'gpu' "
1065  "kind: 'ram' "),
1066  CreateProto<Resource>("device: 'main' "
1067  "kind: 'ram' ")));
1068  EXPECT_FALSE(
1069  util_.ResourcesEqual(CreateProto<Resource>("device: 'gpu' "
1070  "kind: 'ram' "),
1071  CreateProto<Resource>("device: 'gpu' "
1072  "kind: 'processing' ")));
1073  EXPECT_FALSE(
1074  util_.ResourcesEqual(CreateProto<Resource>("device: 'gpu' "
1075  "device_instance { value: 0 } "
1076  "kind: 'ram' "),
1077  CreateProto<Resource>("device: 'gpu' "
1078  "device_instance { value: 1 } "
1079  "kind: 'ram' ")));
1080  EXPECT_FALSE(
1081  util_.ResourcesEqual(CreateProto<Resource>("device: 'gpu' "
1082  "kind: 'ram' "),
1083  CreateProto<Resource>("device: 'gpu' "
1084  "device_instance { value: 1 } "
1085  "kind: 'ram' ")));
1086 }
1087 
1088 TEST_F(ResourceUtilTest, LessThanOrEqualEmpty) {
1089  const auto a = CreateProto<ResourceAllocation>("");
1090  EXPECT_TRUE(util_.LessThanOrEqual(a, a));
1091 }
1092 
1093 TEST_F(ResourceUtilTest, LessThanOrEqualOneEntry) {
1094  const auto a = CreateProto<ResourceAllocation>(
1095  "resource_quantities { "
1096  " resource { "
1097  " device: 'gpu' "
1098  " device_instance { value: 1 } "
1099  " kind: 'processing' "
1100  " } "
1101  " quantity: 10 "
1102  "} ");
1103  const auto b = CreateProto<ResourceAllocation>(
1104  "resource_quantities { "
1105  " resource { "
1106  " device: 'gpu' "
1107  " device_instance { value: 1 } "
1108  " kind: 'processing' "
1109  " } "
1110  " quantity: 20 "
1111  "} ");
1112  EXPECT_TRUE(util_.LessThanOrEqual(a, a));
1113  EXPECT_TRUE(util_.LessThanOrEqual(a, b));
1114  EXPECT_FALSE(util_.LessThanOrEqual(b, a));
1115 }
1116 
1117 TEST_F(ResourceUtilTest, LessThanOrEqualTwoEntries) {
1118  const auto a = CreateProto<ResourceAllocation>(
1119  "resource_quantities { "
1120  " resource { "
1121  " device: 'gpu' "
1122  " device_instance { value: 0 } "
1123  " kind: 'processing' "
1124  " } "
1125  " quantity: 10 "
1126  "} "
1127  "resource_quantities { "
1128  " resource { "
1129  " device: 'gpu' "
1130  " device_instance { value: 1 } "
1131  " kind: 'ram' "
1132  " } "
1133  " quantity: 4 "
1134  "} ");
1135  const auto b = CreateProto<ResourceAllocation>(
1136  "resource_quantities { "
1137  " resource { "
1138  " device: 'gpu' "
1139  " device_instance { value: 0 } "
1140  " kind: 'processing' "
1141  " } "
1142  " quantity: 5 "
1143  "} "
1144  "resource_quantities { "
1145  " resource { "
1146  " device: 'gpu' "
1147  " device_instance { value: 1 } "
1148  " kind: 'ram' "
1149  " } "
1150  " quantity: 4 "
1151  "} ");
1152  EXPECT_TRUE(util_.LessThanOrEqual(a, a));
1153  EXPECT_TRUE(util_.LessThanOrEqual(b, a));
1154  EXPECT_FALSE(util_.LessThanOrEqual(a, b));
1155 }
1156 
1157 TEST_F(ResourceUtilTest, LessThanOrEqualImplicitZero) {
1158  const auto a = CreateProto<ResourceAllocation>(
1159  "resource_quantities { "
1160  " resource { "
1161  " device: 'gpu' "
1162  " device_instance { value: 0 } "
1163  " kind: 'processing' "
1164  " } "
1165  " quantity: 10 "
1166  "} "
1167  "resource_quantities { "
1168  " resource { "
1169  " device: 'gpu' "
1170  " device_instance { value: 1 } "
1171  " kind: 'ram' "
1172  " } "
1173  " quantity: 4 "
1174  "} ");
1175  const auto b = CreateProto<ResourceAllocation>(
1176  "resource_quantities { "
1177  " resource { "
1178  " device: 'gpu' "
1179  " device_instance { value: 0 } "
1180  " kind: 'processing' "
1181  " } "
1182  " quantity: 5 "
1183  "} ");
1184  EXPECT_TRUE(util_.LessThanOrEqual(b, a));
1185  EXPECT_FALSE(util_.LessThanOrEqual(a, b));
1186 }
1187 
1188 // Test LessThanOrEqual(lhs, rhs) where 'lhs' is unbound. ('rhs' is always
1189 // bound.)
1190 TEST_F(ResourceUtilTest, LessThanOrEqualUnbound) {
1191  const auto base = CreateProto<ResourceAllocation>(
1192  "resource_quantities { "
1193  " resource { "
1194  " device: 'main' "
1195  " device_instance { value: 0 } "
1196  " kind: 'processing' "
1197  " } "
1198  " quantity: 1000 "
1199  "} "
1200  "resource_quantities { "
1201  " resource { "
1202  " device: 'gpu' "
1203  " device_instance { value: 0 } "
1204  " kind: 'processing' "
1205  " } "
1206  " quantity: 100 "
1207  "} "
1208  "resource_quantities { "
1209  " resource { "
1210  " device: 'gpu' "
1211  " device_instance { value: 1 } "
1212  " kind: 'processing' "
1213  " } "
1214  " quantity: 50 "
1215  "} "
1216  "resource_quantities { "
1217  " resource { "
1218  " device: 'gpu' "
1219  " device_instance { value: 0 } "
1220  " kind: 'ram' "
1221  " } "
1222  " quantity: 2 "
1223  "} "
1224  "resource_quantities { "
1225  " resource { "
1226  " device: 'gpu' "
1227  " device_instance { value: 1 } "
1228  " kind: 'ram' "
1229  " } "
1230  " quantity: 4 "
1231  "} ");
1232 
1233  EXPECT_TRUE(util_.LessThanOrEqual(CreateProto<ResourceAllocation>(""), base));
1234  EXPECT_TRUE(util_.LessThanOrEqual(
1235  CreateProto<ResourceAllocation>("resource_quantities { "
1236  " resource { "
1237  " device: 'main' "
1238  " device_instance { value: 0 } "
1239  " kind: 'processing' "
1240  " } "
1241  " quantity: 100 "
1242  "} "
1243  "resource_quantities { "
1244  " resource { "
1245  " device: 'gpu' "
1246  " kind: 'ram' "
1247  " } "
1248  " quantity: 4 "
1249  "} "),
1250  base));
1251  EXPECT_TRUE(util_.LessThanOrEqual(
1252  CreateProto<ResourceAllocation>("resource_quantities { "
1253  " resource { "
1254  " device: 'gpu' "
1255  " kind: 'ram' "
1256  " } "
1257  " quantity: 4 "
1258  "} "),
1259  base));
1260  EXPECT_FALSE(util_.LessThanOrEqual(
1261  CreateProto<ResourceAllocation>("resource_quantities { "
1262  " resource { "
1263  " device: 'gpu' "
1264  " kind: 'ram' "
1265  " } "
1266  " quantity: 5 "
1267  "} "),
1268  base));
1269  EXPECT_TRUE(util_.LessThanOrEqual(
1270  CreateProto<ResourceAllocation>("resource_quantities { "
1271  " resource { "
1272  " device: 'gpu' "
1273  " device_instance { value: 0 } "
1274  " kind: 'processing' "
1275  " } "
1276  " quantity: 100 "
1277  "} "
1278  "resource_quantities { "
1279  " resource { "
1280  " device: 'gpu' "
1281  " kind: 'ram' "
1282  " } "
1283  " quantity: 4 "
1284  "} "),
1285  base));
1286  EXPECT_TRUE(util_.LessThanOrEqual(
1287  CreateProto<ResourceAllocation>("resource_quantities { "
1288  " resource { "
1289  " device: 'gpu' "
1290  " kind: 'processing' "
1291  " } "
1292  " quantity: 50 "
1293  "} "
1294  "resource_quantities { "
1295  " resource { "
1296  " device: 'gpu' "
1297  " kind: 'ram' "
1298  " } "
1299  " quantity: 4 "
1300  "} "),
1301  base));
1302  EXPECT_TRUE(util_.LessThanOrEqual(
1303  CreateProto<ResourceAllocation>("resource_quantities { "
1304  " resource { "
1305  " device: 'gpu' "
1306  " device_instance { value: 0 } "
1307  " kind: 'processing' "
1308  " } "
1309  " quantity: 90 "
1310  "} "
1311  "resource_quantities { "
1312  " resource { "
1313  " device: 'gpu' "
1314  " device_instance { value: 1 } "
1315  " kind: 'processing' "
1316  " } "
1317  " quantity: 40 "
1318  "} "
1319  "resource_quantities { "
1320  " resource { "
1321  " device: 'gpu' "
1322  " kind: 'processing' "
1323  " } "
1324  " quantity: 10 "
1325  "} "),
1326  base));
1327  EXPECT_FALSE(util_.LessThanOrEqual(
1328  CreateProto<ResourceAllocation>("resource_quantities { "
1329  " resource { "
1330  " device: 'gpu' "
1331  " kind: 'processing' "
1332  " } "
1333  " quantity: 101 "
1334  "} "
1335  "resource_quantities { "
1336  " resource { "
1337  " device: 'gpu' "
1338  " kind: 'ram' "
1339  " } "
1340  " quantity: 4 "
1341  "} "),
1342  base));
1343  EXPECT_FALSE(util_.LessThanOrEqual(
1344  CreateProto<ResourceAllocation>("resource_quantities { "
1345  " resource { "
1346  " device: 'gpu' "
1347  " kind: 'processing' "
1348  " } "
1349  " quantity: 100 "
1350  "} "
1351  "resource_quantities { "
1352  " resource { "
1353  " device: 'gpu' "
1354  " kind: 'ram' "
1355  " } "
1356  " quantity: 5 "
1357  "} "),
1358  base));
1359  EXPECT_FALSE(util_.LessThanOrEqual(
1360  CreateProto<ResourceAllocation>("resource_quantities { "
1361  " resource { "
1362  " device: 'gpu' "
1363  " device_instance { value: 0 } "
1364  " kind: 'processing' "
1365  " } "
1366  " quantity: 90 "
1367  "} "
1368  "resource_quantities { "
1369  " resource { "
1370  " device: 'gpu' "
1371  " device_instance { value: 1 } "
1372  " kind: 'processing' "
1373  " } "
1374  " quantity: 40 "
1375  "} "
1376  "resource_quantities { "
1377  " resource { "
1378  " device: 'gpu' "
1379  " kind: 'processing' "
1380  " } "
1381  " quantity: 20 "
1382  "} "),
1383  base));
1384 }
1385 
1386 TEST_F(ResourceUtilTest, Overbind) {
1387  EXPECT_THAT(util_.Overbind(CreateProto<ResourceAllocation>("")),
1388  EqualsProto(""));
1389  EXPECT_THAT(util_.Overbind(CreateProto<ResourceAllocation>(
1390  "resource_quantities { "
1391  " resource { "
1392  " device: 'main' "
1393  " device_instance { value: 0 } "
1394  " kind: 'processing' "
1395  " } "
1396  " quantity: 100 "
1397  "} "
1398  "resource_quantities { "
1399  " resource { "
1400  " device: 'gpu' "
1401  " device_instance { value: 0 } "
1402  " kind: 'ram' "
1403  " } "
1404  " quantity: 4 "
1405  "} ")),
1406  EqualsProto("resource_quantities { "
1407  " resource { "
1408  " device: 'main' "
1409  " device_instance { value: 0 } "
1410  " kind: 'processing' "
1411  " } "
1412  " quantity: 100 "
1413  "} "
1414  "resource_quantities { "
1415  " resource { "
1416  " device: 'gpu' "
1417  " device_instance { value: 0 } "
1418  " kind: 'ram' "
1419  " } "
1420  " quantity: 4 "
1421  "} "));
1422  EXPECT_THAT(util_.Overbind(CreateProto<ResourceAllocation>(
1423  "resource_quantities { "
1424  " resource { "
1425  " device: 'gpu' "
1426  " kind: 'ram' "
1427  " } "
1428  " quantity: 4 "
1429  "} "
1430  "resource_quantities { "
1431  " resource { "
1432  " device: 'gpu' "
1433  " device_instance { value: 1 } "
1434  " kind: 'processing' "
1435  " } "
1436  " quantity: 100 "
1437  "} ")),
1438  EqualsProto("resource_quantities { "
1439  " resource { "
1440  " device: 'gpu' "
1441  " device_instance { value: 0 } "
1442  " kind: 'ram' "
1443  " } "
1444  " quantity: 4 "
1445  "} "
1446  "resource_quantities { "
1447  " resource { "
1448  " device: 'gpu' "
1449  " device_instance { value: 1 } "
1450  " kind: 'ram' "
1451  " } "
1452  " quantity: 4 "
1453  "} "
1454  "resource_quantities { "
1455  " resource { "
1456  " device: 'gpu' "
1457  " device_instance { value: 1 } "
1458  " kind: 'processing' "
1459  " } "
1460  " quantity: 100 "
1461  "} "));
1462  EXPECT_THAT(util_.Overbind(CreateProto<ResourceAllocation>(
1463  "resource_quantities { "
1464  " resource { "
1465  " device: 'gpu' "
1466  " kind: 'ram' "
1467  " } "
1468  " quantity: 4 "
1469  "} "
1470  "resource_quantities { "
1471  " resource { "
1472  " device: 'gpu' "
1473  " device_instance { value: 1 } "
1474  " kind: 'ram' "
1475  " } "
1476  " quantity: 2 "
1477  "} ")),
1478  EqualsProto("resource_quantities { "
1479  " resource { "
1480  " device: 'gpu' "
1481  " device_instance { value: 0 } "
1482  " kind: 'ram' "
1483  " } "
1484  " quantity: 4 "
1485  "} "
1486  "resource_quantities { "
1487  " resource { "
1488  " device: 'gpu' "
1489  " device_instance { value: 1 } "
1490  " kind: 'ram' "
1491  " } "
1492  " quantity: 6 "
1493  "} "));
1494 }
1495 
1496 TEST_F(ResourceUtilTest, MaxEmpty) {
1497  const auto lhs = CreateProto<ResourceAllocation>("");
1498  const auto rhs = CreateProto<ResourceAllocation>("");
1499  EXPECT_THAT(util_.Max(lhs, rhs), EqualsProto(""));
1500 }
1501 
1502 TEST_F(ResourceUtilTest, MaxBound) {
1503  const auto lhs = CreateProto<ResourceAllocation>(
1504  "resource_quantities { "
1505  " resource { "
1506  " device: 'main' "
1507  " device_instance { value: 0 } "
1508  " kind: 'processing' "
1509  " } "
1510  " quantity: 100 "
1511  "} "
1512  "resource_quantities { "
1513  " resource { "
1514  " device: 'main' "
1515  " device_instance { value: 0 } "
1516  " kind: 'ram' "
1517  " } "
1518  " quantity: 8 "
1519  "} ");
1520  const auto rhs = CreateProto<ResourceAllocation>(
1521  "resource_quantities { "
1522  " resource { "
1523  " device: 'main' "
1524  " device_instance { value: 0 } "
1525  " kind: 'processing' "
1526  " } "
1527  " quantity: 300 "
1528  "} "
1529  "resource_quantities { "
1530  " resource { "
1531  " device: 'gpu' "
1532  " device_instance { value: 0 } "
1533  " kind: 'ram' "
1534  " } "
1535  " quantity: 4 "
1536  "} ");
1537  EXPECT_THAT(util_.Max(lhs, rhs),
1538  EqualsProto("resource_quantities { "
1539  " resource { "
1540  " device: 'main' "
1541  " device_instance { value: 0 } "
1542  " kind: 'processing' "
1543  " } "
1544  " quantity: 300 "
1545  "} "
1546  "resource_quantities { "
1547  " resource { "
1548  " device: 'gpu' "
1549  " device_instance { value: 0 } "
1550  " kind: 'ram' "
1551  " } "
1552  " quantity: 4 "
1553  "} "
1554  "resource_quantities { "
1555  " resource { "
1556  " device: 'main' "
1557  " device_instance { value: 0 } "
1558  " kind: 'ram' "
1559  " } "
1560  " quantity: 8 "
1561  "} "));
1562 }
1563 
1564 TEST_F(ResourceUtilTest, MaxBoundAndUnbound) {
1565  const auto lhs = CreateProto<ResourceAllocation>(
1566  "resource_quantities { "
1567  " resource { "
1568  " device: 'main' "
1569  " device_instance { value: 0 } "
1570  " kind: 'processing' "
1571  " } "
1572  " quantity: 100 "
1573  "} "
1574  "resource_quantities { "
1575  " resource { "
1576  " device: 'gpu' "
1577  " kind: 'ram' "
1578  " } "
1579  " quantity: 8 "
1580  "} ");
1581  const auto rhs = CreateProto<ResourceAllocation>(
1582  "resource_quantities { "
1583  " resource { "
1584  " device: 'main' "
1585  " device_instance { value: 0 } "
1586  " kind: 'processing' "
1587  " } "
1588  " quantity: 300 "
1589  "} "
1590  "resource_quantities { "
1591  " resource { "
1592  " device: 'gpu' "
1593  " device_instance { value: 0 } "
1594  " kind: 'ram' "
1595  " } "
1596  " quantity: 4 "
1597  "} ");
1598  EXPECT_THAT(util_.Max(lhs, rhs),
1599  EqualsProto("resource_quantities { "
1600  " resource { "
1601  " device: 'main' "
1602  " device_instance { value: 0 } "
1603  " kind: 'processing' "
1604  " } "
1605  " quantity: 300 "
1606  "} "
1607  "resource_quantities { "
1608  " resource { "
1609  " device: 'gpu' "
1610  " device_instance { value: 0 } "
1611  " kind: 'ram' "
1612  " } "
1613  " quantity: 4 "
1614  "} "
1615  "resource_quantities { "
1616  " resource { "
1617  " device: 'gpu' "
1618  " kind: 'ram' "
1619  " } "
1620  " quantity: 8 "
1621  "} "));
1622 }
1623 
1624 TEST_F(ResourceUtilTest, MaxUnbound) {
1625  const auto lhs = CreateProto<ResourceAllocation>(
1626  "resource_quantities { "
1627  " resource { "
1628  " device: 'main' "
1629  " kind: 'processing' "
1630  " } "
1631  " quantity: 100 "
1632  "} "
1633  "resource_quantities { "
1634  " resource { "
1635  " device: 'main' "
1636  " kind: 'ram' "
1637  " } "
1638  " quantity: 8 "
1639  "} ");
1640  const auto rhs = CreateProto<ResourceAllocation>(
1641  "resource_quantities { "
1642  " resource { "
1643  " device: 'main' "
1644  " kind: 'processing' "
1645  " } "
1646  " quantity: 300 "
1647  "} "
1648  "resource_quantities { "
1649  " resource { "
1650  " device: 'main' "
1651  " kind: 'ram' "
1652  " } "
1653  " quantity: 4 "
1654  "} ");
1655  EXPECT_THAT(util_.Max(lhs, rhs),
1656  EqualsProto("resource_quantities { "
1657  " resource { "
1658  " device: 'main' "
1659  " device_instance { value: 0 } "
1660  " kind: 'processing' "
1661  " } "
1662  " quantity: 300 "
1663  "} "
1664  "resource_quantities { "
1665  " resource { "
1666  " device: 'main' "
1667  " device_instance { value: 0 } "
1668  " kind: 'ram' "
1669  " } "
1670  " quantity: 8 "
1671  "} "));
1672 }
1673 
1674 TEST_F(ResourceUtilTest, MinEmpty) {
1675  const auto lhs = CreateProto<ResourceAllocation>("");
1676  const auto rhs = CreateProto<ResourceAllocation>("");
1677  EXPECT_THAT(util_.Min(lhs, rhs), EqualsProto(""));
1678 }
1679 
1680 TEST_F(ResourceUtilTest, MinBound) {
1681  const auto lhs = CreateProto<ResourceAllocation>(
1682  "resource_quantities { "
1683  " resource { "
1684  " device: 'main' "
1685  " device_instance { value: 0 } "
1686  " kind: 'processing' "
1687  " } "
1688  " quantity: 100 "
1689  "} "
1690  "resource_quantities { "
1691  " resource { "
1692  " device: 'main' "
1693  " device_instance { value: 0 } "
1694  " kind: 'ram' "
1695  " } "
1696  " quantity: 8 "
1697  "} ");
1698  const auto rhs = CreateProto<ResourceAllocation>(
1699  "resource_quantities { "
1700  " resource { "
1701  " device: 'main' "
1702  " device_instance { value: 0 } "
1703  " kind: 'processing' "
1704  " } "
1705  " quantity: 300 "
1706  "} "
1707  "resource_quantities { "
1708  " resource { "
1709  " device: 'gpu' "
1710  " device_instance { value: 0 } "
1711  " kind: 'ram' "
1712  " } "
1713  " quantity: 4 "
1714  "} ");
1715  EXPECT_THAT(util_.Min(lhs, rhs),
1716  EqualsProto("resource_quantities { "
1717  " resource { "
1718  " device: 'main' "
1719  " device_instance { value: 0 } "
1720  " kind: 'processing' "
1721  " } "
1722  " quantity: 100 "
1723  "} "));
1724 }
1725 
1726 TEST_F(ResourceUtilTest, MinBoundAndUnbound) {
1727  const auto lhs = CreateProto<ResourceAllocation>(
1728  "resource_quantities { "
1729  " resource { "
1730  " device: 'main' "
1731  " device_instance { value: 0 } "
1732  " kind: 'processing' "
1733  " } "
1734  " quantity: 100 "
1735  "} "
1736  "resource_quantities { "
1737  " resource { "
1738  " device: 'gpu' "
1739  " kind: 'ram' "
1740  " } "
1741  " quantity: 8 "
1742  "} ");
1743  const auto rhs = CreateProto<ResourceAllocation>(
1744  "resource_quantities { "
1745  " resource { "
1746  " device: 'main' "
1747  " device_instance { value: 0 } "
1748  " kind: 'processing' "
1749  " } "
1750  " quantity: 300 "
1751  "} "
1752  "resource_quantities { "
1753  " resource { "
1754  " device: 'gpu' "
1755  " device_instance { value: 0 } "
1756  " kind: 'ram' "
1757  " } "
1758  " quantity: 4 "
1759  "} ");
1760  EXPECT_THAT(util_.Min(lhs, rhs),
1761  EqualsProto("resource_quantities { "
1762  " resource { "
1763  " device: 'main' "
1764  " device_instance { value: 0 } "
1765  " kind: 'processing' "
1766  " } "
1767  " quantity: 100 "
1768  "} "));
1769 }
1770 
1771 TEST_F(ResourceUtilTest, MinUnbound) {
1772  const auto lhs = CreateProto<ResourceAllocation>(
1773  "resource_quantities { "
1774  " resource { "
1775  " device: 'main' "
1776  " kind: 'processing' "
1777  " } "
1778  " quantity: 100 "
1779  "} "
1780  "resource_quantities { "
1781  " resource { "
1782  " device: 'main' "
1783  " kind: 'ram' "
1784  " } "
1785  " quantity: 8 "
1786  "} ");
1787  const auto rhs = CreateProto<ResourceAllocation>(
1788  "resource_quantities { "
1789  " resource { "
1790  " device: 'main' "
1791  " kind: 'processing' "
1792  " } "
1793  " quantity: 300 "
1794  "} "
1795  "resource_quantities { "
1796  " resource { "
1797  " device: 'main' "
1798  " kind: 'ram' "
1799  " } "
1800  " quantity: 4 "
1801  "} ");
1802  EXPECT_THAT(util_.Min(lhs, rhs),
1803  EqualsProto("resource_quantities { "
1804  " resource { "
1805  " device: 'main' "
1806  " device_instance { value: 0 } "
1807  " kind: 'processing' "
1808  " } "
1809  " quantity: 100 "
1810  "} "
1811  "resource_quantities { "
1812  " resource { "
1813  " device: 'main' "
1814  " device_instance { value: 0 } "
1815  " kind: 'ram' "
1816  " } "
1817  " quantity: 4 "
1818  "} "));
1819 }
1820 
1821 TEST_F(ResourceUtilTest, OverrideDeviceValidity) {
1822  const auto base_resource = CreateProto<ResourceAllocation>(
1823  "resource_quantities { "
1824  " resource { "
1825  " device: 'main' "
1826  " kind: 'processing' "
1827  " } "
1828  " quantity: 100 "
1829  "} "
1830  "resource_quantities { "
1831  " resource { "
1832  " device: 'tpu' "
1833  " kind: 'hbm' "
1834  " } "
1835  " quantity: 8 "
1836  "} ");
1837  const auto valid_override_resource = CreateProto<ResourceAllocation>(
1838  "resource_quantities { "
1839  " resource { "
1840  " device: 'main' "
1841  " kind: 'processing' "
1842  " } "
1843  " quantity: 300 "
1844  "} "
1845  "resource_quantities { "
1846  " resource { "
1847  " device: 'tpu' "
1848  " kind: 'hbm' "
1849  " } "
1850  " quantity: 4 "
1851  "} ");
1852  const auto invalid_override_resource = CreateProto<ResourceAllocation>(
1853  "resource_quantities { "
1854  " resource { "
1855  " device: 'main' "
1856  " kind: 'processing' "
1857  " } "
1858  " quantity: 300 "
1859  "} "
1860  "resource_quantities { "
1861  " resource { "
1862  " device: 'gpu' "
1863  " kind: 'ram' "
1864  " } "
1865  " quantity: 4 "
1866  "} ");
1867  TF_EXPECT_OK(util_.VerifyOverrideDeviceValidity(base_resource,
1868  valid_override_resource));
1869  EXPECT_FALSE(util_
1870  .VerifyOverrideDeviceValidity(base_resource,
1871  invalid_override_resource)
1872  .ok());
1873 }
1874 
1875 } // namespace
1876 } // namespace serving
1877 } // namespace tensorflow