87 lines
2.3 KiB
Go
87 lines
2.3 KiB
Go
|
package etcd
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"os"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/hashicorp/vault/helper/testhelpers/docker"
|
||
|
clientv3 "go.etcd.io/etcd/client/v3"
|
||
|
)
|
||
|
|
||
|
type Config struct {
|
||
|
docker.ServiceURL
|
||
|
}
|
||
|
|
||
|
// PrepareTestContainer creates etcd docker container. If environment variabe
|
||
|
// ETCD_ADDR is set, the tests are executed against specified address and etcd
|
||
|
// container is not launched.
|
||
|
func PrepareTestContainer(t *testing.T, version string) (func(), *Config) {
|
||
|
if addr := os.Getenv("ETCD_ADDR"); addr != "" {
|
||
|
url, err := docker.NewServiceURLParse(addr)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
return func() {}, &Config{ServiceURL: *url}
|
||
|
}
|
||
|
|
||
|
// Check https://github.com/etcd-io/etcd/releases for latest releases.
|
||
|
runner, err := docker.NewServiceRunner(docker.RunOptions{
|
||
|
ContainerName: "etcd",
|
||
|
ImageRepo: "gcr.io/etcd-development/etcd",
|
||
|
ImageTag: version,
|
||
|
Cmd: []string{"/usr/local/bin/etcd",
|
||
|
"--name", "s1",
|
||
|
"--listen-client-urls", "http://0.0.0.0:2379",
|
||
|
"--advertise-client-urls", "http://0.0.0.0:2379",
|
||
|
"--listen-peer-urls", "http://0.0.0.0:2380",
|
||
|
"--initial-advertise-peer-urls", "http://0.0.0.0:2380",
|
||
|
"--initial-cluster", "s1=http://0.0.0.0:2380",
|
||
|
"--initial-cluster-token", "tkn",
|
||
|
"--initial-cluster-state", "new",
|
||
|
"--log-level", "info",
|
||
|
"--logger", "zap",
|
||
|
"--log-outputs", "stderr",
|
||
|
},
|
||
|
Ports: []string{"2379/tcp"},
|
||
|
})
|
||
|
if err != nil {
|
||
|
t.Fatalf("Could not start docker etcd container: %s", err)
|
||
|
}
|
||
|
|
||
|
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
|
||
|
address := fmt.Sprintf("%s:%d", host, port)
|
||
|
s := docker.NewServiceURL(url.URL{
|
||
|
Scheme: "http",
|
||
|
Host: address,
|
||
|
})
|
||
|
|
||
|
client, err := clientv3.New(clientv3.Config{
|
||
|
Endpoints: []string{address},
|
||
|
DialTimeout: 2 * time.Minute,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("could not connect to etcd container: %w", err)
|
||
|
}
|
||
|
|
||
|
// Enable authentication for the tests.
|
||
|
client.RoleAdd(ctx, "root")
|
||
|
client.UserAdd(ctx, "root", "insecure")
|
||
|
client.UserGrantRole(ctx, "root", "root")
|
||
|
client.AuthEnable(ctx)
|
||
|
client.Close()
|
||
|
|
||
|
return &Config{
|
||
|
ServiceURL: *s,
|
||
|
}, nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
t.Fatalf("Could not start docker etcd container: %s", err)
|
||
|
}
|
||
|
|
||
|
return svc.Cleanup, svc.Config.(*Config)
|
||
|
}
|