|
|
|
|
@ -18,12 +18,10 @@ import (
|
|
|
|
|
// ensure that values being tested on never expire.
|
|
|
|
|
var neverExpire = time.Now().UTC().Add(time.Hour * 24 * 365 * 100) |
|
|
|
|
|
|
|
|
|
// StorageFactory is a method for creating a new storage. The returned storage sould be initialized
|
|
|
|
|
// but shouldn't have any existing data in it.
|
|
|
|
|
type StorageFactory func() storage.Storage |
|
|
|
|
|
|
|
|
|
// RunTestSuite runs a set of conformance tests against a storage.
|
|
|
|
|
func RunTestSuite(t *testing.T, sf StorageFactory) { |
|
|
|
|
// RunTests runs a set of conformance tests against a storage. newStorage should
|
|
|
|
|
// return an initialized but empty storage. The storage will be closed at the
|
|
|
|
|
// end of each test run.
|
|
|
|
|
func RunTests(t *testing.T, newStorage func() storage.Storage) { |
|
|
|
|
tests := []struct { |
|
|
|
|
name string |
|
|
|
|
run func(t *testing.T, s storage.Storage) |
|
|
|
|
@ -33,10 +31,13 @@ func RunTestSuite(t *testing.T, sf StorageFactory) {
|
|
|
|
|
{"ClientCRUD", testClientCRUD}, |
|
|
|
|
{"RefreshTokenCRUD", testRefreshTokenCRUD}, |
|
|
|
|
{"PasswordCRUD", testPasswordCRUD}, |
|
|
|
|
{"GarbageCollection", testGC}, |
|
|
|
|
} |
|
|
|
|
for _, test := range tests { |
|
|
|
|
t.Run(test.name, func(t *testing.T) { |
|
|
|
|
test.run(t, sf()) |
|
|
|
|
s := newStorage() |
|
|
|
|
test.run(t, s) |
|
|
|
|
s.Close() |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -276,3 +277,92 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) {
|
|
|
|
|
t.Errorf("after deleting password expected storage.ErrNotFound, got %v", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func testGC(t *testing.T, s storage.Storage) { |
|
|
|
|
n := time.Now() |
|
|
|
|
c := storage.AuthCode{ |
|
|
|
|
ID: storage.NewID(), |
|
|
|
|
ClientID: "foobar", |
|
|
|
|
RedirectURI: "https://localhost:80/callback", |
|
|
|
|
Nonce: "foobar", |
|
|
|
|
Scopes: []string{"openid", "email"}, |
|
|
|
|
Expiry: n.Add(time.Second), |
|
|
|
|
ConnectorID: "ldap", |
|
|
|
|
ConnectorData: []byte(`{"some":"data"}`), |
|
|
|
|
Claims: storage.Claims{ |
|
|
|
|
UserID: "1", |
|
|
|
|
Username: "jane", |
|
|
|
|
Email: "jane.doe@example.com", |
|
|
|
|
EmailVerified: true, |
|
|
|
|
Groups: []string{"a", "b"}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if err := s.CreateAuthCode(c); err != nil { |
|
|
|
|
t.Fatalf("failed creating auth code: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := s.GarbageCollect(n); err != nil { |
|
|
|
|
t.Errorf("garbage collection failed: %v", err) |
|
|
|
|
} |
|
|
|
|
if _, err := s.GetAuthCode(c.ID); err != nil { |
|
|
|
|
t.Errorf("expected to be able to get auth code after GC: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if r, err := s.GarbageCollect(n.Add(time.Minute)); err != nil { |
|
|
|
|
t.Errorf("garbage collection failed: %v", err) |
|
|
|
|
} else if r.AuthCodes != 1 { |
|
|
|
|
t.Errorf("expected to garbage collect 1 objects, got %d", r.AuthCodes) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := s.GetAuthCode(c.ID); err == nil { |
|
|
|
|
t.Errorf("expected auth code to be GC'd") |
|
|
|
|
} else if err != storage.ErrNotFound { |
|
|
|
|
t.Errorf("expected storage.ErrNotFound, got %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
a := storage.AuthRequest{ |
|
|
|
|
ID: storage.NewID(), |
|
|
|
|
ClientID: "foobar", |
|
|
|
|
ResponseTypes: []string{"code"}, |
|
|
|
|
Scopes: []string{"openid", "email"}, |
|
|
|
|
RedirectURI: "https://localhost:80/callback", |
|
|
|
|
Nonce: "foo", |
|
|
|
|
State: "bar", |
|
|
|
|
ForceApprovalPrompt: true, |
|
|
|
|
LoggedIn: true, |
|
|
|
|
Expiry: n, |
|
|
|
|
ConnectorID: "ldap", |
|
|
|
|
ConnectorData: []byte(`{"some":"data"}`), |
|
|
|
|
Claims: storage.Claims{ |
|
|
|
|
UserID: "1", |
|
|
|
|
Username: "jane", |
|
|
|
|
Email: "jane.doe@example.com", |
|
|
|
|
EmailVerified: true, |
|
|
|
|
Groups: []string{"a", "b"}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if err := s.CreateAuthRequest(a); err != nil { |
|
|
|
|
t.Fatalf("failed creating auth request: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := s.GarbageCollect(n); err != nil { |
|
|
|
|
t.Errorf("garbage collection failed: %v", err) |
|
|
|
|
} |
|
|
|
|
if _, err := s.GetAuthRequest(a.ID); err != nil { |
|
|
|
|
t.Errorf("expected to be able to get auth code after GC: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if r, err := s.GarbageCollect(n.Add(time.Minute)); err != nil { |
|
|
|
|
t.Errorf("garbage collection failed: %v", err) |
|
|
|
|
} else if r.AuthRequests != 1 { |
|
|
|
|
t.Errorf("expected to garbage collect 1 objects, got %d", r.AuthRequests) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := s.GetAuthRequest(a.ID); err == nil { |
|
|
|
|
t.Errorf("expected auth code to be GC'd") |
|
|
|
|
} else if err != storage.ErrNotFound { |
|
|
|
|
t.Errorf("expected storage.ErrNotFound, got %v", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|