diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index a2ec9c25b28..987910fe027 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -861,10 +861,6 @@ "ImportPath": "github.com/spf13/pflag", "Rev": "08b1a584251b5b62f458943640fc8ebd4d50aaa5" }, - { - "ImportPath": "github.com/ssoroka/ttime", - "Rev": "881f221816e0300201ac24f6c31e54e3bb958de7" - }, { "ImportPath": "github.com/stretchr/objx", "Rev": "d40df0cc104c06eae2dfe03d7dddb83802d52f9a" diff --git a/Godeps/LICENSES.md b/Godeps/LICENSES.md index f09cd9f1864..652d803eae6 100644 --- a/Godeps/LICENSES.md +++ b/Godeps/LICENSES.md @@ -84,7 +84,6 @@ github.com/Sirupsen/logrus | MITname github.com/skynetservices/skydns | MITname github.com/spf13/cobra | Apache-2 github.com/spf13/pflag | spdxBSD3 -github.com/ssoroka/ttime | UNKNOWN github.com/stretchr/objx | MIT? github.com/stretchr/testify | MIT? github.com/syndtr/gocapability | spdxBSD2 diff --git a/Godeps/_workspace/src/github.com/ssoroka/ttime/README.md b/Godeps/_workspace/src/github.com/ssoroka/ttime/README.md deleted file mode 100644 index 788ddceb34a..00000000000 --- a/Godeps/_workspace/src/github.com/ssoroka/ttime/README.md +++ /dev/null @@ -1,42 +0,0 @@ -This is an experiment in making time easier to mock in Go tests. - -You should be able to alias the ttime library to time to avoid having to change all your time.Now() methods to ttime.Now() throughout your code. - -All methods return actual time.Time structs (if they were supposed to). - -example code: - - import ( - time "github.com/ssoroka/ttime" - ) - - fmt.Printf("The starting time is %v", time.Now().UTC()) - - // in test this will not sleep at all, but it will advance the clock 5 seconds. - // in production, it's identical to time.Sleep - time.Sleep(5 * time.Second) - fmt.Printf("The time after sleeping for 5 seconds is %v", time.Now().UTC()) - - time.After(10 * time.Second, func() { - // This will execute after 10 seconds in production and immediately in tests. - fmt.Printf("It is now %v", time.Now().UTC()) - }) - -example test: - - func TestFreezingTime(t *testing.T) { - time.Freeze(time.Now()) // freeze the system clock, at least as far as ttime is concerned. - - // or freeze time at a specific date/time (eg, test leap-year support!): - now, err := time.Parse(time.RFC3339, "2012-02-29T00:00:00Z") - if err != nil { panic("date time parse failed") } - time.Freeze(now) - defer time.Unfreeze() - - // test leap-year-specific code - if !isLeapYear(time.Now()) { - t.Error("Oh no! isLeapYear is broken!") - } - - t.Logf("It is now %v", time.Now().UTC()) - } diff --git a/Godeps/_workspace/src/github.com/ssoroka/ttime/ttime.go b/Godeps/_workspace/src/github.com/ssoroka/ttime/ttime.go deleted file mode 100644 index d22730413bc..00000000000 --- a/Godeps/_workspace/src/github.com/ssoroka/ttime/ttime.go +++ /dev/null @@ -1,108 +0,0 @@ -package ttime - -import "time" - -var ( - currentTime time.Time - timeFrozen bool -) - -type Duration time.Duration -type Location time.Location -type Month time.Month -type ParseError time.ParseError -type Ticker time.Ticker -type Time time.Time -type Timer time.Timer -type Weekday time.Weekday - -var ( - // import a ton of constants so we can act like the time library. - Parse = time.Parse - ParseDuration = time.ParseDuration - Date = time.Date - ParseInLocation = time.ParseInLocation - FixedZone = time.FixedZone - LoadLocation = time.LoadLocation - Sunday = time.Sunday - Monday = time.Monday - Tuesday = time.Tuesday - Wednesday = time.Wednesday - Thursday = time.Thursday - Friday = time.Friday - Saturday = time.Saturday - ANSIC = time.ANSIC - UnixDate = time.UnixDate - RubyDate = time.RubyDate - RFC822 = time.RFC822 - RFC822Z = time.RFC822Z - RFC850 = time.RFC850 - RFC1123 = time.RFC1123 - RFC1123Z = time.RFC1123Z - RFC3339 = time.RFC3339 - RFC3339Nano = time.RFC3339Nano - Kitchen = time.Kitchen - Stamp = time.Stamp - StampMilli = time.StampMilli - StampMicro = time.StampMicro - StampNano = time.StampNano - // constants that I really should redefine: - NewTimer = time.NewTimer - NewTicker = time.NewTicker - Unix = time.Unix -) - -func Freeze(t time.Time) { - currentTime = t - timeFrozen = true -} - -func Unfreeze() { - timeFrozen = false -} - -func IsFrozen() bool { - return timeFrozen -} - -func Now() time.Time { - if timeFrozen { - return currentTime - } else { - return time.Now() - } -} - -func After(d time.Duration) <-chan time.Time { - if timeFrozen { - currentTime = currentTime.Add(d) - c := make(chan time.Time, 1) - c <- currentTime - return c - } else { - return time.After(d) - } -} - -func Tick(d time.Duration) <-chan time.Time { - if timeFrozen { - c := make(chan time.Time, 1) - go func() { - for { - currentTime = currentTime.Add(d) - c <- currentTime - } - }() - return c - } else { - return time.Tick(d) - } -} - -func Sleep(d time.Duration) { - if timeFrozen && d > 0 { - currentTime = currentTime.Add(d) - } else { - time.Sleep(d) - } -} diff --git a/pkg/kubelet/image_manager.go b/pkg/kubelet/image_manager.go index 59a895fe2a7..73eeb09efb3 100644 --- a/pkg/kubelet/image_manager.go +++ b/pkg/kubelet/image_manager.go @@ -156,7 +156,7 @@ func (im *realImageManager) GetImageList() ([]kubecontainer.Image, error) { return images, nil } -func (im *realImageManager) detectImages(detected time.Time) error { +func (im *realImageManager) detectImages(detectTime time.Time) error { images, err := im.runtime.ListImages() if err != nil { return err @@ -185,7 +185,7 @@ func (im *realImageManager) detectImages(detected time.Time) error { // New image, set it as detected now. if _, ok := im.imageRecords[image.ID]; !ok { im.imageRecords[image.ID] = &imageRecord{ - firstDetected: detected, + firstDetected: detectTime, } } @@ -228,7 +228,7 @@ func (im *realImageManager) GarbageCollect() error { if usagePercent >= im.policy.HighThresholdPercent { amountToFree := usage - (int64(im.policy.LowThresholdPercent) * capacity / 100) glog.Infof("[ImageManager]: Disk usage on %q (%s) is at %d%% which is over the high threshold (%d%%). Trying to free %d bytes", fsInfo.Device, fsInfo.Mountpoint, usagePercent, im.policy.HighThresholdPercent, amountToFree) - freed, err := im.freeSpace(amountToFree) + freed, err := im.freeSpace(amountToFree, time.Now()) if err != nil { return err } @@ -249,9 +249,8 @@ func (im *realImageManager) GarbageCollect() error { // bytes freed is always returned. // Note that error may be nil and the number of bytes free may be less // than bytesToFree. -func (im *realImageManager) freeSpace(bytesToFree int64) (int64, error) { - startTime := time.Now() - err := im.detectImages(startTime) +func (im *realImageManager) freeSpace(bytesToFree int64, freeTime time.Time) (int64, error) { + err := im.detectImages(freeTime) if err != nil { return 0, err } @@ -274,13 +273,13 @@ func (im *realImageManager) freeSpace(bytesToFree int64) (int64, error) { spaceFreed := int64(0) for _, image := range images { // Images that are currently in used were given a newer lastUsed. - if image.lastUsed.After(startTime) { + if image.lastUsed.After(freeTime) { break } // Avoid garbage collect the image if the image is not old enough. // In such a case, the image may have just been pulled down, and will be used by a container right away. - if startTime.Sub(image.firstDetected) < im.minAge { + if freeTime.Sub(image.firstDetected) < im.minAge { continue } diff --git a/pkg/kubelet/image_manager_test.go b/pkg/kubelet/image_manager_test.go index 02f9f2d9eb1..538277b55e3 100644 --- a/pkg/kubelet/image_manager_test.go +++ b/pkg/kubelet/image_manager_test.go @@ -22,12 +22,12 @@ import ( "time" cadvisorapiv2 "github.com/google/cadvisor/info/v2" - "github.com/ssoroka/ttime" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/util" ) var zero time.Time @@ -231,7 +231,7 @@ func TestFreeSpaceImagesInUseContainersAreIgnored(t *testing.T) { }, } - spaceFreed, err := manager.freeSpace(2048) + spaceFreed, err := manager.freeSpace(2048, time.Now()) assert := assert.New(t) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) @@ -271,7 +271,7 @@ func TestFreeSpaceRemoveByLeastRecentlyUsed(t *testing.T) { require.NoError(t, manager.detectImages(time.Now())) require.Equal(t, manager.imageRecordsLen(), 2) - spaceFreed, err := manager.freeSpace(1024) + spaceFreed, err := manager.freeSpace(1024, time.Now()) assert := assert.New(t) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) @@ -302,7 +302,7 @@ func TestFreeSpaceTiesBrokenByDetectedTime(t *testing.T) { require.NoError(t, manager.detectImages(time.Now())) require.Equal(t, manager.imageRecordsLen(), 2) - spaceFreed, err := manager.freeSpace(1024) + spaceFreed, err := manager.freeSpace(1024, time.Now()) assert := assert.New(t) require.NoError(t, err) assert.EqualValues(2048, spaceFreed) @@ -330,7 +330,7 @@ func TestFreeSpaceImagesAlsoDoesLookupByRepoTags(t *testing.T) { }, } - spaceFreed, err := manager.freeSpace(1024) + spaceFreed, err := manager.freeSpace(1024, time.Now()) assert := assert.New(t) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) @@ -431,18 +431,20 @@ func TestGarbageCollectImageNotOldEnough(t *testing.T) { }, } - require.NoError(t, manager.detectImages(ttime.Now())) + fakeClock := util.FakeClock{Time: time.Now()} + fmt.Println(fakeClock.Now()) + require.NoError(t, manager.detectImages(fakeClock.Now())) require.Equal(t, manager.imageRecordsLen(), 2) // no space freed since one image is in used, and another one is not old enough - spaceFreed, err := manager.freeSpace(1024) + spaceFreed, err := manager.freeSpace(1024, fakeClock.Now()) assert := assert.New(t) require.NoError(t, err) assert.EqualValues(0, spaceFreed) assert.Len(fakeRuntime.ImageList, 2) - // sleep 1 minute, then 1 image will be garbage collected - ttime.Sleep(defaultGCAge) - spaceFreed, err = manager.freeSpace(1024) + // move clock by minAge duration, then 1 image will be garbage collected + fakeClock.Step(manager.minAge) + spaceFreed, err = manager.freeSpace(1024, fakeClock.Now()) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) assert.Len(fakeRuntime.ImageList, 1)