Improve `fetch` tests in Cell (#627)

This commit is contained in:
Azer Koçulu 2018-02-08 19:41:07 +08:00 committed by Igor Mandrigin
parent 00df3ff9f8
commit 5bea85fa9b
1 changed files with 78 additions and 31 deletions

View File

@ -1,6 +1,8 @@
package jail package jail
import ( import (
"fmt"
"net"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
@ -75,59 +77,104 @@ func (s *CellTestSuite) TestCellLoopRace() {
} }
} }
// TestJailFetchRace tests multiple fetch callbacks, // TestJailFetchRace tests multiple sending multiple HTTP requests simultaneously in one cell, using `fetch`.
// supposed to be run with '-race' flag. // Supposed to be run with '-race' flag.
func (s *CellTestSuite) TestCellFetchRace() { func (s *CellTestSuite) TestCellFetchRace() {
body := `{"key": "value"}` // How many request should the test perform ?
const requestCount = 5
// Create a test server that simply outputs the "i" parameter passed.
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json") w.Header().Add("Content-Type", "application/json")
w.Write([]byte(body)) //nolint: errcheck w.Write([]byte(r.URL.Query()["i"][0])) //nolint: errcheck
})) }))
defer server.Close() defer server.Close()
cell := s.cell cell := s.cell
dataCh := make(chan otto.Value, 1) dataCh := make(chan otto.Value, 1)
errCh := make(chan otto.Value, 1) errCh := make(chan otto.Value, 1)
err := cell.Set("__captureSuccess", func(res otto.Value) { dataCh <- res })
s.NoError(err)
err = cell.Set("__captureError", func(res otto.Value) { errCh <- res })
s.NoError(err)
fetchCode := `fetch('%s?i=%d').then(function(r) {
return r.text()
}).then(function(data) {
__captureSuccess(data)
}).catch(function (e) {
__captureError(e)
})`
for i := 0; i < requestCount; i++ {
_, err = cell.Run(fmt.Sprintf(fetchCode, server.URL, i))
s.NoError(err)
}
expected := map[string]bool{} // It'll help us verify if every request was successfully completed.
for i := 0; i < requestCount; i++ {
select {
case data := <-dataCh:
// Mark the request as successful.
expected[data.String()] = true
case _ = <-errCh:
s.Fail("fetch failed to complete the request")
case <-time.After(5 * time.Second):
s.Fail("test timed out")
return
}
}
// Make sure every request was completed successfully.
for i := 0; i < requestCount; i++ {
s.Equal(expected[fmt.Sprintf("%d", i)], true)
}
// There might be some tasks about to call `ready`,
// add a little delay before `TearDownTest` closes the loop.
time.Sleep(100 * time.Millisecond)
}
func (s *CellTestSuite) TestCellFetchErrorRace() {
cell := s.cell
dataCh := make(chan otto.Value, 1)
errCh := make(chan otto.Value, 1)
err := cell.Set("__captureSuccess", func(res otto.Value) { dataCh <- res }) err := cell.Set("__captureSuccess", func(res otto.Value) { dataCh <- res })
s.NoError(err) s.NoError(err)
err = cell.Set("__captureError", func(res otto.Value) { errCh <- res }) err = cell.Set("__captureError", func(res otto.Value) { errCh <- res })
s.NoError(err) s.NoError(err)
// run JS code for fetching valid URL // Find a free port in localhost
_, err = cell.Run(`fetch('` + server.URL + `').then(function(r) { freeportListener, err := net.Listen("tcp", "127.0.0.1:0")
s.Require().NoError(err)
defer freeportListener.Close()
// Send an HTTP request to the free port that we found above
_, err = cell.Run(fmt.Sprintf(`fetch('%s').then(function(r) {
return r.text() return r.text()
}).then(function(data) { }).then(function(data) {
__captureSuccess(data) __captureSuccess(data)
}).catch(function (e) { }).catch(function (e) {
__captureError(e) __captureError(e)
})`) })`, freeportListener.Addr().String()))
s.NoError(err) s.NoError(err)
// run JS code for fetching invalid URL select {
_, err = cell.Run(`fetch('http://👽/nonexistent').then(function(r) { case _ = <-dataCh:
return r.text() s.Fail("fetch didn't return error for nonexistent url")
}).then(function(data) { case e := <-errCh:
__captureSuccess(data) name, err := e.Object().Get("name")
}).catch(function (e) { s.NoError(err)
__captureError(e) s.Equal("Error", name.String())
})`) _, err = e.Object().Get("message")
s.NoError(err) s.NoError(err)
case <-time.After(5 * time.Second):
for i := 0; i < 2; i++ { s.Fail("test timed out")
select { return
case data := <-dataCh:
s.Equal(body, data.String())
case e := <-errCh:
name, err := e.Object().Get("name")
s.NoError(err)
s.Equal("Error", name.String())
_, err = e.Object().Get("message")
s.NoError(err)
case <-time.After(5 * time.Second):
s.Fail("test timed out")
return
}
} }
} }