github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/webdriver/webapp_server.go (about) 1 package webdriver 2 3 import ( 4 "flag" 5 "fmt" 6 "io" 7 "log" 8 "os" 9 "os/exec" 10 11 "github.com/web-platform-tests/wpt.fyi/shared/sharedtest" 12 ) 13 14 var ( 15 staging = flag.Bool("staging", false, "Use the app's deployed staging instance") 16 remoteHost = flag.String("remote_host", "staging.wpt.fyi", "Remote host of the staging webapp") 17 ) 18 19 // StaticTestDataRevision is the SHA for the local (static) test run summaries. 20 const StaticTestDataRevision = "24278ab61781de72ed363b866ae6b50b86822b27" 21 22 // AppServer is an abstraction for navigating an instance of the webapp. 23 type AppServer interface { 24 // Hook for closing the process that runs the webserver. 25 io.Closer 26 27 // GetWebappURL returns the URL for the given path on the running webapp. 28 GetWebappURL(path string) string 29 } 30 31 type remoteAppServer struct { 32 host string 33 } 34 35 func (i *remoteAppServer) GetWebappURL(path string) string { 36 // Remote (staging) server has HTTPS. 37 return fmt.Sprintf("https://%s%s", i.host, path) 38 } 39 40 func (i *remoteAppServer) Close() error { 41 return nil // Nothing needed here :) 42 } 43 44 type devAppServerInstance struct { 45 gcd sharedtest.Instance 46 app *exec.Cmd 47 port int 48 } 49 50 func (i *devAppServerInstance) GetWebappURL(path string) string { 51 // Local dev server doesn't have HTTPS. 52 return fmt.Sprintf("http://localhost:%d%s", i.port, path) 53 } 54 55 func (i *devAppServerInstance) Close() error { 56 i.app.Process.Kill() 57 return i.gcd.Close() 58 } 59 60 // newDevAppServer creates a dev appserve instance. 61 func newDevAppServer() (*devAppServerInstance, error) { 62 gcd, err := sharedtest.NewAEInstance(true) 63 if err != nil { 64 return nil, err 65 } 66 port := pickUnusedPort() 67 os.Setenv("PORT", fmt.Sprint(port)) 68 // Start the webapp server at last to pick up env vars (including those 69 // set by NewAEInstance). 70 // When running a test, CWD is the directory where the test file is; 71 // reset it to the root of the repo to run the server. 72 app := exec.Command("./web") 73 app.Dir = ".." 74 if err = app.Start(); err != nil { 75 return nil, err 76 } 77 78 s := &devAppServerInstance{ 79 gcd: gcd, 80 app: app, 81 port: port, 82 } 83 return s, nil 84 } 85 86 // NewWebserver creates an AppServer instance, which may be backed by local or 87 // remote (staging) servers. 88 func NewWebserver() (s AppServer, err error) { 89 if *staging { 90 return &remoteAppServer{ 91 host: *remoteHost, 92 }, nil 93 } 94 95 app, err := newDevAppServer() 96 if err != nil { 97 return nil, err 98 } 99 if err = addStaticData(app); err != nil { 100 // dev_appserver has started. 101 app.Close() 102 return nil, err 103 } 104 return app, err 105 } 106 107 func addStaticData(i *devAppServerInstance) (err error) { 108 cmd := exec.Command( 109 "go", 110 "run", 111 "../util/populate_dev_data.go", 112 fmt.Sprintf("--local_host=localhost:%d", i.port), 113 "--remote_runs=false", 114 "--static_runs=true", 115 ) 116 output, err := cmd.CombinedOutput() 117 if err != nil { 118 log.Printf("%s", output) 119 return err 120 } 121 return nil 122 }