mirror of
https://github.com/YuzuZensai/Minikura.git
synced 2026-09-13 18:59:25 +00:00
226 lines
5.8 KiB
Go
226 lines
5.8 KiB
Go
package resources
|
|
|
|
import (
|
|
"testing"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
v1alpha1 "github.com/YuzuZensai/Minikura/operator/api/v1alpha1"
|
|
)
|
|
|
|
func testServer() *v1alpha1.MinecraftServer {
|
|
return &v1alpha1.MinecraftServer{
|
|
ObjectMeta: metav1.ObjectMeta{Name: "smp", Namespace: "minikura"},
|
|
Spec: v1alpha1.MinecraftServerSpec{
|
|
Type: v1alpha1.ServerStateful,
|
|
ListenPort: 25565,
|
|
ServiceType: v1alpha1.ExposureClusterIP,
|
|
JarType: "PAPER",
|
|
MinecraftVersion: "1.20.4",
|
|
StorageSize: "10Gi",
|
|
Resources: v1alpha1.Resources{MemoryLimitMB: 4096},
|
|
},
|
|
}
|
|
}
|
|
|
|
func envValue(env []corev1.EnvVar, name string) (string, bool) {
|
|
for i := len(env) - 1; i >= 0; i-- {
|
|
if env[i].Name == name {
|
|
return env[i].Value, true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func TestMinecraftEnvCarriesSpecConfig(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.Properties = v1alpha1.MinecraftProperties{
|
|
Difficulty: "HARD",
|
|
GameMode: "SURVIVAL",
|
|
MaxPlayers: 50,
|
|
MOTD: "welcome",
|
|
}
|
|
|
|
env := minecraftEnv(mc)
|
|
|
|
for _, want := range []struct{ key, value string }{
|
|
{"TYPE", "PAPER"},
|
|
{"VERSION", "1.20.4"},
|
|
{"DIFFICULTY", "HARD"},
|
|
{"MAX_PLAYERS", "50"},
|
|
{"MOTD", "welcome"},
|
|
} {
|
|
got, ok := envValue(env, want.key)
|
|
if !ok {
|
|
t.Errorf("%s missing from env", want.key)
|
|
continue
|
|
}
|
|
if got != want.value {
|
|
t.Errorf("%s = %q, want %q", want.key, got, want.value)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOptionalPropertiesOmitted(t *testing.T) {
|
|
env := minecraftEnv(testServer())
|
|
for _, key := range []string{"MOTD", "SEED", "LEVEL_TYPE"} {
|
|
if _, ok := envValue(env, key); ok {
|
|
t.Errorf("%s should be omitted when unset", key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestServiceNodePortPinned(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.ServiceType = v1alpha1.ExposureNodePort
|
|
mc.Spec.NodePort = 30123
|
|
|
|
svc := MinecraftService(mc)
|
|
if svc.Spec.Type != corev1.ServiceTypeNodePort {
|
|
t.Fatalf("type = %v, want NodePort", svc.Spec.Type)
|
|
}
|
|
if svc.Spec.Ports[0].NodePort != 30123 {
|
|
t.Errorf("nodePort = %d, want 30123", svc.Spec.Ports[0].NodePort)
|
|
}
|
|
}
|
|
|
|
func TestServiceNodePortUnsetLeavesAllocation(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.ServiceType = v1alpha1.ExposureNodePort
|
|
|
|
svc := MinecraftService(mc)
|
|
if svc.Spec.Ports[0].NodePort != 0 {
|
|
t.Errorf("nodePort = %d, want 0 so the API server allocates one", svc.Spec.Ports[0].NodePort)
|
|
}
|
|
}
|
|
|
|
func TestSelectorExcludesMutableLabels(t *testing.T) {
|
|
mc := testServer()
|
|
sts, err := MinecraftStatefulSet(mc)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
selector := sts.Spec.Selector.MatchLabels
|
|
if _, ok := selector[v1alpha1.LabelServerType]; ok {
|
|
t.Error("selector must not include the mutable server-type label")
|
|
}
|
|
if selector["app"] != ServerName(mc.Name) {
|
|
t.Errorf("selector app = %q, want %q", selector["app"], ServerName(mc.Name))
|
|
}
|
|
|
|
for k, v := range selector {
|
|
if sts.Spec.Template.Labels[k] != v {
|
|
t.Errorf("pod template missing selector label %s=%s", k, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStatefulSetStorage(t *testing.T) {
|
|
sts, err := MinecraftStatefulSet(testServer())
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
claims := sts.Spec.VolumeClaimTemplates
|
|
if len(claims) != 1 {
|
|
t.Fatalf("volumeClaimTemplates = %d, want 1", len(claims))
|
|
}
|
|
if got := claims[0].Spec.Resources.Requests.Storage().String(); got != "10Gi" {
|
|
t.Errorf("storage = %s, want 10Gi", got)
|
|
}
|
|
}
|
|
|
|
func TestStatefulSetRejectsBadStorageSize(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.StorageSize = "ten-gigs"
|
|
|
|
if _, err := MinecraftStatefulSet(mc); err == nil {
|
|
t.Error("expected an error for an unparseable storageSize")
|
|
}
|
|
}
|
|
|
|
func TestStatelessHasNoDataVolume(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.Type = v1alpha1.ServerStateless
|
|
|
|
dep := MinecraftDeployment(mc)
|
|
for _, m := range dep.Spec.Template.Spec.Containers[0].VolumeMounts {
|
|
if m.Name == "data" {
|
|
t.Error("stateless server should not mount a data volume")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMinecraftConfigMap(t *testing.T) {
|
|
cm := MinecraftConfigMap(testServer())
|
|
if cm.Name != "minecraft-smp-config" {
|
|
t.Errorf("name = %q", cm.Name)
|
|
}
|
|
if cm.Data["jar-type"] != "PAPER" || cm.Data["minecraft-version"] != "1.20.4" {
|
|
t.Errorf("data = %v", cm.Data)
|
|
}
|
|
}
|
|
|
|
func TestMinecraftAPIKeyAndOptionalEnv(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.APIKeySecretRef = "minikura-key"
|
|
mc.Spec.Properties.LevelSeed = "abc"
|
|
mc.Spec.Properties.LevelType = "flat"
|
|
falseVal := false
|
|
mc.Spec.Properties.OnlineMode = &falseVal
|
|
|
|
env := minecraftEnv(mc)
|
|
got, ok := envValue(env, "SEED")
|
|
if !ok || got != "abc" {
|
|
t.Errorf("SEED = %q, %v", got, ok)
|
|
}
|
|
got, ok = envValue(env, "LEVEL_TYPE")
|
|
if !ok || got != "flat" {
|
|
t.Errorf("LEVEL_TYPE = %q, %v", got, ok)
|
|
}
|
|
got, ok = envValue(env, "ONLINE_MODE")
|
|
if !ok || got != "false" {
|
|
t.Errorf("ONLINE_MODE = %q, %v", got, ok)
|
|
}
|
|
|
|
found := false
|
|
for _, e := range env {
|
|
if e.Name == "MINIKURA_API_KEY" {
|
|
found = true
|
|
if e.ValueFrom == nil || e.ValueFrom.SecretKeyRef == nil {
|
|
t.Fatal("expected secret ref for API key")
|
|
}
|
|
if e.ValueFrom.SecretKeyRef.Name != "minikura-key" || e.ValueFrom.SecretKeyRef.Key != "api-key" {
|
|
t.Errorf("secret ref = %+v", e.ValueFrom.SecretKeyRef)
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("MINIKURA_API_KEY missing")
|
|
}
|
|
}
|
|
|
|
func TestStatefulSetDefaultStorage(t *testing.T) {
|
|
mc := testServer()
|
|
mc.Spec.StorageSize = ""
|
|
sts, err := MinecraftStatefulSet(mc)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if got := sts.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests.Storage().String(); got != "1Gi" {
|
|
t.Errorf("storage = %s, want 1Gi", got)
|
|
}
|
|
}
|
|
|
|
func TestMinecraftServiceDefaultsToClusterIP(t *testing.T) {
|
|
svc := MinecraftService(testServer())
|
|
if svc.Spec.Type != corev1.ServiceTypeClusterIP {
|
|
t.Errorf("type = %v", svc.Spec.Type)
|
|
}
|
|
if svc.Spec.Ports[0].Port != 25565 {
|
|
t.Errorf("port = %d", svc.Spec.Ports[0].Port)
|
|
}
|
|
}
|