mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:24:18 -04:00
215 lines
6.3 KiB
Go
215 lines
6.3 KiB
Go
//go:build windows || darwin
|
|
|
|
package updatemanager
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path"
|
|
"testing"
|
|
"time"
|
|
|
|
v "github.com/hashicorp/go-version"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/peer"
|
|
"github.com/netbirdio/netbird/client/internal/statemanager"
|
|
)
|
|
|
|
type versionUpdateMock struct {
|
|
latestVersion *v.Version
|
|
onUpdate func()
|
|
}
|
|
|
|
func (v versionUpdateMock) StopWatch() {}
|
|
|
|
func (v versionUpdateMock) SetDaemonVersion(newVersion string) bool {
|
|
return false
|
|
}
|
|
|
|
func (v *versionUpdateMock) SetOnUpdateListener(updateFn func()) {
|
|
v.onUpdate = updateFn
|
|
}
|
|
|
|
func (v versionUpdateMock) LatestVersion() *v.Version {
|
|
return v.latestVersion
|
|
}
|
|
|
|
func (v versionUpdateMock) StartFetcher() {}
|
|
|
|
func Test_LatestVersion(t *testing.T) {
|
|
testMatrix := []struct {
|
|
name string
|
|
daemonVersion string
|
|
initialLatestVersion *v.Version
|
|
latestVersion *v.Version
|
|
shouldUpdateInit bool
|
|
shouldUpdateLater bool
|
|
}{
|
|
{
|
|
name: "Should only trigger update once due to time between triggers being < 5 Minutes",
|
|
daemonVersion: "1.0.0",
|
|
initialLatestVersion: v.Must(v.NewSemver("1.0.1")),
|
|
latestVersion: v.Must(v.NewSemver("1.0.2")),
|
|
shouldUpdateInit: true,
|
|
shouldUpdateLater: false,
|
|
},
|
|
{
|
|
name: "Shouldn't update initially, but should update as soon as latest version is fetched",
|
|
daemonVersion: "1.0.0",
|
|
initialLatestVersion: nil,
|
|
latestVersion: v.Must(v.NewSemver("1.0.1")),
|
|
shouldUpdateInit: false,
|
|
shouldUpdateLater: true,
|
|
},
|
|
}
|
|
|
|
for idx, c := range testMatrix {
|
|
mockUpdate := &versionUpdateMock{latestVersion: c.initialLatestVersion}
|
|
tmpFile := path.Join(t.TempDir(), fmt.Sprintf("update-test-%d.json", idx))
|
|
m, _ := newManager(peer.NewRecorder(""), statemanager.New(tmpFile))
|
|
m.update = mockUpdate
|
|
|
|
targetVersionChan := make(chan string, 1)
|
|
|
|
m.triggerUpdateFn = func(ctx context.Context, targetVersion string) error {
|
|
targetVersionChan <- targetVersion
|
|
return nil
|
|
}
|
|
m.currentVersion = c.daemonVersion
|
|
m.Start(context.Background())
|
|
m.SetVersion("latest")
|
|
var triggeredInit bool
|
|
select {
|
|
case targetVersion := <-targetVersionChan:
|
|
if targetVersion != c.initialLatestVersion.String() {
|
|
t.Errorf("%s: Initial update version mismatch, expected %v, got %v", c.name, c.initialLatestVersion.String(), targetVersion)
|
|
}
|
|
triggeredInit = true
|
|
case <-time.After(10 * time.Millisecond):
|
|
triggeredInit = false
|
|
}
|
|
if triggeredInit != c.shouldUpdateInit {
|
|
t.Errorf("%s: Initial update trigger mismatch, expected %v, got %v", c.name, c.shouldUpdateInit, triggeredInit)
|
|
}
|
|
|
|
mockUpdate.latestVersion = c.latestVersion
|
|
mockUpdate.onUpdate()
|
|
|
|
var triggeredLater bool
|
|
select {
|
|
case targetVersion := <-targetVersionChan:
|
|
if targetVersion != c.latestVersion.String() {
|
|
t.Errorf("%s: Update version mismatch, expected %v, got %v", c.name, c.latestVersion.String(), targetVersion)
|
|
}
|
|
triggeredLater = true
|
|
case <-time.After(10 * time.Millisecond):
|
|
triggeredLater = false
|
|
}
|
|
if triggeredLater != c.shouldUpdateLater {
|
|
t.Errorf("%s: Update trigger mismatch, expected %v, got %v", c.name, c.shouldUpdateLater, triggeredLater)
|
|
}
|
|
|
|
m.Stop()
|
|
}
|
|
}
|
|
|
|
func Test_HandleUpdate(t *testing.T) {
|
|
testMatrix := []struct {
|
|
name string
|
|
daemonVersion string
|
|
latestVersion *v.Version
|
|
expectedVersion string
|
|
shouldUpdate bool
|
|
}{
|
|
{
|
|
name: "Update to a specific version should update regardless of if latestVersion is available yet",
|
|
daemonVersion: "0.55.0",
|
|
latestVersion: nil,
|
|
expectedVersion: "0.56.0",
|
|
shouldUpdate: true,
|
|
},
|
|
{
|
|
name: "Update to specific version should not update if version matches",
|
|
daemonVersion: "0.55.0",
|
|
latestVersion: nil,
|
|
expectedVersion: "0.55.0",
|
|
shouldUpdate: false,
|
|
},
|
|
{
|
|
name: "Update to specific version should not update if current version is newer",
|
|
daemonVersion: "0.55.0",
|
|
latestVersion: nil,
|
|
expectedVersion: "0.54.0",
|
|
shouldUpdate: false,
|
|
},
|
|
{
|
|
name: "Update to latest version should update if latest is newer",
|
|
daemonVersion: "0.55.0",
|
|
latestVersion: v.Must(v.NewSemver("0.56.0")),
|
|
expectedVersion: "latest",
|
|
shouldUpdate: true,
|
|
},
|
|
{
|
|
name: "Update to latest version should not update if latest == current",
|
|
daemonVersion: "0.56.0",
|
|
latestVersion: v.Must(v.NewSemver("0.56.0")),
|
|
expectedVersion: "latest",
|
|
shouldUpdate: false,
|
|
},
|
|
{
|
|
name: "Should not update if daemon version is invalid",
|
|
daemonVersion: "development",
|
|
latestVersion: v.Must(v.NewSemver("1.0.0")),
|
|
expectedVersion: "latest",
|
|
shouldUpdate: false,
|
|
},
|
|
{
|
|
name: "Should not update if expecting latest and latest version is unavailable",
|
|
daemonVersion: "0.55.0",
|
|
latestVersion: nil,
|
|
expectedVersion: "latest",
|
|
shouldUpdate: false,
|
|
},
|
|
{
|
|
name: "Should not update if expected version is invalid",
|
|
daemonVersion: "0.55.0",
|
|
latestVersion: nil,
|
|
expectedVersion: "development",
|
|
shouldUpdate: false,
|
|
},
|
|
}
|
|
for idx, c := range testMatrix {
|
|
tmpFile := path.Join(t.TempDir(), fmt.Sprintf("update-test-%d.json", idx))
|
|
m, _ := newManager(peer.NewRecorder(""), statemanager.New(tmpFile))
|
|
m.update = &versionUpdateMock{latestVersion: c.latestVersion}
|
|
targetVersionChan := make(chan string, 1)
|
|
|
|
m.triggerUpdateFn = func(ctx context.Context, targetVersion string) error {
|
|
targetVersionChan <- targetVersion
|
|
return nil
|
|
}
|
|
|
|
m.currentVersion = c.daemonVersion
|
|
m.Start(context.Background())
|
|
m.SetVersion(c.expectedVersion)
|
|
|
|
var updateTriggered bool
|
|
select {
|
|
case targetVersion := <-targetVersionChan:
|
|
if c.expectedVersion == "latest" && targetVersion != c.latestVersion.String() {
|
|
t.Errorf("%s: Update version mismatch, expected %v, got %v", c.name, c.latestVersion.String(), targetVersion)
|
|
} else if c.expectedVersion != "latest" && targetVersion != c.expectedVersion {
|
|
t.Errorf("%s: Update version mismatch, expected %v, got %v", c.name, c.expectedVersion, targetVersion)
|
|
}
|
|
updateTriggered = true
|
|
case <-time.After(10 * time.Millisecond):
|
|
updateTriggered = false
|
|
}
|
|
|
|
if updateTriggered != c.shouldUpdate {
|
|
t.Errorf("%s: Update trigger mismatch, expected %v, got %v", c.name, c.shouldUpdate, updateTriggered)
|
|
}
|
|
m.Stop()
|
|
}
|
|
}
|