featurebase/etcd/leasedkv_test.go
Seebs a6aa1097f1 listen on localhost:0 instead of :0
MacOS's firewall complains about a previously unknown app trying to
listen for network connections whenever we run go test. That's because
we *are* listening for network connections on arbitrary interfaces, not
just on localhost as we probably intended. Fix that.
2022-03-18 13:38:30 -05:00

127 lines
2.9 KiB
Go

// Copyright 2021 Molecula Corp. All rights reserved.
package etcd
import (
"context"
"fmt"
"net"
"os"
"testing"
"time"
"github.com/molecula/featurebase/v3/disco"
"github.com/molecula/featurebase/v3/logger"
"github.com/molecula/featurebase/v3/testhook"
"github.com/pkg/errors"
"go.etcd.io/etcd/embed"
"go.etcd.io/etcd/etcdserver/api/v3client"
"go.etcd.io/etcd/pkg/types"
)
const initVal = "test"
const newVal = "newValue"
// listenerWithURL builds a TCP listener and corresponding http://localhost:%d
// URL, and returns those. Identical to the copy in /test, except we can't
// import that because it imports us.
func listenerWithURL() (listener *net.TCPListener, url string, err error) {
l, err := net.Listen("tcp", "localhost:0")
if err != nil {
return listener, url, err
}
listener = l.(*net.TCPListener)
port := listener.Addr().(*net.TCPAddr).Port
url = fmt.Sprintf("http://localhost:%d", port)
return listener, url, err
}
func TestLeasedKv(t *testing.T) {
cfg := embed.NewConfig()
clientListener, clientURL, err := listenerWithURL()
if err != nil {
t.Fatal(errors.Wrap(err, "creating client listener"))
}
peerListener, peerURL, err := listenerWithURL()
if err != nil {
t.Fatal(errors.Wrap(err, "creating peer listener"))
}
cfg.LPUrls = types.MustNewURLs([]string{peerURL})
cfg.LPeerSocket = []*net.TCPListener{peerListener}
cfg.APUrls = types.MustNewURLs([]string{peerURL})
cfg.LCUrls = types.MustNewURLs([]string{clientURL})
cfg.LClientSocket = []*net.TCPListener{clientListener}
cfg.ACUrls = types.MustNewURLs([]string{clientURL})
cfg.InitialCluster = cfg.Name + "=" + peerURL
dir, err := testhook.TempDir(t, "leasedkv-*")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
cfg.Dir = dir
etcd, err := embed.StartEtcd(cfg)
if err != nil {
t.Fatal(err)
}
cli := v3client.New(etcd.Server)
defer func() {
etcd.Close()
<-etcd.Server.StopNotify()
cli.Close()
}()
wrapper := &Etcd{e: etcd, cli: cli, logger: logger.NewLogfLogger(t)}
lkv := newLeasedKV(wrapper, "/test", 1)
ctx := context.Background()
err = lkv.Start(initVal)
if err != nil {
t.Fatal(err)
}
v, err := lkv.Get(ctx)
if err != nil {
t.Fatal(err)
}
if v != initVal {
t.Fatal("obtained value is not the same as expected. Obtained:", v, "Expected:", initVal)
}
err = lkv.Set(ctx, "otherValue")
if err != nil {
t.Fatal(err)
}
err = lkv.Set(ctx, "3")
if err != nil {
t.Fatal(err)
}
err = lkv.Set(ctx, newVal)
if err != nil {
t.Fatal(err)
}
v, err = lkv.Get(ctx)
if err != nil {
t.Fatal(err)
}
if v != newVal {
t.Fatal("obtained value is not the same as expected. Obtained:", v, "Expected:", newVal)
}
time.Sleep(5 * time.Second)
lkv.Stop()
// we need to wait to force the lease expiration
time.Sleep(5 * time.Second)
_, err = lkv.Get(ctx)
if err == nil || !errors.Is(err, disco.ErrNoResults) {
t.Fatal("expected error:", disco.ErrNoResults, "obtained:", err)
}
}