func (j *Job) Run() { // If the job panics, just print a stack trace. // Don't let the whole process die. defer func() { if err := recover(); err != nil { if revelError := revel.NewErrorFromPanic(err); revelError != nil { revel.ERROR.Print(err, "\n", revelError.Stack) } else { revel.ERROR.Print(err, "\n", string(debug.Stack())) } } }() if !selfConcurrent { j.running.Lock() defer j.running.Unlock() } if workPermits != nil { workPermits <- struct{}{} defer func() { <-workPermits }() } atomic.StoreUint32(&j.status, 1) defer atomic.StoreUint32(&j.status, 0) j.inner.Run() }
// Run runs a single test, given by the argument. func (c TestRunner) Run(suite, test string) revel.Result { result := TestResult{Name: test} for _, testSuite := range revel.TestSuites { t := reflect.TypeOf(testSuite).Elem() if t.Name() != suite { continue } // Found the suite, create a new instance and run the named method. v := reflect.New(t) func() { defer func() { if err := recover(); err != nil { error := revel.NewErrorFromPanic(err) if error == nil { result.ErrorHtml = template.HTML(html.EscapeString(fmt.Sprint(err))) } else { var buffer bytes.Buffer tmpl, _ := revel.MainTemplateLoader.Template("TestRunner/FailureDetail.html") tmpl.Render(&buffer, error) result.ErrorHtml = template.HTML(buffer.String()) } } }() // Initialize the test suite with a NewTestSuite() testSuiteInstance := v.Elem().FieldByName("TestSuite") testSuiteInstance.Set(reflect.ValueOf(revel.NewTestSuite())) // Call Before(), call the test, and call After(). if m := v.MethodByName("Before"); m.IsValid() { m.Call(NONE) } v.MethodByName(test).Call(NONE) if m := v.MethodByName("After"); m.IsValid() { m.Call(NONE) } // No panic means success. result.Passed = true }() break } return c.RenderJson(result) }