示例#1
0
文件: job.go 项目: R510/revel
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()
}
示例#2
0
// 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 {
						testSuite := v.Elem().FieldByName("TestSuite").Interface().(revel.TestSuite)
						res := formatResponse(testSuite)

						var buffer bytes.Buffer
						tmpl, _ := revel.MainTemplateLoader.Template("TestRunner/FailureDetail.html")
						tmpl.Render(&buffer, map[string]interface{}{
							"error":    error,
							"response": res,
							"postfix":  suite + "_" + test,
						})
						result.ErrorSummary = errorSummary(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)
			}

			if m := v.MethodByName("After"); m.IsValid() {
				defer m.Call(NONE)
			}

			v.MethodByName(test).Call(NONE)

			// No panic means success.
			result.Passed = true
		}()
		break
	}
	return c.RenderJson(result)
}
示例#3
0
// Run runs a single test, given by the argument.
func (c TestRunner) Run(suite, test string) revel.Result {
	// Check whether requested test exists.
	suiteIndex, ok := registeredTests[suite+"."+test]
	if !ok {
		return c.NotFound("Test %s.%s does not exist", suite, test)
	}

	result := TestResult{Name: test}

	// Found the suite, create a new instance and run the named method.
	t := testSuites[suiteIndex].Elem
	v := reflect.New(t)
	func() {
		// When the function stops executing try to recover from panic.
		defer func() {
			if err := recover(); err != nil {
				// If panic error is empty, exit.
				panicErr := revel.NewErrorFromPanic(err)
				if panicErr == nil {
					return
				}

				// Otherwise, prepare and format the response of server if possible.
				testSuite := v.Elem().FieldByName("TestSuite").Interface().(testing.TestSuite)
				res := formatResponse(testSuite)

				// Render the error and save to the result structure.
				var buffer bytes.Buffer
				tmpl, _ := revel.MainTemplateLoader.Template("TestRunner/FailureDetail.html")
				tmpl.Render(&buffer, map[string]interface{}{
					"error":    panicErr,
					"response": res,
					"postfix":  suite + "_" + test,
				})
				result.ErrorSummary = errorSummary(panicErr)
				result.ErrorHTML = template.HTML(buffer.String())
			}
		}()

		// Initialize the test suite with a NewTestSuite()
		testSuiteInstance := v.Elem().FieldByName("TestSuite")
		testSuiteInstance.Set(reflect.ValueOf(testing.NewTestSuite()))

		// Make sure After method will be executed at the end.
		if m := v.MethodByName("After"); m.IsValid() {
			defer m.Call(none)
		}

		// Start from running Before method of test suite if exists.
		if m := v.MethodByName("Before"); m.IsValid() {
			m.Call(none)
		}

		// Start the test method itself.
		v.MethodByName(test).Call(none)

		// No panic means success.
		result.Passed = true
	}()

	return c.RenderJson(result)
}