github.com/argoproj/argo-cd/v2@v2.10.5/test/testutil.go (about) 1 package test 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "net" 9 "os" 10 "testing" 11 "time" 12 13 log "github.com/sirupsen/logrus" 14 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 15 "k8s.io/client-go/tools/cache" 16 "sigs.k8s.io/yaml" 17 ) 18 19 // StartInformer is a helper to start an informer, wait for its cache to sync and return a cancel func 20 func StartInformer(informer cache.SharedIndexInformer) context.CancelFunc { 21 ctx, cancel := context.WithCancel(context.Background()) 22 go informer.Run(ctx.Done()) 23 if !cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) { 24 log.Fatal("Timed out waiting for informer cache to sync") 25 } 26 return cancel 27 } 28 29 // GetFreePort finds an available free port on the OS 30 func GetFreePort() (int, error) { 31 ln, err := net.Listen("tcp", "[::]:0") 32 if err != nil { 33 return 0, err 34 } 35 return ln.Addr().(*net.TCPAddr).Port, ln.Close() 36 } 37 38 // WaitForPortListen waits until the given address is listening on the port 39 func WaitForPortListen(addr string, timeout time.Duration) error { 40 ticker := time.NewTicker(100 * time.Millisecond) 41 defer ticker.Stop() 42 timer := time.NewTimer(timeout) 43 if timeout == 0 { 44 timer.Stop() 45 } else { 46 defer timer.Stop() 47 } 48 for { 49 select { 50 case <-ticker.C: 51 if portIsOpen(addr) { 52 return nil 53 } 54 case <-timer.C: 55 return fmt.Errorf("timeout after %s", timeout.String()) 56 } 57 } 58 } 59 60 func portIsOpen(addr string) bool { 61 conn, err := net.Dial("tcp", addr) 62 if err != nil { 63 return false 64 } 65 _ = conn.Close() 66 return true 67 } 68 69 // Read the contents of a file and returns it as string. Panics on error. 70 func MustLoadFileToString(path string) string { 71 o, err := os.ReadFile(path) 72 if err != nil { 73 panic(err.Error()) 74 } 75 return string(o) 76 } 77 78 func YamlToUnstructured(yamlStr string) *unstructured.Unstructured { 79 obj := make(map[string]interface{}) 80 err := yaml.Unmarshal([]byte(yamlStr), &obj) 81 if err != nil { 82 panic(err) 83 } 84 return &unstructured.Unstructured{Object: obj} 85 } 86 87 // ToMap converts any object to a map[string]interface{} 88 func ToMap(obj interface{}) map[string]interface{} { 89 data, err := json.Marshal(obj) 90 if err != nil { 91 panic(err) 92 } 93 var res map[string]interface{} 94 err = json.Unmarshal(data, &res) 95 if err != nil { 96 panic(err) 97 } 98 return res 99 } 100 101 // GetTestDir will return the full directory path of the 102 // calling test file. 103 func GetTestDir(t *testing.T) string { 104 t.Helper() 105 cwd, err := os.Getwd() 106 if err != nil { 107 t.Fatal(err) 108 } 109 return cwd 110 } 111 112 // CaptureLogEntries captures log entries generated by the logger and return it as string 113 func CaptureLogEntries(run func()) string { 114 f := log.StandardLogger().Formatter 115 log.SetFormatter(&log.TextFormatter{DisableColors: true}) 116 defer log.SetFormatter(f) 117 output := bytes.NewBuffer(nil) 118 log.SetOutput(output) 119 log.SetLevel(log.DebugLevel) 120 defer log.SetOutput(os.Stdout) 121 122 run() 123 124 return output.String() 125 }