[management] use peer.Status.LastSeen field to detect stale peer.Status.Connected values (#7268)

This commit is contained in:
dmitri-netbird
2026-10-28 18:39:51 +01:00
committed by GitHub
parent 4ff3267542
commit dea73ff13f
20 changed files with 348 additions and 30 deletions
@@ -4,15 +4,19 @@ import (
"context"
"fmt"
"sync"
"sync/atomic"
"testing"
"testing/synctest"
"time"
pb "github.com/golang/protobuf/proto" //nolint
"github.com/netbirdio/netbird/management/internals/controllers/network_map"
"github.com/netbirdio/netbird/shared/management/proto"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"github.com/netbirdio/netbird/management/internals/controllers/network_map"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/shared/management/proto"
)
func TestSendPeerUpdates_FirstUpdate(t *testing.T) {
@@ -118,6 +122,61 @@ func TestSendPeerUpdates_ServerContextDone(t *testing.T) {
wg.Wait()
}
func TestSendPeerUpdates_HeartbeatOnlyOnInterval(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
ctrl := gomock.NewController(t)
secretsManager := NewMockSecretsManager(ctrl)
updateDebouncer := NewMockDebouncer(ctrl)
syncSender := NewMocksyncSender(ctrl)
var heartbeats atomic.Int32
pu := PeerUpdateHandler{
peerKey: mustGenerateKey(t),
updates: make(chan *network_map.UpdateMessage),
secretsManager: secretsManager,
encrypter: testEncrypter{},
debouncer: updateDebouncer,
srv: syncSender,
cleanupFunc: func() {},
heartbeat: func() { heartbeats.Add(1) },
}
msg := network_map.UpdateMessage{
Update: &proto.SyncResponse{Version: 1},
}
srvCtx, cancel := context.WithCancel(context.Background())
srvKey := mustGenerateKey(t)
updateDebouncer.EXPECT().ProcessUpdate(gomock.Eq(&msg)).Return(true)
updateDebouncer.EXPECT().TimerChannel().AnyTimes().Return(make(chan time.Time))
syncSender.EXPECT().Context().AnyTimes().Return(srvCtx)
secretsManager.EXPECT().GetWGKey().Return(srvKey, nil)
syncSender.EXPECT().Send(gomock.Any())
updateDebouncer.EXPECT().Stop()
done := make(chan struct{})
go func() {
defer close(done)
pu.HandleUpdates(context.Background()) //nolint:errcheck
}()
pu.updates <- &msg
synctest.Wait()
assert.Zero(t, heartbeats.Load(), "an update must not write a heartbeat")
time.Sleep(nbpeer.HeartbeatInterval)
synctest.Wait()
assert.Equal(t, int32(1), heartbeats.Load(), "one heartbeat per interval")
time.Sleep(nbpeer.HeartbeatInterval)
synctest.Wait()
assert.Equal(t, int32(2), heartbeats.Load(), "one heartbeat per interval")
cancel()
<-done
})
}
func mustGenerateKey(t *testing.T) wgtypes.Key {
t.Helper()
k, err := wgtypes.GenerateKey()