mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
* Move group into a separate helper module for reuse * Add shutdownCh to worker The shutdown channel is used to signal that worker has stopped. * Make server shutdown block on workers' shutdownCh * Fix waiting for eval broker state change blocking indefinitely There was a race condition in the GenericNotifier between the Run and WaitForChange functions, where WaitForChange blocks trying to write to a full unsubscribeCh, but the Run function never reads from the unsubscribeCh as it has already stopped. This commit fixes it by unblocking if the notifier has been stopped. * Bound the amount of time server shutdown waits on worker completion * Fix lostcancel linter error * Fix worker test using unexpected worker constructor * Add changelog --------- Co-authored-by: Marvin Chin <marvinchin@users.noreply.github.com>
64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package broker
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hashicorp/nomad/ci"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGenericNotifier(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
// Create the new notifier.
|
|
ctx, cancelFn := context.WithCancel(context.Background())
|
|
defer cancelFn()
|
|
|
|
notifier := NewGenericNotifier(ctx)
|
|
go notifier.Run()
|
|
|
|
// Ensure we have buffered channels.
|
|
require.Equal(t, 1, cap(notifier.publishCh))
|
|
require.Equal(t, 1, cap(notifier.subscribeCh))
|
|
require.Equal(t, 1, cap(notifier.unsubscribeCh))
|
|
|
|
// Test that the timeout works.
|
|
var timeoutWG sync.WaitGroup
|
|
|
|
for i := 0; i < 6; i++ {
|
|
go func(wg *sync.WaitGroup) {
|
|
wg.Add(1)
|
|
msg := notifier.WaitForChange(100 * time.Millisecond)
|
|
require.Equal(t, "wait timed out after 100ms", msg)
|
|
wg.Done()
|
|
}(&timeoutWG)
|
|
}
|
|
timeoutWG.Wait()
|
|
|
|
// Test that all subscribers receive an update when a single notification
|
|
// is sent.
|
|
var notifiedWG sync.WaitGroup
|
|
|
|
for i := 0; i < 6; i++ {
|
|
go func(wg *sync.WaitGroup) {
|
|
wg.Add(1)
|
|
msg := notifier.WaitForChange(3 * time.Second)
|
|
require.Equal(t, "we got an update and not a timeout", msg)
|
|
wg.Done()
|
|
}(¬ifiedWG)
|
|
}
|
|
|
|
// Ensure the routines have had time to start before sending the notify
|
|
// signal, otherwise the test is a flake.
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
notifier.Notify("we got an update and not a timeout")
|
|
notifiedWG.Wait()
|
|
}
|