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  }