814 lines
31 KiB
Go
814 lines
31 KiB
Go
/*
|
|
* Copyright 2025 The Dragonfly Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package persistentcache
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/go-redis/redismock/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/mock/gomock"
|
|
|
|
logger "d7y.io/dragonfly/v2/internal/dflog"
|
|
"d7y.io/dragonfly/v2/pkg/container/set"
|
|
pkgredis "d7y.io/dragonfly/v2/pkg/redis"
|
|
pkgtypes "d7y.io/dragonfly/v2/pkg/types"
|
|
"d7y.io/dragonfly/v2/scheduler/config"
|
|
)
|
|
|
|
func TestHostManager_Load(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
hostID string
|
|
mockRedis func(mock redismock.ClientMock)
|
|
expectedHost *Host
|
|
expectedLoaded bool
|
|
expectedError bool
|
|
errorMsg string
|
|
}{
|
|
{
|
|
name: "host exists in Redis",
|
|
hostID: "host1",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host1",
|
|
"type": "normal",
|
|
"hostname": "hostname1",
|
|
"ip": "127.0.0.1",
|
|
"port": "8080",
|
|
"download_port": "8081",
|
|
"disable_shared": "false",
|
|
"os": "linux",
|
|
"platform": "x86_64",
|
|
"platform_family": "debian",
|
|
"platform_version": "11",
|
|
"kernel_version": "5.10",
|
|
"cpu_logical_count": "4",
|
|
"cpu_physical_count": "2",
|
|
"cpu_percent": "50.0",
|
|
"cpu_processe_percent": "25.0",
|
|
"cpu_times_user": "10.0",
|
|
"cpu_times_system": "5.0",
|
|
"cpu_times_idle": "100.0",
|
|
"cpu_times_nice": "0.0",
|
|
"cpu_times_iowait": "1.0",
|
|
"cpu_times_irq": "0.5",
|
|
"cpu_times_softirq": "0.2",
|
|
"cpu_times_steal": "0.1",
|
|
"cpu_times_guest": "0.0",
|
|
"cpu_times_guest_nice": "0.0",
|
|
"memory_total": "8000000000",
|
|
"memory_available": "4000000000",
|
|
"memory_used": "4000000000",
|
|
"memory_used_percent": "50.0",
|
|
"memory_processe_used_percent": "25.0",
|
|
"memory_free": "2000000000",
|
|
"network_tcp_connection_count": "100",
|
|
"network_upload_tcp_connection_count": "50",
|
|
"network_location": "location1",
|
|
"network_idc": "idc1",
|
|
"network_download_rate": "1000000",
|
|
"network_download_rate_limit": "2000000",
|
|
"network_upload_rate": "500000",
|
|
"network_upload_rate_limit": "1000000",
|
|
"disk_total": "100000000000",
|
|
"disk_free": "50000000000",
|
|
"disk_used": "50000000000",
|
|
"disk_used_percent": "50.0",
|
|
"disk_inodes_total": "100000",
|
|
"disk_inodes_used": "50000",
|
|
"disk_inodes_free": "50000",
|
|
"disk_inodes_used_percent": "50.0",
|
|
"disk_write_bandwidth": "10000000",
|
|
"disk_read_bandwidth": "20000000",
|
|
"build_git_version": "v1.0.0",
|
|
"build_git_commit": "commit1",
|
|
"build_go_version": "1.16",
|
|
"build_platform": "linux/amd64",
|
|
"scheduler_cluster_id": "1",
|
|
"announce_interval": "300",
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
"updated_at": time.Now().Format(time.RFC3339),
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host1")).SetVal(mockData)
|
|
},
|
|
expectedHost: &Host{
|
|
ID: "host1",
|
|
Type: pkgtypes.HostTypeNormal,
|
|
Hostname: "hostname1",
|
|
IP: "127.0.0.1",
|
|
Port: 8080,
|
|
DownloadPort: 8081,
|
|
DisableShared: false,
|
|
OS: "linux",
|
|
Platform: "x86_64",
|
|
PlatformFamily: "debian",
|
|
PlatformVersion: "11",
|
|
KernelVersion: "5.10",
|
|
CPU: CPU{LogicalCount: 4, PhysicalCount: 2, Percent: 50.0, ProcessPercent: 25.0, Times: CPUTimes{User: 10.0, System: 5.0, Idle: 100.0, Nice: 0.0, Iowait: 1.0, Irq: 0.5, Softirq: 0.2, Steal: 0.1, Guest: 0.0, GuestNice: 0.0}},
|
|
Memory: Memory{Total: 8000000000, Available: 4000000000, Used: 4000000000, UsedPercent: 50.0, ProcessUsedPercent: 25.0, Free: 2000000000},
|
|
Network: Network{TCPConnectionCount: 100, UploadTCPConnectionCount: 50, Location: "location1", IDC: "idc1", DownloadRate: 1000000, DownloadRateLimit: 2000000, UploadRate: 500000, UploadRateLimit: 1000000},
|
|
Disk: Disk{Total: 100000000000, Free: 50000000000, Used: 50000000000, UsedPercent: 50.0, InodesTotal: 100000, InodesUsed: 50000, InodesFree: 50000, InodesUsedPercent: 50.0, WriteBandwidth: 10000000, ReadBandwidth: 20000000},
|
|
Build: Build{GitVersion: "v1.0.0", GitCommit: "commit1", GoVersion: "1.16", Platform: "linux/amd64"},
|
|
SchedulerClusterID: 1,
|
|
AnnounceInterval: time.Duration(300),
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
Log: logger.WithHost("host1", "hostname1", "127.0.0.1"),
|
|
},
|
|
expectedLoaded: true,
|
|
},
|
|
{
|
|
name: "host does not exist in Redis",
|
|
hostID: "host2",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host2")).SetVal(map[string]string{})
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
},
|
|
{
|
|
name: "redis returns an error",
|
|
hostID: "host3",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host3")).SetErr(fmt.Errorf("Redis error"))
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid port value",
|
|
hostID: "host4",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host4",
|
|
"port": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host4")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid scheduler_cluster_id value",
|
|
hostID: "host5",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host5",
|
|
"scheduler_cluster_id": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host5")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid disable_shared value",
|
|
hostID: "host6",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host6",
|
|
"disable_shared": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host6")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid cpu_logical_count value",
|
|
hostID: "host7",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host7",
|
|
"cpu_logical_count": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host7")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid cpu_percent value",
|
|
hostID: "host8",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host8",
|
|
"cpu_percent": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host8")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid memory_total value",
|
|
hostID: "host9",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host9",
|
|
"memory_total": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host9")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid network_tcp_connection_count value",
|
|
hostID: "host10",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host10",
|
|
"network_tcp_connection_count": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host10")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid disk_total value",
|
|
hostID: "host11",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host11",
|
|
"disk_total": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host11")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid announce_interval value",
|
|
hostID: "host12",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host12",
|
|
"announce_interval": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host12")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid created_at value",
|
|
hostID: "host13",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host13",
|
|
"created_at": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host13")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "invalid updated_at value",
|
|
hostID: "host14",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mockData := map[string]string{
|
|
"id": "host14",
|
|
"updated_at": "invalid",
|
|
}
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host14")).SetVal(mockData)
|
|
},
|
|
expectedHost: nil,
|
|
expectedLoaded: false,
|
|
expectedError: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
rdb, mock := redismock.NewClientMock()
|
|
tt.mockRedis(mock)
|
|
|
|
h := &hostManager{
|
|
config: &config.Config{
|
|
Manager: config.ManagerConfig{
|
|
SchedulerClusterID: 1,
|
|
},
|
|
},
|
|
rdb: rdb,
|
|
}
|
|
|
|
host, loaded := h.Load(context.Background(), tt.hostID)
|
|
if tt.expectedError {
|
|
assert.Error(t, nil)
|
|
assert.Contains(t, "", tt.errorMsg)
|
|
} else {
|
|
assert.NoError(t, nil)
|
|
}
|
|
|
|
if tt.expectedLoaded {
|
|
assert.NotNil(t, host)
|
|
assert.Equal(t, tt.expectedHost.ID, host.ID)
|
|
assert.Equal(t, tt.expectedHost.Type, host.Type)
|
|
assert.Equal(t, tt.expectedHost.Hostname, host.Hostname)
|
|
assert.Equal(t, tt.expectedHost.IP, host.IP)
|
|
assert.Equal(t, tt.expectedHost.Port, host.Port)
|
|
assert.Equal(t, tt.expectedHost.DownloadPort, host.DownloadPort)
|
|
assert.Equal(t, tt.expectedHost.DisableShared, host.DisableShared)
|
|
assert.Equal(t, tt.expectedHost.OS, host.OS)
|
|
assert.Equal(t, tt.expectedHost.Platform, host.Platform)
|
|
assert.Equal(t, tt.expectedHost.PlatformFamily, host.PlatformFamily)
|
|
assert.Equal(t, tt.expectedHost.PlatformVersion, host.PlatformVersion)
|
|
assert.Equal(t, tt.expectedHost.KernelVersion, host.KernelVersion)
|
|
assert.Equal(t, tt.expectedHost.CPU, host.CPU)
|
|
assert.Equal(t, tt.expectedHost.Memory, host.Memory)
|
|
assert.Equal(t, tt.expectedHost.Network, host.Network)
|
|
assert.Equal(t, tt.expectedHost.Disk, host.Disk)
|
|
assert.Equal(t, tt.expectedHost.Build, host.Build)
|
|
assert.Equal(t, tt.expectedHost.SchedulerClusterID, host.SchedulerClusterID)
|
|
assert.Equal(t, tt.expectedHost.AnnounceInterval.Abs(), host.AnnounceInterval.Abs())
|
|
assert.Equal(t, tt.expectedHost.CreatedAt.Format(time.RFC3339), host.CreatedAt.Format(time.RFC3339))
|
|
assert.Equal(t, tt.expectedHost.UpdatedAt.Format(time.RFC3339), host.UpdatedAt.Format(time.RFC3339))
|
|
}
|
|
|
|
assert.Equal(t, tt.expectedLoaded, loaded)
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("there were unfulfilled expectations: %s", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostManager_LoadAll(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mockRedis func(mock redismock.ClientMock)
|
|
expectedError bool
|
|
expectedHosts int
|
|
}{
|
|
{
|
|
name: "scan fails",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectSScan(pkgredis.MakePersistentCacheHostsInScheduler(1), 0, "*", 10).
|
|
SetErr(fmt.Errorf("redis scan error"))
|
|
},
|
|
expectedError: true,
|
|
expectedHosts: 0,
|
|
},
|
|
{
|
|
name: "some hosts fail to load",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectSScan(pkgredis.MakePersistentCacheHostsInScheduler(1), 0, "*", 10).
|
|
SetVal([]string{"host1", "host2"}, 0)
|
|
// host1 loaded successfully
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host1")).
|
|
SetVal(map[string]string{
|
|
"id": "host1",
|
|
"type": "normal",
|
|
"hostname": "hostname1",
|
|
"ip": "127.0.0.1",
|
|
"port": "8080",
|
|
"download_port": "8081",
|
|
"disable_shared": "false",
|
|
"os": "linux",
|
|
"platform": "x86_64",
|
|
"platform_family": "debian",
|
|
"platform_version": "11",
|
|
"kernel_version": "5.10",
|
|
"cpu_logical_count": "4",
|
|
"cpu_physical_count": "2",
|
|
"cpu_percent": "50.0",
|
|
"cpu_processe_percent": "25.0",
|
|
"cpu_times_user": "10.0",
|
|
"cpu_times_system": "5.0",
|
|
"cpu_times_idle": "100.0",
|
|
"cpu_times_nice": "0.0",
|
|
"cpu_times_iowait": "1.0",
|
|
"cpu_times_irq": "0.5",
|
|
"cpu_times_softirq": "0.2",
|
|
"cpu_times_steal": "0.1",
|
|
"cpu_times_guest": "0.0",
|
|
"cpu_times_guest_nice": "0.0",
|
|
"memory_total": "8000000000",
|
|
"memory_available": "4000000000",
|
|
"memory_used": "4000000000",
|
|
"memory_used_percent": "50.0",
|
|
"memory_processe_used_percent": "25.0",
|
|
"memory_free": "2000000000",
|
|
"network_tcp_connection_count": "100",
|
|
"network_upload_tcp_connection_count": "50",
|
|
"network_location": "location1",
|
|
"network_idc": "idc1",
|
|
"network_download_rate": "1000000",
|
|
"network_download_rate_limit": "2000000",
|
|
"network_upload_rate": "500000",
|
|
"network_upload_rate_limit": "1000000",
|
|
"disk_total": "100000000000",
|
|
"disk_free": "50000000000",
|
|
"disk_used": "50000000000",
|
|
"disk_used_percent": "50.0",
|
|
"disk_inodes_total": "100000",
|
|
"disk_inodes_used": "50000",
|
|
"disk_inodes_free": "50000",
|
|
"disk_inodes_used_percent": "50.0",
|
|
"disk_write_bandwidth": "10000000",
|
|
"disk_read_bandwidth": "20000000",
|
|
"build_git_version": "v1.0.0",
|
|
"build_git_commit": "commit1",
|
|
"build_go_version": "1.16",
|
|
"build_platform": "linux/amd64",
|
|
"scheduler_cluster_id": "1",
|
|
"announce_interval": "0",
|
|
"updated_at": time.Now().Format(time.RFC3339),
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
})
|
|
// host2 load fails
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host2")).
|
|
SetErr(fmt.Errorf("redis hgetall error"))
|
|
},
|
|
expectedError: false,
|
|
expectedHosts: 1,
|
|
},
|
|
{
|
|
name: "multiple scans, all loaded successfully",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
// First scan
|
|
mock.ExpectSScan(pkgredis.MakePersistentCacheHostsInScheduler(1), 0, "*", 10).
|
|
SetVal([]string{"host3"}, 123)
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host3")).
|
|
SetVal(map[string]string{
|
|
"id": "host3",
|
|
"type": "normal",
|
|
"hostname": "hostname1",
|
|
"ip": "127.0.0.1",
|
|
"port": "8080",
|
|
"download_port": "8081",
|
|
"disable_shared": "false",
|
|
"os": "linux",
|
|
"platform": "x86_64",
|
|
"platform_family": "debian",
|
|
"platform_version": "11",
|
|
"kernel_version": "5.10",
|
|
"cpu_logical_count": "4",
|
|
"cpu_physical_count": "2",
|
|
"cpu_percent": "50.0",
|
|
"cpu_processe_percent": "25.0",
|
|
"cpu_times_user": "10.0",
|
|
"cpu_times_system": "5.0",
|
|
"cpu_times_idle": "100.0",
|
|
"cpu_times_nice": "0.0",
|
|
"cpu_times_iowait": "1.0",
|
|
"cpu_times_irq": "0.5",
|
|
"cpu_times_softirq": "0.2",
|
|
"cpu_times_steal": "0.1",
|
|
"cpu_times_guest": "0.0",
|
|
"cpu_times_guest_nice": "0.0",
|
|
"memory_total": "8000000000",
|
|
"memory_available": "4000000000",
|
|
"memory_used": "4000000000",
|
|
"memory_used_percent": "50.0",
|
|
"memory_processe_used_percent": "25.0",
|
|
"memory_free": "2000000000",
|
|
"network_tcp_connection_count": "100",
|
|
"network_upload_tcp_connection_count": "50",
|
|
"network_location": "location1",
|
|
"network_idc": "idc1",
|
|
"network_download_rate": "1000000",
|
|
"network_download_rate_limit": "2000000",
|
|
"network_upload_rate": "500000",
|
|
"network_upload_rate_limit": "1000000",
|
|
"disk_total": "100000000000",
|
|
"disk_free": "50000000000",
|
|
"disk_used": "50000000000",
|
|
"disk_used_percent": "50.0",
|
|
"disk_inodes_total": "100000",
|
|
"disk_inodes_used": "50000",
|
|
"disk_inodes_free": "50000",
|
|
"disk_inodes_used_percent": "50.0",
|
|
"disk_write_bandwidth": "10000000",
|
|
"disk_read_bandwidth": "20000000",
|
|
"build_git_version": "v1.0.0",
|
|
"build_git_commit": "commit1",
|
|
"build_go_version": "1.16",
|
|
"build_platform": "linux/amd64",
|
|
"scheduler_cluster_id": "1",
|
|
"announce_interval": "0",
|
|
"updated_at": time.Now().Format(time.RFC3339),
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
})
|
|
// Second scan
|
|
mock.ExpectSScan(pkgredis.MakePersistentCacheHostsInScheduler(1), 123, "*", 10).
|
|
SetVal([]string{"host4"}, 0)
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host4")).
|
|
SetVal(map[string]string{
|
|
"id": "host4",
|
|
"type": "normal",
|
|
"hostname": "hostname1",
|
|
"ip": "127.0.0.1",
|
|
"port": "8080",
|
|
"download_port": "8081",
|
|
"disable_shared": "false",
|
|
"os": "linux",
|
|
"platform": "x86_64",
|
|
"platform_family": "debian",
|
|
"platform_version": "11",
|
|
"kernel_version": "5.10",
|
|
"cpu_logical_count": "4",
|
|
"cpu_physical_count": "2",
|
|
"cpu_percent": "50.0",
|
|
"cpu_processe_percent": "25.0",
|
|
"cpu_times_user": "10.0",
|
|
"cpu_times_system": "5.0",
|
|
"cpu_times_idle": "100.0",
|
|
"cpu_times_nice": "0.0",
|
|
"cpu_times_iowait": "1.0",
|
|
"cpu_times_irq": "0.5",
|
|
"cpu_times_softirq": "0.2",
|
|
"cpu_times_steal": "0.1",
|
|
"cpu_times_guest": "0.0",
|
|
"cpu_times_guest_nice": "0.0",
|
|
"memory_total": "8000000000",
|
|
"memory_available": "4000000000",
|
|
"memory_used": "4000000000",
|
|
"memory_used_percent": "50.0",
|
|
"memory_processe_used_percent": "25.0",
|
|
"memory_free": "2000000000",
|
|
"network_tcp_connection_count": "100",
|
|
"network_upload_tcp_connection_count": "50",
|
|
"network_location": "location1",
|
|
"network_idc": "idc1",
|
|
"network_download_rate": "1000000",
|
|
"network_download_rate_limit": "2000000",
|
|
"network_upload_rate": "500000",
|
|
"network_upload_rate_limit": "1000000",
|
|
"disk_total": "100000000000",
|
|
"disk_free": "50000000000",
|
|
"disk_used": "50000000000",
|
|
"disk_used_percent": "50.0",
|
|
"disk_inodes_total": "100000",
|
|
"disk_inodes_used": "50000",
|
|
"disk_inodes_free": "50000",
|
|
"disk_inodes_used_percent": "50.0",
|
|
"disk_write_bandwidth": "10000000",
|
|
"disk_read_bandwidth": "20000000",
|
|
"build_git_version": "v1.0.0",
|
|
"build_git_commit": "commit1",
|
|
"build_go_version": "1.16",
|
|
"build_platform": "linux/amd64",
|
|
"scheduler_cluster_id": "1",
|
|
"announce_interval": "0",
|
|
"updated_at": time.Now().Format(time.RFC3339),
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
})
|
|
},
|
|
expectedError: false,
|
|
expectedHosts: 2,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
rdb, mock := redismock.NewClientMock()
|
|
tt.mockRedis(mock)
|
|
|
|
h := &hostManager{
|
|
config: &config.Config{
|
|
Manager: config.ManagerConfig{SchedulerClusterID: 1},
|
|
},
|
|
rdb: rdb,
|
|
}
|
|
|
|
hosts, err := h.LoadAll(context.Background())
|
|
if tt.expectedError {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.expectedHosts, len(hosts))
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("redis expectations were not met: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostManager_LoadRandom(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
n int
|
|
blocklist set.SafeSet[string]
|
|
mockRedis func(mock redismock.ClientMock)
|
|
expectedErr bool
|
|
expectedHostCount int
|
|
}{
|
|
{
|
|
name: "smembers fails",
|
|
n: 2,
|
|
blocklist: set.NewSafeSet[string](),
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectSMembers(pkgredis.MakePersistentCacheHostsInScheduler(1)).
|
|
SetErr(fmt.Errorf("redis error"))
|
|
},
|
|
expectedErr: true,
|
|
expectedHostCount: 0,
|
|
},
|
|
{
|
|
name: "some hosts in blocklist",
|
|
n: 3,
|
|
blocklist: func() set.SafeSet[string] {
|
|
s := set.NewSafeSet[string]()
|
|
s.Add("host1")
|
|
s.Add("host2")
|
|
s.Add("host3")
|
|
return s
|
|
}(),
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectSMembers(pkgredis.MakePersistentCacheHostsInScheduler(1)).
|
|
SetVal([]string{"host1", "host2", "host3"})
|
|
},
|
|
expectedErr: false,
|
|
expectedHostCount: 0, // host2 is skipped
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
rdb, mock := redismock.NewClientMock()
|
|
tt.mockRedis(mock)
|
|
|
|
h := &hostManager{
|
|
config: &config.Config{
|
|
Manager: config.ManagerConfig{
|
|
SchedulerClusterID: 1,
|
|
},
|
|
},
|
|
rdb: rdb,
|
|
}
|
|
|
|
hosts, err := h.LoadRandom(context.Background(), tt.n, tt.blocklist)
|
|
if tt.expectedErr {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
assert.Len(t, hosts, tt.expectedHostCount)
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("unmet redis expectations: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostManager_RunGC(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mockRedis func(mock redismock.ClientMock)
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "loadAll fails",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
mock.ExpectSScan(pkgredis.MakePersistentCacheHostsInScheduler(1), 0, "*", 10).
|
|
SetErr(fmt.Errorf("redis error"))
|
|
},
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "hosts found, none older than 2 intervals => no delete",
|
|
mockRedis: func(mock redismock.ClientMock) {
|
|
// Return a single host
|
|
mock.ExpectSScan(pkgredis.MakePersistentCacheHostsInScheduler(1), 0, "*", 10).
|
|
SetVal([]string{"host1"}, 0)
|
|
mock.ExpectHGetAll(pkgredis.MakePersistentCacheHostKeyInScheduler(1, "host1")).
|
|
SetVal(map[string]string{
|
|
"id": "host1",
|
|
"type": "normal",
|
|
"hostname": "hostname1",
|
|
"ip": "127.0.0.1",
|
|
"port": "8080",
|
|
"download_port": "8081",
|
|
"disable_shared": "false",
|
|
"os": "linux",
|
|
"platform": "x86_64",
|
|
"platform_family": "debian",
|
|
"platform_version": "11",
|
|
"kernel_version": "5.10",
|
|
"cpu_logical_count": "4",
|
|
"cpu_physical_count": "2",
|
|
"cpu_percent": "50.0",
|
|
"cpu_processe_percent": "25.0",
|
|
"cpu_times_user": "10.0",
|
|
"cpu_times_system": "5.0",
|
|
"cpu_times_idle": "100.0",
|
|
"cpu_times_nice": "0.0",
|
|
"cpu_times_iowait": "1.0",
|
|
"cpu_times_irq": "0.5",
|
|
"cpu_times_softirq": "0.2",
|
|
"cpu_times_steal": "0.1",
|
|
"cpu_times_guest": "0.0",
|
|
"cpu_times_guest_nice": "0.0",
|
|
"memory_total": "8000000000",
|
|
"memory_available": "4000000000",
|
|
"memory_used": "4000000000",
|
|
"memory_used_percent": "50.0",
|
|
"memory_processe_used_percent": "25.0",
|
|
"memory_free": "2000000000",
|
|
"network_tcp_connection_count": "100",
|
|
"network_upload_tcp_connection_count": "50",
|
|
"network_location": "location1",
|
|
"network_idc": "idc1",
|
|
"network_download_rate": "1000000",
|
|
"network_download_rate_limit": "2000000",
|
|
"network_upload_rate": "500000",
|
|
"network_upload_rate_limit": "1000000",
|
|
"disk_total": "100000000000",
|
|
"disk_free": "50000000000",
|
|
"disk_used": "50000000000",
|
|
"disk_used_percent": "50.0",
|
|
"disk_inodes_total": "100000",
|
|
"disk_inodes_used": "50000",
|
|
"disk_inodes_free": "50000",
|
|
"disk_inodes_used_percent": "50.0",
|
|
"disk_write_bandwidth": "10000000",
|
|
"disk_read_bandwidth": "20000000",
|
|
"build_git_version": "v1.0.0",
|
|
"build_git_commit": "commit1",
|
|
"build_go_version": "1.16",
|
|
"build_platform": "linux/amd64",
|
|
"scheduler_cluster_id": "1",
|
|
"announce_interval": "0",
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
"updated_at": time.Now().Format(time.RFC3339),
|
|
})
|
|
},
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
rdb, mock := redismock.NewClientMock()
|
|
tt.mockRedis(mock)
|
|
|
|
h := &hostManager{
|
|
config: &config.Config{
|
|
Manager: config.ManagerConfig{
|
|
SchedulerClusterID: 1,
|
|
},
|
|
},
|
|
rdb: rdb,
|
|
}
|
|
|
|
err := h.RunGC(context.Background())
|
|
if tt.expectErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Errorf("unmet redis expectations: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|