go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/swarming/server/cfg/pools_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 cfg 16 17 import ( 18 "context" 19 "testing" 20 21 "go.chromium.org/luci/common/errors" 22 "go.chromium.org/luci/config/validation" 23 24 configpb "go.chromium.org/luci/swarming/proto/config" 25 26 . "github.com/smartystreets/goconvey/convey" 27 ) 28 29 var goodPoolsCfg = &configpb.PoolsCfg{ 30 Pool: []*configpb.Pool{ 31 { 32 Name: []string{"a"}, 33 Realm: "test:1", 34 DefaultTaskRealm: "test:default", 35 }, 36 { 37 Name: []string{"b", "c"}, 38 Realm: "test:2", 39 }, 40 }, 41 } 42 43 func TestNewPoolsConfig(t *testing.T) { 44 t.Parallel() 45 46 Convey("Works", t, func() { 47 pools, err := newPoolsConfig(goodPoolsCfg) 48 So(err, ShouldBeNil) 49 So(pools, ShouldHaveLength, 3) 50 51 So(pools["a"].Realm, ShouldEqual, "test:1") 52 So(pools["b"].Realm, ShouldEqual, "test:2") 53 So(pools["c"].Realm, ShouldEqual, "test:2") 54 55 So(pools["a"].DefaultTaskRealm, ShouldEqual, "test:default") 56 So(pools["b"].DefaultTaskRealm, ShouldEqual, "") 57 So(pools["c"].DefaultTaskRealm, ShouldEqual, "") 58 }) 59 } 60 61 func TestPoolsValidation(t *testing.T) { 62 t.Parallel() 63 64 call := func(cfg *configpb.PoolsCfg) []string { 65 ctx := validation.Context{Context: context.Background()} 66 ctx.SetFile("pools.cfg") 67 validatePoolsCfg(&ctx, cfg) 68 if err := ctx.Finalize(); err != nil { 69 var verr *validation.Error 70 errors.As(err, &verr) 71 out := make([]string, len(verr.Errors)) 72 for i, err := range verr.Errors { 73 out[i] = err.Error() 74 } 75 return out 76 } 77 return nil 78 } 79 80 Convey("Empty", t, func() { 81 So(call(&configpb.PoolsCfg{}), ShouldBeNil) 82 }) 83 84 Convey("Good", t, func() { 85 So(call(goodPoolsCfg), ShouldBeNil) 86 }) 87 88 Convey("Errors", t, func() { 89 onePool := func(p *configpb.Pool) *configpb.PoolsCfg { 90 return &configpb.PoolsCfg{ 91 Pool: []*configpb.Pool{p}, 92 } 93 } 94 95 testCases := []struct { 96 cfg *configpb.PoolsCfg 97 err string 98 }{ 99 { 100 cfg: onePool(&configpb.Pool{ 101 Name: []string{"a"}, 102 Realm: "test:1", 103 Schedulers: &configpb.Schedulers{}, 104 }), 105 err: "(pool #1 (a)): setting deprecated field `schedulers`", 106 }, 107 { 108 cfg: onePool(&configpb.Pool{ 109 Name: []string{"a"}, 110 Realm: "test:1", 111 BotMonitoring: "bzzz", 112 }), 113 err: "(pool #1 (a)): setting deprecated field `bot_monitoring`", 114 }, 115 { 116 cfg: onePool(&configpb.Pool{ 117 Realm: "test:1", 118 }), 119 err: "(pool #1 (unnamed)): at least one pool name must be given", 120 }, 121 { 122 cfg: onePool(&configpb.Pool{ 123 Name: []string{"a", ""}, 124 Realm: "test:1", 125 }), 126 err: `(pool #1 (a,)): bad pool name "": the value cannot be empty`, 127 }, 128 { 129 cfg: onePool(&configpb.Pool{ 130 Name: []string{"a", "a"}, 131 Realm: "test:1", 132 }), 133 err: "(pool #1 (a,a)): pool \"a\" was already declared", 134 }, 135 { 136 cfg: onePool(&configpb.Pool{ 137 Name: []string{"a"}, 138 }), 139 err: "(pool #1 (a)): missing required `realm` field", 140 }, 141 { 142 cfg: onePool(&configpb.Pool{ 143 Name: []string{"a"}, 144 Realm: "not-global", 145 }), 146 err: "(pool #1 (a)): bad `realm` field: bad global realm name \"not-global\" - should be <project>:<realm>", 147 }, 148 { 149 cfg: onePool(&configpb.Pool{ 150 Name: []string{"a"}, 151 Realm: "test:1", 152 DefaultTaskRealm: "not-global", 153 }), 154 err: "(pool #1 (a)): bad `default_task_realm` field: bad global realm name \"not-global\" - should be <project>:<realm>", 155 }, 156 } 157 for _, cs := range testCases { 158 So(call(cs.cfg), ShouldResemble, []string{`in "pools.cfg" ` + cs.err}) 159 } 160 }) 161 }