mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 17:35:43 +03:00
* test: use statedb factory Swapping fields on Client after it has been created is a race. * test: lock before checking heartbeat state Fixes races * test: fix races by copying fsm objects A common source of data races in tests is when they insert a fixture directly into memdb and then later mutate the object. Since objects in the state store are readonly, any later mutation is a data race. * test: lock when peeking at eval stats * test: lock when peeking at serf state * test: lock when looking at stats * test: fix default eval broker state test The test was not applying the config callback. In addition the test raced against the configuration being applied. Waiting for the keyring to be initialized resolved the race in my testing, but given the high concurrency of the various leadership subsystems it's possible it may still flake.
74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package client
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hashicorp/nomad/ci"
|
|
"github.com/hashicorp/nomad/client/config"
|
|
"github.com/hashicorp/nomad/helper/uuid"
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
"github.com/hashicorp/nomad/testutil"
|
|
"github.com/shoenig/test/must"
|
|
)
|
|
|
|
func TestHeartbeatStop_allocHook(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
server, _, cleanupS1 := testServer(t, nil)
|
|
defer cleanupS1()
|
|
testutil.WaitForLeader(t, server.RPC)
|
|
|
|
client, cleanupC1 := TestClient(t, func(c *config.Config) {
|
|
c.RPCHandler = server
|
|
})
|
|
defer cleanupC1()
|
|
|
|
// an allocation, with a tiny lease
|
|
d := 1 * time.Microsecond
|
|
alloc := &structs.Allocation{
|
|
ID: uuid.Generate(),
|
|
TaskGroup: "foo",
|
|
Job: &structs.Job{
|
|
TaskGroups: []*structs.TaskGroup{
|
|
{
|
|
Name: "foo",
|
|
Disconnect: &structs.DisconnectStrategy{
|
|
StopOnClientAfter: &d,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Resources: &structs.Resources{
|
|
CPU: 100,
|
|
MemoryMB: 100,
|
|
DiskMB: 0,
|
|
},
|
|
}
|
|
|
|
// alloc added to heartbeatStop.allocs
|
|
err := client.addAlloc(alloc, "")
|
|
must.NoError(t, err)
|
|
testutil.WaitForResult(func() (bool, error) {
|
|
client.heartbeatLock.Lock()
|
|
_, ok := client.heartbeatStop.allocInterval[alloc.ID]
|
|
client.heartbeatLock.Unlock()
|
|
return ok, nil
|
|
}, func(err error) {
|
|
must.NoError(t, err)
|
|
})
|
|
|
|
// the tiny lease causes the watch loop to destroy it
|
|
testutil.WaitForResult(func() (bool, error) {
|
|
_, ok := client.heartbeatStop.allocInterval[alloc.ID]
|
|
return !ok, nil
|
|
}, func(err error) {
|
|
must.NoError(t, err)
|
|
})
|
|
|
|
must.Nil(t, client.allocs[alloc.ID])
|
|
}
|