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 }