diff --git a/pkg/controllers/gitserver/image_test.go b/pkg/controllers/gitserver/image_test.go index 9efcbd21..7a77d2b4 100644 --- a/pkg/controllers/gitserver/image_test.go +++ b/pkg/controllers/gitserver/image_test.go @@ -3,8 +3,16 @@ package gitserver import ( "context" "fmt" + "github.com/cnoe-io/idpbuilder/pkg/kind" + "github.com/docker/docker/api/types/container" + "github.com/docker/go-connections/nat" + "io" + "net" + "os" + "strconv" "strings" "testing" + "time" "github.com/cnoe-io/idpbuilder/api/v1alpha1" "github.com/cnoe-io/idpbuilder/pkg/apps" @@ -39,23 +47,74 @@ func TestReconcileGitServerImage(t *testing.T) { }, } - _, err = r.reconcileGitServerImage(ctx, controllerruntime.Request{}, &resource) + dockerClient, err := docker.GetDockerClient() + if err != nil { + t.Errorf("Getting docker client: %v", err) + } + defer dockerClient.Close() + reader, err := dockerClient.ImagePull(ctx, "docker.io/library/registry:2", types.ImagePullOptions{}) + defer reader.Close() + // blocks until pull is completed + io.Copy(os.Stdout, reader) if err != nil { - t.Errorf("reconcile error: %v", err) + t.Fatalf("failed pulilng registry image: %v", err) } - if !strings.HasPrefix(resource.Status.ImageID, "sha256") { - t.Errorf("Invalid or no Image ID in status: %q", resource.Status.ImageID) + waitTimeout := time.Second * 90 + waitInterval := time.Second * 3 + // very crude. no guarantee that the port will be available by the time request is sent to docker + endTime := time.Now().Add(waitTimeout) + for { + if time.Now().After(endTime) { + t.Fatalf("Timed out waiting for port %d to be available", kind.ExposedRegistryPort) + } + conn, cErr := net.DialTimeout("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(int(kind.ExposedRegistryPort))), time.Second*3) + if cErr != nil { + break + } + conn.Close() + time.Sleep(waitInterval) } - dockerClient, err := docker.GetDockerClient() + resp, err := dockerClient.ContainerCreate(ctx, &container.Config{ + Image: "docker.io/library/registry:2", + Tty: false, + ExposedPorts: nat.PortSet{ + nat.Port(fmt.Sprintf("%d/tcp", kind.InternalRegistryPort)): struct{}{}, + }, + }, &container.HostConfig{ + PortBindings: nat.PortMap{ + nat.Port(fmt.Sprintf("%d/tcp", kind.InternalRegistryPort)): []nat.PortBinding{ + { + HostIP: "0.0.0.0", + HostPort: fmt.Sprintf("%d", kind.ExposedRegistryPort), + }, + }, + }, + }, nil, nil, "testcase-registry") if err != nil { - t.Errorf("Getting docker client: %v", err) + t.Fatalf("failed creating registry container %v", err) } + defer dockerClient.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true}) + + err = dockerClient.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}) + if err != nil { + t.Fatalf("failed starting container %v", err) + } + + _, err = r.reconcileGitServerImage(ctx, controllerruntime.Request{}, &resource) + if err != nil { + t.Fatalf("reconcile error: %v", err) + } + + if !strings.HasPrefix(resource.Status.ImageID, "sha256") { + t.Fatalf("Invalid or no Image ID in status: %q", resource.Status.ImageID) + } imageNameID := fmt.Sprintf("%s@%s", GetImageTag(&resource), resource.Status.ImageID) _, err = dockerClient.ImageRemove(ctx, imageNameID, types.ImageRemoveOptions{}) if err != nil { t.Errorf("Removing docker image: %v", err) } } + diff --git a/pkg/kind/registry_test.go b/pkg/kind/registry_test.go index 06309b8b..084f8536 100644 --- a/pkg/kind/registry_test.go +++ b/pkg/kind/registry_test.go @@ -3,6 +3,7 @@ package kind import ( "context" "testing" + "time" "github.com/cnoe-io/idpbuilder/pkg/docker" "github.com/docker/docker/api/types" @@ -19,6 +20,12 @@ func TestReconcileRegistry(t *testing.T) { } defer dockerCli.Close() + kindNetwork, err := dockerCli.NetworkCreate(ctx, "kind", types.NetworkCreate{}) + if err != nil { + t.Fatalf("Failed creaking kind network: %v", err) + } + defer dockerCli.NetworkRemove(ctx, kindNetwork.ID) + // Create cluster cluster, err := NewCluster("testcase", "v1.26.3", "", "", "") if err != nil { @@ -26,9 +33,22 @@ func TestReconcileRegistry(t *testing.T) { } // Create registry - err = cluster.ReconcileRegistry(ctx) - if err != nil { - t.Fatalf("Error reconciling registry: %v", err) + defer dockerCli.ContainerRemove(ctx, cluster.getRegistryContainerName(), types.ContainerRemoveOptions{Force: true}) + waitTimeout := time.Second * 90 + waitInterval := time.Second * 3 + endTime := time.Now().Add(waitTimeout) + + for { + if time.Now().After(endTime) { + t.Fatalf("Timed out waiting for registry. recent error: %v", err) + } + err = cluster.ReconcileRegistry(ctx) + if err == nil { + break + } + t.Logf("Failed to reconcile: %v", err) + dockerCli.ContainerRemove(ctx, cluster.getRegistryContainerName(), types.ContainerRemoveOptions{Force: true}) + time.Sleep(waitInterval) } // Get resulting container @@ -36,6 +56,8 @@ func TestReconcileRegistry(t *testing.T) { if err != nil { t.Fatalf("Error getting registry container after reconcile: %v", err) } + defer dockerCli.ImageRemove(ctx, container.ImageID, types.ImageRemoveOptions{}) + if container == nil { t.Fatal("Expected registry container after reconcile but got nil") } @@ -45,9 +67,5 @@ func TestReconcileRegistry(t *testing.T) { if err != nil { t.Fatalf("Error reconciling registry: %v", err) } - - // Cleanup - if err = dockerCli.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{Force: true}); err != nil { - t.Fatalf("Error removing registry docker container after reconcile: %v", err) - } } +