func (s *HealthcheckSuite) TestWithoutChecker(t *c.C) { // start app with a service but no checker app, _ := s.createAppWithService(t, "ping", &host.Service{ Name: "ping-without-checker", Create: true, }) t.Assert(flynn(t, "/", "-a", app.Name, "scale", "ping=1"), Succeeds) // make sure app is registered and unregistered when the process terminates _, err := s.discoverdClient(t).Instances("ping-without-checker", 3*time.Second) t.Assert(err, c.IsNil) events := make(chan *discoverd.Event) stream, err := s.discoverdClient(t).Service("ping-without-checker").Watch(events) defer stream.Close() t.Assert(err, c.IsNil) t.Assert(flynn(t, "/", "-a", app.Name, "scale", "ping=0"), Succeeds) outer: for { select { case e := <-events: if e.Kind != discoverd.EventKindDown { continue } break outer case <-time.After(time.Second * 30): t.Error("Timed out waiting for a down event!") } } }
func (s *HostSuite) TestAttachFinishedInteractiveJob(t *c.C) { cluster := s.clusterClient(t) // run a quick interactive job cmd := exec.CommandUsingCluster(cluster, exec.DockerImage(imageURIs["test-apps"]), "/bin/true") cmd.TTY = true runErr := make(chan error) go func() { runErr <- cmd.Run() }() select { case err := <-runErr: t.Assert(err, c.IsNil) case <-time.After(30 * time.Second): t.Fatal("timed out waiting for interactive job") } h, err := cluster.Host(cmd.HostID) t.Assert(err, c.IsNil) // Getting the logs for the job should fail, as it has none because it was // interactive attachErr := make(chan error) go func() { _, err = h.Attach(&host.AttachReq{JobID: cmd.Job.ID, Flags: host.AttachFlagLogs}, false) attachErr <- err }() select { case err := <-attachErr: t.Assert(err, c.NotNil) case <-time.After(time.Second): t.Error("timed out waiting for attach") } }
func (s *LogAggregatorSuite) TestReplication(t *c.C) { app := s.newCliTestApp(t) app.flynn("scale", "ish=1") defer app.flynn("scale", "ish=0") defer app.cleanup() aggHost := "logaggregator.discoverd" waitForAggregator := func(wantUp bool) func() { ch := make(chan *discoverd.Event) stream, err := app.disc.Service("logaggregator").Watch(ch) t.Assert(err, c.IsNil) up := make(chan struct{}) go func() { timeout := time.After(60 * time.Second) defer close(up) defer stream.Close() var current bool for { select { case <-timeout: t.Error("logaggregator did not come back within a minute") return case event := <-ch: switch { case event.Kind == discoverd.EventKindCurrent: current = true case !wantUp && current && event.Kind == discoverd.EventKindDown: return case wantUp && current && event.Kind == discoverd.EventKindUp: aggHost, _, _ = net.SplitHostPort(event.Instance.Addr) return } } } }() return func() { <-up } } longLine := strings.Repeat("a", 10050) longLine0 := longLine[:10000] longLine1 := longLine[10000:] aggregators, err := app.disc.Instances("logaggregator", time.Second) t.Assert(err, c.IsNil) if len(aggregators) == 0 || len(aggregators) > 2 { t.Errorf("unexpected number of aggregators: %d", len(aggregators)) } else if len(aggregators) == 2 { wait := waitForAggregator(false) flynn(t, "/", "-a", "logaggregator", "scale", "app=1") wait() } instances, err := app.disc.Instances(app.name, time.Second*100) t.Assert(err, c.IsNil) ish := instances[0] cc := s.controllerClient(t) readLines := func(expectedLines ...string) { lineCount := 10 lc, _ := client.New("http://" + aggHost) out, err := lc.GetLog(app.id, &logagg.LogOpts{Follow: true, Lines: &lineCount}) t.Assert(err, c.IsNil) done := make(chan struct{}) var lines []string go func() { defer close(done) dec := json.NewDecoder(out) for { var msg client.Message if err := dec.Decode(&msg); err != nil { return } lines = append(lines, msg.Msg) if reflect.DeepEqual(lines, expectedLines) { return } } }() select { case <-time.After(60 * time.Second): case <-done: } out.Close() t.Assert(lines, c.DeepEquals, expectedLines) } runIshCommand(ish, "echo line1") runIshCommand(ish, "echo line2") runIshCommand(ish, "echo "+longLine) readLines("line1", "line2", longLine0, longLine1) // kill logaggregator wait := waitForAggregator(true) jobs, err := cc.JobList("logaggregator") t.Assert(err, c.IsNil) for _, j := range jobs { if j.State == ct.JobStateUp { t.Assert(cc.DeleteJob(app.name, j.ID), c.IsNil) } } wait() // confirm that logs are replayed when it comes back runIshCommand(ish, "echo line3") readLines("line1", "line2", longLine0, longLine1, "line3") // start new logaggregator wait = waitForAggregator(true) flynn(t, "/", "-a", "logaggregator", "scale", "app=2") wait() // confirm that logs show up in the new aggregator runIshCommand(ish, "echo line4") readLines("line1", "line2", longLine0, longLine1, "line3", "line4") }