2018-03-22 17:11:03 -04:00
package service // import "github.com/docker/docker/volume/service"
2015-09-18 19:58:05 -04:00
import (
2018-03-22 17:11:03 -04:00
"context"
2015-10-19 20:41:22 -04:00
"errors"
2017-11-15 13:13:22 -05:00
"fmt"
"net"
2016-12-01 17:17:07 -05:00
"os"
2015-09-23 16:29:14 -04:00
"strings"
2015-09-18 19:58:05 -04:00
"testing"
2017-09-19 14:34:41 -04:00
"github.com/docker/docker/volume"
2018-03-19 17:18:52 -04:00
volumedrivers "github.com/docker/docker/volume/drivers"
2018-03-22 17:11:03 -04:00
"github.com/docker/docker/volume/service/opts"
2016-09-12 03:34:19 -04:00
volumetestutils "github.com/docker/docker/volume/testutils"
2017-12-22 16:30:49 -05:00
"github.com/google/go-cmp/cmp"
2020-02-07 08:39:24 -05:00
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
2015-09-18 19:58:05 -04:00
)
func TestCreate ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
s , cleanup := setupTest ( t )
defer cleanup ( )
s . drivers . Register ( volumetestutils . NewFakeDriver ( "fake" ) , "fake" )
2016-12-01 17:17:07 -05:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
v , err := s . Create ( ctx , "fake1" , "fake" )
2015-09-18 19:58:05 -04:00
if err != nil {
t . Fatal ( err )
}
if v . Name ( ) != "fake1" {
t . Fatalf ( "Expected fake1 volume, got %v" , v )
}
2018-03-22 17:11:03 -04:00
if l , _ , _ := s . Find ( ctx , nil ) ; len ( l ) != 1 {
2015-09-18 19:58:05 -04:00
t . Fatalf ( "Expected 1 volume in the store, got %v: %v" , len ( l ) , l )
}
2018-03-22 17:11:03 -04:00
if _ , err := s . Create ( ctx , "none" , "none" ) ; err == nil {
2015-09-18 19:58:05 -04:00
t . Fatalf ( "Expected unknown driver error, got nil" )
}
2018-03-22 17:11:03 -04:00
_ , err = s . Create ( ctx , "fakeerror" , "fake" , opts . WithCreateOptions ( map [ string ] string { "error" : "create error" } ) )
2015-11-13 15:30:13 -05:00
expected := & OpErr { Op : "create" , Name : "fakeerror" , Err : errors . New ( "create error" ) }
2015-10-19 20:41:22 -04:00
if err != nil && err . Error ( ) != expected . Error ( ) {
t . Fatalf ( "Expected create fakeError: create error, got %v" , err )
2015-09-18 19:58:05 -04:00
}
}
func TestRemove ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
s , cleanup := setupTest ( t )
defer cleanup ( )
s . drivers . Register ( volumetestutils . NewFakeDriver ( "fake" ) , "fake" )
s . drivers . Register ( volumetestutils . NewFakeDriver ( "noop" ) , "noop" )
2015-09-23 16:29:14 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
2015-09-23 16:29:14 -04:00
// doing string compare here since this error comes directly from the driver
expected := "no such volume"
2018-03-22 17:11:03 -04:00
var v volume . Volume = volumetestutils . NoopVolume { }
if err := s . Remove ( ctx , v ) ; err == nil || ! strings . Contains ( err . Error ( ) , expected ) {
2015-09-23 16:29:14 -04:00
t . Fatalf ( "Expected error %q, got %v" , expected , err )
2015-09-18 19:58:05 -04:00
}
2015-09-23 16:29:14 -04:00
2018-03-22 17:11:03 -04:00
v , err := s . Create ( ctx , "fake1" , "fake" , opts . WithCreateReference ( "fake" ) )
2015-09-18 19:58:05 -04:00
if err != nil {
t . Fatal ( err )
}
2015-09-23 16:29:14 -04:00
2018-03-22 17:11:03 -04:00
if err := s . Remove ( ctx , v ) ; ! IsInUse ( err ) {
2015-09-23 16:29:14 -04:00
t . Fatalf ( "Expected ErrVolumeInUse error, got %v" , err )
2015-09-18 19:58:05 -04:00
}
2018-03-22 17:11:03 -04:00
s . Release ( ctx , v . Name ( ) , "fake" )
if err := s . Remove ( ctx , v ) ; err != nil {
2015-09-18 19:58:05 -04:00
t . Fatal ( err )
}
2018-03-22 17:11:03 -04:00
if l , _ , _ := s . Find ( ctx , nil ) ; len ( l ) != 0 {
2015-09-18 19:58:05 -04:00
t . Fatalf ( "Expected 0 volumes in the store, got %v, %v" , len ( l ) , l )
}
}
2015-09-23 16:29:14 -04:00
func TestList ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
2021-08-24 06:10:50 -04:00
dir , err := os . MkdirTemp ( "" , "test-list" )
2018-03-19 17:18:52 -04:00
assert . NilError ( t , err )
2016-12-01 17:17:07 -05:00
defer os . RemoveAll ( dir )
2015-09-23 16:29:14 -04:00
2018-03-19 17:18:52 -04:00
drivers := volumedrivers . NewStore ( nil )
drivers . Register ( volumetestutils . NewFakeDriver ( "fake" ) , "fake" )
drivers . Register ( volumetestutils . NewFakeDriver ( "fake2" ) , "fake2" )
2018-03-22 17:11:03 -04:00
s , err := NewStore ( dir , drivers )
2018-03-19 17:18:52 -04:00
assert . NilError ( t , err )
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
if _ , err := s . Create ( ctx , "test" , "fake" ) ; err != nil {
2015-09-23 16:29:14 -04:00
t . Fatal ( err )
2015-09-18 19:58:05 -04:00
}
2018-03-22 17:11:03 -04:00
if _ , err := s . Create ( ctx , "test2" , "fake2" ) ; err != nil {
2015-09-23 16:29:14 -04:00
t . Fatal ( err )
2015-09-18 19:58:05 -04:00
}
2018-03-22 17:11:03 -04:00
ls , _ , err := s . Find ( ctx , nil )
2015-09-23 16:29:14 -04:00
if err != nil {
t . Fatal ( err )
2015-09-18 19:58:05 -04:00
}
2015-09-23 16:29:14 -04:00
if len ( ls ) != 2 {
t . Fatalf ( "expected 2 volumes, got: %d" , len ( ls ) )
2015-09-18 19:58:05 -04:00
}
2016-12-01 17:17:07 -05:00
if err := s . Shutdown ( ) ; err != nil {
t . Fatal ( err )
}
2015-09-18 19:58:05 -04:00
2015-09-23 16:29:14 -04:00
// and again with a new store
2018-03-22 17:11:03 -04:00
s , err = NewStore ( dir , drivers )
2016-03-16 17:52:34 -04:00
if err != nil {
t . Fatal ( err )
}
2022-05-31 11:01:43 -04:00
defer s . Shutdown ( )
2018-03-22 17:11:03 -04:00
ls , _ , err = s . Find ( ctx , nil )
2015-09-23 16:29:14 -04:00
if err != nil {
t . Fatal ( err )
}
if len ( ls ) != 2 {
t . Fatalf ( "expected 2 volumes, got: %d" , len ( ls ) )
2015-09-18 19:58:05 -04:00
}
}
2018-03-22 17:11:03 -04:00
func TestFindByDriver ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
s , cleanup := setupTest ( t )
defer cleanup ( )
2018-03-22 17:11:03 -04:00
assert . Assert ( t , s . drivers . Register ( volumetestutils . NewFakeDriver ( "fake" ) , "fake" ) )
assert . Assert ( t , s . drivers . Register ( volumetestutils . NewFakeDriver ( "noop" ) , "noop" ) )
2015-09-18 19:58:05 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
_ , err := s . Create ( ctx , "fake1" , "fake" )
assert . NilError ( t , err )
2015-09-18 19:58:05 -04:00
2018-03-22 17:11:03 -04:00
_ , err = s . Create ( ctx , "fake2" , "fake" )
assert . NilError ( t , err )
2015-09-18 19:58:05 -04:00
2018-03-22 17:11:03 -04:00
_ , err = s . Create ( ctx , "fake3" , "noop" )
assert . NilError ( t , err )
l , _ , err := s . Find ( ctx , ByDriver ( "fake" ) )
assert . NilError ( t , err )
assert . Equal ( t , len ( l ) , 2 )
l , _ , err = s . Find ( ctx , ByDriver ( "noop" ) )
assert . NilError ( t , err )
assert . Equal ( t , len ( l ) , 1 )
l , _ , err = s . Find ( ctx , ByDriver ( "nosuchdriver" ) )
assert . NilError ( t , err )
assert . Equal ( t , len ( l ) , 0 )
2015-09-18 19:58:05 -04:00
}
2016-01-25 14:39:41 -05:00
2018-03-22 17:11:03 -04:00
func TestFindByReferenced ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
s , cleanup := setupTest ( t )
defer cleanup ( )
2016-01-25 14:39:41 -05:00
2018-03-19 17:18:52 -04:00
s . drivers . Register ( volumetestutils . NewFakeDriver ( "fake" ) , "fake" )
s . drivers . Register ( volumetestutils . NewFakeDriver ( "noop" ) , "noop" )
2016-03-16 17:52:34 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
if _ , err := s . Create ( ctx , "fake1" , "fake" , opts . WithCreateReference ( "volReference" ) ) ; err != nil {
2016-03-16 17:52:34 -04:00
t . Fatal ( err )
}
2018-03-22 17:11:03 -04:00
if _ , err := s . Create ( ctx , "fake2" , "fake" ) ; err != nil {
2016-01-25 14:39:41 -05:00
t . Fatal ( err )
}
2018-03-22 17:11:03 -04:00
dangling , _ , err := s . Find ( ctx , ByReferenced ( false ) )
2019-01-21 07:16:02 -05:00
assert . NilError ( t , err )
2018-03-22 17:11:03 -04:00
assert . Assert ( t , len ( dangling ) == 1 )
assert . Check ( t , dangling [ 0 ] . Name ( ) == "fake2" )
2016-01-25 14:39:41 -05:00
2018-03-22 17:11:03 -04:00
used , _ , err := s . Find ( ctx , ByReferenced ( true ) )
2019-01-21 07:16:02 -05:00
assert . NilError ( t , err )
2018-03-22 17:11:03 -04:00
assert . Assert ( t , len ( used ) == 1 )
assert . Check ( t , used [ 0 ] . Name ( ) == "fake1" )
2016-01-25 14:39:41 -05:00
}
2016-02-16 21:10:45 -05:00
func TestDerefMultipleOfSameRef ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
s , cleanup := setupTest ( t )
defer cleanup ( )
s . drivers . Register ( volumetestutils . NewFakeDriver ( "fake" ) , "fake" )
2016-03-16 17:52:34 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
v , err := s . Create ( ctx , "fake1" , "fake" , opts . WithCreateReference ( "volReference" ) )
2016-02-16 21:10:45 -05:00
if err != nil {
t . Fatal ( err )
}
2018-03-22 17:11:03 -04:00
if _ , err := s . Get ( ctx , "fake1" , opts . WithGetDriver ( "fake" ) , opts . WithGetReference ( "volReference" ) ) ; err != nil {
2016-02-16 21:10:45 -05:00
t . Fatal ( err )
}
2018-03-22 17:11:03 -04:00
s . Release ( ctx , v . Name ( ) , "volReference" )
if err := s . Remove ( ctx , v ) ; err != nil {
2016-02-16 21:10:45 -05:00
t . Fatal ( err )
}
}
2017-09-19 14:34:41 -04:00
func TestCreateKeepOptsLabelsWhenExistsRemotely ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
s , cleanup := setupTest ( t )
defer cleanup ( )
2017-09-19 14:34:41 -04:00
vd := volumetestutils . NewFakeDriver ( "fake" )
2018-03-19 17:18:52 -04:00
s . drivers . Register ( vd , "fake" )
2017-09-19 14:34:41 -04:00
// Create a volume in the driver directly
if _ , err := vd . Create ( "foo" , nil ) ; err != nil {
t . Fatal ( err )
}
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
v , err := s . Create ( ctx , "foo" , "fake" , opts . WithCreateLabels ( map [ string ] string { "hello" : "world" } ) )
2017-09-19 14:34:41 -04:00
if err != nil {
t . Fatal ( err )
}
switch dv := v . ( type ) {
case volume . DetailedVolume :
if dv . Labels ( ) [ "hello" ] != "world" {
t . Fatalf ( "labels don't match" )
}
default :
t . Fatalf ( "got unexpected type: %T" , v )
}
}
2017-11-15 13:13:22 -05:00
func TestDefererencePluginOnCreateError ( t * testing . T ) {
2018-03-19 17:18:52 -04:00
t . Parallel ( )
2017-11-15 13:13:22 -05:00
var (
l net . Listener
err error
)
for i := 32768 ; l == nil && i < 40000 ; i ++ {
l , err = net . Listen ( "tcp" , fmt . Sprintf ( "127.0.0.1:%d" , i ) )
}
if l == nil {
t . Fatalf ( "could not create listener: %v" , err )
}
defer l . Close ( )
2018-03-19 17:18:52 -04:00
s , cleanup := setupTest ( t )
defer cleanup ( )
2017-11-15 13:13:22 -05:00
d := volumetestutils . NewFakeDriver ( "TestDefererencePluginOnCreateError" )
p , err := volumetestutils . MakeFakePlugin ( d , l )
if err != nil {
t . Fatal ( err )
}
pg := volumetestutils . NewFakePluginGetter ( p )
2018-03-19 17:18:52 -04:00
s . drivers = volumedrivers . NewStore ( pg )
2017-11-15 13:13:22 -05:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
2017-11-15 13:13:22 -05:00
// create a good volume so we have a plugin reference
2018-03-22 17:11:03 -04:00
_ , err = s . Create ( ctx , "fake1" , d . Name ( ) )
2017-11-15 13:13:22 -05:00
if err != nil {
t . Fatal ( err )
}
// Now create another one expecting an error
2018-03-22 17:11:03 -04:00
_ , err = s . Create ( ctx , "fake2" , d . Name ( ) , opts . WithCreateOptions ( map [ string ] string { "error" : "some error" } ) )
2017-11-15 13:13:22 -05:00
if err == nil || ! strings . Contains ( err . Error ( ) , "some error" ) {
t . Fatalf ( "expected an error on create: %v" , err )
}
// There should be only 1 plugin reference
if refs := volumetestutils . FakeRefs ( p ) ; refs != 1 {
t . Fatalf ( "expected 1 plugin reference, got: %d" , refs )
}
}
2018-03-13 15:39:23 -04:00
func TestRefDerefRemove ( t * testing . T ) {
t . Parallel ( )
driverName := "test-ref-deref-remove"
2018-03-19 17:18:52 -04:00
s , cleanup := setupTest ( t )
defer cleanup ( )
s . drivers . Register ( volumetestutils . NewFakeDriver ( driverName ) , driverName )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
v , err := s . Create ( ctx , "test" , driverName , opts . WithCreateReference ( "test-ref" ) )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
err = s . Remove ( ctx , v )
2018-03-13 15:28:34 -04:00
assert . Assert ( t , is . ErrorContains ( err , "" ) )
assert . Equal ( t , errVolumeInUse , err . ( * OpErr ) . Err )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
s . Release ( ctx , v . Name ( ) , "test-ref" )
err = s . Remove ( ctx , v )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
}
func TestGet ( t * testing . T ) {
t . Parallel ( )
driverName := "test-get"
2018-03-19 17:18:52 -04:00
s , cleanup := setupTest ( t )
defer cleanup ( )
s . drivers . Register ( volumetestutils . NewFakeDriver ( driverName ) , driverName )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
_ , err := s . Get ( ctx , "not-exist" )
2018-03-13 15:28:34 -04:00
assert . Assert ( t , is . ErrorContains ( err , "" ) )
assert . Equal ( t , errNoSuchVolume , err . ( * OpErr ) . Err )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
v1 , err := s . Create ( ctx , "test" , driverName , opts . WithCreateLabels ( map [ string ] string { "a" : "1" } ) )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
v2 , err := s . Get ( ctx , "test" )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2017-12-22 16:30:49 -05:00
assert . DeepEqual ( t , v1 , v2 , cmpVolume )
2018-03-13 15:39:23 -04:00
dv := v2 . ( volume . DetailedVolume )
2018-03-13 15:28:34 -04:00
assert . Equal ( t , "1" , dv . Labels ( ) [ "a" ] )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
err = s . Remove ( ctx , v1 )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
}
2018-03-22 17:11:03 -04:00
func TestGetWithReference ( t * testing . T ) {
2018-03-13 15:39:23 -04:00
t . Parallel ( )
driverName := "test-get-with-ref"
2018-03-19 17:18:52 -04:00
s , cleanup := setupTest ( t )
defer cleanup ( )
s . drivers . Register ( volumetestutils . NewFakeDriver ( driverName ) , driverName )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
ctx := context . Background ( )
_ , err := s . Get ( ctx , "not-exist" , opts . WithGetDriver ( driverName ) , opts . WithGetReference ( "test-ref" ) )
2018-03-13 15:28:34 -04:00
assert . Assert ( t , is . ErrorContains ( err , "" ) )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
v1 , err := s . Create ( ctx , "test" , driverName , opts . WithCreateLabels ( map [ string ] string { "a" : "1" } ) )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
v2 , err := s . Get ( ctx , "test" , opts . WithGetDriver ( driverName ) , opts . WithGetReference ( "test-ref" ) )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2017-12-22 16:30:49 -05:00
assert . DeepEqual ( t , v1 , v2 , cmpVolume )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
err = s . Remove ( ctx , v2 )
2018-03-13 15:28:34 -04:00
assert . Assert ( t , is . ErrorContains ( err , "" ) )
assert . Equal ( t , errVolumeInUse , err . ( * OpErr ) . Err )
2018-03-13 15:39:23 -04:00
2018-03-22 17:11:03 -04:00
s . Release ( ctx , v2 . Name ( ) , "test-ref" )
err = s . Remove ( ctx , v2 )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
}
2017-12-22 16:30:49 -05:00
var cmpVolume = cmp . AllowUnexported ( volumetestutils . FakeVolume { } , volumeWrapper { } )
2018-03-19 17:18:52 -04:00
func setupTest ( t * testing . T ) ( * VolumeStore , func ( ) ) {
2018-03-13 15:39:23 -04:00
t . Helper ( )
2022-05-09 07:26:05 -04:00
dirName := strings . ReplaceAll ( t . Name ( ) , string ( os . PathSeparator ) , "_" )
2021-08-24 06:10:50 -04:00
dir , err := os . MkdirTemp ( "" , dirName )
2018-03-13 15:28:34 -04:00
assert . NilError ( t , err )
2018-03-13 15:39:23 -04:00
2018-03-19 17:18:52 -04:00
cleanup := func ( ) {
2018-03-22 17:11:03 -04:00
t . Helper ( )
2018-03-13 15:39:23 -04:00
err := os . RemoveAll ( dir )
2018-03-13 15:28:34 -04:00
assert . Check ( t , err )
2018-03-13 15:39:23 -04:00
}
2018-03-22 17:11:03 -04:00
s , err := NewStore ( dir , volumedrivers . NewStore ( nil ) )
2018-03-13 15:28:34 -04:00
assert . Check ( t , err )
2018-03-19 17:18:52 -04:00
return s , func ( ) {
2018-03-13 15:39:23 -04:00
s . Shutdown ( )
2018-03-19 17:18:52 -04:00
cleanup ( )
2018-03-13 15:39:23 -04:00
}
}
2018-03-22 17:11:03 -04:00
func TestFilterFunc ( t * testing . T ) {
testDriver := volumetestutils . NewFakeDriver ( "test" )
testVolume , err := testDriver . Create ( "test" , nil )
assert . NilError ( t , err )
testVolume2 , err := testDriver . Create ( "test2" , nil )
assert . NilError ( t , err )
testVolume3 , err := testDriver . Create ( "test3" , nil )
assert . NilError ( t , err )
for _ , test := range [ ] struct {
vols [ ] volume . Volume
fn filterFunc
desc string
expect [ ] volume . Volume
} {
{ desc : "test nil list" , vols : nil , expect : nil , fn : func ( volume . Volume ) bool { return true } } ,
{ desc : "test empty list" , vols : [ ] volume . Volume { } , expect : [ ] volume . Volume { } , fn : func ( volume . Volume ) bool { return true } } ,
{ desc : "test filter non-empty to empty" , vols : [ ] volume . Volume { testVolume } , expect : [ ] volume . Volume { } , fn : func ( volume . Volume ) bool { return false } } ,
{ desc : "test nothing to fitler non-empty list" , vols : [ ] volume . Volume { testVolume } , expect : [ ] volume . Volume { testVolume } , fn : func ( volume . Volume ) bool { return true } } ,
{ desc : "test filter some" , vols : [ ] volume . Volume { testVolume , testVolume2 } , expect : [ ] volume . Volume { testVolume } , fn : func ( v volume . Volume ) bool { return v . Name ( ) == testVolume . Name ( ) } } ,
{ desc : "test filter middle" , vols : [ ] volume . Volume { testVolume , testVolume2 , testVolume3 } , expect : [ ] volume . Volume { testVolume , testVolume3 } , fn : func ( v volume . Volume ) bool { return v . Name ( ) != testVolume2 . Name ( ) } } ,
{ desc : "test filter middle and last" , vols : [ ] volume . Volume { testVolume , testVolume2 , testVolume3 } , expect : [ ] volume . Volume { testVolume } , fn : func ( v volume . Volume ) bool { return v . Name ( ) != testVolume2 . Name ( ) && v . Name ( ) != testVolume3 . Name ( ) } } ,
{ desc : "test filter first and last" , vols : [ ] volume . Volume { testVolume , testVolume2 , testVolume3 } , expect : [ ] volume . Volume { testVolume2 } , fn : func ( v volume . Volume ) bool { return v . Name ( ) != testVolume . Name ( ) && v . Name ( ) != testVolume3 . Name ( ) } } ,
} {
t . Run ( test . desc , func ( t * testing . T ) {
test := test
t . Parallel ( )
filter ( & test . vols , test . fn )
assert . DeepEqual ( t , test . vols , test . expect , cmpVolume )
} )
}
}