2019-10-22 13:20:26 +00:00
|
|
|
package csimanager
|
|
|
|
|
|
|
|
import (
|
2020-03-19 21:09:49 +00:00
|
|
|
"context"
|
|
|
|
"sync"
|
2019-10-22 13:20:26 +00:00
|
|
|
"testing"
|
2020-03-19 21:09:49 +00:00
|
|
|
"time"
|
2019-10-22 13:20:26 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/nomad/client/dynamicplugins"
|
|
|
|
"github.com/hashicorp/nomad/helper/testlog"
|
2020-03-19 21:09:49 +00:00
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
"github.com/hashicorp/nomad/plugins/csi"
|
2019-10-22 13:20:26 +00:00
|
|
|
"github.com/hashicorp/nomad/plugins/csi/fake"
|
2020-03-19 21:09:49 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-10-22 13:20:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func setupTestNodeInstanceManager(t *testing.T) (*fake.Client, *instanceManager) {
|
|
|
|
tp := &fake.Client{}
|
|
|
|
|
|
|
|
logger := testlog.HCLogger(t)
|
|
|
|
pinfo := &dynamicplugins.PluginInfo{
|
|
|
|
Name: "test-plugin",
|
|
|
|
}
|
|
|
|
|
|
|
|
return tp, &instanceManager{
|
2020-01-08 12:47:07 +00:00
|
|
|
logger: logger,
|
|
|
|
info: pinfo,
|
|
|
|
client: tp,
|
|
|
|
fp: &pluginFingerprinter{
|
2020-03-19 21:09:49 +00:00
|
|
|
logger: logger.Named("fingerprinter"),
|
|
|
|
info: pinfo,
|
|
|
|
client: tp,
|
|
|
|
fingerprintNode: true,
|
|
|
|
hadFirstSuccessfulFingerprintCh: make(chan struct{}),
|
2019-10-22 13:20:26 +00:00
|
|
|
},
|
2019-12-18 12:24:39 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-19 21:09:49 +00:00
|
|
|
|
|
|
|
func TestInstanceManager_Shutdown(t *testing.T) {
|
|
|
|
|
|
|
|
var pluginHealth bool
|
|
|
|
var lock sync.Mutex
|
|
|
|
ctx, cancelFn := context.WithCancel(context.Background())
|
|
|
|
client, im := setupTestNodeInstanceManager(t)
|
|
|
|
im.shutdownCtx = ctx
|
|
|
|
im.shutdownCtxCancelFn = cancelFn
|
|
|
|
im.shutdownCh = make(chan struct{})
|
|
|
|
im.updater = func(_ string, info *structs.CSIInfo) {
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
|
|
|
pluginHealth = info.Healthy
|
|
|
|
}
|
|
|
|
|
|
|
|
// set up a mock successful fingerprint so that we can get
|
|
|
|
// a healthy plugin before shutting down
|
|
|
|
client.NextPluginGetCapabilitiesResponse = &csi.PluginCapabilitySet{}
|
|
|
|
client.NextPluginGetCapabilitiesErr = nil
|
|
|
|
client.NextNodeGetInfoResponse = &csi.NodeGetInfoResponse{NodeID: "foo"}
|
|
|
|
client.NextNodeGetInfoErr = nil
|
|
|
|
client.NextNodeGetCapabilitiesResponse = &csi.NodeCapabilitySet{}
|
|
|
|
client.NextNodeGetCapabilitiesErr = nil
|
|
|
|
client.NextPluginProbeResponse = true
|
|
|
|
|
|
|
|
go im.runLoop()
|
|
|
|
|
|
|
|
require.Eventually(t, func() bool {
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
|
|
|
return pluginHealth
|
|
|
|
}, 1*time.Second, 10*time.Millisecond)
|
|
|
|
|
|
|
|
cancelFn() // fires im.shutdown()
|
|
|
|
|
|
|
|
require.Eventually(t, func() bool {
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
|
|
|
return !pluginHealth
|
|
|
|
}, 1*time.Second, 10*time.Millisecond)
|
|
|
|
|
|
|
|
}
|