From de68ea117bbc5b7054288f6d8bebfe899f5b24c4 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 07:30:45 +0200 Subject: [PATCH 01/15] add version_data_loader_test.go --- go.mod | 3 + go.sum | 5 + tw/twdataloader/server_data_loader.go | 100 ++++++++++---------- tw/twdataloader/version_data_loader.go | 12 ++- tw/twdataloader/version_data_loader_test.go | 67 +++++++++++++ 5 files changed, 133 insertions(+), 54 deletions(-) create mode 100644 tw/twdataloader/version_data_loader_test.go diff --git a/go.mod b/go.mod index 9ba0f64..75972b1 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,10 @@ require ( github.com/Kichiyaki/gopgutil/v10 v10.0.0-20210521204542-cc672e361b3d github.com/go-pg/pg/v10 v10.10.2 github.com/pkg/errors v0.9.1 + github.com/stretchr/objx v0.3.0 // indirect + github.com/stretchr/testify v1.7.0 // indirect github.com/vmihailenco/msgpack/v5 v5.3.1 // indirect go.opentelemetry.io/otel v0.20.0 // indirect golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index c263c6d..937728c 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= @@ -177,6 +180,8 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= diff --git a/tw/twdataloader/server_data_loader.go b/tw/twdataloader/server_data_loader.go index 38ebee1..d58b1c2 100644 --- a/tw/twdataloader/server_data_loader.go +++ b/tw/twdataloader/server_data_loader.go @@ -49,7 +49,7 @@ type parsedODLine struct { Score int } -func (d *ServerDataLoader) parseODLine(line []string) (*parsedODLine, error) { +func (dl *ServerDataLoader) parseODLine(line []string) (*parsedODLine, error) { if len(line) != 3 { return nil, errors.New("invalid line format (should be rank,id,score)") } @@ -70,19 +70,19 @@ func (d *ServerDataLoader) parseODLine(line []string) (*parsedODLine, error) { return p, nil } -func (d *ServerDataLoader) LoadOD(tribe bool) (map[int]*twmodel.OpponentsDefeated, error) { +func (dl *ServerDataLoader) LoadOD(tribe bool) (map[int]*twmodel.OpponentsDefeated, error) { m := make(map[int]*twmodel.OpponentsDefeated) formattedURLs := []string{ - fmt.Sprintf("%s%s", d.baseURL, EndpointKillAll), - fmt.Sprintf("%s%s", d.baseURL, EndpointKillAtt), - fmt.Sprintf("%s%s", d.baseURL, EndpointKillDef), - fmt.Sprintf("%s%s", d.baseURL, EndpointKillSup), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillAll), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillAtt), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillDef), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillSup), } if tribe { formattedURLs = []string{ - fmt.Sprintf("%s%s", d.baseURL, EndpointKillAllTribe), - fmt.Sprintf("%s%s", d.baseURL, EndpointKillAttTribe), - fmt.Sprintf("%s%s", d.baseURL, EndpointKillDefTribe), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillAllTribe), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillAttTribe), + fmt.Sprintf("%s%s", dl.baseURL, EndpointKillDefTribe), "", } } @@ -90,16 +90,16 @@ func (d *ServerDataLoader) LoadOD(tribe bool) (map[int]*twmodel.OpponentsDefeate if formattedURL == "" { continue } - lines, err := d.getCSVData(formattedURL, true) + lines, err := dl.getCSVData(formattedURL, true) if err != nil { //fallback to not gzipped file - lines, err = d.getCSVData(strings.ReplaceAll(formattedURL, ".gz", ""), false) + lines, err = dl.getCSVData(strings.ReplaceAll(formattedURL, ".gz", ""), false) if err != nil { return nil, errors.Wrapf(err, "couldn't load data, formattedURL %s", formattedURL) } } for _, line := range lines { - parsed, err := d.parseODLine(line) + parsed, err := dl.parseODLine(line) if err != nil { return nil, errors.Wrapf(err, "couldn't parse the line, url %s, line %s", formattedURL, strings.Join(line, ",")) } @@ -125,7 +125,7 @@ func (d *ServerDataLoader) LoadOD(tribe bool) (map[int]*twmodel.OpponentsDefeate return m, nil } -func (d *ServerDataLoader) parsePlayerLine(line []string) (*twmodel.Player, error) { +func (dl *ServerDataLoader) parsePlayerLine(line []string) (*twmodel.Player, error) { if len(line) != 6 { return nil, errors.New("invalid line format (should be id,name,tribeid,villages,points,rank)") } @@ -163,11 +163,11 @@ func (d *ServerDataLoader) parsePlayerLine(line []string) (*twmodel.Player, erro return player, nil } -func (d *ServerDataLoader) LoadPlayers() ([]*twmodel.Player, error) { - formattedURL := d.baseURL + EndpointPlayer - lines, err := d.getCSVData(formattedURL, true) +func (dl *ServerDataLoader) LoadPlayers() ([]*twmodel.Player, error) { + formattedURL := dl.baseURL + EndpointPlayer + lines, err := dl.getCSVData(formattedURL, true) if err != nil { - lines, err = d.getCSVData(d.baseURL+EndpointPlayerNotGzipped, false) + lines, err = dl.getCSVData(dl.baseURL+EndpointPlayerNotGzipped, false) if err != nil { return nil, errors.Wrapf(err, "couldn't load data, url %s", formattedURL) } @@ -175,7 +175,7 @@ func (d *ServerDataLoader) LoadPlayers() ([]*twmodel.Player, error) { var players []*twmodel.Player for _, line := range lines { - player, err := d.parsePlayerLine(line) + player, err := dl.parsePlayerLine(line) if err != nil { return nil, errors.Wrapf(err, "couldn't parse the line, url %s, line %s", formattedURL, strings.Join(line, ",")) } @@ -185,7 +185,7 @@ func (d *ServerDataLoader) LoadPlayers() ([]*twmodel.Player, error) { return players, nil } -func (d *ServerDataLoader) parseTribeLine(line []string) (*twmodel.Tribe, error) { +func (dl *ServerDataLoader) parseTribeLine(line []string) (*twmodel.Tribe, error) { if len(line) != 8 { return nil, errors.New("invalid line format (should be id,name,tag,members,villages,points,allpoints,rank)") } @@ -231,18 +231,18 @@ func (d *ServerDataLoader) parseTribeLine(line []string) (*twmodel.Tribe, error) return tribe, nil } -func (d *ServerDataLoader) LoadTribes() ([]*twmodel.Tribe, error) { - formattedURL := d.baseURL + EndpointTribe - lines, err := d.getCSVData(formattedURL, true) +func (dl *ServerDataLoader) LoadTribes() ([]*twmodel.Tribe, error) { + formattedURL := dl.baseURL + EndpointTribe + lines, err := dl.getCSVData(formattedURL, true) if err != nil { - lines, err = d.getCSVData(d.baseURL+EndpointTribeNotGzipped, false) + lines, err = dl.getCSVData(dl.baseURL+EndpointTribeNotGzipped, false) if err != nil { return nil, errors.Wrapf(err, "couldn't load data, url %s", formattedURL) } } var tribes []*twmodel.Tribe for _, line := range lines { - tribe, err := d.parseTribeLine(line) + tribe, err := dl.parseTribeLine(line) if err != nil { return nil, errors.Wrapf(err, "couldn't parse the line, url %s, line %s", formattedURL, strings.Join(line, ",")) } @@ -251,7 +251,7 @@ func (d *ServerDataLoader) LoadTribes() ([]*twmodel.Tribe, error) { return tribes, nil } -func (d *ServerDataLoader) parseVillageLine(line []string) (*twmodel.Village, error) { +func (dl *ServerDataLoader) parseVillageLine(line []string) (*twmodel.Village, error) { if len(line) != 7 { return nil, errors.New("invalid line format (should be id,name,x,y,playerID,points,bonus)") } @@ -288,18 +288,18 @@ func (d *ServerDataLoader) parseVillageLine(line []string) (*twmodel.Village, er return village, nil } -func (d *ServerDataLoader) LoadVillages() ([]*twmodel.Village, error) { - formattedURL := d.baseURL + EndpointVillage - lines, err := d.getCSVData(formattedURL, true) +func (dl *ServerDataLoader) LoadVillages() ([]*twmodel.Village, error) { + formattedURL := dl.baseURL + EndpointVillage + lines, err := dl.getCSVData(formattedURL, true) if err != nil { - lines, err = d.getCSVData(d.baseURL+EndpointVillageNotGzipped, false) + lines, err = dl.getCSVData(dl.baseURL+EndpointVillageNotGzipped, false) if err != nil { return nil, errors.Wrapf(err, "couldn't load data, formattedURL %s", formattedURL) } } var villages []*twmodel.Village for _, line := range lines { - village, err := d.parseVillageLine(line) + village, err := dl.parseVillageLine(line) if err != nil { return nil, errors.Wrapf(err, "couldn't parse the line, formattedURL %s, line %s", formattedURL, strings.Join(line, ",")) } @@ -308,7 +308,7 @@ func (d *ServerDataLoader) LoadVillages() ([]*twmodel.Village, error) { return villages, nil } -func (d *ServerDataLoader) parseEnnoblementLine(line []string) (*twmodel.Ennoblement, error) { +func (dl *ServerDataLoader) parseEnnoblementLine(line []string) (*twmodel.Ennoblement, error) { if len(line) != 4 { return nil, errors.New("invalid line format (should be village_id,timestamp,new_owner_id,old_owner_id)") } @@ -339,20 +339,20 @@ type LoadEnnoblementsConfig struct { EnnobledAtGT time.Time } -func (d *ServerDataLoader) LoadEnnoblements(cfg *LoadEnnoblementsConfig) ([]*twmodel.Ennoblement, error) { +func (dl *ServerDataLoader) LoadEnnoblements(cfg *LoadEnnoblementsConfig) ([]*twmodel.Ennoblement, error) { if cfg == nil { cfg = &LoadEnnoblementsConfig{} } yesterdaysDate := time.Now().Add(-23 * time.Hour) - formattedURL := d.baseURL + EndpointConquer + formattedURL := dl.baseURL + EndpointConquer compressed := true if cfg.EnnobledAtGT.After(yesterdaysDate) || cfg.EnnobledAtGT.Equal(yesterdaysDate) { - formattedURL = d.baseURL + fmt.Sprintf(EndpointGetConquer, cfg.EnnobledAtGT.Unix()) + formattedURL = dl.baseURL + fmt.Sprintf(EndpointGetConquer, cfg.EnnobledAtGT.Unix()) compressed = false } - lines, err := d.getCSVData(formattedURL, compressed) + lines, err := dl.getCSVData(formattedURL, compressed) if err != nil && compressed { - lines, err = d.getCSVData(d.baseURL+EndpointConquerNotGzipped, false) + lines, err = dl.getCSVData(dl.baseURL+EndpointConquerNotGzipped, false) } if err != nil { return nil, errors.Wrapf(err, "couldn't load data, formattedURL %s", formattedURL) @@ -360,7 +360,7 @@ func (d *ServerDataLoader) LoadEnnoblements(cfg *LoadEnnoblementsConfig) ([]*twm var ennoblements []*twmodel.Ennoblement for _, line := range lines { - ennoblement, err := d.parseEnnoblementLine(line) + ennoblement, err := dl.parseEnnoblementLine(line) if err != nil { return nil, errors.Wrapf(err, "couldn't parse the line, formattedURL %s, line %s", formattedURL, strings.Join(line, ",")) } @@ -371,38 +371,38 @@ func (d *ServerDataLoader) LoadEnnoblements(cfg *LoadEnnoblementsConfig) ([]*twm return ennoblements, nil } -func (d *ServerDataLoader) GetConfig() (*twmodel.ServerConfig, error) { - formattedURL := d.baseURL + EndpointConfig +func (dl *ServerDataLoader) GetConfig() (*twmodel.ServerConfig, error) { + formattedURL := dl.baseURL + EndpointConfig cfg := &twmodel.ServerConfig{} - err := d.getXML(formattedURL, cfg) + err := dl.getXML(formattedURL, cfg) if err != nil { return nil, errors.Wrap(err, "getConfig") } return cfg, nil } -func (d *ServerDataLoader) GetBuildingConfig() (*twmodel.BuildingConfig, error) { - formattedURL := d.baseURL + EndpointBuildingConfig +func (dl *ServerDataLoader) GetBuildingConfig() (*twmodel.BuildingConfig, error) { + formattedURL := dl.baseURL + EndpointBuildingConfig cfg := &twmodel.BuildingConfig{} - err := d.getXML(formattedURL, cfg) + err := dl.getXML(formattedURL, cfg) if err != nil { return nil, errors.Wrap(err, "getBuildingConfig") } return cfg, nil } -func (d *ServerDataLoader) GetUnitConfig() (*twmodel.UnitConfig, error) { - formattedURL := d.baseURL + EndpointUnitConfig +func (dl *ServerDataLoader) GetUnitConfig() (*twmodel.UnitConfig, error) { + formattedURL := dl.baseURL + EndpointUnitConfig cfg := &twmodel.UnitConfig{} - err := d.getXML(formattedURL, cfg) + err := dl.getXML(formattedURL, cfg) if err != nil { return nil, errors.Wrap(err, "getUnitConfig") } return cfg, nil } -func (d *ServerDataLoader) getCSVData(url string, compressed bool) ([][]string, error) { - resp, err := d.client.Get(url) +func (dl *ServerDataLoader) getCSVData(url string, compressed bool) ([][]string, error) { + resp, err := dl.client.Get(url) if err != nil { return nil, err } @@ -413,8 +413,8 @@ func (d *ServerDataLoader) getCSVData(url string, compressed bool) ([][]string, return uncompressAndReadCsvLines(resp.Body) } -func (d *ServerDataLoader) getXML(url string, decode interface{}) error { - resp, err := d.client.Get(url) +func (dl *ServerDataLoader) getXML(url string, decode interface{}) error { + resp, err := dl.client.Get(url) if err != nil { return err } diff --git a/tw/twdataloader/version_data_loader.go b/tw/twdataloader/version_data_loader.go index 2cbafc4..db26962 100644 --- a/tw/twdataloader/version_data_loader.go +++ b/tw/twdataloader/version_data_loader.go @@ -40,8 +40,8 @@ func NewVersionDataLoader(cfg *VersionDataLoaderConfig) *VersionDataLoader { } } -func (d *VersionDataLoader) LoadServers() ([]*Server, error) { - resp, err := d.client.Get(fmt.Sprintf("https://%s%s", d.host, EndpointGetServers)) +func (dl *VersionDataLoader) LoadServers() ([]*Server, error) { + resp, err := dl.client.Get(fmt.Sprintf("https://%s%s", dl.host, EndpointGetServers)) if err != nil { return nil, errors.Wrap(err, "couldn't load servers") } @@ -52,8 +52,12 @@ func (d *VersionDataLoader) LoadServers() ([]*Server, error) { return nil, errors.Wrap(err, "couldn't read the response body") } body, err := phpserialize.Decode(string(bodyBytes)) - if err != nil { - return nil, errors.Wrap(err, "couldn't decode the response body into the go value") + if err != nil || body == nil { + fmtedErr := errors.New("couldn't decode the response body into a go value") + if err != nil { + fmtedErr = errors.Wrap(err, fmtedErr.Error()) + } + return nil, fmtedErr } var servers []*Server diff --git a/tw/twdataloader/version_data_loader_test.go b/tw/twdataloader/version_data_loader_test.go new file mode 100644 index 0000000..f08abed --- /dev/null +++ b/tw/twdataloader/version_data_loader_test.go @@ -0,0 +1,67 @@ +package twdataloader + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "net/http" + "net/http/httptest" + "strconv" + "strings" + "testing" +) + +func prepareTestServer(resp string) *httptest.Server { + return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case EndpointGetServers: + _, err := fmt.Fprintln(w, resp) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + return + default: + w.WriteHeader(http.StatusNotFound) + } + })) +} + +func TestLoadServers(t *testing.T) { + t.Run("invalid payload", func(t *testing.T) { + resp := `:"https://pl165.plemiona.pl";s:5:"pl166";s:25:"https://pl166.plemiona.pl";s:5:"pl167";s:25:"https://pl167.plemiona.pl";}` + ts := prepareTestServer(resp) + defer ts.Close() + + dl := NewVersionDataLoader(&VersionDataLoaderConfig{ + Host: strings.ReplaceAll(ts.URL, "https://", ""), + Client: ts.Client(), + }) + + _, err := dl.LoadServers() + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "couldn't decode the response body into a go value") + }) + + t.Run("success", func(t *testing.T) { + resp := `a:19:{s:5:"pl150";s:25:"https://pl150.plemiona.pl";s:5:"pl151";s:25:"https://pl151.plemiona.pl";s:5:"pl152";s:25:"https://pl152.plemiona.pl";s:5:"pl153";s:25:"https://pl153.plemiona.pl";s:5:"pl154";s:25:"https://pl154.plemiona.pl";s:5:"pl155";s:25:"https://pl155.plemiona.pl";s:5:"pl156";s:25:"https://pl156.plemiona.pl";s:5:"pl157";s:25:"https://pl157.plemiona.pl";s:5:"pl158";s:25:"https://pl158.plemiona.pl";s:5:"pl159";s:25:"https://pl159.plemiona.pl";s:5:"pl160";s:25:"https://pl160.plemiona.pl";s:5:"pl161";s:25:"https://pl161.plemiona.pl";s:5:"pl162";s:25:"https://pl162.plemiona.pl";s:5:"pl163";s:25:"https://pl163.plemiona.pl";s:5:"pl164";s:25:"https://pl164.plemiona.pl";s:4:"plp7";s:24:"https://plp7.plemiona.pl";s:5:"pl165";s:25:"https://pl165.plemiona.pl";s:5:"pl166";s:25:"https://pl166.plemiona.pl";s:5:"pl167";s:25:"https://pl167.plemiona.pl";}` + ts := prepareTestServer(resp) + defer ts.Close() + + expectedLength, err := strconv.Atoi(strings.Split(resp, ":")[1]) + assert.Nil(t, err) + + dl := NewVersionDataLoader(&VersionDataLoaderConfig{ + Host: strings.ReplaceAll(ts.URL, "https://", ""), + Client: ts.Client(), + }) + + servers, err := dl.LoadServers() + assert.Nil(t, err) + cnt := 0 + for _, server := range servers { + if strings.Contains(resp, server.URL) && strings.Contains(resp, server.Key) { + cnt++ + } + } + assert.Equal(t, expectedLength, cnt) + }) +} From 4de5ad58d835a698a8f740f23f7590359b15a4be Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 07:31:45 +0200 Subject: [PATCH 02/15] go mod tidy --- go.mod | 6 +----- go.sum | 18 ------------------ 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 75972b1..4e1cffa 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,6 @@ require ( github.com/Kichiyaki/gopgutil/v10 v10.0.0-20210521204542-cc672e361b3d github.com/go-pg/pg/v10 v10.10.2 github.com/pkg/errors v0.9.1 - github.com/stretchr/objx v0.3.0 // indirect - github.com/stretchr/testify v1.7.0 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.1 // indirect - go.opentelemetry.io/otel v0.20.0 // indirect - golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect + github.com/stretchr/testify v1.7.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 937728c..7ff38f3 100644 --- a/go.sum +++ b/go.sum @@ -16,10 +16,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-pg/pg/v10 v10.9.1 h1:kU4t84zWGGaU0Qsu49FbNtToUVrlSTkNOngW8aQmwvk= github.com/go-pg/pg/v10 v10.9.1/go.mod h1:rgmTPgHgl5EN2CNKKoMwC7QT62t8BqsdpEkUQuiZMQs= -github.com/go-pg/pg/v10 v10.10.1 h1:82lLX4KGs2wOFOvVVIICoU0Si1fLu6Aitniu73HaDuM= -github.com/go-pg/pg/v10 v10.10.1/go.mod h1:EmoJGYErc+stNN/1Jf+o4csXuprjxcRztBnn6cHe38E= github.com/go-pg/pg/v10 v10.10.2 h1:8G2DdKrB3/0nRIlpur0HySEWBJnHYUByiC0ko4XzE8w= github.com/go-pg/pg/v10 v10.10.2/go.mod h1:EmoJGYErc+stNN/1Jf+o4csXuprjxcRztBnn6cHe38E= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= @@ -41,7 +38,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -68,9 +64,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= -github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= @@ -87,17 +80,9 @@ github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -134,8 +119,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -178,7 +161,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 232d9caad3ec4a559b45f546d1cfd67e703a716c Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 11:09:59 +0200 Subject: [PATCH 03/15] add more checks in VersionDataLoader.LoadServers, add more tests --- tw/twdataloader/version_data_loader.go | 16 +++++-- tw/twdataloader/version_data_loader_test.go | 52 ++++++++++++++++----- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/tw/twdataloader/version_data_loader.go b/tw/twdataloader/version_data_loader.go index db26962..4b40017 100644 --- a/tw/twdataloader/version_data_loader.go +++ b/tw/twdataloader/version_data_loader.go @@ -59,11 +59,21 @@ func (dl *VersionDataLoader) LoadServers() ([]*Server, error) { } return nil, fmtedErr } + bodyMap, ok := body.(map[interface{}]interface{}) + if !ok { + return nil, errors.Errorf("expected map, got %T", body) + } var servers []*Server - for serverKey, url := range body.(map[interface{}]interface{}) { - serverKeyStr := serverKey.(string) - urlStr := url.(string) + for serverKey, url := range bodyMap { + serverKeyStr, ok := serverKey.(string) + if !ok { + return nil, errors.Errorf("expected string as the key of the map, got %T", serverKey) + } + urlStr, ok := url.(string) + if !ok { + return nil, errors.Errorf("expected string as the value of the map, got %T", url) + } if serverKeyStr != "" && urlStr != "" { servers = append(servers, &Server{ Key: serverKeyStr, diff --git a/tw/twdataloader/version_data_loader_test.go b/tw/twdataloader/version_data_loader_test.go index f08abed..76ac430 100644 --- a/tw/twdataloader/version_data_loader_test.go +++ b/tw/twdataloader/version_data_loader_test.go @@ -26,19 +26,49 @@ func prepareTestServer(resp string) *httptest.Server { } func TestLoadServers(t *testing.T) { - t.Run("invalid payload", func(t *testing.T) { - resp := `:"https://pl165.plemiona.pl";s:5:"pl166";s:25:"https://pl166.plemiona.pl";s:5:"pl167";s:25:"https://pl167.plemiona.pl";}` - ts := prepareTestServer(resp) - defer ts.Close() + t.Run("invalid response", func(t *testing.T) { + type scenario struct { + resp string + expectedErrMsg string + } - dl := NewVersionDataLoader(&VersionDataLoaderConfig{ - Host: strings.ReplaceAll(ts.URL, "https://", ""), - Client: ts.Client(), - }) + scenarios := []scenario{ + { + resp: `:"https://pl165.plemiona.pl";s:5:"pl166";s:25:"https://pl166.plemiona.pl";s:5:"pl167";s:25:"https://pl167.plemiona.pl";}`, + expectedErrMsg: "couldn't decode the response body into a go value", + }, + { + resp: `a:19:{s:5:"pl150"s:25"https://pl150.plemiona.pl";}`, + expectedErrMsg: "expected string as the value of the map, got ", + }, + { + resp: "a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}", + expectedErrMsg: "expected string as the key of the map, got int64", + }, + { + resp: `O:8:"stdClass":0:{}`, + expectedErrMsg: "expected map, got *phpserialize.PhpObject", + }, + { + resp: `a:2:{s:3:"asd";i:123;s:4:"asd2";i:123;}`, + expectedErrMsg: "expected string as the value of the map, got int64", + }, + } - _, err := dl.LoadServers() - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "couldn't decode the response body into a go value") + for _, scenario := range scenarios { + ts := prepareTestServer(scenario.resp) + + dl := NewVersionDataLoader(&VersionDataLoaderConfig{ + Host: strings.ReplaceAll(ts.URL, "https://", ""), + Client: ts.Client(), + }) + + _, err := dl.LoadServers() + assert.NotNil(t, err) + assert.Contains(t, err.Error(), scenario.expectedErrMsg) + + ts.Close() + } }) t.Run("success", func(t *testing.T) { From 477970b0a69a95be312a2f28198870a5fed88c9c Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 15:44:44 +0200 Subject: [PATCH 04/15] use w.Write instead of fmt.Fprintln --- tw/twdataloader/version_data_loader_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tw/twdataloader/version_data_loader_test.go b/tw/twdataloader/version_data_loader_test.go index 76ac430..45b117e 100644 --- a/tw/twdataloader/version_data_loader_test.go +++ b/tw/twdataloader/version_data_loader_test.go @@ -1,7 +1,6 @@ package twdataloader import ( - "fmt" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" @@ -14,7 +13,7 @@ func prepareTestServer(resp string) *httptest.Server { return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case EndpointGetServers: - _, err := fmt.Fprintln(w, resp) + _, err := w.Write([]byte(resp)) if err != nil { w.WriteHeader(http.StatusInternalServerError) } From a2e82ef96bc9b62cee16fd22e9c79cdbb9a252c2 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 15:58:21 +0200 Subject: [PATCH 05/15] VersionDataLoader.LoadServer doesn't need https:// --- tw/twdataloader/version_data_loader.go | 3 +-- tw/twdataloader/version_data_loader_test.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tw/twdataloader/version_data_loader.go b/tw/twdataloader/version_data_loader.go index 4b40017..1e832c7 100644 --- a/tw/twdataloader/version_data_loader.go +++ b/tw/twdataloader/version_data_loader.go @@ -1,7 +1,6 @@ package twdataloader import ( - "fmt" phpserialize "github.com/Kichiyaki/go-php-serialize" "github.com/pkg/errors" "io/ioutil" @@ -41,7 +40,7 @@ func NewVersionDataLoader(cfg *VersionDataLoaderConfig) *VersionDataLoader { } func (dl *VersionDataLoader) LoadServers() ([]*Server, error) { - resp, err := dl.client.Get(fmt.Sprintf("https://%s%s", dl.host, EndpointGetServers)) + resp, err := dl.client.Get(dl.host + EndpointGetServers) if err != nil { return nil, errors.Wrap(err, "couldn't load servers") } diff --git a/tw/twdataloader/version_data_loader_test.go b/tw/twdataloader/version_data_loader_test.go index 45b117e..ef015e2 100644 --- a/tw/twdataloader/version_data_loader_test.go +++ b/tw/twdataloader/version_data_loader_test.go @@ -10,7 +10,7 @@ import ( ) func prepareTestServer(resp string) *httptest.Server { - return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case EndpointGetServers: _, err := w.Write([]byte(resp)) From 1248c0d7dbf2c7e53f4d9c11cc19e79295b3c9b6 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 16:26:53 +0200 Subject: [PATCH 06/15] prepareTestServer refactor --- tw/twdataloader/helpers.go | 39 +++++++++++++++++++++ tw/twdataloader/version_data_loader_test.go | 25 ++++--------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index 27f25f8..c12e576 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -5,6 +5,7 @@ import ( "encoding/csv" "io" "net/http" + "net/http/httptest" "time" ) @@ -22,3 +23,41 @@ func uncompressAndReadCsvLines(r io.Reader) ([][]string, error) { defer uncompressedStream.Close() return csv.NewReader(uncompressedStream).ReadAll() } + +type handlers struct { + getServers http.HandlerFunc +} + +func (h *handlers) init() { + noop := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + }) + if h.getServers == nil { + h.getServers = noop + } +} + +func prepareTestServer(h *handlers) *httptest.Server { + if h == nil { + h = &handlers{} + } + h.init() + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case EndpointGetServers: + h.getServers(w, r) + return + default: + w.WriteHeader(http.StatusNotFound) + } + })) +} + +func createWriteStringHandler(resp string) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte(resp)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + }) +} diff --git a/tw/twdataloader/version_data_loader_test.go b/tw/twdataloader/version_data_loader_test.go index ef015e2..aa69808 100644 --- a/tw/twdataloader/version_data_loader_test.go +++ b/tw/twdataloader/version_data_loader_test.go @@ -2,28 +2,11 @@ package twdataloader import ( "github.com/stretchr/testify/assert" - "net/http" - "net/http/httptest" "strconv" "strings" "testing" ) -func prepareTestServer(resp string) *httptest.Server { - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case EndpointGetServers: - _, err := w.Write([]byte(resp)) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - } - return - default: - w.WriteHeader(http.StatusNotFound) - } - })) -} - func TestLoadServers(t *testing.T) { t.Run("invalid response", func(t *testing.T) { type scenario struct { @@ -55,7 +38,9 @@ func TestLoadServers(t *testing.T) { } for _, scenario := range scenarios { - ts := prepareTestServer(scenario.resp) + ts := prepareTestServer(&handlers{ + getServers: createWriteStringHandler(scenario.resp), + }) dl := NewVersionDataLoader(&VersionDataLoaderConfig{ Host: strings.ReplaceAll(ts.URL, "https://", ""), @@ -72,7 +57,9 @@ func TestLoadServers(t *testing.T) { t.Run("success", func(t *testing.T) { resp := `a:19:{s:5:"pl150";s:25:"https://pl150.plemiona.pl";s:5:"pl151";s:25:"https://pl151.plemiona.pl";s:5:"pl152";s:25:"https://pl152.plemiona.pl";s:5:"pl153";s:25:"https://pl153.plemiona.pl";s:5:"pl154";s:25:"https://pl154.plemiona.pl";s:5:"pl155";s:25:"https://pl155.plemiona.pl";s:5:"pl156";s:25:"https://pl156.plemiona.pl";s:5:"pl157";s:25:"https://pl157.plemiona.pl";s:5:"pl158";s:25:"https://pl158.plemiona.pl";s:5:"pl159";s:25:"https://pl159.plemiona.pl";s:5:"pl160";s:25:"https://pl160.plemiona.pl";s:5:"pl161";s:25:"https://pl161.plemiona.pl";s:5:"pl162";s:25:"https://pl162.plemiona.pl";s:5:"pl163";s:25:"https://pl163.plemiona.pl";s:5:"pl164";s:25:"https://pl164.plemiona.pl";s:4:"plp7";s:24:"https://plp7.plemiona.pl";s:5:"pl165";s:25:"https://pl165.plemiona.pl";s:5:"pl166";s:25:"https://pl166.plemiona.pl";s:5:"pl167";s:25:"https://pl167.plemiona.pl";}` - ts := prepareTestServer(resp) + ts := prepareTestServer(&handlers{ + getServers: createWriteStringHandler(resp), + }) defer ts.Close() expectedLength, err := strconv.Atoi(strings.Split(resp, ":")[1]) From 4613155d5d5916b68b967bd970e6b6dfc0d88dc6 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 16:40:29 +0200 Subject: [PATCH 07/15] add server_data_loader_test.go --- tw/twdataloader/helpers.go | 14 ++++++++++++++ tw/twdataloader/server_data_loader_test.go | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tw/twdataloader/server_data_loader_test.go diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index c12e576..adf1971 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -47,6 +47,20 @@ func prepareTestServer(h *handlers) *httptest.Server { case EndpointGetServers: h.getServers(w, r) return + case EndpointKillAll: + return + case EndpointKillAtt: + return + case EndpointKillDef: + return + case EndpointKillSup: + return + case EndpointKillAllTribe: + return + case EndpointKillAttTribe: + return + case EndpointKillDefTribe: + return default: w.WriteHeader(http.StatusNotFound) } diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go new file mode 100644 index 0000000..6c61716 --- /dev/null +++ b/tw/twdataloader/server_data_loader_test.go @@ -0,0 +1,19 @@ +package twdataloader + +import ( + "testing" +) + +func TestLoadOD(t *testing.T) { + t.Run("fallback to the not gzipped endpoint", func(t *testing.T) { + + }) + + t.Run("invalid line format", func(t *testing.T) { + + }) + + t.Run("success", func(t *testing.T) { + + }) +} From 6e3d32648d25aa98968131c11aa75384e77e4010 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Tue, 13 Jul 2021 16:47:11 +0200 Subject: [PATCH 08/15] fix one typo --- tw/twdataloader/server_data_loader.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tw/twdataloader/server_data_loader.go b/tw/twdataloader/server_data_loader.go index bef9b4d..bc20235 100644 --- a/tw/twdataloader/server_data_loader.go +++ b/tw/twdataloader/server_data_loader.go @@ -337,7 +337,7 @@ func (dl *ServerDataLoader) LoadEnnoblements(cfg *LoadEnnoblementsConfig) ([]*tw formattedURL = dl.baseURL + fmt.Sprintf(EndpointGetConquer, cfg.EnnobledAtGT.Unix()) compressed = false } - lines, err := d.getCSVData(formattedURL, compressed) + lines, err := dl.getCSVData(formattedURL, compressed) if err != nil { return nil, errors.Wrapf(err, "couldn't load data, formattedURL %s", formattedURL) } From f30ef110dada8bcc027a9f760ca7fcba229204e9 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Wed, 14 Jul 2021 06:40:58 +0200 Subject: [PATCH 09/15] add scenarios to TestLoadOD --- tw/twdataloader/helpers.go | 52 ++++++- tw/twdataloader/server_data_loader_test.go | 149 +++++++++++++++++++- tw/twdataloader/version_data_loader_test.go | 4 +- 3 files changed, 196 insertions(+), 9 deletions(-) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index adf1971..bcfb10f 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -25,7 +25,14 @@ func uncompressAndReadCsvLines(r io.Reader) ([][]string, error) { } type handlers struct { - getServers http.HandlerFunc + getServers http.HandlerFunc + killAll http.HandlerFunc + killAtt http.HandlerFunc + killDef http.HandlerFunc + killSup http.HandlerFunc + killAllTribe http.HandlerFunc + killAttTribe http.HandlerFunc + killDefTribe http.HandlerFunc } func (h *handlers) init() { @@ -35,6 +42,27 @@ func (h *handlers) init() { if h.getServers == nil { h.getServers = noop } + if h.killAll == nil { + h.killAll = noop + } + if h.killAtt == nil { + h.killAtt = noop + } + if h.killDef == nil { + h.killDef = noop + } + if h.killSup == nil { + h.killSup = noop + } + if h.killAllTribe == nil { + h.killAllTribe = noop + } + if h.killAttTribe == nil { + h.killAttTribe = noop + } + if h.killDefTribe == nil { + h.killDefTribe = noop + } } func prepareTestServer(h *handlers) *httptest.Server { @@ -42,24 +70,32 @@ func prepareTestServer(h *handlers) *httptest.Server { h = &handlers{} } h.init() + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case EndpointGetServers: h.getServers(w, r) return case EndpointKillAll: + h.killAll(w, r) return case EndpointKillAtt: + h.killAtt(w, r) return case EndpointKillDef: + h.killDef(w, r) return case EndpointKillSup: + h.killSup(w, r) return case EndpointKillAllTribe: + h.killAllTribe(w, r) return case EndpointKillAttTribe: + h.killAttTribe(w, r) return case EndpointKillDefTribe: + h.killDefTribe(w, r) return default: w.WriteHeader(http.StatusNotFound) @@ -75,3 +111,17 @@ func createWriteStringHandler(resp string) http.HandlerFunc { } }) } + +func createWriteCompressedStringHandler(resp string) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gzipWriter := gzip.NewWriter(w) + defer gzipWriter.Close() + _, err := gzipWriter.Write([]byte(resp)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + if err := gzipWriter.Flush(); err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + }) +} diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index 6c61716..7e9227a 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -1,19 +1,156 @@ package twdataloader import ( + "github.com/stretchr/testify/assert" "testing" + + "github.com/tribalwarshelp/shared/tw/twmodel" ) func TestLoadOD(t *testing.T) { - t.Run("fallback to the not gzipped endpoint", func(t *testing.T) { + type scenario struct { + respKillAll string + respKillAtt string + respKillDef string + respKillSup string + respKillAllTribe string + respKillAttTribe string + respKillDefTribe string + tribe bool + expectedResult map[int]*twmodel.OpponentsDefeated + expectedErrMsg string + } - }) + scenarios := []scenario{ + { + respKillAll: "1,1", + expectedErrMsg: "invalid line format (should be rank,id,score)", + }, + { + respKillAllTribe: "1,1", + expectedErrMsg: "invalid line format (should be rank,id,score)", + tribe: true, + }, + { + respKillAll: "1,1,1", + respKillAtt: "1,1,1", + respKillDef: "1,1,1", + respKillSup: "1,1", + expectedErrMsg: "invalid line format (should be rank,id,score)", + }, + { + respKillAllTribe: "1,1,1", + respKillAttTribe: "1,1,1", + respKillDefTribe: "1,1", + expectedErrMsg: "invalid line format (should be rank,id,score)", + tribe: true, + }, + { + respKillAll: "1,1,1\n2,2,2\n3,3,3", + respKillAtt: "1,1,1\n2,2,2\n3,3,3", + respKillDef: "1,1,1\n2,2,2\n3,3,3", + respKillSup: "1,1,1\n2,2,2\n3,3,3", + expectedResult: map[int]*twmodel.OpponentsDefeated{ + 1: { + RankAtt: 1, + ScoreAtt: 1, + RankDef: 1, + ScoreDef: 1, + RankSup: 1, + ScoreSup: 1, + RankTotal: 1, + ScoreTotal: 1, + }, + 2: { + RankAtt: 2, + ScoreAtt: 2, + RankDef: 2, + ScoreDef: 2, + RankSup: 2, + ScoreSup: 2, + ScoreTotal: 2, + RankTotal: 2, + }, + 3: { + RankAtt: 3, + ScoreAtt: 3, + RankDef: 3, + ScoreDef: 3, + RankSup: 3, + ScoreSup: 3, + ScoreTotal: 3, + RankTotal: 3, + }, + }, + }, + { + respKillAllTribe: "1,1,1\n2,2,2\n3,3,3", + respKillAttTribe: "1,1,1\n2,2,2\n3,3,3", + respKillDefTribe: "1,1,1\n2,2,2\n3,3,3", + expectedResult: map[int]*twmodel.OpponentsDefeated{ + 1: { + RankAtt: 1, + ScoreAtt: 1, + RankDef: 1, + ScoreDef: 1, + ScoreTotal: 1, + RankTotal: 1, + }, + 2: { + RankAtt: 2, + ScoreAtt: 2, + RankDef: 2, + ScoreDef: 2, + ScoreTotal: 2, + RankTotal: 2, + }, + 3: { + RankAtt: 3, + ScoreAtt: 3, + RankDef: 3, + ScoreDef: 3, + ScoreTotal: 3, + RankTotal: 3, + }, + }, + tribe: true, + }, + } - t.Run("invalid line format", func(t *testing.T) { + for _, scenario := range scenarios { + ts := prepareTestServer(&handlers{ + killAll: createWriteCompressedStringHandler(scenario.respKillAll), + killAtt: createWriteCompressedStringHandler(scenario.respKillAtt), + killDef: createWriteCompressedStringHandler(scenario.respKillDef), + killSup: createWriteCompressedStringHandler(scenario.respKillSup), + killAllTribe: createWriteCompressedStringHandler(scenario.respKillAllTribe), + killAttTribe: createWriteCompressedStringHandler(scenario.respKillAttTribe), + killDefTribe: createWriteCompressedStringHandler(scenario.respKillDefTribe), + }) - }) + dl := NewServerDataLoader(&ServerDataLoaderConfig{ + BaseURL: ts.URL, + Client: ts.Client(), + }) - t.Run("success", func(t *testing.T) { + res, err := dl.LoadOD(scenario.tribe) + if scenario.expectedErrMsg != "" { + assert.NotNil(t, err) + assert.Contains(t, err.Error(), scenario.expectedErrMsg) + } else { + assert.Nil(t, err) + } - }) + if scenario.expectedResult != nil { + assert.Len(t, res, len(scenario.expectedResult)) + for id, singleResult := range res { + expected, ok := scenario.expectedResult[id] + assert.True(t, ok) + assert.NotNil(t, expected) + assert.EqualValues(t, expected, singleResult) + } + } + + ts.Close() + } } diff --git a/tw/twdataloader/version_data_loader_test.go b/tw/twdataloader/version_data_loader_test.go index aa69808..1b3f633 100644 --- a/tw/twdataloader/version_data_loader_test.go +++ b/tw/twdataloader/version_data_loader_test.go @@ -43,7 +43,7 @@ func TestLoadServers(t *testing.T) { }) dl := NewVersionDataLoader(&VersionDataLoaderConfig{ - Host: strings.ReplaceAll(ts.URL, "https://", ""), + Host: ts.URL, Client: ts.Client(), }) @@ -66,7 +66,7 @@ func TestLoadServers(t *testing.T) { assert.Nil(t, err) dl := NewVersionDataLoader(&VersionDataLoaderConfig{ - Host: strings.ReplaceAll(ts.URL, "https://", ""), + Host: ts.URL, Client: ts.Client(), }) From 25c3a4f2bcb9821e3a3aef0cda7cbb6b858c67d4 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Sat, 17 Jul 2021 06:23:37 +0200 Subject: [PATCH 10/15] add more scenarios to TestLoadOD, add one more test - TestLoadPlayers --- tw/twdataloader/helpers.go | 11 +++ tw/twdataloader/server_data_loader_test.go | 85 ++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index bcfb10f..f650940 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -33,6 +33,7 @@ type handlers struct { killAllTribe http.HandlerFunc killAttTribe http.HandlerFunc killDefTribe http.HandlerFunc + getPlayers http.HandlerFunc } func (h *handlers) init() { @@ -63,6 +64,9 @@ func (h *handlers) init() { if h.killDefTribe == nil { h.killDefTribe = noop } + if h.getPlayers == nil { + h.getPlayers = noop + } } func prepareTestServer(h *handlers) *httptest.Server { @@ -72,6 +76,10 @@ func prepareTestServer(h *handlers) *httptest.Server { h.init() return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + w.WriteHeader(http.StatusNotFound) + return + } switch r.URL.Path { case EndpointGetServers: h.getServers(w, r) @@ -97,6 +105,9 @@ func prepareTestServer(h *handlers) *httptest.Server { case EndpointKillDefTribe: h.killDefTribe(w, r) return + case EndpointPlayer: + h.getPlayers(w, r) + return default: w.WriteHeader(http.StatusNotFound) } diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index 7e9227a..2d62786 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -45,6 +45,33 @@ func TestLoadOD(t *testing.T) { expectedErrMsg: "invalid line format (should be rank,id,score)", tribe: true, }, + { + respKillAll: "1,1,asd", + expectedErrMsg: "parsedODLine.Score: strconv.Atoi: parsing \"asd\"", + }, + { + respKillAll: "1,asd,1", + expectedErrMsg: "parsedODLine.ID: strconv.Atoi: parsing \"asd\":", + }, + { + respKillAll: "asd,1,1", + expectedErrMsg: "parsedODLine.Rank: strconv.Atoi: parsing \"asd\":", + }, + { + respKillAllTribe: "1,1,asd", + expectedErrMsg: "parsedODLine.Score: strconv.Atoi: parsing \"asd\"", + tribe: true, + }, + { + respKillAllTribe: "1,asd,1", + expectedErrMsg: "parsedODLine.ID: strconv.Atoi: parsing \"asd\":", + tribe: true, + }, + { + respKillAllTribe: "asd,1,1", + expectedErrMsg: "parsedODLine.Rank: strconv.Atoi: parsing \"asd\":", + tribe: true, + }, { respKillAll: "1,1,1\n2,2,2\n3,3,3", respKillAtt: "1,1,1\n2,2,2\n3,3,3", @@ -154,3 +181,61 @@ func TestLoadOD(t *testing.T) { ts.Close() } } + +func TestLoadPlayers(t *testing.T) { + type scenario struct { + resp string + expectedResult []*twmodel.Player + expectedErrMsg string + } + + scenarios := []scenario{ + { + resp: "1,1,1,1", + expectedErrMsg: "invalid line format (should be id,name,tribeid,villages,points,rank)", + }, + { + resp: "1,name,1,500,500", + expectedErrMsg: "invalid line format (should be id,name,tribeid,villages,points,rank)", + }, + } + + for _, scenario := range scenarios { + ts := prepareTestServer(&handlers{ + getPlayers: createWriteCompressedStringHandler(scenario.resp), + }) + + dl := NewServerDataLoader(&ServerDataLoaderConfig{ + BaseURL: ts.URL, + Client: ts.Client(), + }) + + res, err := dl.LoadPlayers() + if scenario.expectedErrMsg != "" { + assert.NotNil(t, err) + assert.Contains(t, err.Error(), scenario.expectedErrMsg) + } else { + assert.Nil(t, err) + } + + if scenario.expectedResult != nil { + assert.Len(t, res, len(scenario.expectedResult)) + for _, singleResult := range res { + found := false + var player *twmodel.Player + for _, expected := range scenario.expectedResult { + if expected.ID == singleResult.ID { + found = true + player = expected + break + } + } + assert.True(t, found) + assert.NotNil(t, player) + assert.EqualValues(t, player, singleResult) + } + } + + ts.Close() + } +} From 1de6302b52e761dc7420bdad729f39dfb2aae07a Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Sat, 17 Jul 2021 06:36:00 +0200 Subject: [PATCH 11/15] add more scenarios to TestLoadPlayers --- tw/twdataloader/server_data_loader_test.go | 96 ++++++++++++++++------ 1 file changed, 72 insertions(+), 24 deletions(-) diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index 2d62786..b10b54a 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -73,40 +73,40 @@ func TestLoadOD(t *testing.T) { tribe: true, }, { - respKillAll: "1,1,1\n2,2,2\n3,3,3", - respKillAtt: "1,1,1\n2,2,2\n3,3,3", - respKillDef: "1,1,1\n2,2,2\n3,3,3", - respKillSup: "1,1,1\n2,2,2\n3,3,3", + respKillAll: "1,1,1\n4,2,4\n2,3,2", + respKillAtt: "2,1,2\n3,2,3\n1,3,1", + respKillDef: "3,1,3\n2,2,2\n4,3,4", + respKillSup: "4,1,4\n1,2,1\n3,3,3", expectedResult: map[int]*twmodel.OpponentsDefeated{ 1: { - RankAtt: 1, - ScoreAtt: 1, - RankDef: 1, - ScoreDef: 1, - RankSup: 1, - ScoreSup: 1, + RankAtt: 2, + ScoreAtt: 2, + RankDef: 3, + ScoreDef: 3, + RankSup: 4, + ScoreSup: 4, RankTotal: 1, ScoreTotal: 1, }, 2: { - RankAtt: 2, - ScoreAtt: 2, - RankDef: 2, - ScoreDef: 2, - RankSup: 2, - ScoreSup: 2, - ScoreTotal: 2, - RankTotal: 2, - }, - 3: { RankAtt: 3, ScoreAtt: 3, - RankDef: 3, - ScoreDef: 3, + RankDef: 2, + ScoreDef: 2, + RankSup: 1, + ScoreSup: 1, + ScoreTotal: 4, + RankTotal: 4, + }, + 3: { + RankAtt: 1, + ScoreAtt: 1, + RankDef: 4, + ScoreDef: 4, RankSup: 3, ScoreSup: 3, - ScoreTotal: 3, - RankTotal: 3, + ScoreTotal: 2, + RankTotal: 2, }, }, }, @@ -189,6 +189,7 @@ func TestLoadPlayers(t *testing.T) { expectedErrMsg string } + exists := true scenarios := []scenario{ { resp: "1,1,1,1", @@ -198,6 +199,53 @@ func TestLoadPlayers(t *testing.T) { resp: "1,name,1,500,500", expectedErrMsg: "invalid line format (should be id,name,tribeid,villages,points,rank)", }, + { + resp: "asd,name,1,500,500,500", + expectedErrMsg: "player.ID: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "1,name,asd,500,500,500", + expectedErrMsg: "player.TribeID: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "1,name,123,asd,500,500", + expectedErrMsg: "player.TotalVillages: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "1,name,123,500,asd,500", + expectedErrMsg: "player.Points: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "1,name,123,500,123,asd", + expectedErrMsg: "player.Rank: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "1,name,123,500,500,asd", + expectedErrMsg: "player.Rank: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "1,name,123,124,125,126\n2,name2,256,257,258,259", + expectedResult: []*twmodel.Player{ + { + ID: 1, + Name: "name", + TribeID: 123, + TotalVillages: 124, + Points: 125, + Rank: 126, + Exists: &exists, + }, + { + ID: 2, + Name: "name2", + TribeID: 256, + TotalVillages: 257, + Points: 258, + Rank: 259, + Exists: &exists, + }, + }, + }, } for _, scenario := range scenarios { From db02f8c4ae6afc01d0fd1380f2aec4985df1674e Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Sat, 17 Jul 2021 06:48:57 +0200 Subject: [PATCH 12/15] add TestLoadTribes --- tw/twdataloader/helpers.go | 7 ++ tw/twdataloader/server_data_loader_test.go | 110 +++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index f650940..5adefcd 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -34,6 +34,7 @@ type handlers struct { killAttTribe http.HandlerFunc killDefTribe http.HandlerFunc getPlayers http.HandlerFunc + getTribes http.HandlerFunc } func (h *handlers) init() { @@ -67,6 +68,9 @@ func (h *handlers) init() { if h.getPlayers == nil { h.getPlayers = noop } + if h.getTribes == nil { + h.getTribes = noop + } } func prepareTestServer(h *handlers) *httptest.Server { @@ -108,6 +112,9 @@ func prepareTestServer(h *handlers) *httptest.Server { case EndpointPlayer: h.getPlayers(w, r) return + case EndpointTribe: + h.getTribes(w, r) + return default: w.WriteHeader(http.StatusNotFound) } diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index b10b54a..ce4fce7 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -287,3 +287,113 @@ func TestLoadPlayers(t *testing.T) { ts.Close() } } + +func TestLoadTribes(t *testing.T) { + type scenario struct { + resp string + expectedResult []*twmodel.Tribe + expectedErrMsg string + } + + ex := true + scenarios := []scenario{ + { + resp: "1,1,1,1", + expectedErrMsg: "invalid line format (should be id,name,tag,members,villages,points,allpoints,rank)", + }, + { + resp: "1,name,1,500,500", + expectedErrMsg: "invalid line format (should be id,name,tag,members,villages,points,allpoints,rank)", + }, + { + resp: "asd,name,tag,500,500,500,500,500", + expectedErrMsg: "tribe.ID: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,tag,asd,500,500,500,500", + expectedErrMsg: "tribe.TotalMembers: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,tag,500,asd,500,500,500", + expectedErrMsg: "tribe.TotalVillages: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,tag,500,500,asd,500,500", + expectedErrMsg: "tribe.Points: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,tag,500,500,500,asd,500", + expectedErrMsg: "tribe.AllPoints: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,tag,500,500,500,500,asd", + expectedErrMsg: "tribe.Rank: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,tag,500,501,502,503,504\n1234,name2,tag2,5000,5001,5002,5003,5004", + expectedResult: []*twmodel.Tribe{ + { + ID: 123, + Name: "name", + Tag: "tag", + TotalMembers: 500, + TotalVillages: 501, + Points: 502, + AllPoints: 503, + Rank: 504, + Exists: &ex, + }, + { + ID: 1234, + Name: "name2", + Tag: "tag2", + TotalMembers: 5000, + TotalVillages: 5001, + Points: 5002, + AllPoints: 5003, + Rank: 5004, + Exists: &ex, + }, + }, + }, + } + + for _, scenario := range scenarios { + ts := prepareTestServer(&handlers{ + getTribes: createWriteCompressedStringHandler(scenario.resp), + }) + + dl := NewServerDataLoader(&ServerDataLoaderConfig{ + BaseURL: ts.URL, + Client: ts.Client(), + }) + + res, err := dl.LoadTribes() + if scenario.expectedErrMsg != "" { + assert.NotNil(t, err) + assert.Contains(t, err.Error(), scenario.expectedErrMsg) + } else { + assert.Nil(t, err) + } + + if scenario.expectedResult != nil { + assert.Len(t, res, len(scenario.expectedResult)) + for _, singleResult := range res { + found := false + var tribe *twmodel.Tribe + for _, expected := range scenario.expectedResult { + if expected.ID == singleResult.ID { + found = true + tribe = expected + break + } + } + assert.True(t, found) + assert.NotNil(t, tribe) + assert.EqualValues(t, tribe, singleResult) + } + } + + ts.Close() + } +} From 77e67c83dd991e1cb58ef3e80b79450ca40f8d6f Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Sat, 17 Jul 2021 07:08:00 +0200 Subject: [PATCH 13/15] add TestLoadVillages --- tw/twdataloader/helpers.go | 7 ++ tw/twdataloader/server_data_loader_test.go | 105 +++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index 5adefcd..5633aa4 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -35,6 +35,7 @@ type handlers struct { killDefTribe http.HandlerFunc getPlayers http.HandlerFunc getTribes http.HandlerFunc + getVillages http.HandlerFunc } func (h *handlers) init() { @@ -71,6 +72,9 @@ func (h *handlers) init() { if h.getTribes == nil { h.getTribes = noop } + if h.getVillages == nil { + h.getVillages = noop + } } func prepareTestServer(h *handlers) *httptest.Server { @@ -115,6 +119,9 @@ func prepareTestServer(h *handlers) *httptest.Server { case EndpointTribe: h.getTribes(w, r) return + case EndpointVillage: + h.getVillages(w, r) + return default: w.WriteHeader(http.StatusNotFound) } diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index ce4fce7..1c56bd7 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -397,3 +397,108 @@ func TestLoadTribes(t *testing.T) { ts.Close() } } + +func TestLoadVillages(t *testing.T) { + type scenario struct { + resp string + expectedResult []*twmodel.Village + expectedErrMsg string + } + + scenarios := []scenario{ + { + resp: "1,1,1,1", + expectedErrMsg: "invalid line format (should be id,name,x,y,playerID,points,bonus)", + }, + { + resp: "1,name,1,500,500", + expectedErrMsg: "invalid line format (should be id,name,x,y,playerID,points,bonus)", + }, + { + resp: "asd,name,500,500,500,500,0", + expectedErrMsg: "village.ID: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,asd,500,500,500,0", + expectedErrMsg: "village.X: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,500,asd,500,500,0", + expectedErrMsg: "village.Y: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,500,500,asd,500,0", + expectedErrMsg: "village.PlayerID: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,500,500,500,asd,0", + expectedErrMsg: "village.Points: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,name,500,500,500,500,asd", + expectedErrMsg: "village.Bonus: strconv.Atoi: parsing \"asd\"", + }, + { + resp: "123,village 1,500,501,502,503,504\n124,village 2,100,101,102,103,104", + expectedResult: []*twmodel.Village{ + { + ID: 123, + Name: "village 1", + X: 500, + Y: 501, + PlayerID: 502, + Points: 503, + Bonus: 504, + }, + { + ID: 124, + Name: "village 2", + X: 100, + Y: 101, + PlayerID: 102, + Points: 103, + Bonus: 104, + }, + }, + }, + } + + for _, scenario := range scenarios { + ts := prepareTestServer(&handlers{ + getVillages: createWriteCompressedStringHandler(scenario.resp), + }) + + dl := NewServerDataLoader(&ServerDataLoaderConfig{ + BaseURL: ts.URL, + Client: ts.Client(), + }) + + res, err := dl.LoadVillages() + if scenario.expectedErrMsg != "" { + assert.NotNil(t, err) + assert.Contains(t, err.Error(), scenario.expectedErrMsg) + } else { + assert.Nil(t, err) + } + + if scenario.expectedResult != nil { + assert.Len(t, res, len(scenario.expectedResult)) + for _, singleResult := range res { + found := false + var village *twmodel.Village + for _, expected := range scenario.expectedResult { + if expected.ID == singleResult.ID { + found = true + village = expected + break + } + } + assert.True(t, found) + assert.NotNil(t, village) + assert.EqualValues(t, village, singleResult) + } + } + + ts.Close() + } +} From 4e82ae6bed53ffdcc4daa8b19e1ebed5e0e63ea2 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Sat, 17 Jul 2021 07:20:22 +0200 Subject: [PATCH 14/15] rename a few fields in the handlers struct and add two new (conquer, getConquer) --- tw/twdataloader/helpers.go | 38 +++++++++++++++------- tw/twdataloader/server_data_loader_test.go | 6 ++-- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index 5633aa4..a41e2e2 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -33,9 +33,11 @@ type handlers struct { killAllTribe http.HandlerFunc killAttTribe http.HandlerFunc killDefTribe http.HandlerFunc - getPlayers http.HandlerFunc - getTribes http.HandlerFunc - getVillages http.HandlerFunc + player http.HandlerFunc + tribe http.HandlerFunc + village http.HandlerFunc + conquer http.HandlerFunc + getConquer http.HandlerFunc } func (h *handlers) init() { @@ -66,14 +68,20 @@ func (h *handlers) init() { if h.killDefTribe == nil { h.killDefTribe = noop } - if h.getPlayers == nil { - h.getPlayers = noop + if h.player == nil { + h.player = noop } - if h.getTribes == nil { - h.getTribes = noop + if h.tribe == nil { + h.tribe = noop } - if h.getVillages == nil { - h.getVillages = noop + if h.village == nil { + h.village = noop + } + if h.conquer == nil { + h.conquer = noop + } + if h.getConquer == nil { + h.getConquer = noop } } @@ -114,13 +122,19 @@ func prepareTestServer(h *handlers) *httptest.Server { h.killDefTribe(w, r) return case EndpointPlayer: - h.getPlayers(w, r) + h.player(w, r) return case EndpointTribe: - h.getTribes(w, r) + h.tribe(w, r) return case EndpointVillage: - h.getVillages(w, r) + h.village(w, r) + return + case EndpointConquer: + h.conquer(w, r) + return + case EndpointGetConquer: + h.getConquer(w, r) return default: w.WriteHeader(http.StatusNotFound) diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index 1c56bd7..be0e363 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -250,7 +250,7 @@ func TestLoadPlayers(t *testing.T) { for _, scenario := range scenarios { ts := prepareTestServer(&handlers{ - getPlayers: createWriteCompressedStringHandler(scenario.resp), + player: createWriteCompressedStringHandler(scenario.resp), }) dl := NewServerDataLoader(&ServerDataLoaderConfig{ @@ -360,7 +360,7 @@ func TestLoadTribes(t *testing.T) { for _, scenario := range scenarios { ts := prepareTestServer(&handlers{ - getTribes: createWriteCompressedStringHandler(scenario.resp), + tribe: createWriteCompressedStringHandler(scenario.resp), }) dl := NewServerDataLoader(&ServerDataLoaderConfig{ @@ -465,7 +465,7 @@ func TestLoadVillages(t *testing.T) { for _, scenario := range scenarios { ts := prepareTestServer(&handlers{ - getVillages: createWriteCompressedStringHandler(scenario.resp), + village: createWriteCompressedStringHandler(scenario.resp), }) dl := NewServerDataLoader(&ServerDataLoaderConfig{ From ee20d129af059c12a9e0c7ffe06ce0b62e2cd168 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Sat, 17 Jul 2021 07:49:16 +0200 Subject: [PATCH 15/15] add TestLoadEnnoblements --- tw/twdataloader/endpoints.go | 3 +- tw/twdataloader/helpers.go | 2 +- tw/twdataloader/server_data_loader_test.go | 122 +++++++++++++++++++++ 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/tw/twdataloader/endpoints.go b/tw/twdataloader/endpoints.go index d06f771..7e5705b 100644 --- a/tw/twdataloader/endpoints.go +++ b/tw/twdataloader/endpoints.go @@ -26,6 +26,7 @@ const ( EndpointKillAllTribeNotGzipped = "/map/kill_all_tribe.txt" EndpointConquer = "/map/conquer.txt.gz" EndpointConquerNotGzipped = "/map/conquer.txt" - EndpointGetConquer = "/interface.php?func=get_conquer&since=%d" + endpointInterface = "/interface.php" + EndpointGetConquer = endpointInterface + "?func=get_conquer&since=%d" EndpointGetServers = "/backend/get_servers.php" ) diff --git a/tw/twdataloader/helpers.go b/tw/twdataloader/helpers.go index a41e2e2..cbd18b4 100644 --- a/tw/twdataloader/helpers.go +++ b/tw/twdataloader/helpers.go @@ -133,7 +133,7 @@ func prepareTestServer(h *handlers) *httptest.Server { case EndpointConquer: h.conquer(w, r) return - case EndpointGetConquer: + case endpointInterface: h.getConquer(w, r) return default: diff --git a/tw/twdataloader/server_data_loader_test.go b/tw/twdataloader/server_data_loader_test.go index be0e363..f4afe03 100644 --- a/tw/twdataloader/server_data_loader_test.go +++ b/tw/twdataloader/server_data_loader_test.go @@ -1,8 +1,10 @@ package twdataloader import ( + "fmt" "github.com/stretchr/testify/assert" "testing" + "time" "github.com/tribalwarshelp/shared/tw/twmodel" ) @@ -502,3 +504,123 @@ func TestLoadVillages(t *testing.T) { ts.Close() } } + +func TestLoadEnnoblements(t *testing.T) { + type scenario struct { + respConquer string + respGetConquer string + cfg *LoadEnnoblementsConfig + expectedResult []*twmodel.Ennoblement + expectedErrMsg string + } + + nowMinus5h := time.Now().Add(-5 * time.Hour).Unix() + nowMinus6h := time.Now().Add(-6 * time.Hour).Unix() + scenarios := []scenario{ + { + respConquer: "1,1,1", + expectedErrMsg: "invalid line format (should be village_id,timestamp,new_owner_id,old_owner_id)", + }, + { + respConquer: "1,name,1,500,500", + expectedErrMsg: "invalid line format (should be village_id,timestamp,new_owner_id,old_owner_id)", + }, + { + respConquer: "asd,123,123,123", + expectedErrMsg: "ennoblement.VillageID: strconv.Atoi: parsing \"asd\"", + }, + { + respConquer: "123,asd,123,123", + expectedErrMsg: "timestamp: strconv.Atoi: parsing \"asd\"", + }, + { + respConquer: "123,123,asd,123", + expectedErrMsg: "ennoblement.NewOwnerID: strconv.Atoi: parsing \"asd\"", + }, + { + respConquer: "123,123,123,asd", + expectedErrMsg: "ennoblement.OldOwnerID: strconv.Atoi: parsing \"asd\"", + }, + { + respConquer: "123,124,125,126\n127,128,129,130", + expectedResult: []*twmodel.Ennoblement{ + { + VillageID: 123, + EnnobledAt: time.Unix(124, 0), + NewOwnerID: 125, + OldOwnerID: 126, + }, + { + VillageID: 127, + EnnobledAt: time.Unix(128, 0), + NewOwnerID: 129, + OldOwnerID: 130, + }, + }, + }, + { + respGetConquer: "123,124,125,126\n127,128,129,130", + cfg: &LoadEnnoblementsConfig{ + EnnobledAtGT: time.Now().Add(5 * time.Hour), + }, + expectedResult: []*twmodel.Ennoblement{}, + }, + { + respConquer: fmt.Sprintf("123,%d,125,126\n127,%d,129,130", nowMinus5h, nowMinus6h), + expectedResult: []*twmodel.Ennoblement{ + { + VillageID: 123, + EnnobledAt: time.Unix(nowMinus5h, 0), + NewOwnerID: 125, + OldOwnerID: 126, + }, + { + VillageID: 127, + EnnobledAt: time.Unix(nowMinus6h, 0), + NewOwnerID: 129, + OldOwnerID: 130, + }, + }, + }, + } + + for _, scenario := range scenarios { + ts := prepareTestServer(&handlers{ + conquer: createWriteCompressedStringHandler(scenario.respConquer), + getConquer: createWriteStringHandler(scenario.respGetConquer), + }) + + dl := NewServerDataLoader(&ServerDataLoaderConfig{ + BaseURL: ts.URL, + Client: ts.Client(), + }) + + res, err := dl.LoadEnnoblements(scenario.cfg) + if scenario.expectedErrMsg != "" { + assert.NotNil(t, err) + assert.Contains(t, err.Error(), scenario.expectedErrMsg) + } else { + assert.Nil(t, err) + } + + if scenario.expectedResult != nil { + assert.Len(t, res, len(scenario.expectedResult)) + for _, singleResult := range res { + found := false + var ennoblement *twmodel.Ennoblement + for _, expected := range scenario.expectedResult { + if expected.VillageID == singleResult.VillageID { + found = true + ennoblement = expected + break + } + } + assert.True(t, found) + assert.NotNil(t, ennoblement) + assert.EqualValues(t, ennoblement, singleResult) + } + } + + ts.Close() + } +}