github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/soft_snooze_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 engine 5 6 import ( 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/keybase/client/go/libkb" 12 keybase1 "github.com/keybase/client/go/protocol/keybase1" 13 "github.com/keybase/clockwork" 14 ) 15 16 type flakeyRooterAPI struct { 17 orig libkb.ExternalAPI 18 flakeOut bool 19 hardFail bool 20 G *libkb.GlobalContext 21 } 22 23 func (e *flakeyRooterAPI) GetText(m libkb.MetaContext, arg libkb.APIArg) (*libkb.ExternalTextRes, error) { 24 e.G.Log.Debug("| flakeyRooterAPI.GetText, hard = %v, flake = %v", e.hardFail, e.flakeOut) 25 return e.orig.GetText(m, arg) 26 } 27 28 func (e *flakeyRooterAPI) Get(m libkb.MetaContext, arg libkb.APIArg) (res *libkb.ExternalAPIRes, err error) { 29 e.G.Log.Debug("| flakeyRooterAPI.Get, hard = %v, flake = %v", e.hardFail, e.flakeOut) 30 // Show an error if we're in flakey mode 31 if strings.Contains(arg.Endpoint, "rooter") { 32 if e.hardFail { 33 return &libkb.ExternalAPIRes{HTTPStatus: 404}, &libkb.APIError{Msg: "NotFound", Code: 404} 34 } 35 if e.flakeOut { 36 return &libkb.ExternalAPIRes{HTTPStatus: 429}, &libkb.APIError{Msg: "Ratelimited", Code: 429} 37 } 38 } 39 40 return e.orig.Get(m, arg) 41 } 42 43 func (e *flakeyRooterAPI) GetHTML(m libkb.MetaContext, arg libkb.APIArg) (res *libkb.ExternalHTMLRes, err error) { 44 e.G.Log.Debug("| flakeyRooterAPI.GetHTML, hard = %v, flake = %v", e.hardFail, e.flakeOut) 45 return e.orig.GetHTML(m, arg) 46 } 47 48 func (e *flakeyRooterAPI) Post(m libkb.MetaContext, arg libkb.APIArg) (res *libkb.ExternalAPIRes, err error) { 49 return e.orig.Post(m, arg) 50 } 51 52 func (e *flakeyRooterAPI) PostHTML(m libkb.MetaContext, arg libkb.APIArg) (res *libkb.ExternalHTMLRes, err error) { 53 return e.orig.PostHTML(m, arg) 54 } 55 56 func TestSoftSnooze(t *testing.T) { 57 tc := SetupEngineTest(t, "track") 58 defer tc.Cleanup() 59 sigVersion := libkb.GetDefaultSigVersion(tc.G) 60 61 fakeClock := clockwork.NewFakeClockAt(time.Now()) 62 tc.G.SetClock(fakeClock) 63 fu := CreateAndSignupFakeUser(tc, "track") 64 65 flakeyAPI := flakeyRooterAPI{orig: tc.G.XAPI, flakeOut: false, G: tc.G} 66 tc.G.XAPI = &flakeyAPI 67 68 idUI := &FakeIdentifyUI{} 69 username := "t_tracy" 70 arg := &keybase1.Identify2Arg{ 71 UserAssertion: username, 72 NeedProofSet: true, 73 IdentifyBehavior: keybase1.TLFIdentifyBehavior_CLI, 74 } 75 uis := libkb.UIs{ 76 LogUI: tc.G.UI.GetLogUI(), 77 IdentifyUI: idUI, 78 SecretUI: fu.NewSecretUI(), 79 } 80 // Identify tracy; all proofs should work 81 eng := NewResolveThenIdentify2(tc.G, arg) 82 m := NewMetaContextForTest(tc).WithUIs(uis) 83 if err := RunEngine2(m, eng); err != nil { 84 t.Fatal(err) 85 } 86 sv := keybase1.SigVersion(sigVersion) 87 targ := TrackTokenArg{ 88 Token: idUI.Token, 89 Options: keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, 90 } 91 92 // Track tracy 93 teng := NewTrackToken(tc.G, &targ) 94 if err := RunEngine2(m, teng); err != nil { 95 t.Fatal(err) 96 } 97 98 defer func() { _ = runUntrack(tc, fu, username, sigVersion) }() 99 100 // Now make her Rooter proof flakey / fail with a 429 101 flakeyAPI.flakeOut = true 102 idUI = &FakeIdentifyUI{} 103 m = m.WithIdentifyUI(idUI) 104 105 // Advance so that our previous cached success is out of 106 // cache on its own, but still can override a 429-like soft failure. 107 fakeClock.Advance(tc.G.Env.GetProofCacheMediumDur() + time.Minute) 108 109 eng = NewResolveThenIdentify2(tc.G, arg) 110 eng.testArgs = &Identify2WithUIDTestArgs{noCache: true} 111 // Should not get an error 112 if err := RunEngine2(m, eng); err != nil { 113 t.Fatal(err) 114 } 115 result, found := idUI.ProofResults["rooter"] 116 if !found { 117 t.Fatal("Failed to find a rooter proof") 118 } 119 if pe := libkb.ImportProofError(result.SnoozedResult); pe == nil { 120 t.Fatal("expected a snoozed error result") 121 } 122 123 // Now time out the success that allowed us to circumvent 124 // the soft failure. 125 fakeClock.Advance(tc.G.Env.GetProofCacheLongDur()) 126 eng = NewResolveThenIdentify2(tc.G, arg) 127 eng.testArgs = &Identify2WithUIDTestArgs{noCache: true} 128 idUI = &FakeIdentifyUI{} 129 m = m.WithIdentifyUI(idUI) 130 if err := RunEngine2(m, eng); err == nil { 131 t.Fatal("Expected a failure in our proof") 132 } 133 134 result, found = idUI.ProofResults["rooter"] 135 if !found { 136 t.Fatal("Failed to find a rooter proof") 137 } 138 if pe := libkb.ImportProofError(result.ProofResult); pe == nil { 139 t.Fatal("expected a Rooter error result") 140 } 141 if !idUI.BrokenTracking { 142 t.Fatal("expected broken tracking!") 143 } 144 145 assertTracking(tc, username) 146 }