github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/puk_upkeep_background_test.go (about)

     1  // Copyright 2017 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package engine
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/keybase/client/go/libkb"
    11  	"github.com/keybase/client/go/protocol/keybase1"
    12  	"github.com/keybase/clockwork"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestPerUserKeyUpkeepBackgroundUnnecessary(t *testing.T) {
    17  	tc := SetupEngineTest(t, "pukup")
    18  	defer tc.Cleanup()
    19  	fakeClock := clockwork.NewFakeClockAt(time.Now())
    20  	tc.G.SetClock(fakeClock)
    21  
    22  	fu := CreateAndSignupFakeUser(tc, "pukup")
    23  
    24  	t.Logf("user has a per-user-key")
    25  	startingSeqno := getUserSeqno(&tc, fu.UID())
    26  
    27  	advance := func(d time.Duration) {
    28  		tc.G.Log.Debug("+ fakeClock#advance(%s) start: %s", d, fakeClock.Now())
    29  		fakeClock.Advance(d)
    30  		tc.G.Log.Debug("- fakeClock#adance(%s) end: %s", d, fakeClock.Now())
    31  	}
    32  
    33  	metaCh := make(chan string, 100)
    34  	roundResCh := make(chan error, 100)
    35  	arg := &PerUserKeyUpgradeBackgroundArgs{
    36  		testingMetaCh:     metaCh,
    37  		testingRoundResCh: roundResCh,
    38  	}
    39  	eng := NewPerUserKeyUpgradeBackground(tc.G, arg)
    40  	eng.task.args.Settings.StartStagger = 0 // Disable stagger for deterministic testing
    41  	m := NewMetaContextForTestWithLogUI(tc)
    42  	err := RunEngine2(m, eng)
    43  	require.NoError(t, err)
    44  
    45  	expectMeta(t, metaCh, "loop-start")
    46  	advance(PerUserKeyUpgradeBackgroundSettings.Start + time.Second)
    47  	expectMeta(t, metaCh, "woke-start")
    48  
    49  	// first run doesn't do anything
    50  	select {
    51  	case x := <-roundResCh:
    52  		require.Equal(t, nil, x, "round result")
    53  	case <-time.After(5 * time.Second):
    54  		require.FailNow(t, "channel timed out")
    55  	}
    56  	expectMeta(t, metaCh, "loop-round-complete")
    57  
    58  	checkPerUserKeyCount(&tc, 1)
    59  	checkUserSeqno(&tc, fu.UID(), startingSeqno)
    60  
    61  	eng.Shutdown()
    62  	expectMeta(t, metaCh, "loop-exit")
    63  	expectMeta(t, metaCh, "")
    64  }
    65  
    66  // The useful case of rolling the key after a deprovision.
    67  func TestPerUserKeyUpkeepBackgroundWork(t *testing.T) {
    68  	tc := SetupEngineTest(t, "pukup")
    69  	defer tc.Cleanup()
    70  	fakeClock := clockwork.NewFakeClockAt(time.Now())
    71  	tc.G.SetClock(fakeClock)
    72  
    73  	fu := CreateAndSignupFakeUser(tc, "pukup")
    74  
    75  	t.Logf("provision second device")
    76  	tcY, cleanup := provisionNewDeviceKex(&tc, fu)
    77  	defer cleanup()
    78  
    79  	t.Logf("second device deprovisions itself")
    80  	{
    81  		eng := NewDeprovisionEngine(tcY.G, fu.Username, true /* doRevoke */, libkb.LogoutOptions{})
    82  		uis := libkb.UIs{
    83  			LogUI:    tcY.G.UI.GetLogUI(),
    84  			SecretUI: fu.NewSecretUI(),
    85  		}
    86  		m := libkb.NewMetaContextTODO(tcY.G).WithUIs(uis)
    87  		err := RunEngine2(m, eng)
    88  		require.NoError(t, err, "deprovision")
    89  	}
    90  
    91  	preUpkeepSeqno := getUserSeqno(&tc, fu.UID())
    92  
    93  	t.Logf("load self to bust the upak cache")
    94  	// Upkeep hits the cache. It's ok that upkeep doesn't notice a deprovision
    95  	// right away. Bust the upak cache as a way of simulating time passing
    96  	// for the sake of this test.
    97  	loadArg := libkb.NewLoadUserArg(tc.G).
    98  		WithUID(fu.UID()).
    99  		WithSelf(true).
   100  		WithForcePoll(true). // <-
   101  		WithPublicKeyOptional()
   102  	_, _, err := tc.G.GetUPAKLoader().LoadV2(loadArg)
   103  	require.NoError(t, err)
   104  
   105  	advance := func(d time.Duration) {
   106  		tc.G.Log.Debug("+ fakeClock#advance(%s) start: %s", d, fakeClock.Now())
   107  		fakeClock.Advance(d)
   108  		tc.G.Log.Debug("- fakeClock#adance(%s) end: %s", d, fakeClock.Now())
   109  	}
   110  
   111  	metaCh := make(chan string, 100)
   112  	roundResCh := make(chan error, 100)
   113  	arg := &PerUserKeyUpkeepBackgroundArgs{
   114  		testingMetaCh:     metaCh,
   115  		testingRoundResCh: roundResCh,
   116  	}
   117  	eng := NewPerUserKeyUpkeepBackground(tc.G, arg)
   118  	eng.task.args.Settings.StartStagger = 0 // Disable stagger for deterministic testing
   119  	m := NewMetaContextForTestWithLogUI(tc)
   120  	err = RunEngine2(m, eng)
   121  	require.NoError(t, err)
   122  
   123  	expectMeta(t, metaCh, "loop-start")
   124  	advance(PerUserKeyUpkeepBackgroundSettings.Start + time.Second)
   125  	expectMeta(t, metaCh, "woke-start")
   126  
   127  	select {
   128  	case x := <-roundResCh:
   129  		require.Equal(t, nil, x, "round result")
   130  	case <-time.After(5 * time.Second):
   131  		require.FailNow(t, "channel timed out")
   132  	}
   133  	expectMeta(t, metaCh, "loop-round-complete")
   134  
   135  	checkUserSeqno(&tc, fu.UID(), preUpkeepSeqno+keybase1.Seqno(1))
   136  
   137  	// second run that doesn't do anything
   138  	advance(PerUserKeyUpkeepBackgroundSettings.Interval + time.Second)
   139  	expectMeta(t, metaCh, "woke-interval")
   140  	advance(PerUserKeyUpkeepBackgroundSettings.WakeUp + time.Second)
   141  	expectMeta(t, metaCh, "woke-wakeup") // this line has flaked before (CORE-5410)
   142  	select {
   143  	case x := <-roundResCh:
   144  		require.Equal(t, nil, x, "round result")
   145  	case <-time.After(5 * time.Second):
   146  		require.FailNow(t, "channel timed out")
   147  	}
   148  	expectMeta(t, metaCh, "loop-round-complete")
   149  	checkUserSeqno(&tc, fu.UID(), preUpkeepSeqno+keybase1.Seqno(1))
   150  
   151  	checkPerUserKeyCount(&tc, 3)
   152  	checkPerUserKeyCountLocal(&tc, 3)
   153  
   154  	eng.Shutdown()
   155  	expectMeta(t, metaCh, "loop-exit")
   156  	expectMeta(t, metaCh, "")
   157  }