package dockerutils import ( "context" "fmt" "net/http" "strings" "testing" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/volume" uuid "github.com/satori/go.uuid" "github.com/stretchr/testify/require" ) // TestContainerCRUD // Test the following API functions: // - ContainerListByLabels // - ContainerListByNames // - ContainerRemoveByNames // - ContainerRemoveByLabels // - ContainerRemoveByIDs func TestContainerCRUD(t *testing.T) { var ( ctx = context.Background() require = require.New(t) iterations = 5 cleanupLabels = map[string]string{ uuid.NewV4().String(): uuid.NewV4().String(), } ) dockerClient, err := New() require.NoError(err) t.Cleanup(func() { dockerClient.ContainerRemoveByLabels(ctx, cleanupLabels) }) // Create Containers containerIDs := make([]string, 0) containerNames := make([]string, 0) for i := 0; i < iterations; i++ { containerName := uuid.NewV4().String() containerID, err := dockerClient.NewBuilder("nginx:alpine"). Labels(cleanupLabels). Port("80"). Pull(). WithName(containerName). Start(ctx) require.NoError(err) containerNames = append(containerNames, containerName) containerIDs = append(containerIDs, containerID) } // ListByLabels containers, err := dockerClient.ContainerListByLabels(ctx, true, cleanupLabels) require.NoError(err) require.Len(containers, iterations) for _, container := range containers { require.Contains(containerIDs, container.ID) require.Contains(containerNames, strings.Split(container.Names[0], "/")[1]) } // ListByNames containers, err = dockerClient.ContainerListByNames(ctx, true, containerNames...) require.NoError(err) require.Len(containers, iterations) for _, container := range containers { require.Contains(containerIDs, container.ID) require.Contains(containerNames, strings.Split(container.Names[0], "/")[1]) } // RemoveByLabels err = dockerClient.ContainerRemoveByLabels(ctx, cleanupLabels) require.NoError(err) containers, err = dockerClient.ContainerListByLabels(ctx, true, cleanupLabels) require.NoError(err) require.Len(containers, 0) // Create containerIDs = make([]string, 0) containerNames = make([]string, 0) for i := 0; i < iterations; i++ { containerName := uuid.NewV4().String() containerID, err := dockerClient.NewBuilder("nginx:alpine"). Labels(cleanupLabels). Port("80"). Pull(). WithName(containerName). Start(ctx) require.NoError(err) containerNames = append(containerNames, containerName) containerIDs = append(containerIDs, containerID) } // RemoveByNames err = dockerClient.ContainerRemoveByNames(ctx, containerNames...) require.NoError(err) containers, err = dockerClient.ContainerListByNames(ctx, true, containerNames...) require.NoError(err) require.Len(containers, 0) // Create containerIDs = make([]string, 0) containerNames = make([]string, 0) for i := 0; i < iterations; i++ { containerName := uuid.NewV4().String() containerID, err := dockerClient.NewBuilder("nginx:alpine"). Labels(cleanupLabels). Port("80"). Pull(). WithName(containerName). Start(ctx) require.NoError(err) containerNames = append(containerNames, containerName) containerIDs = append(containerIDs, containerID) } // RemoveByID err = dockerClient.ContainerRemoveByIDs(ctx, containerIDs...) require.NoError(err) containers, err = dockerClient.ContainerListByLabels(ctx, true, cleanupLabels) require.NoError(err) require.Len(containers, 0) } // TestNetworkCRUD // Test the following API functions: // - NetworkListByLabels // - NetworkListByNames // - NetworkRemoveByLabels // - NetworkRemoveByNames // - NetworkRemoveByIDs func TestNetworkCRUD(t *testing.T) { var ( ctx = context.Background() require = require.New(t) iterations = 5 cleanupLabels = map[string]string{ uuid.NewV4().String(): uuid.NewV4().String(), } ) dockerClient, err := New() require.NoError(err) t.Cleanup(func() { dockerClient.NetworkRemoveByLabels(ctx, cleanupLabels) }) // Create Networks networkIDs := make([]string, 0) networkNames := make([]string, 0) for i := 0; i < iterations; i++ { networkName := uuid.NewV4().String() resp, err := dockerClient.NetworkCreate(ctx, networkName, types.NetworkCreate{ Labels: cleanupLabels, }) require.NoError(err) networkNames = append(networkNames, networkName) networkIDs = append(networkIDs, resp.ID) } // ListByLabels networks, err := dockerClient.NetworkListByLabels(ctx, cleanupLabels) require.NoError(err) require.Len(networks, iterations) for _, network := range networks { require.Contains(networkIDs, network.ID) require.Contains(networkNames, network.Name) } // ListByLabels, network with label does not exist networks, err = dockerClient.NetworkListByLabels(ctx, map[string]string{uuid.NewV4().String(): uuid.NewV4().String()}) require.NoError(err) require.Len(networks, 0) // ListByNames networks, err = dockerClient.NetworkListByNames(ctx, networkNames...) require.NoError(err) require.Len(networks, iterations) for _, network := range networks { require.Contains(networkIDs, network.ID) require.Contains(networkNames, network.Name) } // ListByNames, network with names does not exist networks, err = dockerClient.NetworkListByNames(ctx, uuid.NewV4().String(), uuid.NewV4().String()) require.Error(err) require.Nil(networks) // RemoveByLabels err = dockerClient.NetworkRemoveByLabels(ctx, cleanupLabels) require.NoError(err) networks, err = dockerClient.NetworkListByLabels(ctx, cleanupLabels) require.NoError(err) require.Len(networks, 0) // RemoveByLabels, label does not exists err = dockerClient.NetworkRemoveByLabels(ctx, map[string]string{uuid.NewV4().String(): uuid.NewV4().String()}) require.NoError(err) // Create Networks networkIDs = make([]string, 0) networkNames = make([]string, 0) for i := 0; i < iterations; i++ { networkName := uuid.NewV4().String() resp, err := dockerClient.NetworkCreate(ctx, networkName, types.NetworkCreate{ Labels: cleanupLabels, }) require.NoError(err) networkNames = append(networkNames, networkName) networkIDs = append(networkIDs, resp.ID) } // RemoveByNames err = dockerClient.NetworkRemoveByNames(ctx, networkNames...) require.NoError(err) networks, err = dockerClient.NetworkListByNames(ctx, networkNames...) require.Error(err) require.Nil(networks) // RemoveByNames, name does not exists err = dockerClient.NetworkRemoveByNames(ctx, uuid.NewV4().String()) require.Error(err) // Create Networks networkIDs = make([]string, 0) networkNames = make([]string, 0) for i := 0; i < iterations; i++ { networkName := uuid.NewV4().String() resp, err := dockerClient.NetworkCreate(ctx, networkName, types.NetworkCreate{ Labels: cleanupLabels, }) require.NoError(err) networkNames = append(networkNames, networkName) networkIDs = append(networkIDs, resp.ID) } // RemoveByIDs err = dockerClient.NetworkRemoveByIDs(ctx, networkIDs...) require.NoError(err) networks, err = dockerClient.NetworkListByNames(ctx, networkNames...) require.Error(err) require.Nil(networks) // RemoveByID, id does not exists err = dockerClient.NetworkRemoveByIDs(ctx, uuid.NewV4().String()) require.Error(err) } func TestVolumeCRUD(t *testing.T) { var ( ctx = context.Background() require = require.New(t) iterations = 5 cleanupLabels = map[string]string{ uuid.NewV4().String(): uuid.NewV4().String(), } ) dockerClient, err := New() require.NoError(err) t.Cleanup(func() { dockerClient.VolumeRemoveByLabels(ctx, cleanupLabels) }) // Create Volumes volumeNames := make([]string, 0) for i := 0; i < iterations; i++ { volumeName := uuid.NewV4().String() volume, err := dockerClient.VolumeCreate(ctx, volume.VolumeCreateBody{ Name: volumeName, Labels: cleanupLabels, }) require.NoError(err) volumeNames = append(volumeNames, volume.Name) } // ListByLabels volumes, err := dockerClient.VolumeListByLabels(ctx, cleanupLabels) require.NoError(err) require.Len(volumes.Volumes, iterations) for _, volume := range volumes.Volumes { require.Contains(volumeNames, volume.Name) } // ListByLabels, network with label does not exist volumes, err = dockerClient.VolumeListByLabels(ctx, map[string]string{uuid.NewV4().String(): uuid.NewV4().String()}) require.NoError(err) require.Len(volumes.Volumes, 0) // ListByNames volumes, err = dockerClient.VolumeListByNames(ctx, volumeNames...) require.NoError(err) require.Len(volumes.Volumes, iterations) for _, volume := range volumes.Volumes { require.Contains(volumeNames, volume.Name) } // ListByNames, network with names does not exist volumes, err = dockerClient.VolumeListByNames(ctx, uuid.NewV4().String(), uuid.NewV4().String()) require.Error(err) require.Nil(volumes.Volumes) // RemoveByLabels err = dockerClient.VolumeRemoveByLabels(ctx, cleanupLabels) require.NoError(err) volumes, err = dockerClient.VolumeListByLabels(ctx, cleanupLabels) require.NoError(err) require.Len(volumes.Volumes, 0) // RemoveByLabels, labels does not exists err = dockerClient.NetworkRemoveByLabels(ctx, map[string]string{uuid.NewV4().String(): uuid.NewV4().String()}) require.NoError(err) // Create Volumes volumeNames = make([]string, 0) for i := 0; i < iterations; i++ { volumeName := uuid.NewV4().String() volume, err := dockerClient.VolumeCreate(ctx, volume.VolumeCreateBody{ Name: volumeName, Labels: cleanupLabels, }) require.NoError(err) volumeNames = append(volumeNames, volume.Name) } // RemoveByNames err = dockerClient.VolumeRemoveByNames(ctx, volumeNames...) require.NoError(err) volumes, err = dockerClient.VolumeListByNames(ctx, volumeNames...) require.Error(err) require.Nil(volumes.Volumes) // RemoveByNames, name does not exists err = dockerClient.NetworkRemoveByNames(ctx, uuid.NewV4().String()) require.Error(err) } // TestContainerMultipleNetworks // Test if a container can be accessed over multiple networks/ips. func TestContainerMultipleNetworks(t *testing.T) { var ( ctx = context.Background() require = require.New(t) iterations = 5 cleanupLabels = map[string]string{ uuid.NewV4().String(): uuid.NewV4().String(), } ) dockerClient, err := New() require.NoError(err) t.Cleanup(func() { dockerClient.ContainerRemoveByLabels(ctx, cleanupLabels) dockerClient.NetworkRemoveByLabels(ctx, cleanupLabels) }) // Create Containers containerIDs := make([]string, 0) containerNames := make([]string, 0) containersNetworks := make(map[string]map[string][]string, 0) for i := 0; i < iterations; i++ { containerName := uuid.NewV4().String() containerNetworks := map[string][]string{ uuid.NewV4().String(): { uuid.NewV4().String(), uuid.NewV4().String(), }, uuid.NewV4().String(): { uuid.NewV4().String(), uuid.NewV4().String(), }, } builder := dockerClient.NewBuilder("nginx:alpine"). Labels(cleanupLabels). Port("80"). Pull(). WithName(containerName) for networkName, aliasses := range containerNetworks { _, err := dockerClient.NetworkCreate(ctx, networkName, types.NetworkCreate{ Labels: cleanupLabels, }) require.NoError(err) builder.Network(networkName, aliasses...) } containerID, err := builder.Start(ctx) require.NoError(err) containerNames = append(containerNames, containerName) containerIDs = append(containerIDs, containerID) containersNetworks[containerID] = containerNetworks } for containerID, containerNetworks := range containersNetworks { for networkName := range containerNetworks { networks, err := dockerClient.NetworkListByNames(ctx, networkName) require.NoError(err) for _, network := range networks { n, err := dockerClient.NetworkInspect(ctx, network.ID, types.NetworkInspectOptions{ Verbose: true, }) require.NoError(err) if _, present := n.Containers[containerID]; !present { require.Fail("Container not part of network", "Container %v not found in network %v", containerID, n.Name) } networkIPParts := strings.Split(n.Containers[containerID].IPv4Address, "/") url := fmt.Sprintf("http://%v", networkIPParts[0]) resp, err := http.Get(url) require.NoError(err) defer resp.Body.Close() require.Equal(http.StatusOK, resp.StatusCode) } } } }