ソースを参照

Merge pull request #7364 from gyuho/auth-revi

auth: keep old revision in 'NewAuthStore'
Gyu-Ho Lee 8 年 前
コミット
c0c4c7cb76
3 ファイル変更61 行追加1 行削除
  1. 3 1
      auth/store.go
  2. 27 0
      auth/store_test.go
  3. 31 0
      integration/v3_grpc_test.go

+ 3 - 1
auth/store.go

@@ -916,7 +916,9 @@ func NewAuthStore(be backend.Backend, indexWaiter func(uint64) <-chan struct{})
 		as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(newDeleterFunc(as))
 		as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(newDeleterFunc(as))
 	}
 	}
 
 
-	as.commitRevision(tx)
+	if as.revision == 0 {
+		as.commitRevision(tx)
+	}
 
 
 	tx.Unlock()
 	tx.Unlock()
 	be.ForceCommit()
 	be.ForceCommit()

+ 27 - 0
auth/store_test.go

@@ -38,6 +38,33 @@ func dummyIndexWaiter(index uint64) <-chan struct{} {
 	return ch
 	return ch
 }
 }
 
 
+// TestNewAuthStoreRevision ensures newly auth store
+// keeps the old revision when there are no changes.
+func TestNewAuthStoreRevision(t *testing.T) {
+	b, tPath := backend.NewDefaultTmpBackend()
+	defer os.Remove(tPath)
+
+	as := NewAuthStore(b, dummyIndexWaiter)
+	err := enableAuthAndCreateRoot(as)
+	if err != nil {
+		t.Fatal(err)
+	}
+	old := as.Revision()
+	b.Close()
+	as.Close()
+
+	// no changes to commit
+	b2 := backend.NewDefaultBackend(tPath)
+	as = NewAuthStore(b2, dummyIndexWaiter)
+	new := as.Revision()
+	b2.Close()
+	as.Close()
+
+	if old != new {
+		t.Fatalf("expected revision %d, got %d", old, new)
+	}
+}
+
 func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testing.T)) {
 func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testing.T)) {
 	b, tPath := backend.NewDefaultTmpBackend()
 	b, tPath := backend.NewDefaultTmpBackend()
 
 

+ 31 - 0
integration/v3_grpc_test.go

@@ -855,6 +855,37 @@ func TestV3Hash(t *testing.T) {
 	}
 	}
 }
 }
 
 
+// TestV3HashRestart ensures that hash stays the same after restart.
+func TestV3HashRestart(t *testing.T) {
+	defer testutil.AfterTest(t)
+	clus := NewClusterV3(t, &ClusterConfig{Size: 1})
+	defer clus.Terminate(t)
+
+	cli := clus.RandClient()
+	resp, err := toGRPC(cli).Maintenance.Hash(context.Background(), &pb.HashRequest{})
+	if err != nil || resp.Hash == 0 {
+		t.Fatalf("couldn't hash (%v, hash %d)", err, resp.Hash)
+	}
+	hash1 := resp.Hash
+
+	clus.Members[0].Stop(t)
+	clus.Members[0].Restart(t)
+	clus.waitLeader(t, clus.Members)
+	kvc := toGRPC(clus.Client(0)).KV
+	waitForRestart(t, kvc)
+
+	cli = clus.RandClient()
+	resp, err = toGRPC(cli).Maintenance.Hash(context.Background(), &pb.HashRequest{})
+	if err != nil || resp.Hash == 0 {
+		t.Fatalf("couldn't hash (%v, hash %d)", err, resp.Hash)
+	}
+	hash2 := resp.Hash
+
+	if hash1 != hash2 {
+		t.Fatalf("hash expected %d, got %d", hash1, hash2)
+	}
+}
+
 // TestV3StorageQuotaAPI tests the V3 server respects quotas at the API layer
 // TestV3StorageQuotaAPI tests the V3 server respects quotas at the API layer
 func TestV3StorageQuotaAPI(t *testing.T) {
 func TestV3StorageQuotaAPI(t *testing.T) {
 	defer testutil.AfterTest(t)
 	defer testutil.AfterTest(t)