func (s *GitDeploySuite) TestCancel(t *c.C) { r := s.newGitRepo(t, "cancel-hang") t.Assert(r.flynn("create", "cancel-hang"), Succeeds) t.Assert(r.flynn("env", "set", "FOO=bar", "BUILDPACK_URL=https://github.com/kr/heroku-buildpack-inline"), Succeeds) // start watching for slugbuilder events watcher, err := s.controllerClient(t).WatchJobEvents("cancel-hang", "") t.Assert(err, c.IsNil) // start push cmd := exec.Command("git", "push", "flynn", "master") // put the command in its own process group (to emulate the way shells handle Ctrl-C) cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} cmd.Dir = r.dir var stdout io.Reader stdout, _ = cmd.StdoutPipe() cmd.Stderr = cmd.Stdout out := &bytes.Buffer{} stdout = io.TeeReader(stdout, out) err = cmd.Start() t.Assert(err, c.IsNil) done := make(chan struct{}) go func() { select { case <-done: case <-time.After(30 * time.Second): cmd.Process.Signal(syscall.SIGTERM) cmd.Wait() t.Fatal("git push timed out") } }() // wait for sentinel sc := bufio.NewScanner(stdout) found := false for sc.Scan() { if strings.Contains(sc.Text(), "hanging...") { found = true break } } t.Log(out.String()) t.Assert(found, c.Equals, true) // send Ctrl-C to git process group syscall.Kill(-cmd.Process.Pid, syscall.SIGINT) t.Assert(err, c.IsNil) go io.Copy(ioutil.Discard, stdout) cmd.Wait() close(done) // check that slugbuilder exits immediately err = watcher.WaitFor(ct.JobEvents{"slugbuilder": {ct.JobStateUp: 1, ct.JobStateDown: 1}}, 10*time.Second, nil) t.Assert(err, c.IsNil) }
func (s *TaffyDeploySuite) deployWithTaffy(t *c.C, app *ct.App, env, meta, github map[string]string) { client := s.controllerClient(t) taffyRelease, err := client.GetAppRelease("taffy") t.Assert(err, c.IsNil) args := []string{ "/bin/taffy", app.Name, github["clone_url"], github["branch"], github["rev"], } for name, m := range map[string]map[string]string{"--env": env, "--meta": meta} { for k, v := range m { args = append(args, name) args = append(args, fmt.Sprintf("%s=%s", k, v)) } } rwc, err := client.RunJobAttached("taffy", &ct.NewJob{ ReleaseID: taffyRelease.ID, ReleaseEnv: true, Args: args, Meta: map[string]string{ "github": "true", "github_user": github["user"], "github_repo": github["repo"], "branch": github["branch"], "rev": github["rev"], "clone_url": github["clone_url"], "app": app.ID, }, Env: env, }) t.Assert(err, c.IsNil) attachClient := cluster.NewAttachClient(rwc) var outBuf bytes.Buffer exit, err := attachClient.Receive(&outBuf, &outBuf) t.Log(outBuf.String()) t.Assert(exit, c.Equals, 0) t.Assert(err, c.IsNil) }
func (s *HostSuite) TestNotifyOOM(t *c.C) { appID := random.UUID() // subscribe to init log messages from the logaggregator client, err := logaggc.New("") t.Assert(err, c.IsNil) opts := logagg.LogOpts{ Follow: true, StreamTypes: []logagg.StreamType{logagg.StreamTypeInit}, } rc, err := client.GetLog(appID, &opts) t.Assert(err, c.IsNil) defer rc.Close() msgs := make(chan *logaggc.Message) stream := stream.New() defer stream.Close() go func() { defer close(msgs) dec := json.NewDecoder(rc) for { var msg logaggc.Message if err := dec.Decode(&msg); err != nil { stream.Error = err return } select { case msgs <- &msg: case <-stream.StopCh: return } } }() // run the OOM job cmd := exec.CommandUsingCluster( s.clusterClient(t), s.createArtifact(t, "test-apps"), "/bin/oom", ) cmd.Meta = map[string]string{"flynn-controller.app": appID} runErr := make(chan error) go func() { runErr <- cmd.Run() }() // wait for the OOM notification for { select { case err := <-runErr: t.Assert(err, c.IsNil) case msg, ok := <-msgs: if !ok { t.Fatalf("message stream closed unexpectedly: %s", stream.Err()) } t.Log(msg.Msg) if strings.Contains(msg.Msg, "FATAL: a container process was killed due to lack of available memory") { return } case <-time.After(30 * time.Second): t.Fatal("timed out waiting for OOM notification") } } }