package csimanager import ( "context" "sync" "testing" "time" "github.com/hashicorp/nomad/client/dynamicplugins" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/csi" "github.com/hashicorp/nomad/plugins/csi/fake" "github.com/stretchr/testify/require" ) func setupTestNodeInstanceManager(t *testing.T) (*fake.Client, *instanceManager) { tp := &fake.Client{} logger := testlog.HCLogger(t) pinfo := &dynamicplugins.PluginInfo{ Name: "test-plugin", } return tp, &instanceManager{ logger: logger, info: pinfo, client: tp, fp: &pluginFingerprinter{ logger: logger.Named("fingerprinter"), info: pinfo, client: tp, fingerprintNode: true, hadFirstSuccessfulFingerprintCh: make(chan struct{}), }, } } 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) }