"os/exec"
"sort"
"strings"
+ "sync"
"syscall"
"testing"
"time"
ContainerRecord
Logs map[string]*bytes.Buffer
WasSetRunning bool
+ sync.Mutex
}
type KeepTestClient struct {
var otherManifest = ". 68a84f561b1d1708c6baff5e019a9ab3+46+Ae5d0af96944a3690becb1decdf60cc1c937f556d@5693216f 0:46:md5sum.txt\n"
var otherPDH = "a3e8f74c6f101eae01fa08bfb4e49b3a+54"
+var fakeAuthUUID = "zzzzz-gj3su-55pqoyepgi2glem"
+var fakeAuthToken = "a3ltuwzqcu2u4sc0q7yhpc2w7s00fdcqecg5d6e0u3pfohmbjt"
+
type TestDockerClient struct {
imageLoaded string
logReader io.ReadCloser
parameters arvadosclient.Dict,
output interface{}) error {
+ this.Mutex.Lock()
+ defer this.Mutex.Unlock()
+
this.Calls += 1
this.Content = append(this.Content, parameters)
return nil
}
+func (this *ArvTestClient) Call(method, resourceType, uuid, action string, parameters arvadosclient.Dict, output interface{}) error {
+ switch {
+ case method == "GET" && resourceType == "containers" && action == "auth":
+ return json.Unmarshal([]byte(`{
+ "kind": "arvados#api_client_authorization",
+ "uuid": "`+fakeAuthUUID+`",
+ "api_token": "`+fakeAuthToken+`"
+ }`), output)
+ default:
+ return fmt.Errorf("Not found")
+ }
+}
+
func (this *ArvTestClient) Get(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error {
if resourceType == "collections" {
if uuid == hwPDH {
}
func (this *ArvTestClient) Update(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) (err error) {
+ this.Mutex.Lock()
+ defer this.Mutex.Unlock()
this.Calls += 1
this.Content = append(this.Content, parameters)
if resourceType == "containers" {
if parameters["container"].(arvadosclient.Dict)["state"] == "Running" {
this.WasSetRunning = true
}
+ }
+ return nil
+}
+// CalledWith returns the parameters from the first API call whose
+// parameters match jpath/string. E.g., CalledWith(c, "foo.bar",
+// "baz") returns parameters with parameters["foo"]["bar"]=="baz". If
+// no call matches, it returns nil.
+func (this *ArvTestClient) CalledWith(jpath, expect string) arvadosclient.Dict {
+ call: for _, content := range this.Content {
+ var v interface{} = content
+ for _, k := range strings.Split(jpath, ".") {
+ if dict, ok := v.(arvadosclient.Dict); !ok {
+ continue call
+ } else {
+ v = dict[k]
+ }
+ }
+ if v, ok := v.(string); ok && v == expect {
+ return content
+ }
}
return nil
}
return nil
}
+func (this ArvErrorTestClient) Call(method, resourceType, uuid, action string, parameters arvadosclient.Dict, output interface{}) error {
+ return errors.New("ArvError")
+}
+
func (this ArvErrorTestClient) Get(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error {
return errors.New("ArvError")
}
err := cr.LoadImage()
c.Check(err, IsNil)
+ err = cr.CreateContainer()
+ c.Check(err, IsNil)
+
err = cr.StartContainer()
c.Check(err, IsNil)
*cr.ExitCode = 42
cr.finalState = "Complete"
- err := cr.UpdateContainerRecordComplete()
+ err := cr.UpdateContainerRecordFinal()
c.Check(err, IsNil)
c.Check(api.Content[0]["container"].(arvadosclient.Dict)["log"], Equals, *cr.LogsPDH)
cr.Cancelled = true
cr.finalState = "Cancelled"
- err := cr.UpdateContainerRecordComplete()
+ err := cr.UpdateContainerRecordFinal()
c.Check(err, IsNil)
c.Check(api.Content[0]["container"].(arvadosclient.Dict)["log"], IsNil)
// dress rehearsal of the Run() function, starting from a JSON container record.
func FullRunHelper(c *C, record string, fn func(t *TestDockerClient)) (api *ArvTestClient, cr *ContainerRunner) {
rec := ContainerRecord{}
- err := json.NewDecoder(strings.NewReader(record)).Decode(&rec)
+ err := json.Unmarshal([]byte(record), &rec)
c.Check(err, IsNil)
docker := NewTestDockerClient()
}`
rec := ContainerRecord{}
- err := json.NewDecoder(strings.NewReader(record)).Decode(&rec)
+ err := json.Unmarshal([]byte(record), &rec)
c.Check(err, IsNil)
docker := NewTestDockerClient()
go func() {
for cr.ContainerID == "" {
- time.Sleep(1 * time.Second)
+ time.Sleep(time.Millisecond)
}
cr.SigChan <- syscall.SIGINT
}()
err = cr.Run()
c.Check(err, IsNil)
-
- c.Check(api.Calls, Equals, 6)
- c.Check(api.Content[5]["container"].(arvadosclient.Dict)["log"], NotNil)
-
if err != nil {
for k, v := range api.Logs {
c.Log(k)
}
}
+ c.Assert(api.Calls, Equals, 6)
+ c.Check(api.Content[5]["container"].(arvadosclient.Dict)["log"], IsNil)
c.Check(api.Content[5]["container"].(arvadosclient.Dict)["state"], Equals, "Cancelled")
-
c.Check(strings.HasSuffix(api.Logs["stdout"].String(), "foo\n"), Equals, true)
}
}
type ArvMountCmdLine struct {
- Cmd []string
+ Cmd []string
+ token string
}
-func (am *ArvMountCmdLine) ArvMountTest(c []string) (*exec.Cmd, error) {
+func (am *ArvMountCmdLine) ArvMountTest(c []string, token string) (*exec.Cmd, error) {
am.Cmd = c
+ am.token = token
return nil, nil
}
}
func (s *TestSuite) TestStdout(c *C) {
- tmpdir, _ := ioutil.TempDir("", "test-stdout")
- defer func() {
- os.RemoveAll(tmpdir)
- }()
-
helperRecord := `{`
helperRecord += `"command": ["/bin/sh", "-c", "echo $FROBIZ"],`
helperRecord += `"container_image": "d4ab34d3d4f8a72f5c4973051ae69fab+122",`
helperRecord += `"cwd": "/bin",`
helperRecord += `"environment": {"FROBIZ": "bilbo"},`
- helperRecord += `"mounts": {"stdout": {"kind": "file", "path": "` + tmpdir + `/a/b/c.out"} },`
- helperRecord += `"output_path": "` + tmpdir + `",`
+ helperRecord += `"mounts": {"/tmp": {"kind": "tmp"}, "stdout": {"kind": "file", "path": "/tmp/a/b/c.out"} },`
+ helperRecord += `"output_path": "/tmp",`
helperRecord += `"priority": 1,`
helperRecord += `"runtime_constraints": {}`
helperRecord += `}`
- api, cr := FullRunHelper(c, helperRecord, func(t *TestDockerClient) {
+ api, _ := FullRunHelper(c, helperRecord, func(t *TestDockerClient) {
t.logWriter.Write(dockerLog(1, t.env[0][7:]+"\n"))
t.logWriter.Close()
t.finish <- dockerclient.WaitResult{ExitCode: 0}
})
- c.Check(api.Calls, Equals, 6)
+
+ c.Assert(api.Calls, Equals, 6)
c.Check(api.Content[5]["container"].(arvadosclient.Dict)["exit_code"], Equals, 0)
c.Check(api.Content[5]["container"].(arvadosclient.Dict)["state"], Equals, "Complete")
- stdout := cr.HostOutputDir + "/a/b/c.out"
- data, err := ioutil.ReadFile(stdout)
- c.Check(err, IsNil)
- c.Check("bilbo\n", Equals, string(data))
+ c.Check(api.CalledWith("collection.manifest_text", "./a/b 307372fa8fd5c146b22ae7a45b49bc31+6 0:6:c.out\n"), Not(IsNil))
}
// Used by the TestStdoutWithWrongPath*()
func StdoutErrorRunHelper(c *C, record string, fn func(t *TestDockerClient)) (api *ArvTestClient, cr *ContainerRunner, err error) {
rec := ContainerRecord{}
- err = json.NewDecoder(strings.NewReader(record)).Decode(&rec)
+ err = json.Unmarshal([]byte(record), &rec)
c.Check(err, IsNil)
docker := NewTestDockerClient()
c.Check(err, NotNil)
c.Check(strings.Contains(err.Error(), "Unsupported mount kind 'collection' for stdout"), Equals, true)
}
-
-func (s *TestSuite) TestStdoutNoSuchDir(c *C) {
- tmpdir, _ := ioutil.TempDir("", "test-stdout")
- defer func() {
- os.RemoveAll(tmpdir)
- }()
-
- helperRecord := `{`
- helperRecord += `"command": ["/bin/sh", "-c", "echo $FROBIZ"],`
- helperRecord += `"container_image": "d4ab34d3d4f8a72f5c4973051ae69fab+122",`
- helperRecord += `"cwd": "/bin",`
- helperRecord += `"environment": {"FROBIZ": "bilbo"},`
- helperRecord += `"mounts": {"stdout": {"kind": "file", "path": "` + tmpdir + `/nosuchsubdir/a/b/c.out"} },`
- helperRecord += `"output_path": "` + tmpdir + `/nosuchsubdir",`
- helperRecord += `"priority": 1,`
- helperRecord += `"runtime_constraints": {}`
- helperRecord += `}`
-
- _, _, err := StdoutErrorRunHelper(c, helperRecord, func(t *TestDockerClient) {})
- c.Check(err, NotNil)
- c.Check(strings.Contains(err.Error(), "/nosuchsubdir: no such file or directory"), Equals, true)
-}