mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Allow protection of entire environment during tests
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
This commit is contained in:
parent
3a081f53c1
commit
0520581523
2 changed files with 157 additions and 15 deletions
|
@ -32,12 +32,12 @@ func (e *Execution) Clean(t testingT) {
|
|||
if (platform != "windows") || (platform == "windows" && e.DaemonInfo.Isolation == "hyperv") {
|
||||
unpauseAllContainers(t, client)
|
||||
}
|
||||
deleteAllContainers(t, client)
|
||||
deleteAllContainers(t, client, e.protectedElements.containers)
|
||||
deleteAllImages(t, client, e.protectedElements.images)
|
||||
deleteAllVolumes(t, client)
|
||||
deleteAllNetworks(t, client, platform)
|
||||
deleteAllVolumes(t, client, e.protectedElements.volumes)
|
||||
deleteAllNetworks(t, client, platform, e.protectedElements.networks)
|
||||
if platform == "linux" {
|
||||
deleteAllPlugins(t, client)
|
||||
deleteAllPlugins(t, client, e.protectedElements.plugins)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ func getPausedContainers(ctx context.Context, t assert.TestingT, client client.C
|
|||
|
||||
var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
|
||||
|
||||
func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient) {
|
||||
func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) {
|
||||
ctx := context.Background()
|
||||
containers := getAllContainers(ctx, t, apiclient)
|
||||
if len(containers) == 0 {
|
||||
|
@ -74,6 +74,9 @@ func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient)
|
|||
}
|
||||
|
||||
for _, container := range containers {
|
||||
if _, ok := protectedContainers[container.ID]; ok {
|
||||
continue
|
||||
}
|
||||
err := apiclient.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{
|
||||
Force: true,
|
||||
RemoveVolumes: true,
|
||||
|
@ -126,17 +129,20 @@ func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageA
|
|||
assert.NoError(t, err, "failed to remove image %s", ref)
|
||||
}
|
||||
|
||||
func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient) {
|
||||
func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) {
|
||||
volumes, err := c.VolumeList(context.Background(), filters.Args{})
|
||||
assert.NoError(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)
|
||||
assert.NoError(t, err, "failed to remove volume %s", v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string) {
|
||||
func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) {
|
||||
networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||
assert.NoError(t, err, "failed to list networks")
|
||||
|
||||
|
@ -144,6 +150,9 @@ func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatf
|
|||
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
|
||||
|
@ -153,11 +162,14 @@ func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatf
|
|||
}
|
||||
}
|
||||
|
||||
func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient) {
|
||||
func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
|
||||
plugins, err := c.PluginList(context.Background(), filters.Args{})
|
||||
assert.NoError(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.NoError(t, err, "failed to remove plugin %s", p.ID)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,63 @@ import (
|
|||
)
|
||||
|
||||
type protectedElements struct {
|
||||
images map[string]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.DaemonInfo.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 require.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
|
||||
All: true,
|
||||
})
|
||||
require.NoError(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
|
||||
|
@ -20,12 +76,6 @@ func (e *Execution) ProtectImage(t testingT, images ...string) {
|
|||
}
|
||||
}
|
||||
|
||||
func newProtectedElements() protectedElements {
|
||||
return protectedElements{
|
||||
images: map[string]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) {
|
||||
|
@ -42,6 +92,7 @@ func getExistingImages(t require.TestingT, testEnv *Execution) []string {
|
|||
filter := filters.NewArgs()
|
||||
filter.Add("dangling", "false")
|
||||
imageList, err := client.ImageList(context.Background(), types.ImageListOptions{
|
||||
All: true,
|
||||
Filters: filter,
|
||||
})
|
||||
require.NoError(t, err, "failed to list images")
|
||||
|
@ -76,3 +127,82 @@ func ensureFrozenImagesLinux(t testingT, testEnv *Execution) []string {
|
|||
}
|
||||
return images
|
||||
}
|
||||
|
||||
// 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 require.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||
require.NoError(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 require.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
pluginList, err := client.PluginList(context.Background(), filters.Args{})
|
||||
require.NoError(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 require.TestingT, testEnv *Execution) []string {
|
||||
client := testEnv.APIClient()
|
||||
volumeList, err := client.VolumeList(context.Background(), filters.Args{})
|
||||
require.NoError(t, err, "failed to list volumes")
|
||||
|
||||
volumes := []string{}
|
||||
for _, volume := range volumeList.Volumes {
|
||||
volumes = append(volumes, volume.Name)
|
||||
}
|
||||
return volumes
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue