예제 #1
0
// NewHarness method returns a reverse proxy that forwards requests
// to the given port.
func NewHarness() *Harness {
	// Get a template loader to render errors.
	// Prefer the app's views/errors directory, and fall back to the stock error pages.
	revel.MainTemplateLoader = revel.NewTemplateLoader(
		[]string{filepath.Join(revel.RevelPath, "templates")})
	revel.MainTemplateLoader.Refresh()

	addr := revel.HttpAddr
	port := revel.Config.IntDefault("harness.port", 0)
	scheme := "http"
	if revel.HttpSsl {
		scheme = "https"
	}

	// If the server is running on the wildcard address, use "localhost"
	if addr == "" {
		addr = "localhost"
	}

	if port == 0 {
		port = getFreePort()
	}

	serverURL, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port))

	harness := &Harness{
		port:       port,
		serverHost: serverURL.String()[len(scheme+"://"):],
		proxy:      httputil.NewSingleHostReverseProxy(serverURL),
	}

	if revel.HttpSsl {
		harness.proxy.Transport = &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
	}
	return harness
}
예제 #2
0
func testApp(args []string) {
	var err error
	if len(args) == 0 {
		errorf("No import path given.\nRun 'revel help test' for usage.\n")
	}

	mode := "dev"
	if len(args) >= 2 {
		mode = args[1]
	}

	// Find and parse app.conf
	revel.Init(mode, args[0], "")

	// Ensure that the testrunner is loaded in this mode.
	testRunnerFound := false
	for _, module := range revel.Modules {
		if module.ImportPath == revel.Config.StringDefault("module.testrunner", "github.com/revel/modules/testrunner") {
			testRunnerFound = true
			break
		}
	}
	if !testRunnerFound {
		errorf(`Error: The testrunner module is not running.

You can add it to a run mode configuration with the following line:

	module.testrunner = github.com/revel/modules/testrunner

`)
	}

	// Create a directory to hold the test result files.
	resultPath := path.Join(revel.BasePath, "test-results")
	if err = os.RemoveAll(resultPath); err != nil {
		errorf("Failed to remove test result directory %s: %s", resultPath, err)
	}
	if err = os.Mkdir(resultPath, 0777); err != nil {
		errorf("Failed to create test result directory %s: %s", resultPath, err)
	}

	// Direct all the output into a file in the test-results directory.
	file, err := os.OpenFile(path.Join(resultPath, "app.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		errorf("Failed to create log file: %s", err)
	}

	app, reverr := harness.Build()
	if reverr != nil {
		errorf("Error building: %s", reverr)
	}
	cmd := app.Cmd()
	cmd.Stderr = io.MultiWriter(cmd.Stderr, file)
	cmd.Stdout = io.MultiWriter(cmd.Stderr, file)

	// Start the app...
	if err := cmd.Start(); err != nil {
		errorf("%s", err)
	}
	defer cmd.Kill()
	revel.INFO.Printf("Testing %s (%s) in %s mode\n", revel.AppName, revel.ImportPath, mode)

	// Get a list of tests.
	// Since this is the first request to the server, retry/sleep a couple times
	// in case it hasn't finished starting up yet.
	var (
		testSuites []controllers.TestSuiteDesc
		resp       *http.Response
		baseUrl    = fmt.Sprintf("http://127.0.0.1:%d", revel.HttpPort)
	)
	for i := 0; ; i++ {
		if resp, err = http.Get(baseUrl + "/@tests.list"); err == nil {
			if resp.StatusCode == http.StatusOK {
				break
			}
		}
		if i < 3 {
			time.Sleep(3 * time.Second)
			continue
		}
		if err != nil {
			errorf("Failed to request test list: %s", err)
		} else {
			errorf("Failed to request test list: non-200 response")
		}
	}
	defer resp.Body.Close()
	json.NewDecoder(resp.Body).Decode(&testSuites)

	// If a specific TestSuite[.Method] is specified, only run that suite/test
	if len(args) == 3 {
		testSuites = filterTestSuites(testSuites, args[2])
	}
	fmt.Printf("\n%d test suite%s to run.\n", len(testSuites), pluralize(len(testSuites), "", "s"))
	fmt.Println()

	// Load the result template, which we execute for each suite.
	module, _ := revel.ModuleByName("testrunner")
	TemplateLoader := revel.NewTemplateLoader([]string{path.Join(module.Path, "app", "views")})
	if err := TemplateLoader.Refresh(); err != nil {
		errorf("Failed to compile templates: %s", err)
	}
	resultTemplate, err := TemplateLoader.Template("TestRunner/SuiteResult.html")
	if err != nil {
		errorf("Failed to load suite result template: %s", err)
	}

	// Run each suite.
	var (
		overallSuccess = true
		failedResults  []controllers.TestSuiteResult
	)
	for _, suite := range testSuites {
		// Print the name of the suite we're running.
		name := suite.Name
		if len(name) > 22 {
			name = name[:19] + "..."
		}
		fmt.Printf("%-22s", name)

		// Run every test.
		startTime := time.Now()
		suiteResult := controllers.TestSuiteResult{Name: suite.Name, Passed: true}
		for _, test := range suite.Tests {
			testUrl := baseUrl + "/@tests/" + suite.Name + "/" + test.Name
			resp, err := http.Get(testUrl)
			if err != nil {
				errorf("Failed to fetch test result at url %s: %s", testUrl, err)
			}
			defer resp.Body.Close()

			var testResult controllers.TestResult
			json.NewDecoder(resp.Body).Decode(&testResult)
			if !testResult.Passed {
				suiteResult.Passed = false
			}
			suiteResult.Results = append(suiteResult.Results, testResult)
		}
		overallSuccess = overallSuccess && suiteResult.Passed

		// Print result.  (Just PASSED or FAILED, and the time taken)
		suiteResultStr, suiteAlert := "PASSED", ""
		if !suiteResult.Passed {
			suiteResultStr, suiteAlert = "FAILED", "!"
			failedResults = append(failedResults, suiteResult)
		}
		fmt.Printf("%8s%3s%6ds\n", suiteResultStr, suiteAlert, int(time.Since(startTime).Seconds()))
		// Create the result HTML file.
		suiteResultFilename := path.Join(resultPath,
			fmt.Sprintf("%s.%s.html", suite.Name, strings.ToLower(suiteResultStr)))
		suiteResultFile, err := os.Create(suiteResultFilename)
		if err != nil {
			errorf("Failed to create result file %s: %s", suiteResultFilename, err)
		}
		if err = resultTemplate.Render(suiteResultFile, suiteResult); err != nil {
			errorf("Failed to render result template: %s", err)
		}
	}

	fmt.Println()
	if overallSuccess {
		writeResultFile(resultPath, "result.passed", "passed")
		fmt.Println("All Tests Passed.")
	} else {
		for _, failedResult := range failedResults {
			fmt.Printf("Failures:\n")
			for _, result := range failedResult.Results {
				if !result.Passed {
					fmt.Printf("%s.%s\n", failedResult.Name, result.Name)
					fmt.Printf("%s\n\n", result.ErrorSummary)
				}
			}
		}
		writeResultFile(resultPath, "result.failed", "failed")
		errorf("Some tests failed.  See file://%s for results.", resultPath)
	}
}
예제 #3
0
파일: mailer_test.go 프로젝트: R510/revel
func TestSendFromTemplate(t *testing.T) {
	server := `220 hello world
502 EH?
250 mx.google.com at your service
250 Ok resetting state
250 Sender ok
250 Receiver ok
250 Receiver ok
354 Go ahead
250 Data ok
221 Goodbye
`

	snippet1 := `Hello 世界

Welcome Ark, please click the link:
http://www.arkxu.com
`

	snippet2 := `<h1>Hello 世界</h1>

<p>Welcome Ark, please click the link:</p>
<a href="http://www.arkxu.com">http://www.arkxu.com</a>
`
	mailer := &Mailer{Server: "smtp.gmail.com", Port: 587, UserName: "******", Password: "******"}
	mailer.Sender = &Sender{From: "*****@*****.**"}

	// reset the revel template loader for testing purpose
	viewPath, _ := os.Getwd()
	revel.MainTemplateLoader = revel.NewTemplateLoader([]string{viewPath})
	revel.MainTemplateLoader.Refresh()

	// arguments used for template rendering
	var args = make(map[string]interface{})
	args["world"] = "世界"
	args["user"] = struct {
		Name string
		Link string
	}{
		"Ark",
		"http://www.arkxu.com",
	}

	message := &Message{To: []string{"*****@*****.**"}, Subject: "from template 6", Cc: []string{"*****@*****.**"}}
	err := message.RenderTemplate("testdata/testTemplate", args)
	if err != nil {
		fmt.Println(err)
	}

	actualcmds, err := mailer.SendTestMessage(server, message)
	if err != nil {
		fmt.Println(err)
	}

	if strings.Contains(actualcmds, snippet1) {
		t.Errorf("it should contains %s\n", snippet1)
	}

	if strings.Contains(actualcmds, snippet2) {
		t.Errorf("it should contains %s\n", snippet2)
	}

}