github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/testutil/cosmosdb.go (about) 1 package testutil 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "net/http" 7 "net/url" 8 9 "github.com/ory/dockertest/v3" 10 "github.com/ory/dockertest/v3/docker" 11 ) 12 13 const ( 14 CosmosDBLocalPort = "8081" 15 ) 16 17 var cosmosdbLocalURI string 18 19 func GetCosmosDBInstance() (string, func(), error) { 20 dockerPool, err := dockertest.NewPool("") 21 if err != nil { 22 return "", nil, fmt.Errorf("could not connect to Docker: %w", err) 23 } 24 25 cosmosdbDockerRunOptions := &dockertest.RunOptions{ 26 Repository: "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator", 27 Tag: "latest", 28 Env: []string{"AZURE_COSMOS_EMULATOR_PARTITION_COUNT=5", 29 "AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE=true", 30 "AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE=127.0.0.1"}, 31 PortBindings: map[docker.Port][]docker.PortBinding{ 32 "8081/tcp": {{HostPort: CosmosDBLocalPort}}, 33 "10251/tcp": {{HostPort: "10251"}}, 34 "10252/tcp": {{HostPort: "10252"}}, 35 "10253/tcp": {{HostPort: "10253"}}, 36 "10254/tcp": {{HostPort: "10254"}}, 37 "10255/tcp": {{HostPort: "10255"}}, 38 }, 39 ExposedPorts: []string{CosmosDBLocalPort, "10251", "10252", "10253", "10254", "10255"}, 40 } 41 42 resource, err := dockerPool.RunWithOptions(cosmosdbDockerRunOptions) 43 if err != nil { 44 return "", nil, fmt.Errorf("could not start cosmosdb emulator: %w", err) 45 } 46 47 cosmosdbLocalURI = "https://localhost:" + resource.GetPort("8081/tcp") 48 // set cleanup 49 closer := func() { 50 err = dockerPool.Purge(resource) 51 if err != nil { 52 panic("could not kill cosmosdb local container") 53 } 54 } 55 56 // expire, just to make sure 57 err = resource.Expire(dbContainerTimeoutSeconds) 58 if err != nil { 59 return "", nil, fmt.Errorf("could not expire cosmosdb local emulator: %w", err) 60 } 61 p, err := url.JoinPath(cosmosdbLocalURI, "/_explorer/emulator.pem") 62 if err != nil { 63 return "", nil, fmt.Errorf("joining urls: %w", err) 64 } 65 66 err = dockerPool.Retry(func() error { 67 // waiting for cosmosdb container to be ready by issuing an HTTP get request with 68 // exponential backoff retry. The response is not really meaningful for that case 69 // and so is ignored 70 client := http.Client{Transport: &http.Transport{ 71 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //nolint:gosec // ignore self-signed cert for local testing using the emulator 72 }} 73 resp, err := client.Get(p) 74 if err != nil { 75 return err 76 } 77 _ = resp.Body.Close() 78 return nil 79 }) 80 if err != nil { 81 return "", nil, fmt.Errorf("could not connect to cosmosdb emulator at %s: %w", cosmosdbLocalURI, err) 82 } 83 84 // return DB URI 85 return cosmosdbLocalURI, closer, nil 86 }