agones.dev/agones@v1.53.0/pkg/apis/agones/v1/common_test.go (about) 1 // Copyright 2023 Google LLC 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 package v1 16 17 import ( 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 "k8s.io/apimachinery/pkg/util/validation/field" 24 ) 25 26 func TestAllocationOverflowValidate(t *testing.T) { 27 // valid 28 type expected struct { 29 fields []string 30 } 31 32 fixtures := map[string]struct { 33 ao AllocationOverflow 34 expected 35 }{ 36 "empty": { 37 ao: AllocationOverflow{}, 38 expected: expected{ 39 fields: nil, 40 }, 41 }, 42 "bad label name": { 43 ao: AllocationOverflow{ 44 Labels: map[string]string{"$$$foobar": "stuff"}, 45 Annotations: nil, 46 }, 47 expected: expected{ 48 fields: []string{"spec.allocationOverflow.labels"}, 49 }, 50 }, 51 "bad label value": { 52 ao: AllocationOverflow{ 53 Labels: map[string]string{"valid": "$$$NOPE"}, 54 Annotations: nil, 55 }, 56 expected: expected{ 57 fields: []string{"spec.allocationOverflow.labels"}, 58 }, 59 }, 60 "bad annotation name": { 61 ao: AllocationOverflow{ 62 Annotations: map[string]string{"$$$foobar": "stuff"}, 63 }, 64 expected: expected{ 65 fields: []string{"spec.allocationOverflow.annotations"}, 66 }, 67 }, 68 "valid full": { 69 ao: AllocationOverflow{ 70 Labels: map[string]string{"valid": "yes", "still.valid": "check-me-out"}, 71 Annotations: map[string]string{"icando-this": "yes, I can do all kinds of things here $$$"}, 72 }, 73 expected: expected{ 74 fields: nil, 75 }, 76 }, 77 } 78 79 for k, v := range fixtures { 80 t.Run(k, func(t *testing.T) { 81 errs := v.ao.Validate(field.NewPath("spec", "allocationOverflow")) 82 assert.Len(t, errs, len(v.fields)) 83 for i, err := range errs { 84 assert.Equal(t, field.ErrorTypeInvalid, err.Type) 85 assert.Equal(t, v.expected.fields[i], err.Field) 86 } 87 }) 88 } 89 } 90 91 func TestAllocationOverflowCountMatches(t *testing.T) { 92 type expected struct { 93 count int32 94 rest int 95 } 96 97 fixtures := map[string]struct { 98 list func([]*GameServer) 99 ao func(*AllocationOverflow) 100 expected expected 101 }{ 102 "simple": { 103 list: func(_ []*GameServer) {}, 104 ao: func(_ *AllocationOverflow) {}, 105 expected: expected{ 106 count: 2, 107 rest: 0, 108 }, 109 }, 110 "label selector": { 111 list: func(list []*GameServer) { 112 list[0].ObjectMeta.Labels = map[string]string{"colour": "blue"} 113 }, 114 ao: func(ao *AllocationOverflow) { 115 ao.Labels = map[string]string{"colour": "blue"} 116 }, 117 expected: expected{ 118 count: 1, 119 rest: 1, 120 }, 121 }, 122 "annotation selector": { 123 list: func(list []*GameServer) { 124 list[0].ObjectMeta.Annotations = map[string]string{"colour": "green"} 125 }, 126 ao: func(ao *AllocationOverflow) { 127 ao.Annotations = map[string]string{"colour": "green"} 128 }, 129 expected: expected{ 130 count: 1, 131 rest: 1, 132 }, 133 }, 134 "both": { 135 list: func(list []*GameServer) { 136 list[0].ObjectMeta.Labels = map[string]string{"colour": "blue"} 137 list[0].ObjectMeta.Annotations = map[string]string{"colour": "green"} 138 }, 139 ao: func(ao *AllocationOverflow) { 140 ao.Labels = map[string]string{"colour": "blue"} 141 ao.Annotations = map[string]string{"colour": "green"} 142 }, 143 expected: expected{ 144 count: 1, 145 rest: 1, 146 }, 147 }, 148 } 149 150 for k, v := range fixtures { 151 t.Run(k, func(t *testing.T) { 152 list := []*GameServer{ 153 {ObjectMeta: metav1.ObjectMeta{Name: "g1"}, Status: GameServerStatus{State: GameServerStateAllocated}}, 154 {ObjectMeta: metav1.ObjectMeta{Name: "g2"}, Status: GameServerStatus{State: GameServerStateAllocated}}, 155 {ObjectMeta: metav1.ObjectMeta{Name: "g3"}, Status: GameServerStatus{State: GameServerStateReady}}, 156 } 157 v.list(list) 158 ao := &AllocationOverflow{ 159 Labels: nil, 160 Annotations: nil, 161 } 162 v.ao(ao) 163 164 count, rest := ao.CountMatches(list) 165 assert.Equal(t, v.expected.count, count, "count") 166 assert.Equal(t, v.expected.rest, len(rest), "rest") 167 for _, gs := range rest { 168 assert.Equal(t, GameServerStateAllocated, gs.Status.State) 169 } 170 }) 171 } 172 } 173 174 func TestAllocationOverflowApply(t *testing.T) { 175 // check empty 176 gs := &GameServer{} 177 ao := AllocationOverflow{Labels: map[string]string{"colour": "green"}, Annotations: map[string]string{"colour": "blue", "map": "ice cream"}} 178 179 ao.Apply(gs) 180 181 require.Equal(t, ao.Annotations, gs.ObjectMeta.Annotations) 182 require.Equal(t, ao.Labels, gs.ObjectMeta.Labels) 183 184 // check append 185 ao = AllocationOverflow{Labels: map[string]string{"version": "1.0"}, Annotations: map[string]string{"version": "1.0"}} 186 ao.Apply(gs) 187 188 require.Equal(t, map[string]string{"colour": "green", "version": "1.0"}, gs.ObjectMeta.Labels) 189 require.Equal(t, map[string]string{"colour": "blue", "map": "ice cream", "version": "1.0"}, gs.ObjectMeta.Annotations) 190 191 // check overwrite 192 ao = AllocationOverflow{Labels: map[string]string{"colour": "red"}, Annotations: map[string]string{"colour": "green"}} 193 ao.Apply(gs) 194 require.Equal(t, map[string]string{"colour": "red", "version": "1.0"}, gs.ObjectMeta.Labels) 195 require.Equal(t, map[string]string{"colour": "green", "map": "ice cream", "version": "1.0"}, gs.ObjectMeta.Annotations) 196 }