github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/integration_test/itest/context.go (about)

     1  package itest
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/datawire/dlib/dlog"
    12  	"github.com/telepresenceio/telepresence/v2/pkg/client"
    13  	"github.com/telepresenceio/telepresence/v2/pkg/dos"
    14  	"github.com/telepresenceio/telepresence/v2/pkg/log"
    15  	"github.com/telepresenceio/telepresence/v2/pkg/maps"
    16  )
    17  
    18  type profileKey struct{}
    19  
    20  type Profile string
    21  
    22  const (
    23  	DefaultProfile      Profile = "default"
    24  	GkeAutopilotProfile Profile = "gke-autopilot"
    25  )
    26  
    27  func withProfile(ctx context.Context) context.Context {
    28  	profile, ok := dos.LookupEnv(ctx, "TELEPRESENCE_TEST_PROFILE")
    29  	if !ok {
    30  		return context.WithValue(ctx, profileKey{}, DefaultProfile)
    31  	}
    32  	switch profile {
    33  	case string(DefaultProfile):
    34  	case string(GkeAutopilotProfile):
    35  	default:
    36  		panic("Invalid profile " + profile)
    37  	}
    38  	return context.WithValue(ctx, profileKey{}, Profile(profile))
    39  }
    40  
    41  func GetProfile(ctx context.Context) Profile {
    42  	if profile, ok := ctx.Value(profileKey{}).(Profile); ok {
    43  		return profile
    44  	}
    45  	return DefaultProfile
    46  }
    47  
    48  type tContextKey struct{}
    49  
    50  func TestContext(t *testing.T, ossRoot, moduleRoot string) context.Context {
    51  	ctx := context.Background()
    52  	ctx = dlog.WithLogger(ctx, log.NewTestLogger(t, dlog.LogLevelDebug))
    53  	ctx = client.WithEnv(ctx, &client.Env{})
    54  	ctx = SetOSSRoot(ctx, ossRoot)
    55  	ctx = SetModuleRoot(ctx, moduleRoot)
    56  	ctx = withProfile(ctx)
    57  	return WithT(ctx, t)
    58  }
    59  
    60  func WithT(ctx context.Context, t *testing.T) context.Context {
    61  	ctx, cancel := context.WithCancel(dlog.WithLogger(context.WithValue(ctx, tContextKey{}, t), log.NewTestLogger(t, dlog.LogLevelDebug)))
    62  	t.Cleanup(cancel)
    63  	return ctx
    64  }
    65  
    66  func getT(ctx context.Context) *testing.T {
    67  	if t, ok := ctx.Value(tContextKey{}).(*testing.T); ok {
    68  		return t
    69  	}
    70  	panic("No *testing.T in context")
    71  }
    72  
    73  type ossRootKey struct{}
    74  
    75  func GetOSSRoot(ctx context.Context) string {
    76  	if dir, ok := ctx.Value(ossRootKey{}).(string); ok {
    77  		return dir
    78  	}
    79  	ossRoot, err := os.Getwd()
    80  	if err != nil {
    81  		panic("failed to get current directory")
    82  	}
    83  	return ossRoot
    84  }
    85  
    86  // SetOSSRoot sets the OSS module root for the given context to dir.
    87  func SetOSSRoot(ctx context.Context, dir string) context.Context {
    88  	return context.WithValue(ctx, ossRootKey{}, dir)
    89  }
    90  
    91  // WithOSSRoot set the working directory for the Command function to the
    92  // OSS module root.
    93  func WithOSSRoot(ctx context.Context) context.Context {
    94  	return WithWorkingDir(ctx, GetOSSRoot(ctx))
    95  }
    96  
    97  type moduleRootKey struct{}
    98  
    99  func GetModuleRoot(ctx context.Context) string {
   100  	if dir, ok := ctx.Value(moduleRootKey{}).(string); ok {
   101  		return dir
   102  	}
   103  	moduleRoot, err := os.Getwd()
   104  	if err != nil {
   105  		panic("failed to get current directory")
   106  	}
   107  	return filepath.Dir(moduleRoot)
   108  }
   109  
   110  // SetModuleRoot sets the module root for the given context to dir.
   111  func SetModuleRoot(ctx context.Context, dir string) context.Context {
   112  	return context.WithValue(ctx, moduleRootKey{}, dir)
   113  }
   114  
   115  // WithModuleRoot set the working directory for the Command function to the
   116  // module root.
   117  func WithModuleRoot(ctx context.Context) context.Context {
   118  	return WithWorkingDir(ctx, GetModuleRoot(ctx))
   119  }
   120  
   121  type dirContextKey struct{}
   122  
   123  // WithWorkingDir determines the working directory for the Command function.
   124  func WithWorkingDir(ctx context.Context, dir string) context.Context {
   125  	return context.WithValue(ctx, dirContextKey{}, dir)
   126  }
   127  
   128  func GetWorkingDir(ctx context.Context) string {
   129  	if dir, ok := ctx.Value(dirContextKey{}).(string); ok {
   130  		return dir
   131  	}
   132  	dir, err := os.Getwd()
   133  	require.NoError(getT(ctx), err, "failed to get working directory")
   134  	return dir
   135  }
   136  
   137  type envContextKey struct{}
   138  
   139  type envCtxLookuper struct {
   140  	context.Context
   141  }
   142  
   143  func (e envCtxLookuper) Lookup(key string) (string, bool) {
   144  	return LookupEnv(e, key)
   145  }
   146  
   147  // WithEnv adds environment variables to be used by the Command function.
   148  func WithEnv(ctx context.Context, env dos.MapEnv) context.Context {
   149  	if prevEnv := getEnv(ctx); prevEnv != nil {
   150  		merged := make(dos.MapEnv, len(prevEnv)+len(env))
   151  		maps.Merge(merged, prevEnv)
   152  		maps.Merge(merged, env)
   153  		env = merged
   154  	}
   155  	ctx = context.WithValue(ctx, envContextKey{}, env)
   156  	evx, err := client.LoadEnvWith((&envCtxLookuper{ctx}).Lookup)
   157  	if err != nil {
   158  		getT(ctx).Fatal(err)
   159  	}
   160  	return client.WithEnv(ctx, evx)
   161  }
   162  
   163  type userContextkey struct{}
   164  
   165  func WithUser(ctx context.Context, clusterUser string) context.Context {
   166  	return context.WithValue(ctx, userContextkey{}, clusterUser)
   167  }
   168  
   169  func GetUser(ctx context.Context) string {
   170  	if user, ok := ctx.Value(userContextkey{}).(string); ok {
   171  		return user
   172  	}
   173  	return "default"
   174  }
   175  
   176  func LookupEnv(ctx context.Context, key string) (value string, ok bool) {
   177  	if value, ok = getEnv(ctx)[key]; !ok {
   178  		value, ok = GetGlobalHarness(ctx).GlobalEnv(ctx)[key]
   179  	}
   180  	return
   181  }
   182  
   183  func getEnv(ctx context.Context) dos.MapEnv {
   184  	if env, ok := ctx.Value(envContextKey{}).(dos.MapEnv); ok {
   185  		return env
   186  	}
   187  	return nil
   188  }
   189  
   190  type globalHarnessContextKey struct{}
   191  
   192  func withGlobalHarness(ctx context.Context, h Cluster) context.Context {
   193  	return context.WithValue(ctx, globalHarnessContextKey{}, h)
   194  }
   195  
   196  func GetGlobalHarness(ctx context.Context) Cluster {
   197  	if h, ok := ctx.Value(globalHarnessContextKey{}).(Cluster); ok {
   198  		return h
   199  	}
   200  	panic("No globalHarness in context")
   201  }