// 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 }
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) } }
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) } }