-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #749 from pivotal-k8s/move-testing-framework-squash
⚠ Bring in testing framework
- Loading branch information
Showing
36 changed files
with
1,929 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,7 @@ aliases: | |
- shawn-hurley | ||
- gerred | ||
- joelanford | ||
testing-integration-admins: | ||
- apelisse | ||
- hoegaarden | ||
- totherme |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# See the OWNERS docs: https://git.k8s.io/community/contributors/devel/owners.md | ||
|
||
approvers: | ||
- controller-runtime-admins | ||
- testing-integration-admins |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
assets/bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Integration Testing Framework | ||
|
||
This package has been moved from [https://github.com/kubernetes-sigs/testing_frameworks/tree/master/integration](https://github.com/kubernetes-sigs/testing_frameworks/tree/master/integration). | ||
|
||
A framework for integration testing components of kubernetes. This framework is | ||
intended to work properly both in CI, and on a local dev machine. It therefore | ||
explicitly supports both Linux and Darwin. | ||
|
||
For detailed documentation see the | ||
[![GoDoc](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/internal/testing/integration?status.svg)](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/internal/testing/integration). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package addr_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
"testing" | ||
) | ||
|
||
func TestAddr(t *testing.T) { | ||
t.Parallel() | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Addr Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package addr | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"sync" | ||
"time" | ||
) | ||
|
||
const ( | ||
portReserveTime = 1 * time.Minute | ||
portConflictRetry = 100 | ||
) | ||
|
||
type portCache struct { | ||
lock sync.Mutex | ||
ports map[int]time.Time | ||
} | ||
|
||
func (c *portCache) add(port int) bool { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
// remove outdated port | ||
for p, t := range c.ports { | ||
if time.Since(t) > portReserveTime { | ||
delete(c.ports, p) | ||
} | ||
} | ||
// try allocating new port | ||
if _, ok := c.ports[port]; ok { | ||
return false | ||
} | ||
c.ports[port] = time.Now() | ||
return true | ||
} | ||
|
||
var cache = &portCache{ | ||
ports: make(map[int]time.Time), | ||
} | ||
|
||
func suggest() (port int, resolvedHost string, err error) { | ||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0") | ||
if err != nil { | ||
return | ||
} | ||
l, err := net.ListenTCP("tcp", addr) | ||
if err != nil { | ||
return | ||
} | ||
port = l.Addr().(*net.TCPAddr).Port | ||
defer func() { | ||
err = l.Close() | ||
}() | ||
resolvedHost = addr.IP.String() | ||
return | ||
} | ||
|
||
// Suggest suggests an address a process can listen on. It returns | ||
// a tuple consisting of a free port and the hostname resolved to its IP. | ||
// It makes sure that new port allocated does not conflict with old ports | ||
// allocated within 1 minute. | ||
func Suggest() (port int, resolvedHost string, err error) { | ||
for i := 0; i < portConflictRetry; i++ { | ||
port, resolvedHost, err = suggest() | ||
if err != nil { | ||
return | ||
} | ||
if cache.add(port) { | ||
return | ||
} | ||
} | ||
err = fmt.Errorf("no free ports found after %d retries", portConflictRetry) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package addr_test | ||
|
||
import ( | ||
"sigs.k8s.io/controller-runtime/pkg/internal/testing/integration/addr" | ||
|
||
"net" | ||
"strconv" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("SuggestAddress", func() { | ||
It("returns a free port and an address to bind to", func() { | ||
port, host, err := addr.Suggest() | ||
|
||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(host).To(Or(Equal("127.0.0.1"), Equal("::1"))) | ||
Expect(port).NotTo(Equal(0)) | ||
|
||
addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(host, strconv.Itoa(port))) | ||
Expect(err).NotTo(HaveOccurred()) | ||
l, err := net.ListenTCP("tcp", addr) | ||
defer func() { | ||
Expect(l.Close()).To(Succeed()) | ||
}() | ||
Expect(err).NotTo(HaveOccurred()) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package integration | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"net/url" | ||
"time" | ||
|
||
"sigs.k8s.io/controller-runtime/pkg/internal/testing/integration/addr" | ||
"sigs.k8s.io/controller-runtime/pkg/internal/testing/integration/internal" | ||
) | ||
|
||
// APIServer knows how to run a kubernetes apiserver. | ||
type APIServer struct { | ||
// URL is the address the ApiServer should listen on for client connections. | ||
// | ||
// If this is not specified, we default to a random free port on localhost. | ||
URL *url.URL | ||
|
||
// SecurePort is the additional secure port that the APIServer should listen on. | ||
SecurePort int | ||
|
||
// Path is the path to the apiserver binary. | ||
// | ||
// If this is left as the empty string, we will attempt to locate a binary, | ||
// by checking for the TEST_ASSET_KUBE_APISERVER environment variable, and | ||
// the default test assets directory. See the "Binaries" section above (in | ||
// doc.go) for details. | ||
Path string | ||
|
||
// Args is a list of arguments which will passed to the APIServer binary. | ||
// Before they are passed on, they will be evaluated as go-template strings. | ||
// This means you can use fields which are defined and exported on this | ||
// APIServer struct (e.g. "--cert-dir={{ .Dir }}"). | ||
// Those templates will be evaluated after the defaulting of the APIServer's | ||
// fields has already happened and just before the binary actually gets | ||
// started. Thus you have access to calculated fields like `URL` and others. | ||
// | ||
// If not specified, the minimal set of arguments to run the APIServer will | ||
// be used. | ||
Args []string | ||
|
||
// CertDir is a path to a directory containing whatever certificates the | ||
// APIServer will need. | ||
// | ||
// If left unspecified, then the Start() method will create a fresh temporary | ||
// directory, and the Stop() method will clean it up. | ||
CertDir string | ||
|
||
// EtcdURL is the URL of the Etcd the APIServer should use. | ||
// | ||
// If this is not specified, the Start() method will return an error. | ||
EtcdURL *url.URL | ||
|
||
// StartTimeout, StopTimeout specify the time the APIServer is allowed to | ||
// take when starting and stoppping before an error is emitted. | ||
// | ||
// If not specified, these default to 20 seconds. | ||
StartTimeout time.Duration | ||
StopTimeout time.Duration | ||
|
||
// Out, Err specify where APIServer should write its StdOut, StdErr to. | ||
// | ||
// If not specified, the output will be discarded. | ||
Out io.Writer | ||
Err io.Writer | ||
|
||
processState *internal.ProcessState | ||
} | ||
|
||
// Start starts the apiserver, waits for it to come up, and returns an error, | ||
// if occurred. | ||
func (s *APIServer) Start() error { | ||
if s.processState == nil { | ||
if err := s.setProcessState(); err != nil { | ||
return err | ||
} | ||
} | ||
return s.processState.Start(s.Out, s.Err) | ||
} | ||
|
||
func (s *APIServer) setProcessState() error { | ||
if s.EtcdURL == nil { | ||
return fmt.Errorf("expected EtcdURL to be configured") | ||
} | ||
|
||
var err error | ||
|
||
s.processState = &internal.ProcessState{} | ||
|
||
s.processState.DefaultedProcessInput, err = internal.DoDefaulting( | ||
"kube-apiserver", | ||
s.URL, | ||
s.CertDir, | ||
s.Path, | ||
s.StartTimeout, | ||
s.StopTimeout, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Defaulting the secure port | ||
if s.SecurePort == 0 { | ||
s.SecurePort, _, err = addr.Suggest() | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
s.processState.HealthCheckEndpoint = "/healthz" | ||
|
||
s.URL = &s.processState.URL | ||
s.CertDir = s.processState.Dir | ||
s.Path = s.processState.Path | ||
s.StartTimeout = s.processState.StartTimeout | ||
s.StopTimeout = s.processState.StopTimeout | ||
|
||
s.processState.Args, err = internal.RenderTemplates( | ||
internal.DoAPIServerArgDefaulting(s.Args), s, | ||
) | ||
return err | ||
} | ||
|
||
// Stop stops this process gracefully, waits for its termination, and cleans up | ||
// the CertDir if necessary. | ||
func (s *APIServer) Stop() error { | ||
return s.processState.Stop() | ||
} | ||
|
||
// APIServerDefaultArgs exposes the default args for the APIServer so that you | ||
// can use those to append your own additional arguments. | ||
// | ||
// The internal default arguments are explicitly copied here, we don't want to | ||
// allow users to change the internal ones. | ||
var APIServerDefaultArgs = append([]string{}, internal.APIServerDefaultArgs...) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This directory will be the home of some binaries which are downloaded with `pkg/framework/test/scripts/download-binaries`. |
Oops, something went wrong.