func BenchmarkAPIHandler(b *testing.B) { app := testMemoryAppWithClients(1, 100) nCommands := 1000 b.Logf("num channels: %v, num clients: %v, num unique clients %v, num commands: %v", app.clients.nChannels(), app.clients.nClients(), app.clients.nUniqueClients(), nCommands) commands := make([]map[string]interface{}, nCommands) command := map[string]interface{}{ "method": "publish", "params": map[string]interface{}{ "channel": "channel-0", "data": map[string]bool{"benchmarking": true}, }, } for i := 0; i < nCommands; i++ { commands[i] = command } jsonData, _ := json.Marshal(commands) sign := auth.GenerateApiSign("secret", "test1", jsonData) b.ResetTimer() for i := 0; i < b.N; i++ { rec := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/test1", bytes.NewBuffer(jsonData)) req.Header.Add("X-API-Sign", sign) req.Header.Add("Content-Type", "application/json") app.APIHandler(rec, req) } b.StopTimer() }
func (c *Client) send(cmds []Command) (Result, error) { data, err := json.Marshal(cmds) if err != nil { return Result{}, err } client := &http.Client{} client.Timeout = c.Timeout r, err := http.NewRequest("POST", c.Endpoint, bytes.NewBuffer(data)) if err != nil { return Result{}, err } r.Header.Set("X-API-Sign", auth.GenerateApiSign(c.Secret, c.Key, data)) r.Header.Add("Content-Type", "application/json") resp, err := client.Do(r) if err != nil { return Result{}, err } if resp.StatusCode != http.StatusOK { return Result{}, errors.New("wrong status code: " + resp.Status) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) var result Result err = json.Unmarshal(body, &result) return result, err }
func BenchmarkAPIHandler(b *testing.B) { nChannels := 1 nClients := 1000 nCommands := 1000 nMessages := nClients * nCommands sink := make(chan []byte, nMessages) app := testMemoryApp() // Use very large initial capacity so that queue resizes do not affect benchmark. app.config.ClientQueueInitialCapacity = 1000 createTestClients(app, nChannels, nClients, sink) b.Logf("num channels: %v, num clients: %v, num unique clients %v, num commands: %v", app.clients.nChannels(), app.clients.nClients(), app.clients.nUniqueClients(), nCommands) jsonData := getNPublishJSON("channel-0", nCommands) sign := auth.GenerateApiSign("secret", jsonData) b.ResetTimer() for i := 0; i < b.N; i++ { done := make(chan struct{}) go func() { count := 0 for { select { case <-sink: count++ } if count == nMessages { close(done) return } } }() rec := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/test1", bytes.NewBuffer(jsonData)) req.Header.Add("X-API-Sign", sign) req.Header.Add("Content-Type", "application/json") app.APIHandler(rec, req) <-done } b.StopTimer() }
func BenchmarkAPIHandler(b *testing.B) { sent := make(chan bool) nChannels := 1 nClients := 1000 nCommands := 1000 nMessages := nClients * nCommands app := testMemoryAppWithClientsSynchronized(nChannels, nClients, nMessages, sent) b.Logf("num channels: %v, num clients: %v, num unique clients %v, num commands: %v", app.clients.nChannels(), app.clients.nClients(), app.clients.nUniqueClients(), nCommands) jsonData := getNPublishJson("channel-0", nCommands) sign := auth.GenerateApiSign("secret", jsonData) b.ResetTimer() for i := 0; i < b.N; i++ { rec := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/test1", bytes.NewBuffer(jsonData)) req.Header.Add("X-API-Sign", sign) req.Header.Add("Content-Type", "application/json") app.APIHandler(rec, req) // Every nMessages sent to clients we will receive value from this channel. <-sent } b.StopTimer() }
func TestAPIHandler(t *testing.T) { app := testApp() mux := DefaultMux(app, DefaultMuxOptions) server := httptest.NewServer(mux) defer server.Close() // nil body rec := httptest.NewRecorder() req, _ := http.NewRequest("POST", server.URL+"/api/test", nil) app.APIHandler(rec, req) assert.Equal(t, http.StatusBadRequest, rec.Code) // empty body rec = httptest.NewRecorder() req, _ = http.NewRequest("POST", server.URL+"/api/test", strings.NewReader("")) app.APIHandler(rec, req) assert.Equal(t, http.StatusBadRequest, rec.Code) // wrong sign values := url.Values{} values.Set("sign", "wrong") values.Add("data", "data") rec = httptest.NewRecorder() req, _ = http.NewRequest("POST", server.URL+"/api/", strings.NewReader(values.Encode())) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") req.Header.Add("Content-Length", strconv.Itoa(len(values.Encode()))) app.APIHandler(rec, req) assert.Equal(t, http.StatusUnauthorized, rec.Code) // valid form urlencoded request rec = httptest.NewRecorder() values = url.Values{} data := "{\"method\":\"publish\",\"params\":{\"channel\": \"test\", \"data\":{}}}" sign := auth.GenerateApiSign("secret", []byte(data)) values.Set("sign", sign) values.Add("data", data) req, _ = http.NewRequest("POST", server.URL+"/api/test1", strings.NewReader(values.Encode())) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") req.Header.Add("Content-Length", strconv.Itoa(len(values.Encode()))) app.APIHandler(rec, req) assert.Equal(t, http.StatusOK, rec.Code) // valid JSON request rec = httptest.NewRecorder() data = "{\"method\":\"publish\",\"params\":{\"channel\": \"test\", \"data\":{}}}" sign = auth.GenerateApiSign("secret", []byte(data)) req, _ = http.NewRequest("POST", server.URL+"/api/test1", bytes.NewBuffer([]byte(data))) req.Header.Add("X-API-Sign", sign) req.Header.Add("Content-Type", "application/json") app.APIHandler(rec, req) assert.Equal(t, http.StatusOK, rec.Code) // request with unknown method rec = httptest.NewRecorder() values = url.Values{} data = "{\"method\":\"unknown\",\"params\":{\"channel\": \"test\", \"data\":{}}}" sign = auth.GenerateApiSign("secret", []byte(data)) values.Set("sign", sign) values.Add("data", data) req, _ = http.NewRequest("POST", server.URL+"/api/test1", strings.NewReader(values.Encode())) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") req.Header.Add("Content-Length", strconv.Itoa(len(values.Encode()))) app.APIHandler(rec, req) assert.Equal(t, http.StatusBadRequest, rec.Code) }