Example #1
0
// DumpStackOnSIGQUIT listens for a SIGQUIT signal and writes stack dump to the
// given io.Writer when one is received. Blocks, so spawn it as a goroutine.
func DumpStackOnSIGQUIT(curAgent **Agent) {
	in := make(chan os.Signal)
	signal.Notify(in, syscall.SIGQUIT)
	for _ = range in {
		agt := *curAgent
		stackBytes := util.DebugTrace()
		task, command := taskAndCommand(agt)

		// we dump to files and logs without blocking, in case our logging is deadlocked or broken
		go dumpToDisk(task, command, stackBytes)
		go dumpToLogs(task, command, stackBytes, agt)
	}
}
Example #2
0
func TestAgentDebugHandler(t *testing.T) {
	setupTlsConfigs(t)
	for tlsString, tlsConfig := range tlsConfigs {
		Convey("With an agent that has not been started", t, func() {
			testAgent, err := New("", "task1", "task1", "", testConfig.Api.HttpsCert, testPidFile)
			So(err, ShouldBeNil)
			Convey("no task or command should be listed", func() {
				task, command := taskAndCommand(testAgent)
				So(task, ShouldEqual, "no running task")
				So(command, ShouldEqual, "no running command")
			})
		})
		Convey("With agent running a slow test and live API server over "+tlsString, t, func() {
			testTask, _, err := setupAPITestData(testConfig, "timeout_task", "linux-64",
				filepath.Join(testDirectory, "testdata/config_test_plugin/project/evergreen-ci-render.yml"), NoPatch, t)
			testutil.HandleTestingErr(err, t, "Failed to find test task")
			testServer, err := service.CreateTestServer(testConfig, tlsConfig, plugin.APIPlugins, Verbose)
			testutil.HandleTestingErr(err, t, "Couldn't create apiserver: %v", err)
			testAgent, err := New(testServer.URL, testTask.Id, testTask.Secret, "", testConfig.Api.HttpsCert, testPidFile)
			So(err, ShouldBeNil)
			So(testAgent, ShouldNotBeNil)

			Convey("the agent should return the correct running task, command, and trace", func() {
				// run the slow task and take a debug trace during.
				var stack []byte
				var task, command string
				done := make(chan struct{})
				go func() {
					time.Sleep(time.Second)
					task, command = taskAndCommand(testAgent)
					stack = util.DebugTrace()
					dumpToLogs(task, command, stack, testAgent)
					done <- struct{}{}
				}()
				testAgent.RunTask()
				testAgent.APILogger.Flush()
				<-done
				So(task, ShouldEqual, testTask.Id)
				So(command, ShouldEqual, "shell.exec")
				gcTesting := "testing.RunTests" // we know this will be present in the trace
				So(string(stack), ShouldContainSubstring, gcTesting)
				Convey("which should also be present in the logs", func() {
					So(scanLogsForTask(testTask.Id, "", gcTesting), ShouldBeTrue)
				})
			})
		})
	}
}