rate: restore Go 1.6 support

https://golang.org/cl/41194 updatd the x/time/rate package to use the
standard library's context package for golang/go#16745 but App Engine
is stuck 14 months in the past and can only run Go 1.6, which lacks
context.

This CL restores Go 1.6 support.

The Go build system stopped testing packages against Go 1.6 once Go
1.8 came out, so just disable the tests for Go 1.6 rather than jumping
through hoops to make them work.

Change-Id: I271dcd492dd0ca53961340d63b26facb5dbdf025
Reviewed-on: https://go-review.googlesource.com/41624
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Chris Broadfoot <cbro@golang.org>
diff --git a/rate/rate.go b/rate/rate.go
index f657292..eabcd11 100644
--- a/rate/rate.go
+++ b/rate/rate.go
@@ -6,7 +6,6 @@
 package rate
 
 import (
-	"context"
 	"fmt"
 	"math"
 	"sync"
@@ -213,8 +212,19 @@
 	return &r
 }
 
+// contextContext is a temporary(?) copy of the context.Context type
+// to support both Go 1.6 using golang.org/x/net/context and Go 1.7+
+// with the built-in context package. If people ever stop using Go 1.6
+// we can remove this.
+type contextContext interface {
+	Deadline() (deadline time.Time, ok bool)
+	Done() <-chan struct{}
+	Err() error
+	Value(key interface{}) interface{}
+}
+
 // Wait is shorthand for WaitN(ctx, 1).
-func (lim *Limiter) Wait(ctx context.Context) (err error) {
+func (lim *Limiter) wait(ctx contextContext) (err error) {
 	return lim.WaitN(ctx, 1)
 }
 
@@ -222,7 +232,7 @@
 // It returns an error if n exceeds the Limiter's burst size, the Context is
 // canceled, or the expected wait time exceeds the Context's Deadline.
 // The burst limit is ignored if the rate limit is Inf.
-func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) {
+func (lim *Limiter) waitN(ctx contextContext, n int) (err error) {
 	if n > lim.burst && lim.limit != Inf {
 		return fmt.Errorf("rate: Wait(n=%d) exceeds limiter's burst %d", n, lim.burst)
 	}
diff --git a/rate/rate_go16.go b/rate/rate_go16.go
new file mode 100644
index 0000000..6bab185
--- /dev/null
+++ b/rate/rate_go16.go
@@ -0,0 +1,21 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.7
+
+package rate
+
+import "golang.org/x/net/context"
+
+// Wait is shorthand for WaitN(ctx, 1).
+func (lim *Limiter) Wait(ctx context.Context) (err error) {
+	return lim.waitN(ctx, 1)
+}
+
+// WaitN blocks until lim permits n events to happen.
+// It returns an error if n exceeds the Limiter's burst size, the Context is
+// canceled, or the expected wait time exceeds the Context's Deadline.
+func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) {
+	return lim.waitN(ctx, n)
+}
diff --git a/rate/rate_go17.go b/rate/rate_go17.go
new file mode 100644
index 0000000..f90d85f
--- /dev/null
+++ b/rate/rate_go17.go
@@ -0,0 +1,21 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package rate
+
+import "context"
+
+// Wait is shorthand for WaitN(ctx, 1).
+func (lim *Limiter) Wait(ctx context.Context) (err error) {
+	return lim.waitN(ctx, 1)
+}
+
+// WaitN blocks until lim permits n events to happen.
+// It returns an error if n exceeds the Limiter's burst size, the Context is
+// canceled, or the expected wait time exceeds the Context's Deadline.
+func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) {
+	return lim.waitN(ctx, n)
+}
diff --git a/rate/rate_test.go b/rate/rate_test.go
index 9600efa..e8add69 100644
--- a/rate/rate_test.go
+++ b/rate/rate_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.7
+
 package rate
 
 import (
@@ -163,6 +165,9 @@
 }
 
 func TestLongRunningQPS(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
 	if runtime.GOOS == "openbsd" {
 		t.Skip("low resolution time.Sleep invalidates test (golang.org/issue/14183)")
 		return