@@ -50,10 +50,12 @@ import (
5050 "github.com/elastic/apm-server/systemtest/apmservertest"
5151 "github.com/elastic/apm-server/systemtest/estest"
5252 "github.com/elastic/go-elasticsearch/v8"
53+ "github.com/elastic/go-elasticsearch/v8/esapi"
5354)
5455
5556const (
5657 startContainersTimeout = 5 * time .Minute
58+ waitHealthyInterval = 5 * time .Second
5759)
5860
5961var (
@@ -110,6 +112,7 @@ func StartStackContainers() error {
110112 g , ctx := errgroup .WithContext (ctx )
111113 g .Go (func () error { return waitContainerHealthy (ctx , "kibana" ) })
112114 g .Go (func () error { return waitContainerHealthy (ctx , "fleet-server" ) })
115+ g .Go (func () error { return waitGeoIPDatabase (ctx ) })
113116 return g .Wait ()
114117}
115118
@@ -191,11 +194,51 @@ func waitContainerHealthy(ctx context.Context, serviceName string) error {
191194 log .Printf ("Waiting for %s container (%s) to become healthy" , serviceName , container .ID )
192195 first = false
193196 }
194- time .Sleep (5 * time . Second )
197+ time .Sleep (waitHealthyInterval )
195198 }
196199 return nil
197200}
198201
202+ // Elasticsearch downloads the geoIP database after starting up, and then refreshes it
203+ // periodically. In CI the cluster will be fresh, so we wait for the database to be
204+ // downloaded before running any tests which may depend on it being available.
205+ func waitGeoIPDatabase (ctx context.Context ) error {
206+ type geoIPDatabase struct {
207+ Name string
208+ }
209+ type nodeGeoIPStats struct {
210+ Databases []geoIPDatabase
211+ }
212+
213+ first := true
214+ for {
215+ var out struct {
216+ Nodes map [string ]nodeGeoIPStats
217+ }
218+ _ , err := Elasticsearch .Do (ctx , esapi.IngestGeoIPStatsRequest {}, & out )
219+ if err != nil {
220+ return err
221+ }
222+
223+ if n := len (out .Nodes ); n != 1 {
224+ return fmt .Errorf ("expected 1 node, got %d" , n )
225+ }
226+ for _ , nodeStats := range out .Nodes {
227+ for _ , db := range nodeStats .Databases {
228+ if db .Name == "GeoLite2-City.mmdb" {
229+ return nil
230+ }
231+ }
232+ }
233+
234+ if first {
235+ log .Printf ("Waiting for geoIP database to be downloaded" )
236+ first = false
237+ }
238+ time .Sleep (waitHealthyInterval )
239+ }
240+ }
241+
199242func stackContainerInfo (ctx context.Context , docker * client.Client , name string ) (* types.Container , error ) {
200243 containers , err := docker .ContainerList (ctx , types.ContainerListOptions {
201244 Filters : filters .NewArgs (
0 commit comments