From 67cc8bd655c46d7e96947fc2b591589939084bff Mon Sep 17 00:00:00 2001 From: bcmmbaga Date: Tue, 2 Jul 2024 12:57:42 +0300 Subject: [PATCH] add tests --- go.mod | 3 +- go.sum | 2 - management/server/hash.go | 80 ++++++++++++++++++++++------------ management/server/hash_test.go | 54 +++++++++++++++++++++++ management/server/peer/peer.go | 22 +++++----- 5 files changed, 119 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index ed9c40b10..c2c682b9f 100644 --- a/go.mod +++ b/go.mod @@ -67,10 +67,10 @@ require ( github.com/pion/transport/v3 v3.0.1 github.com/pion/turn/v3 v3.0.1 github.com/prometheus/client_golang v1.19.1 + github.com/r3labs/diff v1.1.0 github.com/rs/xid v1.3.0 github.com/shirou/gopsutil/v3 v3.24.4 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 - github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.31.0 github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 @@ -178,7 +178,6 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.15.0 // indirect - github.com/r3labs/diff v1.1.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 // indirect diff --git a/go.sum b/go.sum index eeeeaa2af..7fdac6f49 100644 --- a/go.sum +++ b/go.sum @@ -441,8 +441,6 @@ github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN2 github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= diff --git a/management/server/hash.go b/management/server/hash.go index f385f25c3..f26ca4717 100644 --- a/management/server/hash.go +++ b/management/server/hash.go @@ -1,6 +1,7 @@ package server import ( + "github.com/mitchellh/hashstructure/v2" "github.com/r3labs/diff" log "github.com/sirupsen/logrus" ) @@ -54,39 +55,64 @@ func updateAccountPeersWithHash(account *Account) { // log.Tracef("peer %s doesn't have a channel, skipping network map update", peer.ID) // continue //} + //33006042459 + // 8700718125 remotePeerNetworkMap := account.GetPeerNetworkMap(peer.ID, "netbird.io", approvedPeersMap) //log.Println("firewall rules: ", len(remotePeerNetworkMap.FirewallRules)) - //hashStr, err := hashstructure.Hash(remotePeerNetworkMap, hashstructure.FormatV2, &hashstructure.HashOptions{ - // ZeroNil: true, - // IgnoreZeroValue: true, - // SlicesAsSets: true, - // UseStringer: true, - // //Hasher: xxhash.New(), - //}) - //if err != nil { - // log.Errorf("failed to generate network map hash: %v", err) - //} else { - // if peer.NetworkMapHash == hashStr { - // //log.Debugf("not sending network map update to peer: %s as there is nothing new", peer.ID) - // skipUpdate++ - // continue - // } - // peer.NetworkMapHash = hashStr - //} - - if peer.NetworkMap == nil { - peer.NetworkMap = remotePeerNetworkMap + hashStr, err := hashstructure.Hash(remotePeerNetworkMap, hashstructure.FormatV2, &hashstructure.HashOptions{ + ZeroNil: true, + IgnoreZeroValue: true, + SlicesAsSets: true, + UseStringer: true, + //Hasher: xxhash.New(), + }) + if err != nil { + log.Errorf("failed to generate network map hash: %v", err) } else { - changelog, err := diff.Diff(peer.NetworkMap, remotePeerNetworkMap) - if err != nil { - log.Errorf("failed to generate network map diff: %v", err) - } else { - if len(changelog) == 0 { - continue - } + if peer.NetworkMapHash == hashStr { + //log.Debugf("not sending network map update to peer: %s as there is nothing new", peer.ID) + //skipUpdate++ + continue } + peer.NetworkMapHash = hashStr + } + } +} + +func updateAccountPeersWithDiff(account *Account) { + //start := time.Now() + //var skipUpdate int + //defer func() { + // duration := time.Since(start) + // log.Printf("Finished execution of updateAccountPeers, took %v\n", duration.Nanoseconds()) + // log.Println("not updated peers: ", skipUpdate) + //}() + + peers := account.GetPeers() + approvedPeersMap := make(map[string]struct{}, len(peers)) + for _, peer := range peers { + approvedPeersMap[peer.ID] = struct{}{} + } + + for _, peer := range peers { + //if !am.peersUpdateManager.HasChannel(peer.ID) { + // log.Tracef("peer %s doesn't have a channel, skipping network map update", peer.ID) + // continue + //} + //33006042459 + // 8700718125 + + remotePeerNetworkMap := account.GetPeerNetworkMap(peer.ID, "netbird.io", approvedPeersMap) + peer.NetworkMap = remotePeerNetworkMap + changelog, err := diff.Diff(peer.NetworkMap, remotePeerNetworkMap) + if err != nil { + log.Errorf("failed to generate network map diff: %v", err) + } else { + if len(changelog) == 0 { + continue + } } } } diff --git a/management/server/hash_test.go b/management/server/hash_test.go index 8e2e6ca7e..e74de214a 100644 --- a/management/server/hash_test.go +++ b/management/server/hash_test.go @@ -159,6 +159,15 @@ func BenchmarkTest_updateAccountPeersWithHash100(b *testing.B) { } } +func BenchmarkTest_updateAccountPeersWithDiff100(b *testing.B) { + account := initTestAccount(b, 100) + b.ResetTimer() + for i := 0; i < b.N; i++ { + log.Debug(i) + updateAccountPeersWithDiff(account) + } +} + // 1000 - 6717416375 ns/op // 500 - 1732888875 ns/op func BenchmarkTest_updateAccountPeers200(b *testing.B) { @@ -180,6 +189,15 @@ func BenchmarkTest_updateAccountPeersWithHash200(b *testing.B) { } } +func BenchmarkTest_updateAccountPeersWithDiff200(b *testing.B) { + account := initTestAccount(b, 200) + b.ResetTimer() + for i := 0; i < b.N; i++ { + log.Debug(i) + updateAccountPeersWithDiff(account) + } +} + func BenchmarkTest_updateAccountPeers500(b *testing.B) { account := initTestAccount(b, 500) b.ResetTimer() @@ -199,6 +217,15 @@ func BenchmarkTest_updateAccountPeersWithHash500(b *testing.B) { } } +func BenchmarkTest_updateAccountPeersWithDiff500(b *testing.B) { + account := initTestAccount(b, 500) + b.ResetTimer() + for i := 0; i < b.N; i++ { + log.Debug(i) + updateAccountPeersWithDiff(account) + } +} + func BenchmarkTest_updateAccountPeers1000(b *testing.B) { account := initTestAccount(b, 1000) b.ResetTimer() @@ -218,6 +245,15 @@ func BenchmarkTest_updateAccountPeersWithHash1000(b *testing.B) { } } +func BenchmarkTest_updateAccountPeersWithDiff1000(b *testing.B) { + account := initTestAccount(b, 1000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + log.Debug(i) + updateAccountPeersWithDiff(account) + } +} + func BenchmarkTest_updateAccountPeers1500(b *testing.B) { account := initTestAccount(b, 1500) b.ResetTimer() @@ -237,6 +273,15 @@ func BenchmarkTest_updateAccountPeersWithHash1500(b *testing.B) { } } +func BenchmarkTest_updateAccountPeersWithDiff1500(b *testing.B) { + account := initTestAccount(b, 1500) + b.ResetTimer() + for i := 0; i < b.N; i++ { + log.Debug(i) + updateAccountPeersWithDiff(account) + } +} + func BenchmarkTest_updateAccountPeers2000(b *testing.B) { account := initTestAccount(b, 2000) b.ResetTimer() @@ -255,3 +300,12 @@ func BenchmarkTest_updateAccountPeersWithHash2000(b *testing.B) { updateAccountPeersWithHash(account) } } + +func BenchmarkTest_updateAccountPeersWithDiff2000(b *testing.B) { + account := initTestAccount(b, 2000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + log.Debug(i) + updateAccountPeersWithDiff(account) + } +} diff --git a/management/server/peer/peer.go b/management/server/peer/peer.go index 4a71c28ee..342373ea3 100644 --- a/management/server/peer/peer.go +++ b/management/server/peer/peer.go @@ -18,38 +18,38 @@ type Peer struct { // WireGuard public key Key string `gorm:"index"` // A setup key this peer was registered with - SetupKey string `diff:"-"` + SetupKey string `diff:"-" hash:"ignore"` // IP address of the Peer IP net.IP `gorm:"serializer:json"` // Meta is a Peer system meta data - Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_" diff:"-"` + Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_" diff:"-" hash:"ignore"` // Name is peer's name (machine name) Name string // DNSLabel is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's // domain to the peer label. e.g. peer-dns-label.netbird.cloud DNSLabel string // Status peer's management connection status - Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_" diff:"-"` + Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_" diff:"-" hash:"ignore"` // The user ID that registered the peer - UserID string `diff:"-"` + UserID string `diff:"-" hash:"ignore"` // SSHKey is a public SSH key of the peer SSHKey string // SSHEnabled indicates whether SSH server is enabled on the peer SSHEnabled bool // LoginExpirationEnabled indicates whether peer's login expiration is enabled and once expired the peer has to re-login. // Works with LastLogin - LoginExpirationEnabled bool `diff:"-"` + LoginExpirationEnabled bool `diff:"-" hash:"ignore"` // LastLogin the time when peer performed last login operation - LastLogin time.Time `diff:"-"` + LastLogin time.Time `diff:"-" hash:"ignore"` // CreatedAt records the time the peer was created - CreatedAt time.Time `diff:"-"` + CreatedAt time.Time `diff:"-" hash:"ignore"` // Indicate ephemeral peer attribute - Ephemeral bool `diff:"-"` + Ephemeral bool `diff:"-" hash:"ignore"` // Geo location based on connection IP - Location Location `gorm:"embedded;embeddedPrefix:location_" diff:"-"` + Location Location `gorm:"embedded;embeddedPrefix:location_" diff:"-" hash:"ignore"` - NetworkMap any `diff:"-"` - //NetworkMapHash uint64 `hash:"ignore"` + NetworkMap any `diff:"-" hash:"ignore"` + NetworkMapHash uint64 ` diff:"-" hash:"ignore"` } type PeerStatus struct { //nolint:revive