-
Notifications
You must be signed in to change notification settings - Fork 619
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
211 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package deallocator | ||
|
||
import ( | ||
"context" | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
"time" | ||
|
||
"github.com/docker/swarmkit/api" | ||
"github.com/docker/swarmkit/manager/state/store" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDeallocatorInit(t *testing.T) { | ||
// start up the memory store | ||
s := store.NewMemoryStore(nil) | ||
require.NotNil(t, s) | ||
defer s.Close() | ||
|
||
// create a service that's pending deletion, with no tasks remaining | ||
// this one should be deleted by the deallocator | ||
// additionally, that service is using a network that's also marked for | ||
// deletion, and another that's not | ||
service1ID := "service1" | ||
network1ID := "network1" | ||
network2ID := "network2" | ||
service1 := newService(service1ID, true, network1ID, network2ID) | ||
network1 := newNetwork(network1ID, true) | ||
network2 := newNetwork(network2ID, false) | ||
|
||
// now let's create another service that's also pending deletion, but still | ||
// has one task associated with it (in any state) - and also uses a network | ||
// that's also marked for deletion | ||
// none of those should get deleted | ||
service2ID := "service2" | ||
network3ID := "network3" | ||
service2 := newService(service2ID, true, network3ID) | ||
network3 := newNetwork(network3ID, true) | ||
task1 := &api.Task{ | ||
ID: "task1", | ||
ServiceID: service2ID, | ||
} | ||
|
||
// let's also have a network that's pending deletion, | ||
// but isn't used by any existing service | ||
// this one should be gone after the init | ||
network4ID := "network4" | ||
network4 := newNetwork(network4ID, true) | ||
|
||
// and finally a network that's not pending deletion, not | ||
// used by any service | ||
network5ID := "network5" | ||
network5 := newNetwork(network5ID, false) | ||
|
||
err := s.Update(func(tx store.Tx) error { | ||
for _, service := range []*api.Service{service1, service2} { | ||
require.NoError(t, store.CreateService(tx, service)) | ||
} | ||
for _, network := range []*api.Network{network1, network2, network3, network4, network5} { | ||
require.NoError(t, store.CreateNetwork(tx, network)) | ||
} | ||
require.NoError(t, store.CreateTask(tx, task1)) | ||
return nil | ||
}) | ||
require.NoError(t, err, "Error setting up test fixtures") | ||
|
||
// create and start the deallocator | ||
deallocator := New(s) | ||
|
||
completed := make(chan struct{}) | ||
var returnValue error | ||
go func() { | ||
returnValue = deallocator.Run(context.Background()) | ||
// allows checking that `Run` does return after we've stopped | ||
close(completed) | ||
}() | ||
|
||
// and then stop it immediately - we're just interested in the init | ||
// phase for this test | ||
deallocator.Stop() | ||
|
||
// let's wait for it to stop - shouldn't take too long | ||
timeout := time.NewTimer(5 * time.Second) // TODO wkpo | ||
select { | ||
case <-completed: | ||
timeout.Stop() | ||
case <-timeout.C: | ||
t.Error("Waited for too long for the deallocator to stop, error from run") | ||
} | ||
require.NoError(t, returnValue) | ||
|
||
// now let's check that the DB is in the state we expect | ||
s.View(func(tx store.ReadTx) { | ||
assert.Nil(t, store.GetService(tx, service1ID)) | ||
assert.Nil(t, store.GetNetwork(tx, network1ID)) | ||
assert.NotNil(t, store.GetNetwork(tx, network2ID)) | ||
|
||
assert.NotNil(t, store.GetService(tx, service2ID)) | ||
assert.NotNil(t, store.GetNetwork(tx, network3ID)) | ||
}) | ||
} | ||
|
||
func newService(id string, pendingDelete bool, networkIDs ...string) *api.Service { | ||
return &api.Service{ | ||
ID: id, | ||
Spec: api.ServiceSpec{ | ||
Annotations: api.Annotations{ | ||
Name: id, | ||
}, | ||
Task: api.TaskSpec{ | ||
Networks: newNetworkConfigs(networkIDs...), | ||
}, | ||
}, | ||
PendingDelete: pendingDelete, | ||
} | ||
} | ||
|
||
func newNetwork(id string, pendingDelete bool) *api.Network { | ||
return &api.Network{ | ||
ID: id, | ||
Spec: api.NetworkSpec{ | ||
Annotations: api.Annotations{ | ||
Name: id, | ||
}, | ||
}, | ||
PendingDelete: pendingDelete, | ||
} | ||
} | ||
|
||
func newNetworkConfigs(networkIDs ...string) []*api.NetworkAttachmentConfig { | ||
networks := make([]*api.NetworkAttachmentConfig, len(networkIDs)) | ||
|
||
for i := 0; i < len(networkIDs); i++ { | ||
networks[i] = &api.NetworkAttachmentConfig{ | ||
Target: networkIDs[i], | ||
} | ||
} | ||
|
||
return networks | ||
} | ||
|
||
// TODO wkpo un test pour la vieille syntaxe de networks? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters