mirror of
https://github.com/foomo/contentserver.git
synced 2025-10-16 12:25:44 +00:00
245 lines
5.8 KiB
Go
245 lines
5.8 KiB
Go
package client
|
|
|
|
import (
|
|
"net"
|
|
"strconv"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/foomo/contentserver/content"
|
|
"github.com/foomo/contentserver/log"
|
|
"github.com/foomo/contentserver/repo/mock"
|
|
"github.com/foomo/contentserver/requests"
|
|
"github.com/foomo/contentserver/server"
|
|
)
|
|
|
|
const pathContentserver = "/contentserver"
|
|
|
|
func dump(t *testing.T, v interface{}) {
|
|
jsonBytes, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
t.Fatal("could not dump v", v, "err", err)
|
|
return
|
|
}
|
|
t.Log(string(jsonBytes))
|
|
}
|
|
|
|
func getFreePort() int {
|
|
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
l, err := net.ListenTCP("tcp", addr)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer l.Close()
|
|
return l.Addr().(*net.TCPAddr).Port
|
|
}
|
|
|
|
func getAvailableAddr() string {
|
|
return "127.0.0.1:" + strconv.Itoa(getFreePort())
|
|
}
|
|
|
|
var (
|
|
testServerSocketAddr string
|
|
testServerWebserverAddr string
|
|
)
|
|
|
|
func initTestServer(t testing.TB) (socketAddr, webserverAddr string) {
|
|
socketAddr = getAvailableAddr()
|
|
webserverAddr = getAvailableAddr()
|
|
testServer, varDir := mock.GetMockData(t)
|
|
log.SelectedLevel = log.LevelError
|
|
go func() {
|
|
err := server.RunServerSocketAndWebServer(
|
|
testServer.URL+"/repo-two-dimensions.json",
|
|
socketAddr,
|
|
webserverAddr,
|
|
pathContentserver,
|
|
varDir,
|
|
)
|
|
if err != nil {
|
|
t.Fatal("test server crashed: ", err)
|
|
}
|
|
}()
|
|
socketClient, errClient := NewClient(socketAddr, 1, time.Duration(time.Millisecond*100))
|
|
if errClient != nil {
|
|
panic(errClient)
|
|
}
|
|
i := 0
|
|
for {
|
|
time.Sleep(time.Millisecond * 100)
|
|
r, err := socketClient.GetRepo()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if r["dimension_foo"].Nodes["id-a"].Data["baz"].(float64) == float64(1) {
|
|
break
|
|
}
|
|
if i > 100 {
|
|
panic("this is taking too long")
|
|
}
|
|
i++
|
|
}
|
|
return
|
|
}
|
|
|
|
func getTestClients(t testing.TB) (socketClient *Client, httpClient *Client) {
|
|
if testServerSocketAddr == "" {
|
|
socketAddr, webserverAddr := initTestServer(t)
|
|
testServerSocketAddr = socketAddr
|
|
testServerWebserverAddr = webserverAddr
|
|
}
|
|
socketClient, errClient := NewClient(testServerSocketAddr, 25, time.Duration(time.Millisecond*100))
|
|
if errClient != nil {
|
|
t.Log(errClient)
|
|
t.Fail()
|
|
}
|
|
httpClient, errHTTPClient := NewHTTPClient("http://" + testServerWebserverAddr + pathContentserver)
|
|
if errHTTPClient != nil {
|
|
t.Log(errHTTPClient)
|
|
t.Fail()
|
|
}
|
|
return
|
|
}
|
|
|
|
func testWithClients(t *testing.T, testFunc func(c *Client)) {
|
|
socketClient, httpClient := getTestClients(t)
|
|
defer socketClient.ShutDown()
|
|
defer httpClient.ShutDown()
|
|
testFunc(socketClient)
|
|
testFunc(httpClient)
|
|
}
|
|
|
|
func TestUpdate(t *testing.T) {
|
|
testWithClients(t, func(c *Client) {
|
|
response, err := c.Update()
|
|
if err != nil {
|
|
t.Fatal("unexpected err", err)
|
|
}
|
|
if !response.Success {
|
|
t.Fatal("update has to return .Sucesss true", response)
|
|
}
|
|
stats := response.Stats
|
|
if !(stats.RepoRuntime > float64(0.0)) || !(stats.OwnRuntime > float64(0.0)) {
|
|
t.Fatal("stats invalid")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestGetURIs(t *testing.T) {
|
|
testWithClients(t, func(c *Client) {
|
|
defer c.ShutDown()
|
|
request := mock.MakeValidURIsRequest()
|
|
uriMap, err := c.GetURIs(request.Dimension, request.IDs)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if uriMap[request.IDs[0]] != "/a" {
|
|
t.Fatal(uriMap)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestGetRepo(t *testing.T) {
|
|
testWithClients(t, func(c *Client) {
|
|
r, err := c.GetRepo()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if r["dimension_foo"].Nodes["id-a"].Data["baz"].(float64) != float64(1) {
|
|
t.Fatal("failed to drill deep for data")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestGetNodes(t *testing.T) {
|
|
testWithClients(t, func(c *Client) {
|
|
nodesRequest := mock.MakeNodesRequest()
|
|
nodes, err := c.GetNodes(nodesRequest.Env, nodesRequest.Nodes)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
testNode, ok := nodes["test"]
|
|
if !ok {
|
|
t.Fatal("that should be a node")
|
|
}
|
|
testData, ok := testNode.Item.Data["foo"]
|
|
if !ok {
|
|
t.Fatal("where is foo")
|
|
}
|
|
if testData != "bar" {
|
|
t.Fatal("testData should have bennd bar not", testData)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestGetContent(t *testing.T) {
|
|
testWithClients(t, func(c *Client) {
|
|
request := mock.MakeValidContentRequest()
|
|
response, err := c.GetContent(request)
|
|
if err != nil {
|
|
t.Fatal("unexpected err", err)
|
|
}
|
|
if request.URI != response.URI {
|
|
dump(t, request)
|
|
dump(t, response)
|
|
t.Fatal("uri mismatch")
|
|
}
|
|
if response.Status != content.StatusOk {
|
|
t.Fatal("unexpected status")
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkSocketClientAndServerGetContent(b *testing.B) {
|
|
socketClient, _ := getTestClients(b)
|
|
benchmarkServerAndClientGetContent(b, 30, 100, socketClient)
|
|
|
|
}
|
|
func BenchmarkWebClientAndServerGetContent(b *testing.B) {
|
|
_, httpClient := getTestClients(b)
|
|
benchmarkServerAndClientGetContent(b, 30, 100, httpClient)
|
|
}
|
|
|
|
func benchmarkServerAndClientGetContent(b *testing.B, numGroups, numCalls int, client GetContentClient) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
start := time.Now()
|
|
benchmarkClientAndServerGetContent(b, numGroups, numCalls, client)
|
|
dur := time.Since(start)
|
|
totalCalls := numGroups * numCalls
|
|
b.Log("requests per second", int(float64(totalCalls)/(float64(dur)/float64(1000000000))), dur, totalCalls)
|
|
}
|
|
}
|
|
|
|
type GetContentClient interface {
|
|
GetContent(request *requests.Content) (response *content.SiteContent, err error)
|
|
}
|
|
|
|
func benchmarkClientAndServerGetContent(b testing.TB, numGroups, numCalls int, client GetContentClient) {
|
|
var wg sync.WaitGroup
|
|
wg.Add(numGroups)
|
|
for group := 0; group < numGroups; group++ {
|
|
go func(g int) {
|
|
defer wg.Done()
|
|
request := mock.MakeValidContentRequest()
|
|
for i := 0; i < numCalls; i++ {
|
|
response, err := client.GetContent(request)
|
|
if err == nil {
|
|
if request.URI != response.URI {
|
|
b.Fatal("uri mismatch")
|
|
}
|
|
if response.Status != content.StatusOk {
|
|
b.Fatal("unexpected status")
|
|
}
|
|
}
|
|
}
|
|
}(group)
|
|
}
|
|
// Wait for all HTTP fetches to complete.
|
|
wg.Wait()
|
|
}
|