github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/systests/common_test.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package systests 5 6 import ( 7 "fmt" 8 "os" 9 "path/filepath" 10 "testing" 11 "time" 12 13 "net/http" 14 _ "net/http/pprof" 15 16 "github.com/keybase/client/go/externalstest" 17 "github.com/keybase/client/go/libkb" 18 keybase1 "github.com/keybase/client/go/protocol/keybase1" 19 "github.com/keybase/clockwork" 20 "github.com/stretchr/testify/require" 21 context "golang.org/x/net/context" 22 ) 23 24 func TestMain(m *testing.M) { 25 if os.Getenv("KEYBASE_SYSTESTS_DEBUG") != "" { 26 go func() { 27 _ = http.ListenAndServe("localhost:8080", nil) 28 }() 29 } 30 os.Exit(m.Run()) 31 } 32 33 func setupTest(t libkb.TestingTB, nm string) *libkb.TestContext { 34 tc := externalstest.SetupTest(t, nm, 2) 35 installInsecureTriplesec(tc.G) 36 tc.SetRuntimeDir(filepath.Join(tc.Tp.Home, "run")) 37 if err := tc.G.ConfigureSocketInfo(); err != nil { 38 t.Fatal(err) 39 } 40 return &tc 41 } 42 43 func cloneContext(prev *libkb.TestContext) *libkb.TestContext { 44 ret := prev.Clone() 45 ret.SetRuntimeDir(filepath.Join(ret.Tp.Home, "run")) 46 if err := ret.G.ConfigureSocketInfo(); err != nil { 47 ret.T.Fatal(err) 48 } 49 return &ret 50 } 51 52 type baseNullUI struct { 53 g *libkb.GlobalContext 54 } 55 56 type dumbUI struct{} 57 58 func (d dumbUI) Printf(format string, args ...interface{}) (int, error) { 59 return 0, nil 60 } 61 func (d dumbUI) PrintfStderr(format string, args ...interface{}) (int, error) { 62 return 0, nil 63 } 64 func (d dumbUI) PrintfUnescaped(format string, args ...interface{}) (int, error) { 65 return 0, nil 66 } 67 68 func (n *baseNullUI) GetDumbOutputUI() libkb.DumbOutputUI { return dumbUI{} } 69 func (n *baseNullUI) GetIdentifyUI() libkb.IdentifyUI { return nil } 70 func (n *baseNullUI) GetIdentifySelfUI() libkb.IdentifyUI { return nil } 71 func (n *baseNullUI) GetIdentifyTrackUI() libkb.IdentifyUI { return nil } 72 func (n *baseNullUI) GetLoginUI() libkb.LoginUI { return nil } 73 func (n *baseNullUI) GetTerminalUI() libkb.TerminalUI { return nil } 74 func (n *baseNullUI) GetSecretUI() libkb.SecretUI { return nil } 75 func (n *baseNullUI) GetProveUI() libkb.ProveUI { return nil } 76 func (n *baseNullUI) GetGPGUI() libkb.GPGUI { return nil } 77 func (n *baseNullUI) GetLogUI() libkb.LogUI { return n.g.Log } 78 func (n *baseNullUI) GetPgpUI() libkb.PgpUI { return nil } 79 func (n *baseNullUI) GetProvisionUI(libkb.KexRole) libkb.ProvisionUI { return nil } 80 81 func (n *baseNullUI) Configure() error { return nil } 82 func (n *baseNullUI) Shutdown() error { return nil } 83 84 type genericUI struct { 85 g *libkb.GlobalContext 86 DumbOutputUI libkb.DumbOutputUI 87 IdentifyUI libkb.IdentifyUI 88 IdentifySelfUI libkb.IdentifyUI 89 IdentifyTrackUI libkb.IdentifyUI 90 LoginUI libkb.LoginUI 91 TerminalUI libkb.TerminalUI 92 SecretUI libkb.SecretUI 93 ProveUI libkb.ProveUI 94 GPGUI libkb.GPGUI 95 LogUI libkb.LogUI 96 PgpUI libkb.PgpUI 97 ProvisionUI libkb.ProvisionUI 98 } 99 100 func (n *genericUI) GetDumbOutputUI() libkb.DumbOutputUI { 101 if n.DumbOutputUI == nil { 102 return dumbUI{} 103 } 104 return n.DumbOutputUI 105 } 106 func (n *genericUI) GetIdentifyUI() libkb.IdentifyUI { return n.IdentifyUI } 107 func (n *genericUI) GetIdentifySelfUI() libkb.IdentifyUI { return n.IdentifyUI } 108 func (n *genericUI) GetIdentifyTrackUI() libkb.IdentifyUI { return n.IdentifyUI } 109 func (n *genericUI) GetLoginUI() libkb.LoginUI { return n.LoginUI } 110 func (n *genericUI) GetTerminalUI() libkb.TerminalUI { return n.TerminalUI } 111 func (n *genericUI) GetSecretUI() libkb.SecretUI { return n.SecretUI } 112 func (n *genericUI) GetProveUI() libkb.ProveUI { return n.ProveUI } 113 func (n *genericUI) GetGPGUI() libkb.GPGUI { return n.GPGUI } 114 func (n *genericUI) GetLogUI() libkb.LogUI { 115 if n.LogUI == nil { 116 return n.g.Log 117 } 118 return n.LogUI 119 } 120 func (n *genericUI) GetPgpUI() libkb.PgpUI { return n.PgpUI } 121 func (n *genericUI) GetProvisionUI(libkb.KexRole) libkb.ProvisionUI { return n.ProvisionUI } 122 123 func (n *genericUI) Configure() error { return nil } 124 func (n *genericUI) Shutdown() error { return nil } 125 126 type nullProvisionUI struct { 127 deviceName string 128 } 129 130 func (n nullProvisionUI) ChooseProvisioningMethod(context.Context, keybase1.ChooseProvisioningMethodArg) (ret keybase1.ProvisionMethod, err error) { 131 return ret, nil 132 } 133 func (n nullProvisionUI) ChooseGPGMethod(context.Context, keybase1.ChooseGPGMethodArg) (ret keybase1.GPGMethod, err error) { 134 return ret, nil 135 } 136 func (n nullProvisionUI) SwitchToGPGSignOK(context.Context, keybase1.SwitchToGPGSignOKArg) (bool, error) { 137 return false, nil 138 } 139 func (n nullProvisionUI) ChooseDevice(context.Context, keybase1.ChooseDeviceArg) (ret keybase1.DeviceID, err error) { 140 return ret, nil 141 } 142 func (n nullProvisionUI) ChooseDeviceType(context.Context, keybase1.ChooseDeviceTypeArg) (ret keybase1.DeviceType, err error) { 143 return ret, nil 144 } 145 func (n nullProvisionUI) DisplayAndPromptSecret(context.Context, keybase1.DisplayAndPromptSecretArg) (ret keybase1.SecretResponse, err error) { 146 return ret, nil 147 } 148 func (n nullProvisionUI) DisplaySecretExchanged(context.Context, int) error { return nil } 149 func (n nullProvisionUI) PromptNewDeviceName(context.Context, keybase1.PromptNewDeviceNameArg) (string, error) { 150 return n.deviceName, nil 151 } 152 func (n nullProvisionUI) ProvisioneeSuccess(context.Context, keybase1.ProvisioneeSuccessArg) error { 153 return nil 154 } 155 func (n nullProvisionUI) ProvisionerSuccess(context.Context, keybase1.ProvisionerSuccessArg) error { 156 return nil 157 } 158 159 func getActiveDevicesAndKeys(tc *libkb.TestContext, username string) ([]*libkb.Device, []libkb.GenericKey) { 160 arg := libkb.NewLoadUserByNameArg(tc.G, username).WithPublicKeyOptional() 161 user, err := libkb.LoadUser(arg) 162 if err != nil { 163 tc.T.Fatal(err) 164 } 165 sibkeys := user.GetComputedKeyFamily().GetAllActiveSibkeys() 166 subkeys := user.GetComputedKeyFamily().GetAllActiveSubkeys() 167 168 activeDevices := []*libkb.Device{} 169 for _, device := range user.GetComputedKeyFamily().GetAllDevices() { 170 if device.Status != nil && *device.Status == libkb.DeviceStatusActive { 171 activeDevices = append(activeDevices, device.Device) 172 } 173 } 174 return activeDevices, append(sibkeys, subkeys...) 175 } 176 177 func pollFor(t *testing.T, label string, totalTime time.Duration, g *libkb.GlobalContext, poller func(i int) bool) { 178 t.Logf("pollFor '%s'", label) 179 totalTime *= libkb.CITimeMultiplier(g) 180 clock := clockwork.NewRealClock() 181 start := clock.Now() 182 endCh := clock.After(totalTime) 183 wait := 10 * time.Millisecond 184 var i int 185 for { 186 satisfied := poller(i) 187 since := clock.Since(start) 188 t.Logf("pollFor '%s' round:%v -> %v running:%v", label, i, satisfied, since) 189 if satisfied { 190 t.Logf("pollFor '%s' succeeded after %v attempts over %v", label, i, since) 191 return 192 } 193 if since > totalTime { 194 // Game over 195 msg := fmt.Sprintf("pollFor '%s' timed out after %v attempts over %v", label, i, since) 196 t.Logf(msg) 197 require.Fail(t, msg) 198 require.FailNow(t, msg) 199 return 200 } 201 t.Logf("pollFor '%s' wait:%v", label, wait) 202 select { 203 case <-endCh: 204 case <-clock.After(wait): 205 } 206 wait *= 2 207 i++ 208 } 209 }