Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flaky: TestGameServerReserve #1565

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ KIND_PROFILE ?= agones
KIND_CONTAINER_NAME=$(KIND_PROFILE)-control-plane

# Game Server image to use while doing end-to-end tests
GS_TEST_IMAGE ?= gcr.io/agones-images/udp-server:0.20
GS_TEST_IMAGE ?= gcr.io/agones-images/udp-server:0.21

ALL_FEATURE_GATES ?= "PlayerTracking=true&ContainerPortAllocation=true"

Expand Down
2 changes: 1 addition & 1 deletion examples/simple-udp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ REPOSITORY = gcr.io/agones-images

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
project_path := $(dir $(mkfile_path))
server_tag = $(REPOSITORY)/udp-server:0.20
server_tag = $(REPOSITORY)/udp-server:0.21
root_path = $(realpath $(project_path)/../..)

# _____ _
Expand Down
18 changes: 14 additions & 4 deletions examples/simple-udp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"net"
"os"
Expand Down Expand Up @@ -144,7 +145,16 @@ func readWriteLoop(conn net.PacketConn, stop chan struct{}, s *sdk.SDK) {
allocate(s)

case "RESERVE":
reserve(s)
if len(parts) != 2 {
respond(conn, sender, "ERROR: Invalid RESERVE, should have 1 argument\n")
continue
}
if dur, err := time.ParseDuration(parts[1]); err != nil {
respond(conn, sender, fmt.Sprintf("ERROR: %s\n", err))
continue
} else {
reserve(s, dur)
}

case "WATCH":
watchGameServerEvents(s)
Expand Down Expand Up @@ -183,7 +193,7 @@ func readWriteLoop(conn net.PacketConn, stop chan struct{}, s *sdk.SDK) {
continue
case 2:
if cap, err := strconv.Atoi(parts[1]); err != nil {
respond(conn, sender, err.Error()+"\n")
respond(conn, sender, fmt.Sprintf("ERROR: %s\n", err))
continue
} else {
setPlayerCapacity(s, int64(cap))
Expand Down Expand Up @@ -245,8 +255,8 @@ func allocate(s *sdk.SDK) {
}

// reserve for 10 seconds
func reserve(s *sdk.SDK) {
if err := s.Reserve(10 * time.Second); err != nil {
func reserve(s *sdk.SDK, duration time.Duration) {
if err := s.Reserve(duration); err != nil {
log.Fatalf("could not reserve gameserver: %v", err)
}
}
Expand Down
121 changes: 65 additions & 56 deletions test/e2e/fleetautoscaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,72 +456,81 @@ func TestAutoscalerWebhook(t *testing.T) {
assert.True(t, found, "Expected error was not received")
}

// Instructions: https://agones.dev/site/docs/getting-started/create-webhook-fleetautoscaler/#chapter-2-configuring-https-fleetautoscaler-webhook-with-ca-bundle
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi @aLekSer , I updated the certs here, and added a comment on how to update and when expiry should happen.

// Expiration: Sept 30, 2021

var webhookKey = `
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----`

var caPem = `
-----BEGIN CERTIFICATE-----
MIICuDCCAaACCQCodpAMm9SwJjANBgkqhkiG9w0BAQsFADAeMQswCQYDVQQGEwJV
UzEPMA0GA1UECwwGQWdvbmVzMB4XDTE5MDEwNDExNTE0NFoXDTIxMTAyNDExNTE0
NFowHjELMAkGA1UEBhMCVVMxDzANBgNVBAsMBkFnb25lczCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBANCHyvwC96pd9SvAa1B/Eh6zG1x0KKWOiXm78Irx
+6yXwyaZl1Z5qQ1mFh98LHeYRd0YX3E2gzVylZoRU+kVDK4TsEsWKMPUiuZ41Ekt
po+alCzjP2ivsDfZ8a/vpr/wYgakXkVjPThjJROqNqHudN26UqAIbsNMZhRLd9QE
qKJ4O6aG5S1MSjdTFTqelrbf+CqsJhymdB3flFEEouq1Jj1KDhB4WZSSm/UJzB6G
4u3cpeBmcLUQGm6fQGobEA+yJZLhEWqpkwvUggB6dsXO1dSHexafiC9ETXlUtTag
5SbNy5hadVQUwgnwSBvv4vGKuQLWqgWsBrk0yZYxJNAoEyECAwEAATANBgkqhkiG
9w0BAQsFAAOCAQEAQ2H3ibQqf3A3DKiuxbHIDdnYzNVvgGaDZpiVr3nhrnyvle5X
GOaFm+27QF4VWoE36CLhXdzDZS8lJHcOXQnJ9O7cjOc91VhuKcfHx0KOaSZ0ySkT
vlKWk9A4Wh4a4AqYJW7gpTTtuPZrvw8Tk/n1ZXFNaWAx7yENNuWb88h4dAD5ZO4s
G9HrHvZnM3WC1AQp4CyZF5rCR6vEE9ddRiJor33zKe4hFBo7BENIYesseYqE+dp3
+H8MnK84Wx1TgSyVJy8yLmqiu2ui8ch1Hfxt8Zcpx7up6HFKFTlN9AyvTiv1a0X/
DU95y10v/hNW4Xzn02G4hkr8siGnHG+PJkOxAw==
MIIDazCCAlOgAwIBAgIUQWAeRC5nziGEM6YlkpDp4ZIY/jEwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA1MTgyMDM4MzRaFw0yMzAz
MDgyMDM4MzRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDV8IUgXP7sJxpSGZdpbK0fs+5JGO8kZDMM0AOGi5ne
HRPjmxIjOPyUQ3xRA1D/l+gvYflfdksfvSLfyz/yL/Sbsun+TatL25xfTcSP5d14
r99kZoARD9ZWyr1L+0DjnkzhzKIZuucuXiitQ4EX5IBIutwpmpPG4BIOLA8ADYct
IjeKNuh37FdDqCbgEsJxkU3oODE+JUve+ZS+ft6VR8IqvSYmigsvSV2tUyabQ/c3
+iXoTg+3yXmNnMeIYczW674YVHqMnMxbPXo2MI3uYX8b/3gqYPywWYVolF+TgPjO
LpUOOy+dfF2gQYNAlv+/PAjwYm7Q5wNwArUH/gFz8467AgMBAAGjUzBRMB0GA1Ud
DgQWBBS8VyQTvN8fDv7GRpN7j8OCFRx9hjAfBgNVHSMEGDAWgBS8VyQTvN8fDv7G
RpN7j8OCFRx9hjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCd
sS/UT6lU8AK4gvidULJhtz05fKP9vFZC2h/vc2zViREUHzQBHOKPHG7Hi76/e/sh
vTZEz7KSDygYbv+wWYtM1sLbt6OaEzNYHUqv6TCi5E6Pdisy+XBjwIqdB0RxxcrP
VQBmsXMBhM4qvhyANuw6O40GgTs2vCbxJkPwFjGwOcOIu5eQm9G/DqJ/Tm66u4YU
C4ll3vZPDgrJoZgou8ufa/+ekLZx0eJ/y/Wn3Wiqm/uEOewoVHCpf70cXNzJ2tT/
Tur3yJmj1KbPlTY5RTZaB/TZSGVBRhPRcu8nMJlp2nZVQtq2Z1NKqF3qFMDy9wyM
kUZOQ8SewyYktz5l+z8N
-----END CERTIFICATE-----`

var webhookCrt = `
-----BEGIN CERTIFICATE-----
MIIC6TCCAdECCQCLqOrlK/jyADANBgkqhkiG9w0BAQsFADAeMQswCQYDVQQGEwJV
UzEPMA0GA1UECwwGQWdvbmVzMB4XDTE5MDEwNDEzMzczOVoXDTIwMDUxODEzMzcz
OVowTzEPMA0GA1UECgwGQWdvbmVzMQ8wDQYDVQQLDAZBZ29uZXMxKzApBgNVBAMM
ImF1dG9zY2FsZXItdGxzLXNlcnZpY2UuZGVmYXVsdC5zdmMwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDZr6qCadvIqwod79rJBIXXv3rqCFeJyS8Umvwy
0ewBVV8M9O4rnTCYM3kiWQh/kgeoz/iKa3DYtcaAWUYiUizK0XwLLyBbieomNljR
dI2aackXcxw7rY+3KzT4nGxGqOSmQfPFXtq0B1VRao/PP3tQ+Fx/rapRbHD/PKMD
UidOP6QPExkrMKqF62AJbYgZKxvqHjO5v/czL9PK0/5oNjk/mEcSXULZk28u36XB
5oX1MBDc+LVcIimnQcgeDQK+IMw7G0o7ji/5m5jK7AEnTt/mfL+PMDf4EOZxeIfZ
2tvgSMzOkSTuhZ9imSiyj75gHsmUNkEA43SvJp62AIeS7DzDAgMBAAEwDQYJKoZI
hvcNAQELBQADggEBAJXHdBh7fw62+fhNsbNbq6HAzigDjf2LrvmuIWlQE6qQnGkx
TVgf+ZnSxvv5u+inOVNkPwbQtoMlWqSBgHMFj3O2mFVnWvO1nj0ajzSN6GAZszws
ZUy8FCRIJbbyqhNsjB/x0ZXM4cpotgtuIe55h7psZU13f7GAuxE8E5anc44Tdufw
ccYzVogM+wEna/pHPOo3ITR4c2k7zVgrr75LkFokUK0fsgFVJ4zTsMP+kQ/UTVmt
kpXqAOUeQx4ZfwM0FI5Yj3Ox5/AsdZ/hNzszjnPFyjKAp+AWjCiDu6VcgFj+WW0L
T1HcD9NOEIwRUO04DY86+P4d0TFY/SwxAiMnwBQ=
MIIDPjCCAiYCFEB3Nm7h3CeNWSnE/YtRSTAOqUw7MA0GCSqGSIb3DQEBCwUAMEUx
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjAwNTE4MjA0MDIzWhcNMjEwOTMwMjA0
MDIzWjByMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE
CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMSswKQYDVQQDDCJhdXRvc2NhbGVy
LXRscy1zZXJ2aWNlLmRlZmF1bHQuc3ZjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAxNq5ql070cs/foKC+Abj6ETgcIq8HJlYT85wbl8wE5sUqsGx5iIt
WZMwFJpEFyW97YNOizc8dYOAGCSLUeEY1aHg0vVSj3tV3jjVD82PtSGhTuE8HGN5
WdzEHavJHraRZB4wYMdjm4cFB6TJ3k8qBz5I8Rjp9CcLtpXTcvm0uWieScVyyOvh
O3XCYXbGo1HLj4wkxL+bYrci8XltTICXmQxT365+YmGNWvaWAUYKm2krmzdvObZB
owzXFohWIsCYpGMaVRbVoYHry/a1S/DXxQ32WuoyRqnFERrV8mrq6kxYQ0LcGvWa
y5n/p0/glyU1IEOi7gEuy9Wccaf1miegQwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB
AQC7S1ZBndfsMDK+58l2N1N/8Gm50XhqsG8u0dFf5bVhLgohOhUCMpj246z0lSLo
hWbdokSjrnUWyvM1Dv+ZWTQ+eS/4UamDyr6993Je1p9fVvHAGped97YAxlSAj5dL
CYr+9xqTPtOAVEwiddbEK2wId4XNuD2yPt0YHP22bATh7UyeyqxWTks6LamNJitZ
qrh1J4ZuqSJtnSXdwh3Zm9aoDxAd966dFXZgsoEg9/Au/C7PpyUx4JH5eTV9wBSy
6T4qnpkTnD01dUdLpwBlshAkVrdJRuKVE/152gQcOJ+tm+eXO0VCs6JWpUowZWAt
rteG9laTLeoJFDeCvc+pzWX+
-----END CERTIFICATE-----`

func TestTlsWebhook(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ func NewFromFlags() (*Framework, error) {
}

viper.SetDefault(kubeconfigFlag, filepath.Join(usr.HomeDir, "/.kube/config"))
viper.SetDefault(gsimageFlag, "gcr.io/agones-images/udp-server:0.20")
viper.SetDefault(gsimageFlag, "gcr.io/agones-images/udp-server:0.21")
viper.SetDefault(pullSecretFlag, "")
viper.SetDefault(stressTestLevelFlag, 0)
viper.SetDefault(perfOutputDirFlag, "")
viper.SetDefault(versionFlag, "")
viper.SetDefault(runtime.FeatureGateFlag, "")

kubeconfig := pflag.String(kubeconfigFlag, viper.GetString(kubeconfigFlag), "kube config path, e.g. $HOME/.kube/config")
gsimage := pflag.String(gsimageFlag, viper.GetString(gsimageFlag), "gameserver image to use for those tests, gcr.io/agones-images/udp-server:0.20")
gsimage := pflag.String(gsimageFlag, viper.GetString(gsimageFlag), "gameserver image to use for those tests, gcr.io/agones-images/udp-server:0.21")
pullSecret := pflag.String(pullSecretFlag, viper.GetString(pullSecretFlag), "optional secret to be used for pulling the gameserver and/or Agones SDK sidecar images")
stressTestLevel := pflag.Int(stressTestLevelFlag, viper.GetInt(stressTestLevelFlag), "enable stress test at given level 0-100")
perfOutputDir := pflag.String(perfOutputDirFlag, viper.GetString(perfOutputDirFlag), "write performance statistics to the specified directory")
Expand Down
83 changes: 29 additions & 54 deletions test/e2e/gameserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ import (
agonesv1 "agones.dev/agones/pkg/apis/agones/v1"
"agones.dev/agones/pkg/util/runtime"
e2eframework "agones.dev/agones/test/e2e/framework"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme"
)

const (
Expand Down Expand Up @@ -560,7 +558,15 @@ func TestGameServerWithPortsMappedToMultipleContainers(t *testing.T) {

func TestGameServerReserve(t *testing.T) {
t.Parallel()
logger := logrus.WithField("test", t.Name())

// We are deliberately not trying to test the transition between Reserved -> Ready.
//
// We have found that trying to catch the GameServer in the Reserved state can be flaky,
// as we can't control the speed in which the Kubernetes API is going to reply to request,
// and we could sometimes miss when the GameServer is in the Reserved State before it goes to Ready.
//
// Therefore we are going to test for concrete states that we don't need to catch while
// in a transitive state.

gs := framework.DefaultGameServer(defaultNs)
gs, err := framework.CreateGameServerAndWaitUntilReady(defaultNs, gs)
Expand All @@ -570,65 +576,34 @@ func TestGameServerReserve(t *testing.T) {
defer framework.AgonesClient.AgonesV1().GameServers(defaultNs).Delete(gs.ObjectMeta.Name, nil) // nolint: errcheck
assert.Equal(t, gs.Status.State, agonesv1.GameServerStateReady)

logger.Info("sending RESERVE command")
reply, err := e2eframework.SendGameServerUDP(gs, "RESERVE")
reply, err := e2eframework.SendGameServerUDP(gs, "RESERVE 0")
if !assert.NoError(t, err) {
assert.FailNow(t, "Could not message GameServer")
}
logger.Info("Received response")
assert.Equal(t, "ACK: RESERVE\n", reply)
assert.Equal(t, "ACK: RESERVE 0\n", reply)

// might as well Sleep, nothing else going to happen for at least 10 seconds. Let other things work.
logger.Info("Waiting for 10 seconds")
time.Sleep(10 * time.Second)

// Since polling the backing GameServer can sometimes pause for longer than 10 seconds,
// we are instead going to look at the event stream for the GameServer to determine that the requisite change to
// Reserved and back to Ready has taken place.
//
// There is a possibility that Events may get dropped if the Kubernetes cluster gets overwhelmed, or
// time out after a period. So if this test becomes flaky because due to these potential issues, we will
// need to find an alternate approach. At this stage through, it seems to be working consistently.
err = wait.PollImmediate(time.Second, 2*time.Minute, func() (bool, error) {
logger.Info("checking gameserver events")
list, err := framework.KubeClient.CoreV1().Events(defaultNs).Search(scheme.Scheme, gs)
if err != nil {
return false, err
}
gs, err = framework.WaitForGameServerState(gs, agonesv1.GameServerStateReserved, 3*time.Minute)
assert.NoError(t, err)

var readyEvent corev1.Event
var reserverdEvent corev1.Event
reply, err = e2eframework.SendGameServerUDP(gs, "ALLOCATE")
if !assert.NoError(t, err) {
assert.FailNow(t, "Could not message GameServer")
}
assert.Equal(t, "ACK: ALLOCATE\n", reply)

for _, e := range list.Items {
if e.Reason == string(agonesv1.GameServerStateReady) {
readyEvent = e
}
if e.Reason == string(agonesv1.GameServerStateReserved) {
reserverdEvent = e
}
}
if readyEvent.Reason == "" || reserverdEvent.Reason == "" {
return false, nil
}
// put it in a totally different state, just to reset things.
gs, err = framework.WaitForGameServerState(gs, agonesv1.GameServerStateAllocated, 3*time.Minute)
assert.NoError(t, err)

// debug once we have both a Ready and Reserved event
for _, e := range list.Items {
logger.WithField("first-time", e.FirstTimestamp).WithField("count", e.Count).
WithField("last-time", e.LastTimestamp).
WithField("name", e.Name).
WithField("reason", e.Reason).WithField("message", e.Message).Info("gs event details")
}
reply, err = e2eframework.SendGameServerUDP(gs, "RESERVE 5s")
if !assert.NoError(t, err) {
assert.FailNow(t, "Could not message GameServer")
}
assert.Equal(t, "ACK: RESERVE 5s\n", reply)

if readyEvent.Count != 2 {
return false, nil
}
diff := readyEvent.LastTimestamp.Sub(reserverdEvent.FirstTimestamp.Time).Seconds()
// allow for some variation
if diff >= 10 && diff <= 20 {
return true, nil
}
return true, errors.Errorf("difference of %v seconds was not between 10 and 20", diff)
})
// sleep, since we're going to wait for the Ready response.
time.Sleep(5 * time.Second)
_, err = framework.WaitForGameServerState(gs, agonesv1.GameServerStateReady, 3*time.Minute)
assert.NoError(t, err)
}

Expand Down