github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/k8s_test.go (about) 1 // Copyright 2018-2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License. 2 3 package runner 4 5 import ( 6 "context" 7 "testing" 8 "time" 9 10 "github.com/leaf-ai/studio-go-runner/internal/types" 11 12 "github.com/karlmutch/k8s" 13 core "github.com/karlmutch/k8s/apis/core/v1" 14 meta "github.com/karlmutch/k8s/apis/meta/v1" 15 16 "github.com/go-stack/stack" 17 "github.com/jjeffery/kv" // MIT License 18 19 "github.com/rs/xid" 20 ) 21 22 // This file contains a number of tests that if Kubernetes is detected as the runtime 23 // the test is being hosted in will be activated and used. This is a unit test 24 // that exercises a listener specifically constructed for the purpose of catching 25 // changes to a configmap. 26 // 27 func TestK8sConfigUnit(t *testing.T) { 28 29 if !*useK8s { 30 t.Skip("no Kubernetes cluster present for testing") 31 } 32 33 if err := IsAliveK8s(); err != nil { 34 t.Fatal(err) 35 } 36 37 client, errGo := k8s.NewInClusterClient() 38 if errGo != nil { 39 t.Fatal(kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())) 40 } 41 42 name := "test-" + xid.New().String() 43 44 configMap := &core.ConfigMap{ 45 Metadata: &meta.ObjectMeta{ 46 Name: k8s.String(name), 47 Namespace: k8s.String(client.Namespace), 48 }, 49 Data: map[string]string{"STATE": types.K8sRunning.String()}, 50 } 51 52 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) 53 defer cancel() 54 55 // Establish a listener for the API under test 56 updateC := make(chan K8sStateUpdate, 1) 57 errC := make(chan kv.Error, 1) 58 59 go func() { 60 // Register a listener for the newly created map 61 if err := ListenK8s(ctx, client.Namespace, name, "", updateC, errC); err != nil { 62 errC <- err 63 } 64 }() 65 66 // Go and create a k8s config map that we can use for testing purposes 67 if errGo = client.Create(ctx, configMap); errGo != nil { 68 t.Fatal(kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())) 69 } 70 71 // Now see if we get the state change with "Running" 72 func() { 73 for { 74 select { 75 case <-ctx.Done(): 76 t.Fatal(kv.NewError("timeout waiting for k8s configmap to change state").With("stack", stack.Trace().TrimRuntime())) 77 case state := <-updateC: 78 if state.Name == name && state.State == types.K8sRunning { 79 return 80 } 81 } 82 } 83 }() 84 85 // Change the map and see if things get notified 86 configMap.Data["STATE"] = types.K8sDrainAndSuspend.String() 87 88 // Go and create a k8s config map that we can use for testing purposes 89 if errGo = client.Update(ctx, configMap); errGo != nil { 90 t.Fatal(kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())) 91 } 92 93 // Now see if we get the state change with "Running" 94 func() { 95 for { 96 select { 97 case <-ctx.Done(): 98 t.Fatal(kv.NewError("timeout waiting for k8s configmap to change state").With("stack", stack.Trace().TrimRuntime())) 99 case state := <-updateC: 100 if state.Name == name && state.State == types.K8sDrainAndSuspend { 101 return 102 } 103 } 104 } 105 }() 106 107 // Cleanup after ourselves 108 if errGo = client.Delete(ctx, configMap); errGo != nil { 109 t.Fatal(kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())) 110 } 111 }