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