Skip to content

Commit

Permalink
Adds GameServerAllocation e2e tests for Counters (#3400)
Browse files Browse the repository at this point in the history
* Adds basic GameServerAllocation e2e test for Counters
Updates Fleet and GameServer e2e tests to delete the fleet after test run Adds Counters to GameServerAllocation example

* Adds tests for gameserverallocation filterting, sorting, and counter actions

* Moving comments so linting passes

* Updates to GameServerAllocation CounterActions tests

* Changes UpdateCounter logic for GameServers Counters
Now truncates for request that take the Counter below zero or beyond Capacity instead of rejecting the increment or decrement request

* Adds fleet label selector to Counter tests
Fixes issue where e2e tests was returnting game servers from different fleets

* Updates Count to the equal to Capacity when Capacity is set to a values less than Count
  • Loading branch information
igooch authored Oct 11, 2023
1 parent f8d57c4 commit e0f859a
Show file tree
Hide file tree
Showing 8 changed files with 620 additions and 30 deletions.
8 changes: 8 additions & 0 deletions examples/gameserverallocation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ spec:
# label/annotation/player selectors to retrieve an already Allocated GameServer.
gameServerState: Ready
# [Stage:Alpha]
# [FeatureFlag:CountsAndLists]
# Counts and Lists provides the configuration for generic (player, room, session, etc.) tracking features.
# Commented out since Alpha, and disabled by default
# counters:
# players:
# minAvailable: 1
# maxAvailable: 10
# [Stage:Alpha]
# [FeatureFlag:PlayerAllocationFilter]
# Provides a filter on minimum and maximum values for player capacity when retrieving a GameServer
# through Allocation. Defaults to no limits.
Expand Down
21 changes: 13 additions & 8 deletions pkg/apis/agones/v1/gameserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,16 +879,16 @@ func (gs *GameServer) UpdateCount(name string, action string, amount int64) erro
cnt := counter.Count
if action == GameServerPriorityIncrement {
cnt += amount
// only check for Count > Capacity when incrementing
if cnt > counter.Capacity {
return errors.Errorf("unable to UpdateCount with Name %s, Action %s, Amount %d. Incremented Count %d is greater than available capacity %d", name, action, amount, cnt, counter.Capacity)
}
} else {
cnt -= amount
// only check for Count < 0 when decrementing
if cnt < 0 {
return errors.Errorf("unable to UpdateCount with Name %s, Action %s, Amount %d. Decremented Count %d is less than 0", name, action, amount, cnt)
}
}
// Truncate to Capacity if Count > Capacity
if cnt > counter.Capacity {
cnt = counter.Capacity
}
// Truncate to Zero if Count is negative
if cnt < 0 {
cnt = 0
}
counter.Count = cnt
gs.Status.Counters[name] = counter
Expand All @@ -904,6 +904,10 @@ func (gs *GameServer) UpdateCounterCapacity(name string, capacity int64) error {
}
if counter, ok := gs.Status.Counters[name]; ok {
counter.Capacity = capacity
// If Capacity is now less than Count, reset Count here to equal Capacity
if counter.Count > counter.Capacity {
counter.Count = counter.Capacity
}
gs.Status.Counters[name] = counter
return nil
}
Expand All @@ -930,6 +934,7 @@ func (gs *GameServer) AppendListValues(name string, values []string) error {
}
if list, ok := gs.Status.Lists[name]; ok {
mergedList := mergeRemoveDuplicates(list.Values, values)
// TODO: Truncate and apply up to cutoff
if len(mergedList) > int(list.Capacity) {
return errors.Errorf("unable to AppendListValues: Name %s, Values %s. Appended list length %d exceeds list capacity %d", name, values, len(mergedList), list.Capacity)
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/apis/agones/v1/gameserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ func TestGameServerUpdateCount(t *testing.T) {
amount: 1,
wantErr: true,
},
"amount less than zero no-op and error": {
"negative amount no-op and error": {
gs: GameServer{Status: GameServerStatus{
Counters: map[string]CounterStatus{
"foos": {
Expand Down Expand Up @@ -1695,7 +1695,7 @@ func TestGameServerUpdateCount(t *testing.T) {
},
wantErr: true,
},
"decrement beyond count no-op and error": {
"decrement beyond zero truncated": {
gs: GameServer{Status: GameServerStatus{
Counters: map[string]CounterStatus{
"baz": {
Expand All @@ -1706,12 +1706,12 @@ func TestGameServerUpdateCount(t *testing.T) {
action: "Decrement",
amount: 100,
want: CounterStatus{
Count: 99,
Count: 0,
Capacity: 100,
},
wantErr: true,
wantErr: false,
},
"increment beyond capacity no-op and error": {
"increment beyond capacity truncated": {
gs: GameServer{Status: GameServerStatus{
Counters: map[string]CounterStatus{
"splayers": {
Expand All @@ -1722,10 +1722,10 @@ func TestGameServerUpdateCount(t *testing.T) {
action: "Increment",
amount: 2,
want: CounterStatus{
Count: 99,
Count: 100,
Capacity: 100,
},
wantErr: true,
wantErr: false,
},
}

Expand Down
12 changes: 7 additions & 5 deletions pkg/apis/allocation/v1/gameserverallocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ func TestGameServerCounterActions(t *testing.T) {
want *agonesv1.GameServer
wantErr bool
}{
"update counter capacity": {
"update counter capacity and count is set to capacity": {
ca: CounterAction{
Capacity: int64Pointer(0),
},
Expand All @@ -850,12 +850,12 @@ func TestGameServerCounterActions(t *testing.T) {
want: &agonesv1.GameServer{Status: agonesv1.GameServerStatus{
Counters: map[string]agonesv1.CounterStatus{
"mages": {
Count: 1,
Count: 0,
Capacity: 0,
}}}},
wantErr: false,
},
"fail update counter capacity and count": {
"fail update counter capacity and truncate update count": {
ca: CounterAction{
Action: &INCREMENT,
Amount: int64Pointer(10),
Expand All @@ -871,7 +871,7 @@ func TestGameServerCounterActions(t *testing.T) {
want: &agonesv1.GameServer{Status: agonesv1.GameServerStatus{
Counters: map[string]agonesv1.CounterStatus{
"sages": {
Count: 99,
Count: 100,
Capacity: 100,
}}}},
wantErr: true,
Expand Down Expand Up @@ -912,7 +912,9 @@ func TestGameServerCounterActions(t *testing.T) {
want: &agonesv1.GameServer{Status: agonesv1.GameServerStatus{
Counters: map[string]agonesv1.CounterStatus{
"heroes": {
Count: 1,
// Note: The Capacity is set first, and Count updated to not be greater than Capacity.
// Then the Count is decremented. See: gameserver.go/UpdateCounterCapacity
Count: 0,
Capacity: 10,
}}}},
wantErr: false,
Expand Down
4 changes: 2 additions & 2 deletions pkg/gameserverallocations/allocator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func TestAllocatorApplyAllocationToGameServerCountsListsActions(t *testing.T) {
Capacity: 40,
}},
},
"CounterActions and ListActions only update list capacity": {
"CounterActions and ListActions truncate counter Count and update list capacity": {
features: fmt.Sprintf("%s=true", runtime.FeatureCountsAndLists),
gs: &gs2,
gsa: &allocationv1.GameServerAllocation{
Expand All @@ -392,7 +392,7 @@ func TestAllocatorApplyAllocationToGameServerCountsListsActions(t *testing.T) {
}}}},
wantCounters: map[string]agonesv1.CounterStatus{
"rooms": {
Count: 101,
Count: 1000,
Capacity: 1000,
}},
wantLists: map[string]agonesv1.ListStatus{
Expand Down
11 changes: 5 additions & 6 deletions test/e2e/fleet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1621,7 +1621,8 @@ func TestFleetAggregatedCounterStatus(t *testing.T) {
}

flt, err := client.Fleets(framework.Namespace).Create(ctx, flt.DeepCopy(), metav1.CreateOptions{})
assert.NoError(t, err)
require.NoError(t, err)
defer client.Fleets(framework.Namespace).Delete(ctx, flt.ObjectMeta.Name, metav1.DeleteOptions{}) // nolint:errcheck
framework.AssertFleetCondition(t, flt, e2e.FleetReadyCount(flt.Spec.Replicas))

// allocate two of them.
Expand Down Expand Up @@ -1650,21 +1651,19 @@ func TestFleetAggregatedCounterStatus(t *testing.T) {
allocatedCapacity := 0
allocatedCount := 0
// set random counts and capacities for each gameserver
for i := range list {
// Do this, otherwise scopelint complains about "using a reference for the variable on range scope"
gs := &list[i]
for _, gs := range list {
count := rand.IntnRange(2, 9)
capacity := rand.IntnRange(count, 100)

totalCapacity += capacity
msg := fmt.Sprintf("SET_COUNTER_CAPACITY games %d", capacity)
reply, err := framework.SendGameServerUDP(t, gs, msg)
reply, err := framework.SendGameServerUDP(t, &gs, msg)
require.NoError(t, err)
assert.Equal(t, "true", reply)

totalCount += count
msg = fmt.Sprintf("SET_COUNTER_COUNT games %d", count)
reply, err = framework.SendGameServerUDP(t, gs, msg)
reply, err = framework.SendGameServerUDP(t, &gs, msg)
require.NoError(t, err)
assert.Equal(t, "true", reply)

Expand Down
4 changes: 2 additions & 2 deletions test/e2e/gameserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,7 @@ func TestCountsAndLists(t *testing.T) {
t.SkipNow()
}
t.Parallel()

ctx := context.Background()
gs := framework.DefaultGameServer(framework.Namespace)

gs.Spec.Counters = make(map[string]agonesv1.CounterStatus)
Expand All @@ -1253,7 +1253,7 @@ func TestCountsAndLists(t *testing.T) {

gs, err := framework.CreateGameServerAndWaitUntilReady(t, framework.Namespace, gs)
require.NoError(t, err)

defer framework.AgonesClient.AgonesV1().GameServers(framework.Namespace).Delete(ctx, gs.ObjectMeta.Name, metav1.DeleteOptions{}) // nolint: errcheck
assert.Equal(t, agonesv1.GameServerStateReady, gs.Status.State)

testCases := map[string]struct {
Expand Down
Loading

0 comments on commit e0f859a

Please sign in to comment.