mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
tests: Make tests operate in /tmp director instead of src.
Thanks to this, unix sockets should be not longer created by integration tests in the the source code directory, so potentially trigger IDE reloads and unnecessery load (and mess).
This commit is contained in:
parent
bfe02c0526
commit
5ddabfdb24
@ -97,6 +97,10 @@ func CheckAfterTest(d time.Duration) error {
|
||||
// BeforeTest is a convenient way to register before-and-after code to a test.
|
||||
// If you execute BeforeTest, you don't need to explicitly register AfterTest.
|
||||
func BeforeTest(t testing.TB) {
|
||||
if err := CheckAfterTest(10 * time.Millisecond); err != nil {
|
||||
t.Skipf("Found leaked goroutined BEFORE test", err)
|
||||
return
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
AfterTest(t)
|
||||
})
|
||||
|
@ -31,16 +31,16 @@ import (
|
||||
|
||||
var (
|
||||
testTLSInfo = transport.TLSInfo{
|
||||
KeyFile: "../../../fixtures/server.key.insecure",
|
||||
CertFile: "../../../fixtures/server.crt",
|
||||
TrustedCAFile: "../../../fixtures/ca.crt",
|
||||
KeyFile: integration.MustAbsPath("../../../fixtures/server.key.insecure"),
|
||||
CertFile: integration.MustAbsPath("../../../fixtures/server.crt"),
|
||||
TrustedCAFile: integration.MustAbsPath("../../../fixtures/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
|
||||
testTLSInfoExpired = transport.TLSInfo{
|
||||
KeyFile: "../../fixtures-expired/server.key.insecure",
|
||||
CertFile: "../../fixtures-expired/server.crt",
|
||||
TrustedCAFile: "../../fixtures-expired/ca.crt",
|
||||
KeyFile: integration.MustAbsPath("../../fixtures-expired/server.key.insecure"),
|
||||
CertFile: integration.MustAbsPath("../../fixtures-expired/server.crt"),
|
||||
TrustedCAFile: integration.MustAbsPath("../../fixtures-expired/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
)
|
||||
|
@ -72,13 +72,12 @@ func createSnapshotFile(t *testing.T, kvs []kv) string {
|
||||
cfg.LCUrls, cfg.ACUrls = cURLs, cURLs
|
||||
cfg.LPUrls, cfg.APUrls = pURLs, pURLs
|
||||
cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String())
|
||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
srv, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
os.RemoveAll(cfg.Dir)
|
||||
srv.Close()
|
||||
}()
|
||||
select {
|
||||
@ -102,12 +101,11 @@ func createSnapshotFile(t *testing.T, kvs []kv) string {
|
||||
}
|
||||
}
|
||||
|
||||
dpPath := filepath.Join(os.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond()))
|
||||
dpPath := filepath.Join(t.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond()))
|
||||
if err = snapshot.Save(context.Background(), zap.NewExample(), ccfg, dpPath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
os.RemoveAll(cfg.Dir)
|
||||
srv.Close()
|
||||
return dpPath
|
||||
}
|
||||
|
@ -83,43 +83,44 @@ var (
|
||||
localListenCount = int64(0)
|
||||
|
||||
testTLSInfo = transport.TLSInfo{
|
||||
KeyFile: "../fixtures/server.key.insecure",
|
||||
CertFile: "../fixtures/server.crt",
|
||||
TrustedCAFile: "../fixtures/ca.crt",
|
||||
KeyFile: MustAbsPath("../fixtures/server.key.insecure"),
|
||||
CertFile: MustAbsPath("../fixtures/server.crt"),
|
||||
TrustedCAFile: MustAbsPath("../fixtures/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
|
||||
testTLSInfoWithSpecificUsage = transport.TLSInfo{
|
||||
KeyFile: "../fixtures/server-serverusage.key.insecure",
|
||||
CertFile: "../fixtures/server-serverusage.crt",
|
||||
ClientKeyFile: "../fixtures/client-clientusage.key.insecure",
|
||||
ClientCertFile: "../fixtures/client-clientusage.crt",
|
||||
TrustedCAFile: "../fixtures/ca.crt",
|
||||
KeyFile: MustAbsPath("../fixtures/server-serverusage.key.insecure"),
|
||||
CertFile: MustAbsPath("../fixtures/server-serverusage.crt"),
|
||||
ClientKeyFile: MustAbsPath("../fixtures/client-clientusage.key.insecure"),
|
||||
ClientCertFile: MustAbsPath("../fixtures/client-clientusage.crt"),
|
||||
TrustedCAFile: MustAbsPath("../fixtures/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
|
||||
testTLSInfoIP = transport.TLSInfo{
|
||||
KeyFile: "../fixtures/server-ip.key.insecure",
|
||||
CertFile: "../fixtures/server-ip.crt",
|
||||
TrustedCAFile: "../fixtures/ca.crt",
|
||||
KeyFile: MustAbsPath("../fixtures/server-ip.key.insecure"),
|
||||
CertFile: MustAbsPath("../fixtures/server-ip.crt"),
|
||||
TrustedCAFile: MustAbsPath("../fixtures/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
|
||||
testTLSInfoExpired = transport.TLSInfo{
|
||||
KeyFile: "./fixtures-expired/server.key.insecure",
|
||||
CertFile: "./fixtures-expired/server.crt",
|
||||
TrustedCAFile: "./fixtures-expired/ca.crt",
|
||||
KeyFile: MustAbsPath("./fixtures-expired/server.key.insecure"),
|
||||
CertFile: MustAbsPath("./fixtures-expired/server.crt"),
|
||||
TrustedCAFile: MustAbsPath("./fixtures-expired/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
|
||||
testTLSInfoExpiredIP = transport.TLSInfo{
|
||||
KeyFile: "./fixtures-expired/server-ip.key.insecure",
|
||||
CertFile: "./fixtures-expired/server-ip.crt",
|
||||
TrustedCAFile: "./fixtures-expired/ca.crt",
|
||||
KeyFile: MustAbsPath("./fixtures-expired/server-ip.key.insecure"),
|
||||
CertFile: MustAbsPath("./fixtures-expired/server-ip.crt"),
|
||||
TrustedCAFile: MustAbsPath("./fixtures-expired/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
|
||||
defaultTokenJWT = "jwt,pub-key=../fixtures/server.crt,priv-key=../fixtures/server.key.insecure,sign-method=RS256,ttl=1s"
|
||||
defaultTokenJWT = fmt.Sprintf("jwt,pub-key=%s,priv-key=%s,sign-method=RS256,ttl=1s",
|
||||
MustAbsPath("../fixtures/server.crt"), MustAbsPath("../fixtures/server.key.insecure"))
|
||||
)
|
||||
|
||||
type ClusterConfig struct {
|
||||
|
@ -34,13 +34,14 @@ import (
|
||||
"go.etcd.io/etcd/pkg/v3/testutil"
|
||||
"go.etcd.io/etcd/pkg/v3/transport"
|
||||
"go.etcd.io/etcd/server/v3/embed"
|
||||
"go.etcd.io/etcd/tests/v3/integration"
|
||||
)
|
||||
|
||||
var (
|
||||
testTLSInfo = transport.TLSInfo{
|
||||
KeyFile: "../../fixtures/server.key.insecure",
|
||||
CertFile: "../../fixtures/server.crt",
|
||||
TrustedCAFile: "../../fixtures/ca.crt",
|
||||
KeyFile: integration.MustAbsPath("../../fixtures/server.key.insecure"),
|
||||
CertFile: integration.MustAbsPath("../../fixtures/server.crt"),
|
||||
TrustedCAFile: integration.MustAbsPath("../../fixtures/ca.crt"),
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
)
|
||||
@ -88,9 +89,7 @@ func TestEmbedEtcd(t *testing.T) {
|
||||
tests[7].cfg.LCUrls = []url.URL{*dnsURL}
|
||||
tests[8].cfg.LPUrls = []url.URL{*dnsURL}
|
||||
|
||||
dir := filepath.Join(os.TempDir(), fmt.Sprintf("embed-etcd"))
|
||||
os.RemoveAll(dir)
|
||||
defer os.RemoveAll(dir)
|
||||
dir := filepath.Join(t.TempDir(), fmt.Sprintf("embed-etcd"))
|
||||
|
||||
for i, tt := range tests {
|
||||
tests[i].cfg.Dir = dir
|
||||
@ -143,9 +142,7 @@ func testEmbedEtcdGracefulStop(t *testing.T, secure bool) {
|
||||
urls := newEmbedURLs(secure, 2)
|
||||
setupEmbedCfg(cfg, []url.URL{urls[0]}, []url.URL{urls[1]})
|
||||
|
||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprintf("embed-etcd"))
|
||||
os.RemoveAll(cfg.Dir)
|
||||
defer os.RemoveAll(cfg.Dir)
|
||||
cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprintf("embed-etcd"))
|
||||
|
||||
e, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@ -70,7 +69,7 @@ func TestLaunchDuplicateMemberShouldFail(t *testing.T) {
|
||||
c := NewCluster(t, size)
|
||||
m := c.Members[0].Clone(t)
|
||||
var err error
|
||||
m.DataDir, err = ioutil.TempDir(os.TempDir(), "etcd")
|
||||
m.DataDir, err = ioutil.TempDir(t.TempDir(), "etcd")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ func TestSnapshotV3RestoreMultiMemberAdd(t *testing.T) {
|
||||
}
|
||||
cfg.InitialCluster = cfg.InitialCluster[1:]
|
||||
cfg.InitialCluster += fmt.Sprintf(",%s=%s", cfg.Name, newPURLs[0].String())
|
||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
|
||||
srv, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
|
@ -29,8 +29,7 @@ import (
|
||||
"go.etcd.io/etcd/etcdctl/v3/snapshot"
|
||||
"go.etcd.io/etcd/pkg/v3/testutil"
|
||||
"go.etcd.io/etcd/server/v3/embed"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zaptest"
|
||||
)
|
||||
|
||||
// TestSnapshotV3RestoreSingle tests single node cluster restoring
|
||||
@ -53,9 +52,9 @@ func TestSnapshotV3RestoreSingle(t *testing.T) {
|
||||
cfg.LCUrls, cfg.ACUrls = cURLs, cURLs
|
||||
cfg.LPUrls, cfg.APUrls = pURLs, pURLs
|
||||
cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String())
|
||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
|
||||
sp := snapshot.NewV3(zap.NewExample())
|
||||
sp := snapshot.NewV3(zaptest.NewLogger(t))
|
||||
pss := make([]string, 0, len(pURLs))
|
||||
for _, p := range pURLs {
|
||||
pss = append(pss, p.String())
|
||||
@ -149,7 +148,7 @@ func TestCorruptedBackupFileCheck(t *testing.T) {
|
||||
t.Fatalf("test file [%s] does not exist: %v", dbPath, err)
|
||||
}
|
||||
|
||||
sp := snapshot.NewV3(zap.NewExample())
|
||||
sp := snapshot.NewV3(zaptest.NewLogger(t))
|
||||
_, err := sp.Status(dbPath)
|
||||
expectedErrKeywords := "snapshot file integrity check failed"
|
||||
/* example error message:
|
||||
@ -187,7 +186,7 @@ func createSnapshotFile(t *testing.T, kvs []kv) string {
|
||||
cfg.LCUrls, cfg.ACUrls = cURLs, cURLs
|
||||
cfg.LPUrls, cfg.APUrls = pURLs, pURLs
|
||||
cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String())
|
||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||
srv, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -217,8 +216,8 @@ func createSnapshotFile(t *testing.T, kvs []kv) string {
|
||||
}
|
||||
}
|
||||
|
||||
sp := snapshot.NewV3(zap.NewExample())
|
||||
dpPath := filepath.Join(os.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond()))
|
||||
sp := snapshot.NewV3(zaptest.NewLogger(t))
|
||||
dpPath := filepath.Join(t.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond()))
|
||||
if err = sp.Save(context.Background(), ccfg, dpPath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -254,9 +253,9 @@ func restoreCluster(t *testing.T, clusterN int, dbPath string) (
|
||||
cfg.LCUrls, cfg.ACUrls = []url.URL{cURLs[i]}, []url.URL{cURLs[i]}
|
||||
cfg.LPUrls, cfg.APUrls = []url.URL{pURLs[i]}, []url.URL{pURLs[i]}
|
||||
cfg.InitialCluster = ics
|
||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()+i))
|
||||
cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond()+i))
|
||||
|
||||
sp := snapshot.NewV3(zap.NewExample())
|
||||
sp := snapshot.NewV3(zaptest.NewLogger(t))
|
||||
if err := sp.Restore(snapshot.RestoreConfig{
|
||||
SnapshotPath: dbPath,
|
||||
Name: cfg.Name,
|
||||
|
@ -15,6 +15,8 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"go.etcd.io/etcd/pkg/v3/testutil"
|
||||
@ -22,4 +24,22 @@ import (
|
||||
|
||||
func BeforeTest(t testing.TB) {
|
||||
testutil.BeforeTest(t)
|
||||
|
||||
previousWD, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Chdir(t.TempDir())
|
||||
t.Cleanup(func() {
|
||||
os.Chdir(previousWD)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func MustAbsPath(path string) string {
|
||||
abs, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return abs
|
||||
}
|
@ -30,7 +30,7 @@ import (
|
||||
func runWithCluster(t testing.TB, runner func(testing.TB, []string)) {
|
||||
testutil.BeforeTest(t)
|
||||
cfg := integration.ClusterConfig{Size: 1}
|
||||
clus := integration.NewClusterV3(nil, &cfg)
|
||||
clus := integration.NewClusterV3(t, &cfg)
|
||||
defer clus.Terminate(t)
|
||||
endpoints := []string{clus.Client(0).Endpoints()[0]}
|
||||
runner(t, endpoints)
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
|
||||
// TestElectionWait tests if followers can correctly wait for elections.
|
||||
func TestElectionWait(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 3})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
@ -107,6 +108,7 @@ func TestElectionWait(t *testing.T) {
|
||||
|
||||
// TestElectionFailover tests that an election will
|
||||
func TestElectionFailover(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 3})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
@ -174,6 +176,7 @@ func TestElectionFailover(t *testing.T) {
|
||||
// TestElectionSessionRelock ensures that campaigning twice on the same election
|
||||
// with the same lock will Proclaim instead of deadlocking.
|
||||
func TestElectionSessionRecampaign(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
cli := clus.RandClient()
|
||||
@ -206,6 +209,7 @@ func TestElectionSessionRecampaign(t *testing.T) {
|
||||
// of bug #6278. https://github.com/etcd-io/etcd/issues/6278
|
||||
//
|
||||
func TestElectionOnPrefixOfExistingKey(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
@ -232,6 +236,7 @@ func TestElectionOnPrefixOfExistingKey(t *testing.T) {
|
||||
// in a new session with the same lease id) does not result in loss of
|
||||
// leadership.
|
||||
func TestElectionOnSessionRestart(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
cli := clus.RandClient()
|
||||
@ -278,6 +283,7 @@ func TestElectionOnSessionRestart(t *testing.T) {
|
||||
// TestElectionObserveCompacted checks that observe can tolerate
|
||||
// a leader key with a modrev less than the compaction revision.
|
||||
func TestElectionObserveCompacted(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
|
@ -1609,20 +1609,20 @@ func TestTLSGRPCAcceptSecureAll(t *testing.T) {
|
||||
// when all certs are atomically replaced by directory renaming.
|
||||
// And expects server to reject client requests, and vice versa.
|
||||
func TestTLSReloadAtomicReplace(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), "fixtures-tmp")
|
||||
tmpDir, err := ioutil.TempDir(t.TempDir(), "fixtures-tmp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.RemoveAll(tmpDir)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
certsDir, err := ioutil.TempDir(os.TempDir(), "fixtures-to-load")
|
||||
certsDir, err := ioutil.TempDir(t.TempDir(), "fixtures-to-load")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(certsDir)
|
||||
|
||||
certsDirExp, err := ioutil.TempDir(os.TempDir(), "fixtures-expired")
|
||||
certsDirExp, err := ioutil.TempDir(t.TempDir(), "fixtures-expired")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -1668,7 +1668,7 @@ func TestTLSReloadAtomicReplace(t *testing.T) {
|
||||
// when new certs are copied over, one by one. And expects server
|
||||
// to reject client requests, and vice versa.
|
||||
func TestTLSReloadCopy(t *testing.T) {
|
||||
certsDir, err := ioutil.TempDir(os.TempDir(), "fixtures-to-load")
|
||||
certsDir, err := ioutil.TempDir(t.TempDir(), "fixtures-to-load")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -1698,7 +1698,7 @@ func TestTLSReloadCopy(t *testing.T) {
|
||||
// when new certs are copied over, one by one. And expects server
|
||||
// to reject client requests, and vice versa.
|
||||
func TestTLSReloadCopyIPOnly(t *testing.T) {
|
||||
certsDir, err := ioutil.TempDir(os.TempDir(), "fixtures-to-load")
|
||||
certsDir, err := ioutil.TempDir(t.TempDir(), "fixtures-to-load")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -2,45 +2,22 @@ package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/client/v3/namespace"
|
||||
"go.etcd.io/etcd/server/v3/embed"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3client"
|
||||
)
|
||||
|
||||
// TestKVWithEmptyValue ensures that a get/delete with an empty value, and with WithFromKey/WithPrefix function will return an empty error.
|
||||
func TestKVWithEmptyValue(t *testing.T) {
|
||||
BeforeTest(t)
|
||||
|
||||
cfg := embed.NewConfig()
|
||||
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
// Use temporary data directory.
|
||||
dir, err := ioutil.TempDir("", "etcd-")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
cfg.Dir = dir
|
||||
client := clus.RandClient()
|
||||
|
||||
// Suppress server log to keep output clean.
|
||||
//cfg.Logger = "zap"
|
||||
//cfg.LogLevel = "error"
|
||||
|
||||
etcd, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer etcd.Close()
|
||||
<-etcd.Server.ReadyNotify()
|
||||
|
||||
client := v3client.New(etcd.Server)
|
||||
defer client.Close()
|
||||
|
||||
_, err = client.Put(context.Background(), "my-namespace/foobar", "data")
|
||||
_, err := client.Put(context.Background(), "my-namespace/foobar", "data")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user