Make Start/Stop methods of ProcessState
This commit is contained in:
parent
ba978619bc
commit
2c1fea7616
|
@ -6,8 +6,6 @@ import (
|
|||
|
||||
"net/url"
|
||||
|
||||
"os/exec"
|
||||
|
||||
"k8s.io/kubectl/pkg/framework/test/internal"
|
||||
)
|
||||
|
||||
|
@ -38,16 +36,15 @@ type APIServer struct {
|
|||
StopTimeout time.Duration
|
||||
StartTimeout time.Duration
|
||||
|
||||
processState internal.ProcessState
|
||||
processState *internal.ProcessState
|
||||
}
|
||||
|
||||
// Start starts the apiserver, waits for it to come up, and returns an error, if occoured.
|
||||
func (s *APIServer) Start() error {
|
||||
var err error
|
||||
|
||||
err = s.ensureInitialized()
|
||||
if err != nil {
|
||||
return err
|
||||
if s.Etcd == nil {
|
||||
s.Etcd = &Etcd{}
|
||||
}
|
||||
|
||||
err = s.Etcd.Start()
|
||||
|
@ -55,32 +52,6 @@ func (s *APIServer) Start() error {
|
|||
return err
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"--authorization-mode=Node,RBAC",
|
||||
"--runtime-config=admissionregistration.k8s.io/v1alpha1",
|
||||
"--v=3", "--vmodule=",
|
||||
"--admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,SecurityContextDeny,DefaultStorageClass,DefaultTolerationSeconds,GenericAdmissionWebhook,ResourceQuota",
|
||||
"--admission-control-config-file=",
|
||||
"--bind-address=0.0.0.0",
|
||||
"--storage-backend=etcd3",
|
||||
fmt.Sprintf("--etcd-servers=%s", s.Etcd.processState.URL.String()),
|
||||
fmt.Sprintf("--cert-dir=%s", s.processState.Dir),
|
||||
fmt.Sprintf("--insecure-port=%s", s.processState.URL.Port()),
|
||||
fmt.Sprintf("--insecure-bind-address=%s", s.processState.URL.Hostname()),
|
||||
}
|
||||
|
||||
s.processState.Session, err = internal.Start(
|
||||
exec.Command(s.processState.Path, args...),
|
||||
fmt.Sprintf("Serving insecurely on %s", s.processState.URL.Host),
|
||||
s.processState.StartTimeout,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *APIServer) ensureInitialized() error {
|
||||
var err error
|
||||
|
||||
s.processState, err = internal.NewProcessState(
|
||||
"kube-apiserver",
|
||||
s.Path,
|
||||
|
@ -92,21 +63,31 @@ func (s *APIServer) ensureInitialized() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if s.Etcd == nil {
|
||||
s.Etcd = &Etcd{}
|
||||
s.processState.Args = []string{
|
||||
"--authorization-mode=Node,RBAC",
|
||||
"--runtime-config=admissionregistration.k8s.io/v1alpha1",
|
||||
"--v=3", "--vmodule=",
|
||||
"--admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,SecurityContextDeny,DefaultStorageClass,DefaultTolerationSeconds,GenericAdmissionWebhook,ResourceQuota",
|
||||
"--admission-control-config-file=",
|
||||
"--bind-address=0.0.0.0",
|
||||
"--storage-backend=etcd3",
|
||||
fmt.Sprintf("--etcd-servers=%s", s.Etcd.processState.URL.String()),
|
||||
fmt.Sprintf("--cert-dir=%s", s.processState.Dir),
|
||||
fmt.Sprintf("--insecure-port=%s", s.processState.URL.Port()),
|
||||
fmt.Sprintf("--insecure-bind-address=%s", s.processState.URL.Hostname()),
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
s.processState.Start(fmt.Sprintf("Serving insecurely on %s", s.processState.URL.Host))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop stops this process gracefully, waits for its termination, and cleans up the cert directory.
|
||||
func (s *APIServer) Stop() error {
|
||||
err := internal.Stop(
|
||||
s.processState.Session,
|
||||
s.processState.StopTimeout,
|
||||
s.processState.Dir,
|
||||
s.processState.DirNeedsCleaning,
|
||||
)
|
||||
err := s.processState.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"net/url"
|
||||
|
@ -21,35 +20,13 @@ type Etcd struct {
|
|||
StopTimeout time.Duration
|
||||
StartTimeout time.Duration
|
||||
|
||||
processState internal.ProcessState
|
||||
processState *internal.ProcessState
|
||||
}
|
||||
|
||||
// Start starts the etcd, waits for it to come up, and returns an error, if occoured.
|
||||
func (e *Etcd) Start() error {
|
||||
err := e.ensureInitialized()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"--debug",
|
||||
"--listen-peer-urls=http://localhost:0",
|
||||
fmt.Sprintf("--advertise-client-urls=%s", e.processState.URL),
|
||||
fmt.Sprintf("--listen-client-urls=%s", e.processState.URL),
|
||||
fmt.Sprintf("--data-dir=%s", e.processState.Dir),
|
||||
}
|
||||
|
||||
e.processState.Session, err = internal.Start(
|
||||
exec.Command(e.processState.Path, args...),
|
||||
fmt.Sprintf("serving insecure client requests on %s", e.processState.URL.Hostname()),
|
||||
e.processState.StartTimeout,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *Etcd) ensureInitialized() error {
|
||||
var err error
|
||||
|
||||
e.processState, err = internal.NewProcessState(
|
||||
"etcd",
|
||||
e.Path,
|
||||
|
@ -57,15 +34,22 @@ func (e *Etcd) ensureInitialized() error {
|
|||
e.DataDir,
|
||||
e.StartTimeout, e.StopTimeout,
|
||||
)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.processState.Args = []string{
|
||||
"--debug",
|
||||
"--listen-peer-urls=http://localhost:0",
|
||||
fmt.Sprintf("--advertise-client-urls=%s", e.processState.URL),
|
||||
fmt.Sprintf("--listen-client-urls=%s", e.processState.URL),
|
||||
fmt.Sprintf("--data-dir=%s", e.processState.Dir),
|
||||
}
|
||||
|
||||
return e.processState.Start(fmt.Sprintf("serving insecure client requests on %s", e.processState.URL.Hostname()))
|
||||
}
|
||||
|
||||
// Stop stops this process gracefully, waits for its termination, and cleans up the data directory.
|
||||
func (e *Etcd) Stop() error {
|
||||
return internal.Stop(
|
||||
e.processState.Session,
|
||||
e.processState.StopTimeout,
|
||||
e.processState.Dir,
|
||||
e.processState.DirNeedsCleaning,
|
||||
)
|
||||
return e.processState.Stop()
|
||||
}
|
||||
|
|
|
@ -21,10 +21,56 @@ type ProcessState struct {
|
|||
Path string
|
||||
StopTimeout time.Duration
|
||||
StartTimeout time.Duration
|
||||
Session *gexec.Session
|
||||
Session *gexec.Session // TODO private?
|
||||
Args []string
|
||||
}
|
||||
|
||||
func Start(command *exec.Cmd, startMessage string, startTimeout time.Duration) (*gexec.Session, error) {
|
||||
// TODO explore ProcessInputs, Defaulter, ProcessState, ...
|
||||
//type ProcessInput struct {
|
||||
// URL *url.URL
|
||||
// Dir string
|
||||
// DirNeedsCleaning bool
|
||||
// Path string
|
||||
// StopTimeout time.Duration
|
||||
// StartTimeout time.Duration
|
||||
//}
|
||||
//
|
||||
//type ProcessState2 struct {
|
||||
// ProcessInput
|
||||
// Args []string
|
||||
// StartString string
|
||||
//}
|
||||
//
|
||||
//func DoDefaulting(url, *url.URL) ProcessInput {
|
||||
// return ProcessInput{}
|
||||
//}
|
||||
//
|
||||
//func NewProcessState(input ProcessInput, args []string, startthing string) ProcessState {
|
||||
// return ProcessState2{input, args, startthing}
|
||||
//}
|
||||
|
||||
func (ps *ProcessState) Start(startMessage string) (err error) {
|
||||
ps.Session, err = Start(
|
||||
ps.Path,
|
||||
ps.Args,
|
||||
startMessage,
|
||||
ps.StartTimeout,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func (ps *ProcessState) Stop() error {
|
||||
return Stop(
|
||||
ps.Session,
|
||||
ps.StopTimeout,
|
||||
ps.Dir,
|
||||
ps.DirNeedsCleaning,
|
||||
)
|
||||
}
|
||||
|
||||
func Start(path string, args []string, startMessage string, startTimeout time.Duration) (*gexec.Session, error) {
|
||||
command := exec.Command(path, args...)
|
||||
|
||||
stdErr := gbytes.NewBuffer()
|
||||
detectedStart := stdErr.Detect(startMessage)
|
||||
timedOut := time.After(startTimeout)
|
||||
|
@ -73,12 +119,12 @@ func NewProcessState(
|
|||
dir string,
|
||||
startTimeout time.Duration,
|
||||
stopTimeout time.Duration,
|
||||
) (ProcessState, error) {
|
||||
) (*ProcessState, error) {
|
||||
if path == "" && symbolicName == "" {
|
||||
return ProcessState{}, fmt.Errorf("Either a path or a symbolic name need to be set")
|
||||
return nil, fmt.Errorf("Either a path or a symbolic name need to be set")
|
||||
}
|
||||
|
||||
state := ProcessState{
|
||||
state := &ProcessState{
|
||||
Path: path,
|
||||
URL: listenURL,
|
||||
Dir: dir,
|
||||
|
@ -95,7 +141,7 @@ func NewProcessState(
|
|||
am := &AddressManager{}
|
||||
port, host, err := am.Initialize()
|
||||
if err != nil {
|
||||
return ProcessState{}, err
|
||||
return nil, err
|
||||
}
|
||||
state.URL = &url.URL{
|
||||
Scheme: "http",
|
||||
|
@ -106,7 +152,7 @@ func NewProcessState(
|
|||
if dir == "" {
|
||||
newDir, err := ioutil.TempDir("", "k8s_test_framework_")
|
||||
if err != nil {
|
||||
return ProcessState{}, err
|
||||
return nil, err
|
||||
}
|
||||
state.Dir = newDir
|
||||
state.DirNeedsCleaning = true
|
||||
|
|
|
@ -15,17 +15,15 @@ import (
|
|||
|
||||
var _ = Describe("Start", func() {
|
||||
var (
|
||||
command *exec.Cmd
|
||||
timeout time.Duration
|
||||
)
|
||||
BeforeEach(func() {
|
||||
command = getSimpleCommand()
|
||||
timeout = 200 * time.Millisecond
|
||||
})
|
||||
|
||||
It("can start a process", func() {
|
||||
timeout = 5 * time.Second
|
||||
session, err := Start(command, "loop 3", timeout)
|
||||
session, err := Start("bash", simpleBashScript, "loop 3", timeout)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Consistently(session.ExitCode).Should(BeNumerically("==", -1))
|
||||
|
@ -33,7 +31,7 @@ var _ = Describe("Start", func() {
|
|||
|
||||
Context("when process takes too long to start", func() {
|
||||
It("returns an timeout error", func() {
|
||||
session, err := Start(command, "loop 3000", timeout)
|
||||
session, err := Start("bash", simpleBashScript, "loop 3000", timeout)
|
||||
|
||||
Expect(err).To(MatchError(ContainSubstring("timeout")))
|
||||
Eventually(session.ExitCode, 10).Should(BeNumerically("==", 143))
|
||||
|
@ -41,11 +39,8 @@ var _ = Describe("Start", func() {
|
|||
})
|
||||
|
||||
Context("when command cannot be started", func() {
|
||||
BeforeEach(func() {
|
||||
command = exec.Command("/notexistent")
|
||||
})
|
||||
It("propagates the error", func() {
|
||||
_, err := Start(command, "does not matter", timeout)
|
||||
_, err := Start("/notexeistent", []string{}, "does not matter", timeout)
|
||||
|
||||
Expect(os.IsNotExist(err)).To(BeTrue())
|
||||
})
|
||||
|
@ -211,17 +206,19 @@ var _ = Describe("NewProcessState", func() {
|
|||
|
||||
})
|
||||
|
||||
func getSimpleCommand() *exec.Cmd {
|
||||
return exec.Command(
|
||||
"bash", "-c",
|
||||
`
|
||||
i=0
|
||||
while true
|
||||
do
|
||||
echo "loop $i" >&2
|
||||
let 'i += 1'
|
||||
sleep 0.2
|
||||
done
|
||||
`,
|
||||
)
|
||||
var simpleBashScript = []string{
|
||||
"-c",
|
||||
`
|
||||
i=0
|
||||
while true
|
||||
do
|
||||
echo "loop $i" >&2
|
||||
let 'i += 1'
|
||||
sleep 0.2
|
||||
done
|
||||
`,
|
||||
}
|
||||
|
||||
func getSimpleCommand() *exec.Cmd {
|
||||
return exec.Command("bash", simpleBashScript...)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue