hooks: default timeout #3282

Merged
merged 6 commits into from May 15, 2017
@@ -48,6 +48,14 @@ func MockCmdWaitTimeout(timeout time.Duration) func() {
}
}
+func MockDefaultHookTimeout(timeout time.Duration) func() {
+ oldDefaultTimeout := defaultHookTimeout
+ defaultHookTimeout = timeout
+ return func() {
+ defaultHookTimeout = oldDefaultTimeout
+ }
+}
+
func MockErrtrackerReport(mock func(string, string, string, map[string]string) (string, error)) (restore func()) {
prev := errtrackerReport
errtrackerReport = mock
@@ -280,6 +280,7 @@ func snapCmd() string {
var syscallKill = syscall.Kill
var cmdWaitTimeout = 5 * time.Second
+var defaultHookTimeout = 10 * time.Minute
@pedronis

pedronis May 9, 2017

Contributor

this matches the forum discussion

func killemAll(cmd *exec.Cmd) error {
pgid, err := syscall.Getpgid(cmd.Process.Pid)
@@ -316,6 +317,9 @@ func runHookAndWait(snapName string, revision snap.Revision, hookName, hookConte
// add timeout handling
var killTimerCh <-chan time.Time
+ if timeout == 0 {
+ timeout = defaultHookTimeout
+ }
if timeout > 0 {
killTimerCh = time.After(timeout)
}
@@ -289,6 +289,30 @@ func (s *hookManagerSuite) TestHookTaskEnforcesTimeout(c *C) {
checkTaskLogContains(c, s.task, `.*exceeded maximum runtime of 200ms`)
}
+func (s *hookManagerSuite) TestHookTaskEnforcesDefaultTimeout(c *C) {
+ restore := hookstate.MockDefaultHookTimeout(150 * time.Millisecond)
+ defer restore()
+
+ // Force the snap command to hang
+ s.command = testutil.MockCommand(c, "snap", "while true; do sleep 1; done")
+
+ s.manager.Ensure()
+ s.manager.Wait()
+
+ s.state.Lock()
+ defer s.state.Unlock()
+
+ c.Check(s.mockHandler.BeforeCalled, Equals, true)
+ c.Check(s.mockHandler.DoneCalled, Equals, false)
+ c.Check(s.mockHandler.ErrorCalled, Equals, true)
+ c.Check(s.mockHandler.Err, ErrorMatches, `.*exceeded maximum runtime of 150ms.*`)
+
+ c.Check(s.task.Kind(), Equals, "run-hook")
+ c.Check(s.task.Status(), Equals, state.ErrorStatus)
+ c.Check(s.change.Status(), Equals, state.ErrorStatus)
+ checkTaskLogContains(c, s.task, `.*exceeded maximum runtime of 150ms`)
+}
+
func (s *hookManagerSuite) TestHookTaskEnforcesMaxWaitTime(c *C) {
var hooksup hookstate.HookSetup