add better generate
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
This commit is contained in:
parent
3fc6abf56b
commit
cdd93563f5
5655 changed files with 1187011 additions and 392 deletions
189
vendor/github.com/docker/docker-ce/components/engine/internal/test/environment/clean.go
generated
vendored
Normal file
189
vendor/github.com/docker/docker-ce/components/engine/internal/test/environment/clean.go
generated
vendored
Normal file
|
@ -0,0 +1,189 @@
|
|||
package environment // import "github.com/docker/docker/internal/test/environment"
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type testingT interface {
|
||||
assert.TestingT
|
||||
logT
|
||||
Fatalf(string, ...interface{})
|
||||
}
|
||||
|
||||
type logT interface {
|
||||
Logf(string, ...interface{})
|
||||
}
|
||||
|
||||
// Clean the environment, preserving protected objects (images, containers, ...)
|
||||
// and removing everything else. It's meant to run after any tests so that they don't
|
||||
// depend on each others.
|
||||
func (e *Execution) Clean(t testingT) {
|
||||
client := e.APIClient()
|
||||
|
||||
platform := e.OSType
|
||||
if (platform != "windows") || (platform == "windows" && e.DaemonInfo.Isolation == "hyperv") {
|
||||
unpauseAllContainers(t, client)
|
||||
}
|
||||
deleteAllContainers(t, client, e.protectedElements.containers)
|
||||
deleteAllImages(t, client, e.protectedElements.images)
|
||||
deleteAllVolumes(t, client, e.protectedElements.volumes)
|
||||
deleteAllNetworks(t, client, platform, e.protectedElements.networks)
|
||||
if platform == "linux" {
|
||||
deleteAllPlugins(t, client, e.protectedElements.plugins)
|
||||
}
|
||||
}
|
||||
|
||||
func unpauseAllContainers(t assert.TestingT, client client.ContainerAPIClient) {
|
||||
ctx := context.Background()
|
||||
containers := getPausedContainers(ctx, t, client)
|
||||
if len(containers) > 0 {
|
||||
for _, container := range containers {
|
||||
err := client.ContainerUnpause(ctx, container.ID)
|
||||
assert.Check(t, err, "failed to unpause container %s", container.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPausedContainers(ctx context.Context, t assert.TestingT, client client.ContainerAPIClient) []types.Container {
|
||||
filter := filters.NewArgs()
|
||||
filter.Add("status", "paused")
|
||||
containers, err := client.ContainerList(ctx, types.ContainerListOptions{
|
||||
Filters: filter,
|
||||
Quiet: true,
|
||||
All: true,
|
||||
})
|
||||
assert.Check(t, err, "failed to list containers")
|
||||
return containers
|
||||
}
|
||||
|
||||
var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
|
||||
|
||||
func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) {
|
||||
ctx := context.Background()
|
||||
containers := getAllContainers(ctx, t, apiclient)
|
||||
if len(containers) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, container := range containers {
|
||||
if _, ok := protectedContainers[container.ID]; ok {
|
||||
continue
|
||||
}
|
||||
err := apiclient.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{
|
||||
Force: true,
|
||||
RemoveVolumes: true,
|
||||
})
|
||||
if err == nil || client.IsErrNotFound(err) || alreadyExists.MatchString(err.Error()) || isErrNotFoundSwarmClassic(err) {
|
||||
continue
|
||||
}
|
||||
assert.Check(t, err, "failed to remove %s", container.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func getAllContainers(ctx context.Context, t assert.TestingT, client client.ContainerAPIClient) []types.Container {
|
||||
containers, err := client.ContainerList(ctx, types.ContainerListOptions{
|
||||
Quiet: true,
|
||||
All: true,
|
||||
})
|
||||
assert.Check(t, err, "failed to list containers")
|
||||
return containers
|
||||
}
|
||||
|
||||
func deleteAllImages(t testingT, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) {
|
||||
images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{})
|
||||
assert.Check(t, err, "failed to list images")
|
||||
|
||||
ctx := context.Background()
|
||||
for _, image := range images {
|
||||
tags := tagsFromImageSummary(image)
|
||||
if len(tags) == 0 {
|
||||
t.Logf("Removing image %s", image.ID)
|
||||
removeImage(ctx, t, apiclient, image.ID)
|
||||
continue
|
||||
}
|
||||
for _, tag := range tags {
|
||||
if _, ok := protectedImages[tag]; !ok {
|
||||
t.Logf("Removing image %s", tag)
|
||||
removeImage(ctx, t, apiclient, tag)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageAPIClient, ref string) {
|
||||
_, err := apiclient.ImageRemove(ctx, ref, types.ImageRemoveOptions{
|
||||
Force: true,
|
||||
})
|
||||
if client.IsErrNotFound(err) {
|
||||
return
|
||||
}
|
||||
assert.Check(t, err, "failed to remove image %s", ref)
|
||||
}
|
||||
|
||||
func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) {
|
||||
volumes, err := c.VolumeList(context.Background(), filters.Args{})
|
||||
assert.Check(t, err, "failed to list volumes")
|
||||
|
||||
for _, v := range volumes.Volumes {
|
||||
if _, ok := protectedVolumes[v.Name]; ok {
|
||||
continue
|
||||
}
|
||||
err := c.VolumeRemove(context.Background(), v.Name, true)
|
||||
// Docker EE may list volumes that no longer exist.
|
||||
if isErrNotFoundSwarmClassic(err) {
|
||||
continue
|
||||
}
|
||||
assert.Check(t, err, "failed to remove volume %s", v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) {
|
||||
networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||
assert.Check(t, err, "failed to list networks")
|
||||
|
||||
for _, n := range networks {
|
||||
if n.Name == "bridge" || n.Name == "none" || n.Name == "host" {
|
||||
continue
|
||||
}
|
||||
if _, ok := protectedNetworks[n.ID]; ok {
|
||||
continue
|
||||
}
|
||||
if daemonPlatform == "windows" && strings.ToLower(n.Name) == "nat" {
|
||||
// nat is a pre-defined network on Windows and cannot be removed
|
||||
continue
|
||||
}
|
||||
err := c.NetworkRemove(context.Background(), n.ID)
|
||||
assert.Check(t, err, "failed to remove network %s", n.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
|
||||
plugins, err := c.PluginList(context.Background(), filters.Args{})
|
||||
// Docker EE does not allow cluster-wide plugin management.
|
||||
if client.IsErrNotImplemented(err) {
|
||||
return
|
||||
}
|
||||
assert.Check(t, err, "failed to list plugins")
|
||||
|
||||
for _, p := range plugins {
|
||||
if _, ok := protectedPlugins[p.Name]; ok {
|
||||
continue
|
||||
}
|
||||
err := c.PluginRemove(context.Background(), p.Name, types.PluginRemoveOptions{Force: true})
|
||||
assert.Check(t, err, "failed to remove plugin %s", p.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Swarm classic aggregates node errors and returns a 500 so we need to check
|
||||
// the error string instead of just IsErrNotFound().
|
||||
func isErrNotFoundSwarmClassic(err error) bool {
|
||||
return err != nil && strings.Contains(strings.ToLower(err.Error()), "no such")
|
||||
}
|
149
vendor/github.com/docker/docker-ce/components/engine/internal/test/environment/environment.go
generated
vendored
Normal file
149
vendor/github.com/docker/docker-ce/components/engine/internal/test/environment/environment.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
package environment // import "github.com/docker/docker/internal/test/environment"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/integration-cli/fixtures/load"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Execution contains information about the current test execution and daemon
|
||||
// under test
|
||||
type Execution struct {
|
||||
client client.APIClient
|
||||
DaemonInfo types.Info
|
||||
OSType string
|
||||
PlatformDefaults PlatformDefaults
|
||||
protectedElements protectedElements
|
||||
}
|
||||
|
||||
// PlatformDefaults are defaults values for the platform of the daemon under test
|
||||
type PlatformDefaults struct {
|
||||
BaseImage string
|
||||
VolumesConfigPath string
|
||||
ContainerStoragePath string
|
||||
}
|
||||
|
||||
// New creates a new Execution struct
|
||||
func New() (*Execution, error) {
|
||||
client, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to create client")
|
||||
}
|
||||
|
||||
info, err := client.Info(context.Background())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get info from daemon")
|
||||
}
|
||||
|
||||
osType := getOSType(info)
|
||||
|
||||
return &Execution{
|
||||
client: client,
|
||||
DaemonInfo: info,
|
||||
OSType: osType,
|
||||
PlatformDefaults: getPlatformDefaults(info, osType),
|
||||
protectedElements: newProtectedElements(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getOSType(info types.Info) string {
|
||||
// Docker EE does not set the OSType so allow the user to override this value.
|
||||
userOsType := os.Getenv("TEST_OSTYPE")
|
||||
if userOsType != "" {
|
||||
return userOsType
|
||||
}
|
||||
return info.OSType
|
||||
}
|
||||
|
||||
func getPlatformDefaults(info types.Info, osType string) PlatformDefaults {
|
||||
volumesPath := filepath.Join(info.DockerRootDir, "volumes")
|
||||
containersPath := filepath.Join(info.DockerRootDir, "containers")
|
||||
|
||||
switch osType {
|
||||
case "linux":
|
||||
return PlatformDefaults{
|
||||
BaseImage: "scratch",
|
||||
VolumesConfigPath: toSlash(volumesPath),
|
||||
ContainerStoragePath: toSlash(containersPath),
|
||||
}
|
||||
case "windows":
|
||||
baseImage := "microsoft/windowsservercore"
|
||||
if override := os.Getenv("WINDOWS_BASE_IMAGE"); override != "" {
|
||||
baseImage = override
|
||||
fmt.Println("INFO: Windows Base image is ", baseImage)
|
||||
}
|
||||
return PlatformDefaults{
|
||||
BaseImage: baseImage,
|
||||
VolumesConfigPath: filepath.FromSlash(volumesPath),
|
||||
ContainerStoragePath: filepath.FromSlash(containersPath),
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown OSType for daemon: %s", osType))
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure in context of daemon, not the local platform. Note we can't
|
||||
// use filepath.FromSlash or ToSlash here as they are a no-op on Unix.
|
||||
func toSlash(path string) string {
|
||||
return strings.Replace(path, `\`, `/`, -1)
|
||||
}
|
||||
|
||||
// IsLocalDaemon is true if the daemon under test is on the same
|
||||
// host as the test process.
|
||||
//
|
||||
// Deterministically working out the environment in which CI is running
|
||||
// to evaluate whether the daemon is local or remote is not possible through
|
||||
// a build tag.
|
||||
//
|
||||
// For example Windows to Linux CI under Jenkins tests the 64-bit
|
||||
// Windows binary build with the daemon build tag, but calls a remote
|
||||
// Linux daemon.
|
||||
//
|
||||
// We can't just say if Windows then assume the daemon is local as at
|
||||
// some point, we will be testing the Windows CLI against a Windows daemon.
|
||||
//
|
||||
// Similarly, it will be perfectly valid to also run CLI tests from
|
||||
// a Linux CLI (built with the daemon tag) against a Windows daemon.
|
||||
func (e *Execution) IsLocalDaemon() bool {
|
||||
return os.Getenv("DOCKER_REMOTE_DAEMON") == ""
|
||||
}
|
||||
|
||||
// IsRemoteDaemon is true if the daemon under test is on different host
|
||||
// as the test process.
|
||||
func (e *Execution) IsRemoteDaemon() bool {
|
||||
return !e.IsLocalDaemon()
|
||||
}
|
||||
|
||||
// Print the execution details to stdout
|
||||
// TODO: print everything
|
||||
func (e *Execution) Print() {
|
||||
if e.IsLocalDaemon() {
|
||||
fmt.Println("INFO: Testing against a local daemon")
|
||||
} else {
|
||||
fmt.Println("INFO: Testing against a remote daemon")
|
||||
}
|
||||
}
|
||||
|
||||
// APIClient returns an APIClient connected to the daemon under test
|
||||
func (e *Execution) APIClient() client.APIClient {
|
||||
return e.client
|
||||
}
|
||||
|
||||
// EnsureFrozenImagesLinux loads frozen test images into the daemon
|
||||
// if they aren't already loaded
|
||||
func EnsureFrozenImagesLinux(testEnv *Execution) error {
|
||||
if testEnv.OSType == "linux" {
|
||||
err := load.FrozenImagesLinux(testEnv.APIClient(), frozenImages...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error loading frozen images")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
205
vendor/github.com/docker/docker-ce/components/engine/internal/test/environment/protect.go
generated
vendored
Normal file
205
vendor/github.com/docker/docker-ce/components/engine/internal/test/environment/protect.go
generated
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
package environment // import "github.com/docker/docker/internal/test/environment"
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
dclient "github.com/docker/docker/client"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
)
|
||||
|
||||
var frozenImages = []string{"busybox:latest", "busybox:glibc", "hello-world:frozen", "debian:jessie"}
|
||||
|
||||
type protectedElements struct {
|
||||
containers map[string]struct{}
|
||||
images map[string]struct{}
|
||||
networks map[string]struct{}
|
||||
plugins map[string]struct{}
|
||||
volumes map[string]struct{}
|
||||
}
|
||||
|
||||
func newProtectedElements() protectedElements {
|
||||
return protectedElements{
|
||||
containers: map[string]struct{}{},
|
||||
images: map[string]struct{}{},
|
||||
networks: map[string]struct{}{},
|
||||
plugins: map[string]struct{}{},
|
||||
volumes: map[string]struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectAll protects the existing environment (containers, images, networks,
|
||||
// volumes, and, on Linux, plugins) from being cleaned up at the end of test
|
||||
// runs
|
||||
func ProtectAll(t testingT, testEnv *Execution) {
|
||||
ProtectContainers(t, testEnv)
|
||||
ProtectImages(t, testEnv)
|
||||
ProtectNetworks(t, testEnv)
|
||||
ProtectVolumes(t, testEnv)
|
||||
if testEnv.OSType == "linux" {
|
||||
ProtectPlugins(t, testEnv)
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectContainer adds the specified container(s) to be protected in case of
|
||||
// clean
|
||||
func (e *Execution) ProtectContainer(t testingT, containers ...string) {
|
||||
for _, container := range containers {
|
||||
e.protectedElements.containers[container] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectContainers protects existing containers from being cleaned up at the
|
||||
// end of test runs
|
||||
func ProtectContainers(t testingT, testEnv *Execution) {
|
||||
containers := getExistingContainers(t, testEnv)
|
||||
testEnv.ProtectContainer(t, containers...)
|
||||
}
|
||||
|
||||
func getExistingContainers(t assert.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
|
||||
All: true,
|
||||
})
|
||||
assert.NilError(t, err, "failed to list containers")
|
||||
|
||||
containers := []string{}
|
||||
for _, container := range containerList {
|
||||
containers = append(containers, container.ID)
|
||||
}
|
||||
return containers
|
||||
}
|
||||
|
||||
// ProtectImage adds the specified image(s) to be protected in case of clean
|
||||
func (e *Execution) ProtectImage(t testingT, images ...string) {
|
||||
for _, image := range images {
|
||||
e.protectedElements.images[image] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectImages protects existing images and on linux frozen images from being
|
||||
// cleaned up at the end of test runs
|
||||
func ProtectImages(t testingT, testEnv *Execution) {
|
||||
images := getExistingImages(t, testEnv)
|
||||
|
||||
if testEnv.OSType == "linux" {
|
||||
images = append(images, frozenImages...)
|
||||
}
|
||||
testEnv.ProtectImage(t, images...)
|
||||
}
|
||||
|
||||
func getExistingImages(t assert.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
filter := filters.NewArgs()
|
||||
filter.Add("dangling", "false")
|
||||
imageList, err := client.ImageList(context.Background(), types.ImageListOptions{
|
||||
All: true,
|
||||
Filters: filter,
|
||||
})
|
||||
assert.NilError(t, err, "failed to list images")
|
||||
|
||||
images := []string{}
|
||||
for _, image := range imageList {
|
||||
images = append(images, tagsFromImageSummary(image)...)
|
||||
}
|
||||
return images
|
||||
}
|
||||
|
||||
func tagsFromImageSummary(image types.ImageSummary) []string {
|
||||
result := []string{}
|
||||
for _, tag := range image.RepoTags {
|
||||
if tag != "<none>:<none>" {
|
||||
result = append(result, tag)
|
||||
}
|
||||
}
|
||||
for _, digest := range image.RepoDigests {
|
||||
if digest != "<none>@<none>" {
|
||||
result = append(result, digest)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ProtectNetwork adds the specified network(s) to be protected in case of
|
||||
// clean
|
||||
func (e *Execution) ProtectNetwork(t testingT, networks ...string) {
|
||||
for _, network := range networks {
|
||||
e.protectedElements.networks[network] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectNetworks protects existing networks from being cleaned up at the end
|
||||
// of test runs
|
||||
func ProtectNetworks(t testingT, testEnv *Execution) {
|
||||
networks := getExistingNetworks(t, testEnv)
|
||||
testEnv.ProtectNetwork(t, networks...)
|
||||
}
|
||||
|
||||
func getExistingNetworks(t assert.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||
assert.NilError(t, err, "failed to list networks")
|
||||
|
||||
networks := []string{}
|
||||
for _, network := range networkList {
|
||||
networks = append(networks, network.ID)
|
||||
}
|
||||
return networks
|
||||
}
|
||||
|
||||
// ProtectPlugin adds the specified plugin(s) to be protected in case of clean
|
||||
func (e *Execution) ProtectPlugin(t testingT, plugins ...string) {
|
||||
for _, plugin := range plugins {
|
||||
e.protectedElements.plugins[plugin] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectPlugins protects existing plugins from being cleaned up at the end of
|
||||
// test runs
|
||||
func ProtectPlugins(t testingT, testEnv *Execution) {
|
||||
plugins := getExistingPlugins(t, testEnv)
|
||||
testEnv.ProtectPlugin(t, plugins...)
|
||||
}
|
||||
|
||||
func getExistingPlugins(t assert.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
pluginList, err := client.PluginList(context.Background(), filters.Args{})
|
||||
// Docker EE does not allow cluster-wide plugin management.
|
||||
if dclient.IsErrNotImplemented(err) {
|
||||
return []string{}
|
||||
}
|
||||
assert.NilError(t, err, "failed to list plugins")
|
||||
|
||||
plugins := []string{}
|
||||
for _, plugin := range pluginList {
|
||||
plugins = append(plugins, plugin.Name)
|
||||
}
|
||||
return plugins
|
||||
}
|
||||
|
||||
// ProtectVolume adds the specified volume(s) to be protected in case of clean
|
||||
func (e *Execution) ProtectVolume(t testingT, volumes ...string) {
|
||||
for _, volume := range volumes {
|
||||
e.protectedElements.volumes[volume] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// ProtectVolumes protects existing volumes from being cleaned up at the end of
|
||||
// test runs
|
||||
func ProtectVolumes(t testingT, testEnv *Execution) {
|
||||
volumes := getExistingVolumes(t, testEnv)
|
||||
testEnv.ProtectVolume(t, volumes...)
|
||||
}
|
||||
|
||||
func getExistingVolumes(t assert.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
volumeList, err := client.VolumeList(context.Background(), filters.Args{})
|
||||
assert.NilError(t, err, "failed to list volumes")
|
||||
|
||||
volumes := []string{}
|
||||
for _, volume := range volumeList.Volumes {
|
||||
volumes = append(volumes, volume.Name)
|
||||
}
|
||||
return volumes
|
||||
}
|
33
vendor/github.com/docker/docker-ce/components/engine/internal/testutil/helpers.go
generated
vendored
Normal file
33
vendor/github.com/docker/docker-ce/components/engine/internal/testutil/helpers.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
package testutil // import "github.com/docker/docker/internal/testutil"
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
)
|
||||
|
||||
type helperT interface {
|
||||
Helper()
|
||||
}
|
||||
|
||||
// ErrorContains checks that the error is not nil, and contains the expected
|
||||
// substring.
|
||||
// Deprecated: use assert.Assert(t, cmp.ErrorContains(err, expected))
|
||||
func ErrorContains(t assert.TestingT, err error, expectedError string, msgAndArgs ...interface{}) {
|
||||
if ht, ok := t.(helperT); ok {
|
||||
ht.Helper()
|
||||
}
|
||||
assert.ErrorContains(t, err, expectedError, msgAndArgs...)
|
||||
}
|
||||
|
||||
// DevZero acts like /dev/zero but in an OS-independent fashion.
|
||||
var DevZero io.Reader = devZero{}
|
||||
|
||||
type devZero struct{}
|
||||
|
||||
func (d devZero) Read(p []byte) (n int, err error) {
|
||||
for i := range p {
|
||||
p[i] = 0
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
14
vendor/github.com/docker/docker-ce/components/engine/internal/testutil/stringutils.go
generated
vendored
Normal file
14
vendor/github.com/docker/docker-ce/components/engine/internal/testutil/stringutils.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
package testutil // import "github.com/docker/docker/internal/testutil"
|
||||
|
||||
import "math/rand"
|
||||
|
||||
// GenerateRandomAlphaOnlyString generates an alphabetical random string with length n.
|
||||
func GenerateRandomAlphaOnlyString(n int) string {
|
||||
// make a really long string
|
||||
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
34
vendor/github.com/docker/docker-ce/components/engine/internal/testutil/stringutils_test.go
generated
vendored
Normal file
34
vendor/github.com/docker/docker-ce/components/engine/internal/testutil/stringutils_test.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package testutil // import "github.com/docker/docker/internal/testutil"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
)
|
||||
|
||||
func testLengthHelper(generator func(int) string, t *testing.T) {
|
||||
expectedLength := 20
|
||||
s := generator(expectedLength)
|
||||
assert.Check(t, is.Equal(expectedLength, len(s)))
|
||||
}
|
||||
|
||||
func testUniquenessHelper(generator func(int) string, t *testing.T) {
|
||||
repeats := 25
|
||||
set := make(map[string]struct{}, repeats)
|
||||
for i := 0; i < repeats; i = i + 1 {
|
||||
str := generator(64)
|
||||
assert.Check(t, is.Equal(64, len(str)))
|
||||
_, ok := set[str]
|
||||
assert.Check(t, !ok, "Random number is repeated")
|
||||
set[str] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRandomAlphaOnlyStringLength(t *testing.T) {
|
||||
testLengthHelper(GenerateRandomAlphaOnlyString, t)
|
||||
}
|
||||
|
||||
func TestGenerateRandomAlphaOnlyStringUniqueness(t *testing.T) {
|
||||
testUniquenessHelper(GenerateRandomAlphaOnlyString, t)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue