Skip to content

Commit 186ca39

Browse files
committed
Fix IPFS test flakyness
Signed-off-by: apostasie <[email protected]>
1 parent 5811b94 commit 186ca39

File tree

3 files changed

+92
-34
lines changed

3 files changed

+92
-34
lines changed

cmd/nerdctl/ipfs_compose_linux_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@ import (
2424

2525
"github.com/containerd/nerdctl/v2/pkg/testutil"
2626
"github.com/containerd/nerdctl/v2/pkg/testutil/nettestutil"
27+
"github.com/containerd/nerdctl/v2/pkg/testutil/testregistry"
2728
"gotest.tools/v3/assert"
2829
)
2930

3031
func TestIPFSComposeUp(t *testing.T) {
3132
testutil.DockerIncompatible(t)
3233
base := testutil.NewBase(t)
33-
ipfsaddr, done := runIPFSDaemonContainer(t, base)
34-
defer done()
34+
35+
iReg := testregistry.NewIPFSRegistry(base, nil, 0, nil, nil)
36+
t.Cleanup(func() {
37+
iReg.Cleanup(nil)
38+
})
39+
ipfsaddr := fmt.Sprintf("/ip4/%s/tcp/%d", iReg.IP, iReg.Port)
40+
3541
tests := []struct {
3642
name string
3743
snapshotter string

cmd/nerdctl/ipfs_linux_test.go

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ package main
1818

1919
import (
2020
"fmt"
21-
"regexp"
2221
"testing"
2322

2423
"github.com/containerd/nerdctl/v2/pkg/infoutil"
2524
"github.com/containerd/nerdctl/v2/pkg/rootlessutil"
2625
"github.com/containerd/nerdctl/v2/pkg/testutil"
26+
"github.com/containerd/nerdctl/v2/pkg/testutil/testregistry"
2727

2828
"gotest.tools/v3/assert"
2929
)
@@ -57,42 +57,21 @@ func TestIPFS(t *testing.T) {
5757
base.Cmd("run", "--rm", decryptImageRef, "/bin/sh", "-c", "echo hello").AssertOK()
5858
}
5959

60-
var iplineRegexp = regexp.MustCompile(`"([0-9\.]*)"`)
61-
6260
func TestIPFSAddress(t *testing.T) {
6361
testutil.DockerIncompatible(t)
6462
base := testutil.NewBase(t)
65-
ipfsaddr, done := runIPFSDaemonContainer(t, base)
66-
defer done()
63+
iReg := testregistry.NewIPFSRegistry(base, nil, 0, nil, nil)
64+
t.Cleanup(func() {
65+
iReg.Cleanup(nil)
66+
})
67+
ipfsaddr := fmt.Sprintf("/ip4/%s/tcp/%d", iReg.IP, iReg.Port)
68+
6769
ipfsCID := pushImageToIPFS(t, base, testutil.AlpineImage, fmt.Sprintf("--ipfs-address=%s", ipfsaddr))
6870
base.Env = append(base.Env, "CONTAINERD_SNAPSHOTTER=overlayfs")
6971
base.Cmd("pull", "--ipfs-address", ipfsaddr, ipfsCID).AssertOK()
7072
base.Cmd("run", "--ipfs-address", ipfsaddr, "--rm", ipfsCID, "echo", "hello").AssertOK()
7173
}
7274

73-
func runIPFSDaemonContainer(t *testing.T, base *testutil.Base) (ipfsAddress string, done func()) {
74-
name := "test-ipfs-address"
75-
var ipfsaddr string
76-
if detachedNetNS, _ := rootlessutil.DetachedNetNS(); detachedNetNS != "" {
77-
// detached-netns mode can't use .NetworkSettings.IPAddress, because the daemon and CNI has different network namespaces
78-
base.Cmd("run", "-d", "-p", "127.0.0.1:5999:5999", "--name", name, "--entrypoint=/bin/sh", testutil.KuboImage, "-c", "ipfs init && ipfs config Addresses.API /ip4/0.0.0.0/tcp/5999 && ipfs daemon --offline").AssertOK()
79-
ipfsaddr = "/ip4/127.0.0.1/tcp/5999"
80-
} else {
81-
base.Cmd("run", "-d", "--name", name, "--entrypoint=/bin/sh", testutil.KuboImage, "-c", "ipfs init && ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001 && ipfs daemon --offline").AssertOK()
82-
iplines := base.Cmd("inspect", name, "-f", "'{{json .NetworkSettings.IPAddress}}'").OutLines()
83-
t.Logf("IPAddress=%v", iplines)
84-
assert.Equal(t, len(iplines), 2)
85-
matches := iplineRegexp.FindStringSubmatch(iplines[0])
86-
t.Logf("ip address matches=%v", matches)
87-
assert.Equal(t, len(matches), 2)
88-
ipfsaddr = fmt.Sprintf("/ip4/%s/tcp/5001", matches[1])
89-
}
90-
return ipfsaddr, func() {
91-
base.Cmd("kill", "test-ipfs-address").AssertOK()
92-
base.Cmd("rm", "test-ipfs-address").AssertOK()
93-
}
94-
}
95-
9675
func TestIPFSCommit(t *testing.T) {
9776
// cgroup is required for nerdctl commit
9877
if rootlessutil.IsRootless() && infoutil.CgroupsVersion() == "1" {

pkg/testutil/testregistry/testregistry_linux.go

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type TokenAuthServer struct {
5555
func EnsureImages(base *testutil.Base) {
5656
base.Cmd("pull", testutil.RegistryImage).AssertOK()
5757
base.Cmd("pull", testutil.DockerAuthImage).AssertOK()
58+
base.Cmd("pull", testutil.KuboImage).AssertOK()
5859
}
5960

6061
func NewAuthServer(base *testutil.Base, ca *testca.CA, port int, user, pass string, tls bool) *TokenAuthServer {
@@ -112,6 +113,8 @@ acl:
112113
port, err = portlock.Acquire(port)
113114
assert.NilError(base.T, err, fmt.Errorf("failed acquiring port: %w", err))
114115
containerName := fmt.Sprintf("auth-%s-%d", name, port)
116+
// Cleanup possible leftovers first
117+
base.Cmd("rm", "-f", containerName).Run()
115118

116119
cleanup := func(err error) {
117120
result := base.Cmd("rm", "-f", containerName).Run()
@@ -232,7 +235,78 @@ func (ba *BasicAuth) Params(base *testutil.Base) []string {
232235
return ret
233236
}
234237

238+
func NewIPFSRegistry(base *testutil.Base, ca *testca.CA, port int, auth Auth, boundCleanup func(error)) *RegistryServer {
239+
EnsureImages(base)
240+
241+
name := testutil.Identifier(base.T)
242+
// listen on 0.0.0.0 to enable 127.0.0.1
243+
listenIP := net.ParseIP("0.0.0.0")
244+
hostIP, err := nettestutil.NonLoopbackIPv4()
245+
assert.NilError(base.T, err, fmt.Errorf("failed finding ipv4 non loopback interface: %w", err))
246+
port, err = portlock.Acquire(port)
247+
assert.NilError(base.T, err, fmt.Errorf("failed acquiring port: %w", err))
248+
249+
containerName := fmt.Sprintf("ipfs-registry-%s-%d", name, port)
250+
// Cleanup possible leftovers first
251+
base.Cmd("rm", "-f", containerName).Run()
252+
253+
args := []string{
254+
"run",
255+
"--pull=never",
256+
"-d",
257+
"-p", fmt.Sprintf("%s:%d:%d", listenIP, port, port),
258+
"--name", containerName,
259+
"--entrypoint=/bin/sh",
260+
testutil.KuboImage,
261+
"-c", "--",
262+
fmt.Sprintf("ipfs init && ipfs config Addresses.API /ip4/0.0.0.0/tcp/%d && ipfs daemon --offline", port),
263+
}
264+
265+
cleanup := func(err error) {
266+
result := base.Cmd("rm", "-f", containerName).Run()
267+
errPortRelease := portlock.Release(port)
268+
if boundCleanup != nil {
269+
boundCleanup(err)
270+
}
271+
if err == nil {
272+
assert.NilError(base.T, result.Error, fmt.Errorf("failed removing container: %w", err))
273+
assert.NilError(base.T, errPortRelease, fmt.Errorf("failed releasing port: %w", err))
274+
}
275+
}
276+
277+
scheme := "http"
278+
279+
err = func() error {
280+
cmd := base.Cmd(args...).Run()
281+
if cmd.Error != nil {
282+
base.T.Logf("%s:\n%s\n%s\n-------\n%s", containerName, cmd.Cmd, cmd.Stdout(), cmd.Stderr())
283+
return cmd.Error
284+
}
285+
286+
if _, err = nettestutil.HTTPGet(fmt.Sprintf("%s://%s:%s/api/v0", scheme, hostIP.String(), strconv.Itoa(port)), 30, true); err != nil {
287+
return err
288+
}
289+
290+
return nil
291+
}()
292+
293+
assert.NilError(base.T, err, fmt.Errorf("failed starting IPFS registry container in a timely manner: %w", err))
294+
295+
return &RegistryServer{
296+
IP: hostIP,
297+
Port: port,
298+
Scheme: scheme,
299+
ListenIP: listenIP,
300+
Cleanup: cleanup,
301+
Logs: func() {
302+
base.T.Logf("%s: %q", containerName, base.Cmd("logs", containerName).Run().String())
303+
},
304+
}
305+
}
306+
235307
func NewRegistry(base *testutil.Base, ca *testca.CA, port int, auth Auth, boundCleanup func(error)) *RegistryServer {
308+
EnsureImages(base)
309+
236310
name := testutil.Identifier(base.T)
237311
// listen on 0.0.0.0 to enable 127.0.0.1
238312
listenIP := net.ParseIP("0.0.0.0")
@@ -242,6 +316,9 @@ func NewRegistry(base *testutil.Base, ca *testca.CA, port int, auth Auth, boundC
242316
assert.NilError(base.T, err, fmt.Errorf("failed acquiring port: %w", err))
243317

244318
containerName := fmt.Sprintf("registry-%s-%d", name, port)
319+
// Cleanup possible leftovers first
320+
base.Cmd("rm", "-f", containerName).Run()
321+
245322
args := []string{
246323
"run",
247324
"--pull=never",
@@ -325,8 +402,6 @@ func NewRegistry(base *testutil.Base, ca *testca.CA, port int, auth Auth, boundC
325402
}()
326403

327404
if err != nil {
328-
// cs := base.Cmd("inspect", containerName).Run()
329-
// base.T.Logf("%s:\n%s\n%s\n=========================\n%s", containerName, cs.Cmd, cs.Stdout(), cs.Stderr())
330405
cl := base.Cmd("logs", containerName).Run()
331406
base.T.Logf("%s:\n%s\n%s\n=========================\n%s", containerName, cl.Cmd, cl.Stdout(), cl.Stderr())
332407
cleanup(err)
@@ -357,8 +432,6 @@ func NewWithTokenAuth(base *testutil.Base, user, pass string, port int, tls bool
357432
}
358433

359434
func NewWithNoAuth(base *testutil.Base, port int, tls bool) *RegistryServer {
360-
EnsureImages(base)
361-
362435
var ca *testca.CA
363436
if tls {
364437
ca = testca.New(base.T)

0 commit comments

Comments
 (0)