1818package systemtest
1919
2020import (
21+ "encoding/json"
22+ "fmt"
23+ "io"
2124 "log"
25+ "net/http"
2226 "os"
27+ "strings"
2328 "testing"
29+ "time"
30+
31+ "github.com/elastic/apm-server/systemtest/apmservertest"
2432)
2533
2634func TestMain (m * testing.M ) {
@@ -30,9 +38,90 @@ func TestMain(m *testing.M) {
3038 log .Fatalf ("failed to start stack containers: %v" , err )
3139 }
3240 initElasticSearch ()
41+ if err := GeoIpLazyDownload (); err != nil {
42+ log .Fatalf ("failed to download geoip database: %v" , err )
43+ }
3344 initKibana ()
3445 initSettings ()
3546 initOTEL ()
3647 log .Println ("INFO: running system tests..." )
3748 os .Exit (m .Run ())
3849}
50+
51+ var stats struct {
52+ GeoIPStats `json:"stats"`
53+ }
54+
55+ type GeoIPStats struct {
56+ DatabasesCount int `json:"databases_count"`
57+ }
58+
59+ const requestBody = `{"metadata": { "service": {"name": "alice", "agent": {"version": "3.14.0", "name": "elastic-node"}}}}
60+ {"metricset": {"samples":{"a":{"value":3.2}}, "timestamp": 1496170422281000}}`
61+
62+ func GeoIpLazyDownload () error {
63+ srv := apmservertest .NewUnstartedServer ()
64+ if err := srv .Start (); err != nil {
65+ return err
66+ }
67+
68+ serverURL := srv .URL + "/intake/v2/events"
69+ req , err := http .NewRequest ("POST" , serverURL , strings .NewReader (requestBody ))
70+ if err != nil {
71+ return err
72+ }
73+
74+ req .Header .Set ("Content-Type" , "application/x-ndjson" )
75+ req .Header .Set ("X-Forwarded-For" , "8.8.8.8" )
76+
77+ resp , err := http .DefaultClient .Do (req )
78+ if err != nil {
79+ return err
80+ }
81+ if resp .StatusCode != http .StatusAccepted {
82+ return fmt .Errorf ("query failed with status code: %d" , resp .StatusCode )
83+ }
84+
85+ io .Copy (io .Discard , resp .Body )
86+ resp .Body .Close ()
87+
88+ if err := waitGeoIPDownload (); err != nil {
89+ return err
90+ }
91+
92+ // Clean all datastreams containing tags.
93+ cleanupElasticsearch ()
94+
95+ return nil
96+ }
97+
98+ func waitGeoIPDownload () error {
99+ timer := time .NewTimer (2 * time .Minute )
100+ ticker := time .NewTicker (500 * time .Millisecond )
101+ defer ticker .Stop ()
102+ defer timer .Stop ()
103+
104+ for {
105+ select {
106+ case <- ticker .C :
107+ resp , err := Elasticsearch .Ingest .GeoIPStats ()
108+ if err != nil {
109+ return err
110+ }
111+ body , err := io .ReadAll (resp .Body )
112+ resp .Body .Close ()
113+ if err != nil {
114+ return err
115+ }
116+ if err := json .Unmarshal (body , & stats ); err != nil {
117+ return err
118+ }
119+ if stats .DatabasesCount == 3 {
120+ log .Println ("GeoIP database downloaded" )
121+ return nil
122+ }
123+ case <- timer .C :
124+ return fmt .Errorf ("download timeout exceeded" )
125+ }
126+ }
127+ }
0 commit comments