// Test that canceling a signing RPC returns the correct error func TestCryptoClientDecryptTLFCryptKeyClientHalfCanceled(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) ctlChan := make(chan struct{}) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, ctlChan) c := newCryptoClientWithClient(config.Codec(), cancelableClient{fc}, logger.NewTestLogger(t)) _, _, ephPublicKey, ephPrivateKey, cryptKey, err := c.MakeRandomTLFKeys() if err != nil { t.Fatal(err) } serverHalf, err := c.MakeRandomTLFCryptKeyServerHalf() if err != nil { t.Fatal(err) } clientHalf, err := c.MaskTLFCryptKey(serverHalf, cryptKey) if err != nil { t.Fatal(err) } encryptedClientHalf, err := c.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.getPublicKey(), clientHalf) if err != nil { t.Fatal(err) } f := func(ctx context.Context) error { _, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey, encryptedClientHalf) return err } testWithCanceledContext(t, context.Background(), ctlChan, ctlChan, f) }
func NewConfigMock(c *gomock.Controller, ctr *SafeTestReporter) *ConfigMock { config := &ConfigMock{} config.mockKbfs = NewMockKBFSOps(c) config.SetKBFSOps(config.mockKbfs) config.mockKbpki = NewMockKBPKI(c) config.SetKBPKI(config.mockKbpki) config.mockKeyman = NewMockKeyManager(c) config.SetKeyManager(config.mockKeyman) config.mockRep = NewMockReporter(c) config.SetReporter(config.mockRep) config.mockMdcache = NewMockMDCache(c) config.SetMDCache(config.mockMdcache) config.mockKcache = NewMockKeyCache(c) config.SetKeyCache(config.mockKcache) config.mockBcache = NewMockBlockCache(c) config.SetBlockCache(config.mockBcache) config.mockCrypto = NewMockCrypto(c) config.SetCrypto(config.mockCrypto) config.mockCodec = NewMockCodec(c) config.mockCodec.EXPECT().RegisterType(gomock.Any(), gomock.Any()). AnyTimes().Return() config.mockCodec.EXPECT().RegisterIfaceSliceType(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return() config.SetCodec(config.mockCodec) config.mockMdops = NewMockMDOps(c) config.SetMDOps(config.mockMdops) config.mockKops = NewMockKeyOps(c) config.SetKeyOps(config.mockKops) config.mockBops = NewMockBlockOps(c) config.SetBlockOps(config.mockBops) config.mockMdserv = NewMockMDServer(c) config.SetMDServer(config.mockMdserv) config.mockKserv = NewMockKeyServer(c) config.SetKeyServer(config.mockKserv) config.mockBserv = NewMockBlockServer(c) config.SetBlockServer(config.mockBserv) config.mockBsplit = NewMockBlockSplitter(c) config.SetBlockSplitter(config.mockBsplit) config.mockNotifier = NewMockNotifier(c) config.SetNotifier(config.mockNotifier) config.mockClock = NewMockClock(c) config.SetClock(config.mockClock) config.mockRekeyQueue = NewMockRekeyQueue(c) config.SetRekeyQueue(config.mockRekeyQueue) config.observer = &FakeObserver{} config.ctr = ctr config.SetLoggerMaker(func(m string) logger.Logger { return logger.NewTestLogger(ctr.t) }) // turn off background flushing by default during tests config.noBGFlush = true config.maxFileBytes = maxFileBytesDefault config.maxNameBytes = maxNameBytesDefault config.maxDirBytes = maxDirBytesDefault return config }
func newKeybaseDaemonRPCWithFakeClient(t *testing.T) ( *KeybaseDaemonRPC, chan struct{}) { ctlChan := make(chan struct{}) c := newKeybaseDaemonRPCWithClient( nil, cancelableClient{blockingClient{ctlChan}}, logger.NewTestLogger(t)) return c, ctlChan }
// Test that when decrypting set of client keys, the first working one // is used to decrypt. func TestCryptoClientDecryptEncryptedTLFCryptKeyClientHalfAny(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) keys := make([]EncryptedTLFCryptKeyClientAndEphemeral, 0, 4) clientHalves := make([]TLFCryptKeyClientHalf, 0, 4) for i := 0; i < 4; i++ { _, _, ephPublicKey, ephPrivateKey, cryptKey, err := c.MakeRandomTLFKeys() if err != nil { t.Fatal(err) } serverHalf, err := c.MakeRandomTLFCryptKeyServerHalf() if err != nil { t.Fatal(err) } clientHalf, err := c.MaskTLFCryptKey(serverHalf, cryptKey) if err != nil { t.Fatal(err) } // See crypto_common_test.go for tests that this actually // performs encryption. encryptedClientHalf, err := c.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.getPublicKey(), clientHalf) if err != nil { t.Fatal(err) } if encryptedClientHalf.Version != EncryptionSecretbox { t.Fatalf("Unexpected encryption version %d", encryptedClientHalf.Version) } keys = append(keys, EncryptedTLFCryptKeyClientAndEphemeral{ PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalf, EPubKey: ephPublicKey, }) clientHalves = append(clientHalves, clientHalf) } decryptedClientHalf, index, err := c.DecryptTLFCryptKeyClientHalfAny( context.Background(), keys) if err != nil { t.Fatal(err) } if index != 0 { t.Errorf("expected first key to work. Actual key index: %d", index) } if clientHalves[0] != decryptedClientHalf { t.Error("clientHalf != decryptedClientHalf") } }
// Test that decrypting an TLF crypt key client half encrypted with // box.Seal works. func TestCryptoClientDecryptTLFCryptKeyClientHalfBoxSeal(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) _, _, ephPublicKey, ephPrivateKey, cryptKey, err := c.MakeRandomTLFKeys() if err != nil { t.Fatal(err) } serverHalf, err := c.MakeRandomTLFCryptKeyServerHalf() if err != nil { t.Fatal(err) } clientHalf, err := c.MaskTLFCryptKey(serverHalf, cryptKey) if err != nil { t.Fatal(err) } var nonce [24]byte err = cryptoRandRead(nonce[:]) if err != nil { t.Fatal(err) } keypair, err := libkb.ImportKeypairFromKID(cryptPrivateKey.getPublicKey().kid) if err != nil { t.Fatal(err) } dhKeyPair, ok := keypair.(libkb.NaclDHKeyPair) if !ok { t.Fatal(libkb.KeyCannotEncryptError{}) } encryptedData := box.Seal(nil, clientHalf.data[:], &nonce, (*[32]byte)(&dhKeyPair.Public), (*[32]byte)(&ephPrivateKey.data)) encryptedClientHalf := EncryptedTLFCryptKeyClientHalf{ Version: EncryptionSecretbox, Nonce: nonce[:], EncryptedData: encryptedData, } decryptedClientHalf, err := c.DecryptTLFCryptKeyClientHalf( context.Background(), ephPublicKey, encryptedClientHalf) if err != nil { t.Fatal(err) } if clientHalf != decryptedClientHalf { t.Error("clientHalf != decryptedClientHalf") } }
// If we cancel the RPC before the RPC returns, the call should error quickly. func TestKeybaseDaemonRPCGetCurrentSessionCanceled(t *testing.T) { serverConn, conn := rpc.MakeConnectionForTest(t) daemon := newKeybaseDaemonRPCWithClient( nil, conn.GetClient(), logger.NewTestLogger(t)) f := func(ctx context.Context) error { _, err := daemon.CurrentSession(ctx, 0) return err } testRPCWithCanceledContext(t, serverConn, f) }
// Test that canceling a signing RPC returns the correct error func TestCryptoClientSignCanceled(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) ctlChan := make(chan struct{}) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, ctlChan) c := newCryptoClientWithClient(config.Codec(), cancelableClient{fc}, logger.NewTestLogger(t)) f := func(ctx context.Context) error { msg := []byte("message") _, err := c.Sign(ctx, msg) return err } testWithCanceledContext(t, context.Background(), ctlChan, ctlChan, f) }
// Test that attempting to decrypt an empty set of client keys fails. func TestCryptoClientDecryptEmptyEncryptedTLFCryptKeyClientHalfAny(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) keys := make([]EncryptedTLFCryptKeyClientAndEphemeral, 0, 0) _, _, err := c.DecryptTLFCryptKeyClientHalfAny( context.Background(), keys) if _, ok := err.(NoKeysError); !ok { t.Fatalf("expected NoKeysError. Actual error: %v", err) } }
func TestKBFSOpsCancelGetFavorites(t *testing.T) { config, _, _ := kbfsOpsConcurInit(t, "test_user") defer CheckConfigAndShutdown(t, config) serverConn, conn := rpc.MakeConnectionForTest(t) daemon := newKeybaseDaemonRPCWithClient( nil, conn.GetClient(), logger.NewTestLogger(t)) config.SetKeybaseDaemon(daemon) f := func(ctx context.Context) error { _, err := config.KBFSOps().GetFavorites(ctx) return err } testRPCWithCanceledContext(t, serverConn, f) }
// Test that signing a message and then verifying it works. func TestCryptoClientSignAndVerify(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) msg := []byte("message") sigInfo, err := c.Sign(context.Background(), msg) if err != nil { t.Fatal(err) } err = c.Verify(msg, sigInfo) if err != nil { t.Error(err) } }
// Test that decrypting a TLF crypt key client half encrypted with the // default method (currently nacl/box) works. func TestCryptoClientDecryptEncryptedTLFCryptKeyClientHalf(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) _, _, ephPublicKey, ephPrivateKey, cryptKey, err := c.MakeRandomTLFKeys() if err != nil { t.Fatal(err) } serverHalf, err := c.MakeRandomTLFCryptKeyServerHalf() if err != nil { t.Fatal(err) } clientHalf, err := c.MaskTLFCryptKey(serverHalf, cryptKey) if err != nil { t.Fatal(err) } // See crypto_common_test.go for tests that this actually // performs encryption. encryptedClientHalf, err := c.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.getPublicKey(), clientHalf) if err != nil { t.Fatal(err) } if encryptedClientHalf.Version != EncryptionSecretbox { t.Fatalf("Unexpected encryption version %d", encryptedClientHalf.Version) } decryptedClientHalf, err := c.DecryptTLFCryptKeyClientHalf( context.Background(), ephPublicKey, encryptedClientHalf) if err != nil { t.Fatal(err) } if clientHalf != decryptedClientHalf { t.Error("clientHalf != decryptedClientHalf") } }
// Test that the session cache works and is invalidated as expected. func TestKeybaseDaemonSessionCache(t *testing.T) { k := MakeLocalUserCryptPublicKeyOrBust( libkb.NormalizedUsername("fake username")) v := MakeLocalUserVerifyingKeyOrBust( libkb.NormalizedUsername("fake username")) session := SessionInfo{ UID: keybase1.UID("fake uid"), Token: "fake token", CryptPublicKey: k, VerifyingKey: v, } client := &fakeKeybaseClient{session: session} c := newKeybaseDaemonRPCWithClient( nil, client, logger.NewTestLogger(t)) // Should fill cache. testCurrentSession(t, client, c, session, expectCall) // Should be cached. testCurrentSession(t, client, c, session, expectCached) // Should invalidate cache. err := c.LoggedOut(context.Background()) if err != nil { t.Fatal(err) } // Should fill cache again. testCurrentSession(t, client, c, session, expectCall) // Should be cached again. testCurrentSession(t, client, c, session, expectCached) // Should invalidate cache. c.OnDisconnected(UsingExistingConnection) // Should fill cache again. testCurrentSession(t, client, c, session, expectCall) }
// Test that the user cache works and is invalidated as expected. func TestKeybaseDaemonUserCache(t *testing.T) { uid1 := keybase1.UID("uid1") uid2 := keybase1.UID("uid2") name1 := libkb.NewNormalizedUsername("name1") name2 := libkb.NewNormalizedUsername("name2") users := map[keybase1.UID]UserInfo{ uid1: {Name: name1}, uid2: {Name: name2}, } client := &fakeKeybaseClient{users: users} c := newKeybaseDaemonRPCWithClient( nil, client, logger.NewTestLogger(t)) // Should fill cache. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCall) // Should be cached. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCached) // Should fill cache. testIdentify(t, client, c, uid2, name2, expectCall) // Should be cached. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCached) // Should not be cached. testIdentify(t, client, c, uid2, name2, expectCall) // Should invalidate cache for uid1. err := c.UserChanged(context.Background(), uid1) require.NoError(t, err) // Should fill cache again. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCall) // Should be cached again. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCached) // Should still be cached. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCached) // Should invalidate cache for uid2. err = c.UserChanged(context.Background(), uid2) require.NoError(t, err) // Should fill cache again. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCall) // Should be cached again. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCached) // Should invalidate cache for all users. c.OnDisconnected(context.Background(), rpc.UsingExistingConnection) // Should fill cache again. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCall) testLoadUserPlusKeys(t, client, c, uid2, name2, expectCall) // Test that CheckForRekey gets called only if the logged-in user // changes. session := SessionInfo{ UID: uid1, } c.setCachedCurrentSession(session) ctr := NewSafeTestReporter(t) mockCtrl := gomock.NewController(ctr) config := NewConfigMock(mockCtrl, ctr) c.config = config defer func() { config.ctr.CheckForFailures() mockCtrl.Finish() }() errChan := make(chan error, 1) config.mockMdserv.EXPECT().CheckForRekeys(gomock.Any()).Do( func(ctx context.Context) { errChan <- nil }).Return(errChan) err = c.UserChanged(context.Background(), uid1) <-errChan // This one shouldn't trigger CheckForRekeys; if it does, the mock // controller will catch it during Finish. err = c.UserChanged(context.Background(), uid2) }
func setTestLogger(config Config, t logger.TestLogBackend) { config.SetLoggerMaker(func(m string) logger.Logger { return logger.NewTestLogger(t) }) }
// Test various failure cases for DecryptTLFCryptKeyClientHalf. func TestCryptoClientDecryptTLFCryptKeyClientHalfFailures(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) _, _, ephPublicKey, ephPrivateKey, cryptKey, err := c.MakeRandomTLFKeys() if err != nil { t.Fatal(err) } serverHalf, err := c.MakeRandomTLFCryptKeyServerHalf() if err != nil { t.Fatal(err) } clientHalf, err := c.MaskTLFCryptKey(serverHalf, cryptKey) if err != nil { t.Fatal(err) } encryptedClientHalf, err := c.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.getPublicKey(), clientHalf) if err != nil { t.Fatal(err) } var expectedErr error // Wrong version. encryptedClientHalfWrongVersion := encryptedClientHalf encryptedClientHalfWrongVersion.Version++ expectedErr = UnknownEncryptionVer{encryptedClientHalfWrongVersion.Version} ctx := context.Background() _, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey, encryptedClientHalfWrongVersion) if err != expectedErr { t.Errorf("Expected %v, got %v", expectedErr, err) } // Wrong sizes. encryptedClientHalfWrongSize := encryptedClientHalf encryptedClientHalfWrongSize.EncryptedData = encryptedClientHalfWrongSize.EncryptedData[:len(encryptedClientHalfWrongSize.EncryptedData)-1] expectedErr = libkb.DecryptionError{} _, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey, encryptedClientHalfWrongSize) if err != expectedErr { t.Errorf("Expected %v, got %v", expectedErr, err) } encryptedClientHalfWrongNonceSize := encryptedClientHalf encryptedClientHalfWrongNonceSize.Nonce = encryptedClientHalfWrongNonceSize.Nonce[:len(encryptedClientHalfWrongNonceSize.Nonce)-1] expectedErr = InvalidNonceError{encryptedClientHalfWrongNonceSize.Nonce} _, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey, encryptedClientHalfWrongNonceSize) if err.Error() != expectedErr.Error() { t.Errorf("Expected %v, got %v", expectedErr, err) } // Corrupt key. ephPublicKeyCorrupt := ephPublicKey ephPublicKeyCorrupt.data[0] = ^ephPublicKeyCorrupt.data[0] expectedErr = libkb.DecryptionError{} _, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKeyCorrupt, encryptedClientHalf) if err != expectedErr { t.Errorf("Expected %v, got %v", expectedErr, err) } // Corrupt data. encryptedClientHalfCorruptData := encryptedClientHalf encryptedClientHalfCorruptData.EncryptedData[0] = ^encryptedClientHalfCorruptData.EncryptedData[0] expectedErr = libkb.DecryptionError{} _, err = c.DecryptTLFCryptKeyClientHalf(ctx, ephPublicKey, encryptedClientHalfCorruptData) if err != expectedErr { t.Errorf("Expected %v, got %v", expectedErr, err) } }
// Test various failure cases for DecryptTLFCryptKeyClientHalfAny and that // if a working key is present, the decryption succeeds. func TestCryptoClientDecryptTLFCryptKeyClientHalfAnyFailures(t *testing.T) { signingKey := MakeFakeSigningKeyOrBust("client sign") cryptPrivateKey := MakeFakeCryptPrivateKeyOrBust("client crypt private") config := testCryptoClientConfig(t) fc := NewFakeCryptoClient(config, signingKey, cryptPrivateKey, nil) c := newCryptoClientWithClient(config.Codec(), fc, logger.NewTestLogger(t)) _, _, ephPublicKey, ephPrivateKey, cryptKey, err := c.MakeRandomTLFKeys() if err != nil { t.Fatal(err) } serverHalf, err := c.MakeRandomTLFCryptKeyServerHalf() if err != nil { t.Fatal(err) } clientHalf, err := c.MaskTLFCryptKey(serverHalf, cryptKey) if err != nil { t.Fatal(err) } encryptedClientHalf, err := c.EncryptTLFCryptKeyClientHalf(ephPrivateKey, cryptPrivateKey.getPublicKey(), clientHalf) if err != nil { t.Fatal(err) } // Wrong version. encryptedClientHalfWrongVersion := encryptedClientHalf encryptedClientHalfWrongVersion.Version++ // Wrong sizes. encryptedClientHalfWrongSize := encryptedClientHalf encryptedClientHalfWrongSize.EncryptedData = encryptedClientHalfWrongSize.EncryptedData[:len(encryptedClientHalfWrongSize.EncryptedData)-1] encryptedClientHalfWrongNonceSize := encryptedClientHalf encryptedClientHalfWrongNonceSize.Nonce = encryptedClientHalfWrongNonceSize.Nonce[:len(encryptedClientHalfWrongNonceSize.Nonce)-1] // Corrupt key. ephPublicKeyCorrupt := ephPublicKey ephPublicKeyCorrupt.data[0] = ^ephPublicKeyCorrupt.data[0] // Corrupt data. encryptedClientHalfCorruptData := encryptedClientHalf encryptedClientHalfCorruptData.EncryptedData = make([]byte, len(encryptedClientHalf.EncryptedData)) copy(encryptedClientHalfCorruptData.EncryptedData, encryptedClientHalf.EncryptedData) encryptedClientHalfCorruptData.EncryptedData[0] = ^encryptedClientHalfCorruptData.EncryptedData[0] keys := []EncryptedTLFCryptKeyClientAndEphemeral{ { PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalfWrongVersion, EPubKey: ephPublicKey, }, { PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalfWrongSize, EPubKey: ephPublicKey, }, { PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalfWrongNonceSize, EPubKey: ephPublicKey, }, { PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalf, EPubKey: ephPublicKeyCorrupt, }, { PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalfCorruptData, EPubKey: ephPublicKey, }, { PubKey: cryptPrivateKey.getPublicKey(), ClientHalf: encryptedClientHalf, EPubKey: ephPublicKey, }, } _, index, err := c.DecryptTLFCryptKeyClientHalfAny( context.Background(), keys) if err != nil { t.Fatal(err) } if index != len(keys)-1 { t.Errorf("expected last key to work. Actual key index: %d", index) } }
// Test that the user cache works and is invalidated as expected. func TestKeybaseDaemonUserCache(t *testing.T) { uid1 := keybase1.UID("uid1") uid2 := keybase1.UID("uid2") name1 := libkb.NewNormalizedUsername("name1") name2 := libkb.NewNormalizedUsername("name2") users := map[keybase1.UID]UserInfo{ uid1: {Name: name1}, uid2: {Name: name2}, } client := &fakeKeybaseClient{users: users} c := newKeybaseDaemonRPCWithClient( nil, client, logger.NewTestLogger(t)) // Should fill cache. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCall) // Should be cached. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCached) // Should fill cache. testIdentify(t, client, c, uid2, name2, expectCall) // Should be cached. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCached) // Should not be cached. testIdentify(t, client, c, uid2, name2, expectCall) // Should invalidate cache for uid1. err := c.UserChanged(context.Background(), uid1) if err != nil { t.Fatal(err) } // Should fill cache again. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCall) // Should be cached again. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCached) // Should still be cached. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCached) // Should invalidate cache for uid2. err = c.UserChanged(context.Background(), uid2) if err != nil { t.Fatal(err) } // Should fill cache again. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCall) // Should be cached again. testLoadUserPlusKeys(t, client, c, uid2, name2, expectCached) // Should invalidate cache for all users. c.OnDisconnected(UsingExistingConnection) // Should fill cache again. testLoadUserPlusKeys(t, client, c, uid1, name1, expectCall) testLoadUserPlusKeys(t, client, c, uid2, name2, expectCall) }