github.com/rudderlabs/rudder-go-kit@v0.30.0/testhelper/docker/resource/zipkin/zipkin.go (about) 1 package zipkin 2 3 import ( 4 "fmt" 5 "net/http" 6 "strconv" 7 "sync" 8 9 "github.com/ory/dockertest/v3" 10 "github.com/ory/dockertest/v3/docker" 11 12 "github.com/rudderlabs/rudder-go-kit/httputil" 13 "github.com/rudderlabs/rudder-go-kit/testhelper" 14 "github.com/rudderlabs/rudder-go-kit/testhelper/docker/resource" 15 ) 16 17 const port = "9411" 18 19 type Resource struct { 20 Port string 21 22 pool *dockertest.Pool 23 resource *dockertest.Resource 24 purged bool 25 purgedMu sync.Mutex 26 } 27 28 func (z *Resource) Purge() error { 29 z.purgedMu.Lock() 30 defer z.purgedMu.Unlock() 31 32 if z.purged { 33 return nil 34 } 35 36 if err := z.pool.Purge(z.resource); err != nil { 37 return err 38 } 39 40 z.purged = true 41 42 return nil 43 } 44 45 func Setup(pool *dockertest.Pool, d resource.Cleaner) (*Resource, error) { 46 freePort, err := testhelper.GetFreePort() 47 if err != nil { 48 return nil, fmt.Errorf("failed to get free port: %w", err) 49 } 50 51 zipkin, err := pool.RunWithOptions(&dockertest.RunOptions{ 52 Repository: "openzipkin/zipkin", 53 ExposedPorts: []string{port}, 54 PortBindings: map[docker.Port][]docker.PortBinding{ 55 port + "/tcp": {{HostPort: strconv.Itoa(freePort)}}, 56 }, 57 }) 58 if err != nil { 59 return nil, fmt.Errorf("failed to start zipkin: %w", err) 60 } 61 62 res := &Resource{ 63 pool: pool, 64 resource: zipkin, 65 Port: zipkin.GetPort(port + "/tcp"), 66 } 67 d.Cleanup(func() { 68 if err := res.Purge(); err != nil { 69 d.Log("Could not purge zipkin resource:", err) 70 } 71 }) 72 73 zipkinHealthURL := "http://localhost:" + strconv.Itoa(freePort) + "/health" 74 healthReq, err := http.NewRequest(http.MethodGet, zipkinHealthURL, nil) 75 if err != nil { 76 return nil, fmt.Errorf("failed to create zipkin health request: %w", err) 77 } 78 79 err = pool.Retry(func() error { 80 resp, err := http.DefaultClient.Do(healthReq) 81 if err != nil { 82 return fmt.Errorf("failed to get zipkin health: %w", err) 83 } 84 85 defer func() { httputil.CloseResponse(resp) }() 86 87 if resp.StatusCode != http.StatusOK { 88 return fmt.Errorf("zipkin health returned status code %d", resp.StatusCode) 89 } 90 91 return nil 92 }) 93 if err != nil { 94 return nil, fmt.Errorf("failed to wait for zipkin to be ready: %w", err) 95 } 96 97 return res, nil 98 }