Browse Source

store: restore minExpireTime check and advance FakeClock appropriately

Jonathan Boulle 11 years ago
parent
commit
1456ae4453
3 changed files with 43 additions and 9 deletions
  1. 1 2
      store/stats_test.go
  2. 6 0
      store/store.go
  3. 36 7
      store/store_test.go

+ 1 - 2
store/stats_test.go

@@ -4,7 +4,6 @@ import (
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
-	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/jonboulle/clockwork"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/stretchr/testify/assert"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/stretchr/testify/assert"
 )
 )
 
 
@@ -88,7 +87,7 @@ func TestStoreStatsDeleteFail(t *testing.T) {
 //Ensure that the number of expirations is recorded in the stats.
 //Ensure that the number of expirations is recorded in the stats.
 func TestStoreStatsExpireCount(t *testing.T) {
 func TestStoreStatsExpireCount(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 	s.clock = fc
 	s.clock = fc
 
 
 	s.Create("/foo", false, "bar", false, fc.Now().Add(500*time.Millisecond))
 	s.Create("/foo", false, "bar", false, fc.Now().Add(500*time.Millisecond))

+ 6 - 0
store/store.go

@@ -467,6 +467,12 @@ func (s *store) internalCreate(nodePath string, dir bool, value string, unique,
 		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", currIndex)
 		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", currIndex)
 	}
 	}
 
 
+	// Assume expire times that are way in the past are
+	// This can occur when the time is serialized to JS
+	if expireTime.Before(minExpireTime) {
+		expireTime = Permanent
+	}
+
 	dirName, nodeName := path.Split(nodePath)
 	dirName, nodeName := path.Split(nodePath)
 
 
 	// walk through the nodePath, create dirs and get the last directory node
 	// walk through the nodePath, create dirs and get the last directory node

+ 36 - 7
store/store_test.go

@@ -38,11 +38,31 @@ func TestStoreGetValue(t *testing.T) {
 	assert.Equal(t, *e.Node.Value, "bar", "")
 	assert.Equal(t, *e.Node.Value, "bar", "")
 }
 }
 
 
+// Ensure that any TTL <= minExpireTime becomes Permanent
+func TestMinExpireTime(t *testing.T) {
+	s := newStore()
+	fc := clockwork.NewFakeClock()
+	s.clock = fc
+	// FakeClock starts at 0, so minExpireTime should be far in the future.. but just in case
+	assert.True(t, minExpireTime.After(fc.Now()), "minExpireTime should be ahead of FakeClock!")
+	s.Create("/foo", false, "Y", false, fc.Now().Add(3*time.Second))
+	fc.Advance(5 * time.Second)
+	// Ensure it hasn't expired
+	s.DeleteExpiredKeys(fc.Now())
+	var eidx uint64 = 1
+	e, err := s.Get("/foo", true, false)
+	assert.Nil(t, err, "")
+	assert.Equal(t, e.EtcdIndex, eidx, "")
+	assert.Equal(t, e.Action, "get", "")
+	assert.Equal(t, e.Node.Key, "/foo", "")
+	assert.Equal(t, e.Node.TTL, 0)
+}
+
 // Ensure that the store can recrusively retrieve a directory listing.
 // Ensure that the store can recrusively retrieve a directory listing.
 // Note that hidden files should not be returned.
 // Note that hidden files should not be returned.
 func TestStoreGetDirectory(t *testing.T) {
 func TestStoreGetDirectory(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 	s.clock = fc
 	s.clock = fc
 	s.Create("/foo", true, "", false, Permanent)
 	s.Create("/foo", true, "", false, Permanent)
 	s.Create("/foo/bar", false, "X", false, Permanent)
 	s.Create("/foo/bar", false, "X", false, Permanent)
@@ -314,7 +334,7 @@ func TestStoreUpdateFailsIfDirectory(t *testing.T) {
 // Ensure that the store can update the TTL on a value.
 // Ensure that the store can update the TTL on a value.
 func TestStoreUpdateValueTTL(t *testing.T) {
 func TestStoreUpdateValueTTL(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 	s.clock = fc
 	s.clock = fc
 
 
 	var eidx uint64 = 2
 	var eidx uint64 = 2
@@ -333,7 +353,7 @@ func TestStoreUpdateValueTTL(t *testing.T) {
 // Ensure that the store can update the TTL on a directory.
 // Ensure that the store can update the TTL on a directory.
 func TestStoreUpdateDirTTL(t *testing.T) {
 func TestStoreUpdateDirTTL(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 	s.clock = fc
 	s.clock = fc
 
 
 	var eidx uint64 = 3
 	var eidx uint64 = 3
@@ -703,7 +723,7 @@ func TestStoreWatchRecursiveCompareAndSwap(t *testing.T) {
 // Ensure that the store can watch for key expiration.
 // Ensure that the store can watch for key expiration.
 func TestStoreWatchExpire(t *testing.T) {
 func TestStoreWatchExpire(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 	s.clock = fc
 	s.clock = fc
 
 
 	var eidx uint64 = 2
 	var eidx uint64 = 2
@@ -783,9 +803,9 @@ func TestStoreRecover(t *testing.T) {
 // Ensure that the store can recover from a previously saved state that includes an expiring key.
 // Ensure that the store can recover from a previously saved state that includes an expiring key.
 func TestStoreRecoverWithExpiration(t *testing.T) {
 func TestStoreRecoverWithExpiration(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	s.clock = clockwork.NewFakeClock()
+	s.clock = newFakeClock()
 
 
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 
 
 	var eidx uint64 = 4
 	var eidx uint64 = 4
 	s.Create("/foo", true, "", false, Permanent)
 	s.Create("/foo", true, "", false, Permanent)
@@ -894,7 +914,7 @@ func TestStoreWatchRecursiveDeleteWithHiddenKey(t *testing.T) {
 // Ensure that the store doesn't see expirations of hidden keys.
 // Ensure that the store doesn't see expirations of hidden keys.
 func TestStoreWatchExpireWithHiddenKey(t *testing.T) {
 func TestStoreWatchExpireWithHiddenKey(t *testing.T) {
 	s := newStore()
 	s := newStore()
-	fc := clockwork.NewFakeClock()
+	fc := newFakeClock()
 	s.clock = fc
 	s.clock = fc
 
 
 	s.Create("/_foo", false, "bar", false, fc.Now().Add(500*time.Millisecond))
 	s.Create("/_foo", false, "bar", false, fc.Now().Add(500*time.Millisecond))
@@ -953,3 +973,12 @@ func nbselect(c <-chan *Event) *Event {
 		return nil
 		return nil
 	}
 	}
 }
 }
+
+// newFakeClock creates a new FakeClock that has been advanced to at least minExpireTime
+func newFakeClock() clockwork.FakeClock {
+	fc := clockwork.NewFakeClock()
+	for minExpireTime.After(fc.Now()) {
+		fc.Advance((0x1 << 62) * time.Nanosecond)
+	}
+	return fc
+}