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  }