2023-04-10 15:36:59 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2018-11-27 04:40:55 +00:00
|
|
|
package pluginmanager
|
|
|
|
|
|
|
|
import (
|
2020-12-10 15:27:15 +00:00
|
|
|
"context"
|
2018-11-27 04:40:55 +00:00
|
|
|
"sync"
|
|
|
|
"testing"
|
2020-12-10 15:27:15 +00:00
|
|
|
"time"
|
2018-11-27 04:40:55 +00:00
|
|
|
|
2022-03-15 12:42:43 +00:00
|
|
|
"github.com/hashicorp/nomad/ci"
|
2018-11-27 04:40:55 +00:00
|
|
|
"github.com/hashicorp/nomad/helper/testlog"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestPluginGroup_RegisterAndRun(t *testing.T) {
|
2022-03-15 12:42:43 +00:00
|
|
|
ci.Parallel(t)
|
2018-11-27 04:40:55 +00:00
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
var hasRun bool
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
wg.Add(1)
|
2019-03-04 18:25:54 +00:00
|
|
|
manager := &MockPluginManager{RunF: func() {
|
2018-11-27 04:40:55 +00:00
|
|
|
hasRun = true
|
|
|
|
wg.Done()
|
|
|
|
}}
|
|
|
|
|
|
|
|
group := New(testlog.HCLogger(t))
|
2019-03-04 18:25:54 +00:00
|
|
|
require.NoError(group.RegisterAndRun(manager))
|
2018-11-27 04:40:55 +00:00
|
|
|
wg.Wait()
|
|
|
|
require.True(hasRun)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPluginGroup_Shutdown(t *testing.T) {
|
2022-03-15 12:42:43 +00:00
|
|
|
ci.Parallel(t)
|
2018-11-27 04:40:55 +00:00
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
var stack []int
|
|
|
|
var stackMu sync.Mutex
|
|
|
|
var runWg sync.WaitGroup
|
|
|
|
var shutdownWg sync.WaitGroup
|
|
|
|
group := New(testlog.HCLogger(t))
|
|
|
|
for i := 1; i < 4; i++ {
|
|
|
|
i := i
|
|
|
|
runWg.Add(1)
|
|
|
|
shutdownWg.Add(1)
|
2019-03-04 18:25:54 +00:00
|
|
|
manager := &MockPluginManager{RunF: func() {
|
2018-11-27 04:40:55 +00:00
|
|
|
stackMu.Lock()
|
|
|
|
defer stackMu.Unlock()
|
|
|
|
defer runWg.Done()
|
|
|
|
stack = append(stack, i)
|
|
|
|
}, ShutdownF: func() {
|
|
|
|
stackMu.Lock()
|
|
|
|
defer stackMu.Unlock()
|
|
|
|
defer shutdownWg.Done()
|
|
|
|
idx := len(stack) - 1
|
|
|
|
val := stack[idx]
|
|
|
|
require.Equal(i, val)
|
|
|
|
stack = stack[:idx]
|
|
|
|
}}
|
2019-03-04 18:25:54 +00:00
|
|
|
require.NoError(group.RegisterAndRun(manager))
|
2018-11-27 04:40:55 +00:00
|
|
|
runWg.Wait()
|
|
|
|
}
|
|
|
|
group.Shutdown()
|
|
|
|
shutdownWg.Wait()
|
|
|
|
require.Empty(stack)
|
|
|
|
|
|
|
|
require.Error(group.RegisterAndRun(&MockPluginManager{}))
|
|
|
|
}
|
2020-12-10 15:27:15 +00:00
|
|
|
|
|
|
|
func TestPluginGroup_WaitForFirstFingerprint(t *testing.T) {
|
2022-03-15 12:42:43 +00:00
|
|
|
ci.Parallel(t)
|
2020-12-10 15:27:15 +00:00
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
managerCh := make(chan struct{})
|
|
|
|
manager := &MockPluginManager{
|
|
|
|
RunF: func() {},
|
|
|
|
WaitForFirstFingerprintCh: managerCh,
|
|
|
|
}
|
|
|
|
|
|
|
|
// close immediately to beat the context timeout
|
|
|
|
close(managerCh)
|
|
|
|
|
|
|
|
group := New(testlog.HCLogger(t))
|
|
|
|
require.NoError(group.RegisterAndRun(manager))
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
groupCh, err := group.WaitForFirstFingerprint(ctx)
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-groupCh:
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
t.Fatal("expected groupCh to be closed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPluginGroup_WaitForFirstFingerprint_Timeout(t *testing.T) {
|
2022-03-15 12:42:43 +00:00
|
|
|
ci.Parallel(t)
|
2020-12-10 15:27:15 +00:00
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
managerCh := make(chan struct{})
|
|
|
|
manager := &MockPluginManager{
|
|
|
|
RunF: func() {},
|
|
|
|
WaitForFirstFingerprintCh: managerCh,
|
|
|
|
}
|
|
|
|
|
|
|
|
group := New(testlog.HCLogger(t))
|
|
|
|
require.NoError(group.RegisterAndRun(manager))
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
groupCh, err := group.WaitForFirstFingerprint(ctx)
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-groupCh:
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
t.Fatal("expected groupCh to be closed due to context timeout")
|
|
|
|
}
|
|
|
|
require.NoError(err)
|
|
|
|
}
|