Skip to content

Commit cb52843

Browse files
committed
test: add missing integration test for PouchContainer
Signed-off-by: Allen Sun <[email protected]>
1 parent e378474 commit cb52843

File tree

9 files changed

+125
-76
lines changed

9 files changed

+125
-76
lines changed

apis/server/exec_bridge.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strconv"
1010

1111
"github.com/alibaba/pouch/apis/types"
12+
"github.com/alibaba/pouch/pkg/errtypes"
1213
"github.com/alibaba/pouch/pkg/httputils"
1314
"github.com/alibaba/pouch/pkg/streams"
1415

@@ -102,6 +103,9 @@ func (s *Server) startContainerExec(ctx context.Context, rw http.ResponseWriter,
102103
}
103104

104105
if err := s.ContainerMgr.StartExec(ctx, name, attach); err != nil {
106+
if errtypes.IsConflict(err) {
107+
return err
108+
}
105109
if config.Detach {
106110
return err
107111
}

apis/server/router.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func HandleErrorResponse(w http.ResponseWriter, err error) {
241241
code = http.StatusNotFound
242242
} else if errtypes.IsInvalidParam(err) {
243243
code = http.StatusBadRequest
244-
} else if errtypes.IsAlreadyExisted(err) {
244+
} else if errtypes.IsAlreadyExisted(err) || errtypes.IsConflict(err) {
245245
code = http.StatusConflict
246246
} else if errtypes.IsNotModified(err) {
247247
code = http.StatusNotModified

daemon/mgr/container.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1656,7 +1656,7 @@ func (mgr *ContainerManager) attachCRILog(c *Container, logPath string) error {
16561656

16571657
func (mgr *ContainerManager) initExecIO(id string, withStdin bool) (*containerio.IO, error) {
16581658
if io := mgr.IOs.Get(id); io != nil {
1659-
return nil, errors.Wrap(errtypes.ErrConflict, "failed to create containerIO")
1659+
return nil, errors.Wrap(errtypes.ErrConflict, "failed to create execIO")
16601660
}
16611661

16621662
cntrio := containerio.NewIO(id, withStdin)

pkg/errtypes/errors.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ func IsPreCheckFailed(err error) bool {
102102
return checkError(err, codePreCheckFailed)
103103
}
104104

105+
// IsConflict checks if the error is conflict.
106+
func IsConflict(err error) bool {
107+
return checkError(err, codeConflict)
108+
}
109+
105110
func checkError(err error, code int) bool {
106111
err = causeError(err)
107112

test/api_container_create_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,29 @@ func testCreateContainerWithBadParam(c *check.C, cname string, obj map[string]in
215215
}
216216

217217
// TestCreateWithBadStopTimeout using bad stopTimeout to create container.
218-
func (suite *APIContainerCreateSuite) TestCreateWithBadStopTimeout(c *check.C) {
218+
func (suite *APIContainerCreateSuite) testCreateWithBadParams(c *check.C) {
219219
testCreateContainerWithBadParam(c,
220220
"TestCreateWithBadStopTimeout",
221221
map[string]interface{}{
222222
"Image": busyboxImage,
223223
"StopTimeout": -1,
224224
})
225+
226+
// too long length
227+
testCreateContainerWithBadParam(c,
228+
"1234567890-1234567890-1234567890-1234567890123456789",
229+
map[string]interface{}{
230+
"Image": busyboxImage,
231+
})
232+
233+
// invalid characters
234+
testCreateContainerWithBadParam(c,
235+
"??????><!@#$%^&*",
236+
map[string]interface{}{
237+
"Image": busyboxImage,
238+
})
239+
240+
// TODO: add more container creation option check
225241
}
226242

227243
func (suite *APIContainerCreateSuite) TestCreateNvidiaConfig(c *check.C) {

test/api_container_exec_inspect_test.go

Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ package main
33
import (
44
"time"
55

6-
"github.com/alibaba/pouch/apis/types"
76
"github.com/alibaba/pouch/test/environment"
8-
"github.com/alibaba/pouch/test/request"
97

108
"github.com/go-check/check"
119
)
@@ -26,70 +24,38 @@ func (suite *APIContainerExecInspectSuite) SetUpTest(c *check.C) {
2624

2725
// TestContainerCreateExecOk tests execing containers is OK.
2826
func (suite *APIContainerExecInspectSuite) TestContainerExecInspectOk(c *check.C) {
29-
c.Skip("skip flaky test due to issue#1372")
3027
cname := "TestContainerExecInspectOk"
3128

3229
CreateBusyboxContainerOk(c, cname)
30+
defer DelContainerForceMultyTime(c, cname)
3331

3432
StartContainerOk(c, cname)
3533

36-
obj := map[string]interface{}{
37-
"Cmd": []string{"sleep", "9"},
38-
"Detach": true,
39-
}
40-
body := request.WithJSONBody(obj)
41-
resp, err := request.Post("/containers/"+cname+"/exec", body)
42-
c.Assert(err, check.IsNil)
43-
CheckRespStatus(c, resp, 201)
44-
45-
var execCreateResp types.ExecCreateResp
46-
err = request.DecodeBody(&execCreateResp, resp.Body)
47-
c.Assert(err, check.IsNil)
48-
49-
execid := execCreateResp.ID
50-
51-
// inspect the exec before exec start
52-
resp, err = request.Get("/exec/" + execid + "/json")
53-
c.Assert(err, check.IsNil)
54-
CheckRespStatus(c, resp, 200)
55-
56-
var execInspect01 types.ContainerExecInspect
57-
request.DecodeBody(&execInspect01, resp.Body)
34+
// create an exec and get the execID
35+
// and inspect the exec before exec start
5836

59-
c.Assert(execInspect01.Running, check.Equals, false)
60-
c.Assert(execInspect01.ExitCode, check.Equals, int64(0))
61-
62-
// start the exec
37+
execid := CreateExecCmdOk(c, cname, "sleep", "9")
6338
{
64-
resp, conn, _, err := StartContainerExec(c, execid, false, false)
65-
c.Assert(err, check.IsNil)
66-
CheckRespStatus(c, resp, 101)
67-
c.Assert(conn.Close(), check.IsNil)
39+
execInspectResp := InspectExecOk(execid)
40+
c.Assert(execInspectResp.Running, check.Equals, false)
41+
c.Assert(execInspectResp.ExitCode, check.Equals, int64(0))
6842
}
6943

70-
// inspect the exec after exec start
71-
resp, err = request.Get("/exec/" + execid + "/json")
72-
c.Assert(err, check.IsNil)
73-
CheckRespStatus(c, resp, 200)
74-
75-
var execInspect02 types.ContainerExecInspect
76-
request.DecodeBody(&execInspect02, resp.Body)
44+
// start the exec
45+
StartContainerExecOk(c, execid)
7746

78-
c.Assert(execInspect02.Running, check.Equals, true)
79-
c.Assert(execInspect02.ExitCode, check.Equals, int64(0))
47+
// inspect the exec after exec start
48+
{
49+
execInspectResp = InspectExecOk(execid)
50+
c.Assert(execInspectResp.Running, check.Equals, true)
51+
c.Assert(execInspectResp.ExitCode, check.Equals, int64(0))
52+
}
8053

8154
// sleep 10s to wait the process exit
82-
time.Sleep(10 * time.Second)
83-
84-
resp, err = request.Get("/exec/" + execid + "/json")
85-
c.Assert(err, check.IsNil)
86-
CheckRespStatus(c, resp, 200)
87-
88-
var execInspect03 types.ContainerExecInspect
89-
request.DecodeBody(&execInspect03, resp.Body)
90-
91-
c.Assert(execInspect03.Running, check.Equals, false)
92-
c.Assert(execInspect03.ExitCode, check.Equals, int64(0))
93-
94-
DelContainerForceMultyTime(c, cname)
55+
{
56+
time.Sleep(10 * time.Second)
57+
execInspectResp = InspectExecOk(execid)
58+
c.Assert(execInspectResp.Running, check.Equals, false)
59+
c.Assert(execInspectResp.ExitCode, check.Equals, int64(0))
60+
}
9561
}

test/api_container_exec_start_test.go

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"crypto/rand"
77
"encoding/hex"
8+
"fmt"
89
"io"
910
"net"
1011
"strings"
@@ -114,7 +115,7 @@ func (suite *APIContainerExecStartSuite) TestContainerExecStartWithoutUpgrade(c
114115
defer DelContainerForceMultyTime(c, cname)
115116

116117
StartContainerOk(c, cname)
117-
execid := CreateExecEchoOk(c, cname, content)
118+
execid := CreateExecCmdOk(c, cname, "echo", content)
118119

119120
obj := map[string]interface{}{}
120121
resp, conn, br, err := request.Hijack("/exec/"+execid+"/start", request.WithJSONBody(obj))
@@ -133,7 +134,7 @@ func (suite *APIContainerExecStartSuite) TestContainerExecStart(c *check.C) {
133134

134135
StartContainerOk(c, cname)
135136

136-
execid := CreateExecEchoOk(c, cname, content)
137+
execid := CreateExecCmdOk(c, cname, "echo", content)
137138

138139
resp, conn, reader, err := StartContainerExec(c, execid, false, false)
139140
c.Assert(err, check.IsNil)
@@ -151,20 +152,58 @@ func (suite *APIContainerExecStartSuite) TestContainerExecStartNotFound(c *check
151152
CheckRespStatus(c, resp, 404)
152153
}
153154

154-
// TestContainerExecStartStopped tests start a process in a stopped container return error.
155-
func (suite *APIContainerExecStartSuite) TestContainerExecStartStopped(c *check.C) {
156-
// TODO: missing case
157-
helpwantedForMissingCase(c, "container api exec start stoped case")
158-
}
155+
// TestContainerExecStartStopped tests start a process in a stopped and pause container return error.
156+
func (suite *APIContainerExecStartSuite) TestExecStartInStoppedAndPausedContainer(c *check.C) {
157+
cname := "TestExecStartInStoppedAndPausedContainer"
158+
159+
// only create the container, the container is stopped/created.
160+
CreateBusyboxContainerOk(c, cname)
161+
defer DelContainerForceMultyTime(c, cname)
162+
StartContainerOk(c, cname)
163+
164+
execid := CreateExecCmdOk(c, cname, "echo", "test")
165+
166+
// test exec start in stopped container
167+
168+
// stop the running container
169+
StopContainerOk(c, cname)
170+
171+
obj := map[string]interface{}{}
172+
body := request.WithJSONBody(obj)
173+
resp, err := request.Post(fmt.Sprintf("/exec/%s/start", execid), body)
174+
175+
c.Assert(err, check.IsNil)
176+
CheckRespStatus(c, resp, 409)
177+
178+
// start and pause the container
179+
StartContainerOk(c, cname)
180+
PauseContainerOk(c, cname)
159181

160-
// TestContainerExecStartPaused tests start a process in a paused container return error.
161-
func (suite *APIContainerExecStartSuite) TestContainerExecStartPaused(c *check.C) {
162-
// TODO: missing case
163-
helpwantedForMissingCase(c, "container api exec start paused case")
182+
// test exec start in paused container
183+
resp, err = request.Post(fmt.Sprintf("/exec/%s/start", execid), body)
184+
185+
c.Assert(err, check.IsNil)
186+
CheckRespStatus(c, resp, 409)
164187
}
165188

166189
// TestContainerExecStartDup tests start a process twice return error.
167190
func (suite *APIContainerExecStartSuite) TestContainerExecStartDup(c *check.C) {
168-
// TODO: missing case
169-
helpwantedForMissingCase(c, "container api exec start twice case")
191+
cname := "TestContainerExecStartDup"
192+
193+
CreateBusyboxContainerOk(c, cname)
194+
defer DelContainerForceMultyTime(c, cname)
195+
196+
StartContainerOk(c, cname)
197+
198+
obj := map[string]interface{}{}
199+
body := request.WithJSONBody(obj)
200+
201+
execid := CreateExecCmdOk(c, cname, "top")
202+
resp, err := request.Post(fmt.Sprintf("/exec/%s/start", execid), body)
203+
c.Assert(err, check.IsNil)
204+
CheckRespStatus(c, resp, 200)
205+
206+
resp, err = request.Post(fmt.Sprintf("/exec/%s/start", execid), body)
207+
c.Assert(err, check.IsNil)
208+
CheckRespStatus(c, resp, 409)
170209
}

test/api_container_start_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,4 @@ func (suite *APIContainerStartSuite) TestStartAlreadyRunningContainer(c *check.C
105105
resp, err := request.Post("/containers/" + cname + "/start")
106106
c.Assert(err, check.IsNil)
107107
CheckRespStatus(c, resp, 304)
108-
109108
}

test/util_api.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ func DelImageForceOk(c *check.C, iname string) {
198198
CheckRespStatus(c, resp, 204)
199199
}
200200

201-
// CreateExecEchoOk exec process's environment with "echo" CMD.
202-
func CreateExecEchoOk(c *check.C, cname string, echo string) string {
201+
// CreateExecCmdOk exec process's environment with specific CMD.
202+
func CreateExecCmdOk(c *check.C, cname string, cmd ...string) string {
203203
obj := map[string]interface{}{
204-
"Cmd": []string{"echo", echo},
204+
"Cmd": cmd,
205205
"Detach": true,
206206
"AttachStderr": true,
207207
"AttachStdout": true,
@@ -221,8 +221,16 @@ func CreateExecEchoOk(c *check.C, cname string, echo string) string {
221221
return got.ID
222222
}
223223

224+
// StartContainerExecOk starts executing a process in container and check if it is successful.
225+
func StartContainerExecOk(c *check.C, execID string) {
226+
resp, conn, _, err := startContainerExec(c, execID, false, false)
227+
c.Assert(err, check.IsNil)
228+
CheckRespStatus(c, resp, 101)
229+
c.Assert(conn.Close(), check.IsNil)
230+
}
231+
224232
// StartContainerExec starts executing a process in the container.
225-
func StartContainerExec(c *check.C, execid string, tty bool, detach bool) (*http.Response, net.Conn, *bufio.Reader, error) {
233+
func startContainerExec(c *check.C, execid string, tty bool, detach bool) (*http.Response, net.Conn, *bufio.Reader, error) {
226234
obj := map[string]interface{}{
227235
"Detach": detach,
228236
"Tty": tty,
@@ -234,6 +242,18 @@ func StartContainerExec(c *check.C, execid string, tty bool, detach bool) (*http
234242
request.WithJSONBody(obj))
235243
}
236244

245+
// InspectExecOk inspects an exec of container.
246+
func InspectExecOk(c *check.C, execID string) types.ContainerExecInspect {
247+
resp, err := request.Get("/exec/" + execid + "/json")
248+
c.Assert(err, check.IsNil)
249+
CheckRespStatus(c, resp, 200)
250+
251+
var execInspectResp types.ContainerExecInspect
252+
err = request.DecodeBody(&execInspectResp, resp.Body)
253+
c.Assert(err, check.IsNil)
254+
return execInspectResp
255+
}
256+
237257
// CreateVolumeOK creates a volume in pouchd.
238258
func CreateVolumeOK(c *check.C, name, driver string, options map[string]string) {
239259
obj := map[string]interface{}{

0 commit comments

Comments
 (0)