完善 channel create 测试用例

This commit is contained in:
2025-04-03 16:39:57 +08:00
parent 175f55c24f
commit 9d8850aec1
4 changed files with 489 additions and 78 deletions

View File

@@ -20,6 +20,8 @@
- [ ] Limiter
- [ ] Compress
业务代码和测试代码共用的控制变量可以优化为环境变量
channel 优化:
- 重新梳理逻辑流程,简化循环
- 端口分配时加锁

26
pkg/testutil/tools.go Normal file
View File

@@ -0,0 +1,26 @@
package testutil
import (
"reflect"
"sort"
)
// SliceEqual 检查两个字符串切片是否完全相等(忽略顺序)
func SliceEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
// 复制切片以避免修改原始数据
aCopy := make([]string, len(a))
bCopy := make([]string, len(b))
copy(aCopy, a)
copy(bCopy, b)
// 排序两个切片
sort.Strings(aCopy)
sort.Strings(bCopy)
// 比较排序后的切片
return reflect.DeepEqual(aCopy, bCopy)
}

View File

@@ -269,7 +269,8 @@ func (s *channelService) CreateChannel(
Scan(&resource)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return ChannelServiceErr("套餐不存在")
// 禁止 id 猜测
return ChannelServiceErr("无权限访问")
}
return err
}
@@ -417,7 +418,7 @@ func assignEdge(q *q.Query, count int, filter NodeFilterConfig) (*AssignEdgeResu
for i, proxy := range proxies {
proxyIds[i] = proxy.ID
}
channels, err := q.Channel.
channels, err := q.Channel.Debug().
Select(
q.Channel.ProxyID,
q.Channel.ProxyPort).
@@ -661,8 +662,6 @@ func assignPort(
Omit(
q.Channel.NodeID,
q.Channel.NodeHost,
q.Channel.Username,
q.Channel.Password,
q.Channel.DeletedAt,
).
Save(channels...)

View File

@@ -7,7 +7,7 @@ import (
"platform/pkg/remote"
"platform/pkg/testutil"
"platform/web/models"
"slices"
"reflect"
"strings"
"testing"
"time"
@@ -271,6 +271,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
mr := testutil.SetupRedisTest(t)
db := testutil.SetupDBTest(t)
mc := testutil.SetupCloudClientMock(t)
mg := testutil.SetupGatewayClientMock(t)
type args struct {
ctx context.Context
@@ -297,21 +298,6 @@ func Test_channelService_CreateChannel(t *testing.T) {
{ID: 3, UserID: 101, Host: "789.789.789.789"},
}
db.Create(whitelists)
var resource = &models.Resource{
ID: 1,
UserID: 101,
Active: true,
}
db.Create(resource)
var resourcePss = &models.ResourcePss{
ID: 1,
ResourceID: 1,
Type: 1,
Live: 180,
Expire: time.Now().AddDate(1, 0, 0),
DailyLimit: 10000,
}
db.Create(resourcePss)
var proxy = &models.Proxy{
ID: 1,
Version: 1,
@@ -324,13 +310,32 @@ func Test_channelService_CreateChannel(t *testing.T) {
mc.AutoQueryMock = func() (remote.CloudConnectResp, error) {
return remote.CloudConnectResp{
"test-proxy": []remote.AutoConfig{
{Province: "河南", City: "郑州", Isp: "电信", Count: 10},
{Province: "河南", Count: 10},
},
}, nil
}
var clearDb = func() {
db.Exec("delete from resource where true")
var resource = &models.Resource{
ID: 1,
UserID: 101,
Active: true,
}
db.Create(resource)
db.Exec("delete from resource_pss where true")
var resourcePss = &models.ResourcePss{
ID: 1,
ResourceID: 1,
Type: 1,
Live: 180,
Expire: time.Now().AddDate(1, 0, 0),
DailyLimit: 10000,
}
db.Create(resourcePss)
db.Exec("delete from channel where true")
db.Exec("update resource_pss set daily_used = 0, daily_last = null, used = 0 where true")
}
tests := []struct {
name string
@@ -349,16 +354,70 @@ func Test_channelService_CreateChannel(t *testing.T) {
protocol: ProtocolHTTP,
authType: ChannelAuthTypePass,
count: 3,
nodeFilter: []NodeFilterConfig{{Prov: "河南", City: "郑州", Isp: "电信"}},
nodeFilter: []NodeFilterConfig{{Prov: "北京市"}},
},
setup: func() {
mr.FlushAll()
clearDb()
want: func(t *testing.T, got []*PortInfo) error {
// 验证返回结果
if len(got) == 0 {
return fmt.Errorf("返回的 PortInfo 不应为空")
mc.ConnectMock = func(param remote.CloudConnectReq) error {
if param.Uuid != proxy.Name {
return fmt.Errorf("代理名称不符合预期: %s", param.Uuid)
}
if len(param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
}
if !reflect.DeepEqual(param.AutoConfig, []remote.AutoConfig{
{Province: "河南省", Count: 10},
{Province: "北京市", Count: 6},
}) {
return fmt.Errorf("自动配置不符合预期: %v", param.AutoConfig)
}
return nil
}
// 验证协议正确
mg.PortConfigsMock = func(c *testutil.MockGatewayClient, params []remote.PortConfigsReq) error {
if c.Host != proxy.Host {
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
}
if len(params) != 3 {
return fmt.Errorf("端口数量不符合预期: %d", len(params))
}
for _, param := range params {
if param.Status != true {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.AutoEdgeConfig == nil {
return fmt.Errorf("自动边缘节点配置不符合预期: %v", param.AutoEdgeConfig)
}
if param.Userpass == nil || *param.Userpass == "" {
return fmt.Errorf("用户名密码不符合预期: %v", param.Userpass)
}
if param.Whitelist == nil || len(*param.Whitelist) != 0 {
return fmt.Errorf("白名单不符合预期: %v", param.Whitelist)
}
config := param.AutoEdgeConfig
if config.Province != "北京市" {
return fmt.Errorf("自动边缘节点省份不符合预期: %s", param.AutoEdgeConfig.Province)
}
if *config.Count != 1 {
return fmt.Errorf("自动边缘节点数量不符合预期: %d", param.AutoEdgeConfig.Count)
}
if config.PacketLoss != 30 {
return fmt.Errorf("自动边缘节点丢包率不符合预期: %d", param.AutoEdgeConfig.PacketLoss)
}
}
return nil
}
},
want: func(t *testing.T, got []*PortInfo) error {
// 验证返回结果
if len(got) != 3 {
return fmt.Errorf("返回的 PortInfo 数量不正确,期望 3得到 %d", len(got))
}
// 验证结果
var gotMap = make(map[int]PortInfo)
for _, port := range got {
if port.Proto != "http" {
return fmt.Errorf("期望协议为 http得到 %s", port.Proto)
@@ -366,11 +425,12 @@ func Test_channelService_CreateChannel(t *testing.T) {
if port.Host != proxy.Host {
return fmt.Errorf("期望主机为 %s得到 %s", proxy.Host, port.Host)
}
gotMap[port.Port] = *port
}
// 验证数据库字段
var channels []*models.Channel
db.Where("user_id = ? AND proxy_id = ?", userAuth.Payload.Id, proxy.ID).Find(&channels)
db.Where("user_id = ? and deleted_at is null", userAuth.Payload.Id).Find(&channels)
for _, ch := range channels {
if ch.Protocol != "http" {
return fmt.Errorf("通道协议不正确,期望 http得到 %s", ch.Protocol)
@@ -378,30 +438,60 @@ func Test_channelService_CreateChannel(t *testing.T) {
if ch.UserID != userAuth.Payload.Id {
return fmt.Errorf("通道用户ID不正确期望 %d得到 %d", userAuth.Payload.Id, ch.UserID)
}
// todo 多代理分配策略,验证 proxy_host
if ch.ProxyID != proxy.ID {
return fmt.Errorf("通道代理ID不正确期望 %d得到 %d", proxy.ID, ch.ProxyID)
}
var info, ok = gotMap[int(ch.ProxyPort)]
if !ok {
return fmt.Errorf("通道端口 %d 不在返回结果中", ch.ProxyPort)
}
if ch.AuthPass != true && ch.AuthIP != false {
return fmt.Errorf("通道认证类型不正确,期望 Pass得到 %v", ch.AuthPass)
}
if ch.Protocol != info.Proto {
return fmt.Errorf("通道协议不正确,期望 %s得到 %s", info.Proto, ch.Protocol)
}
if ch.Username != *info.Username {
return fmt.Errorf("通道用户名不正确,期望 %s得到 %s", *info.Username, ch.Username)
}
if ch.Password != *info.Password {
return fmt.Errorf("通道密码不正确,期望 %s得到 %s", *info.Password, ch.Password)
}
if ch.Expiration.IsZero() {
return fmt.Errorf("通道过期时间不应为空")
}
// 检查Redis缓存中的字段
key := fmt.Sprintf("channel:%d", ch.ID)
if !mr.Exists(key) {
return fmt.Errorf("Redis缓存中应有键 %s", key)
return fmt.Errorf("redis缓存中应有键 %s", key)
}
data, _ := mr.Get(key)
var cachedChannel models.Channel
err := json.Unmarshal([]byte(data), &cachedChannel)
var cache models.Channel
err := json.Unmarshal([]byte(data), &cache)
if err != nil {
return fmt.Errorf("无法解析缓存数据: %v", err)
}
if cachedChannel.ID != ch.ID {
return fmt.Errorf("缓存ID不正确期望 %d得到 %d", ch.ID, cachedChannel.ID)
}
if cachedChannel.Protocol != ch.Protocol {
return fmt.Errorf("缓存协议不正确,期望 %s得到 %s", ch.Protocol, cachedChannel.Protocol)
if reflect.DeepEqual(cache, *ch) {
return fmt.Errorf("缓存数据与数据库不匹配: %v", cache)
}
}
// 检查跨天用量更新
var pss models.ResourcePss
db.Where("resource_id = ?", 1).First(&pss)
if pss.DailyUsed != 3 {
return fmt.Errorf("套餐每日用量不正确,期望 3得到 %d", pss.DailyUsed)
}
if pss.DailyLast.IsZero() {
return fmt.Errorf("套餐每日最后更新时间不应为空")
}
if pss.Used != 3 {
return fmt.Errorf("套餐总用量不正确,期望 3得到 %d", pss.Used)
}
return nil
},
},
@@ -413,23 +503,289 @@ func Test_channelService_CreateChannel(t *testing.T) {
resourceId: 1,
protocol: ProtocolHTTP,
authType: ChannelAuthTypeIp,
count: 2,
count: 3,
nodeFilter: []NodeFilterConfig{{Prov: "北京市"}},
},
setup: func() {
mr.FlushAll()
clearDb()
mc.ConnectMock = func(param remote.CloudConnectReq) error {
if param.Uuid != proxy.Name {
return fmt.Errorf("代理名称不符合预期: %s", param.Uuid)
}
if len(param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
}
if !reflect.DeepEqual(param.AutoConfig, []remote.AutoConfig{
{Province: "河南省", Count: 10},
{Province: "北京市", Count: 6},
}) {
return fmt.Errorf("自动配置不符合预期: %v", param.AutoConfig)
}
return nil
}
mg.PortConfigsMock = func(c *testutil.MockGatewayClient, params []remote.PortConfigsReq) error {
if c.Host != proxy.Host {
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
}
if len(params) != 3 {
return fmt.Errorf("端口数量不符合预期: %d", len(params))
}
for _, param := range params {
if param.Status != true {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.AutoEdgeConfig == nil {
return fmt.Errorf("自动边缘节点配置不符合预期: %v", param.AutoEdgeConfig)
}
if param.Userpass == nil || *param.Userpass != "" {
return fmt.Errorf("用户名密码不符合预期: %v", *param.Userpass)
}
if param.Whitelist == nil || len(*param.Whitelist) == 0 {
return fmt.Errorf("白名单不符合预期: %v", param.Whitelist)
}
config := param.AutoEdgeConfig
if config.Province != "北京市" {
return fmt.Errorf("自动边缘节点省份不符合预期: %s", param.AutoEdgeConfig.Province)
}
if *config.Count != 1 {
return fmt.Errorf("自动边缘节点数量不符合预期: %d", param.AutoEdgeConfig.Count)
}
if config.PacketLoss != 30 {
return fmt.Errorf("自动边缘节点丢包率不符合预期: %d", param.AutoEdgeConfig.PacketLoss)
}
}
return nil
}
},
want: func(t *testing.T, got []*PortInfo) error {
// 验证返回结果
if len(got) != 3 {
return fmt.Errorf("返回的 PortInfo 数量不正确,期望 3得到 %d", len(got))
}
// 验证结果
var gotMap = make(map[int]PortInfo)
for _, port := range got {
if port.Proto != "http" {
return fmt.Errorf("期望协议为 http得到 %s", port.Proto)
}
if port.Host != proxy.Host {
return fmt.Errorf("期望主机为 %s得到 %s", proxy.Host, port.Host)
}
gotMap[port.Port] = *port
}
// 验证数据库字段
var channels []*models.Channel
db.Where("user_id = ? and deleted_at is null", userAuth.Payload.Id).Find(&channels)
for _, ch := range channels {
if ch.Protocol != "http" {
return fmt.Errorf("通道协议不正确,期望 http得到 %s", ch.Protocol)
}
if ch.UserID != userAuth.Payload.Id {
return fmt.Errorf("通道用户ID不正确期望 %d得到 %d", userAuth.Payload.Id, ch.UserID)
}
// todo 多代理分配策略,验证 proxy_host
if ch.ProxyID != proxy.ID {
return fmt.Errorf("通道代理ID不正确期望 %d得到 %d", proxy.ID, ch.ProxyID)
}
var info, ok = gotMap[int(ch.ProxyPort)]
if !ok {
return fmt.Errorf("通道端口 %d 不在返回结果中", ch.ProxyPort)
}
if ch.AuthPass != false && ch.AuthIP != true {
return fmt.Errorf("通道认证类型不正确,期望 Pass得到 %v", ch.AuthPass)
}
if ch.Protocol != info.Proto {
return fmt.Errorf("通道协议不正确,期望 %s得到 %s", info.Proto, ch.Protocol)
}
if ch.Expiration.IsZero() {
return fmt.Errorf("通道过期时间不应为空")
}
// 检查Redis缓存中的字段
key := fmt.Sprintf("channel:%d", ch.ID)
if !mr.Exists(key) {
return fmt.Errorf("redis缓存中应有键 %s", key)
}
data, _ := mr.Get(key)
var cache models.Channel
err := json.Unmarshal([]byte(data), &cache)
if err != nil {
return fmt.Errorf("无法解析缓存数据: %v", err)
}
if reflect.DeepEqual(cache, *ch) {
return fmt.Errorf("缓存数据与数据库不匹配: %v", cache)
}
}
// 检查跨天用量更新
var pss models.ResourcePss
db.Where("resource_id = ?", 1).First(&pss)
if pss.DailyUsed != 3 {
return fmt.Errorf("套餐每日用量不正确,期望 3得到 %d", pss.DailyUsed)
}
if pss.DailyLast.IsZero() {
return fmt.Errorf("套餐每日最后更新时间不应为空")
}
if pss.Used != 3 {
return fmt.Errorf("套餐总用量不正确,期望 3得到 %d", pss.Used)
}
return nil
},
},
{
name: "管理员创建SOCKS5密码通道",
name: "管理员替用户创建HTTP密码通道",
args: args{
ctx: ctx,
auth: adminAuth,
resourceId: 1,
protocol: ProtocolSocks5,
authType: ChannelAuthTypePass,
count: 2,
count: 3,
nodeFilter: []NodeFilterConfig{{Prov: "北京市"}},
},
setup: func() {
mr.FlushAll()
clearDb()
mc.ConnectMock = func(param remote.CloudConnectReq) error {
if param.Uuid != proxy.Name {
return fmt.Errorf("代理名称不符合预期: %s", param.Uuid)
}
if len(param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
}
if !reflect.DeepEqual(param.AutoConfig, []remote.AutoConfig{
{Province: "河南省", Count: 10},
{Province: "北京市", Count: 6},
}) {
return fmt.Errorf("自动配置不符合预期: %v", param.AutoConfig)
}
return nil
}
mg.PortConfigsMock = func(c *testutil.MockGatewayClient, params []remote.PortConfigsReq) error {
if c.Host != proxy.Host {
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
}
if len(params) != 3 {
return fmt.Errorf("端口数量不符合预期: %d", len(params))
}
for _, param := range params {
if param.Status != true {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.AutoEdgeConfig == nil {
return fmt.Errorf("自动边缘节点配置不符合预期: %v", param.AutoEdgeConfig)
}
if param.Userpass == nil || *param.Userpass == "" {
return fmt.Errorf("用户名密码不符合预期: %v", param.Userpass)
}
if param.Whitelist == nil || len(*param.Whitelist) != 0 {
return fmt.Errorf("白名单不符合预期: %v", param.Whitelist)
}
config := param.AutoEdgeConfig
if config.Province != "北京市" {
return fmt.Errorf("自动边缘节点省份不符合预期: %s", param.AutoEdgeConfig.Province)
}
if *config.Count != 1 {
return fmt.Errorf("自动边缘节点数量不符合预期: %d", param.AutoEdgeConfig.Count)
}
if config.PacketLoss != 30 {
return fmt.Errorf("自动边缘节点丢包率不符合预期: %d", param.AutoEdgeConfig.PacketLoss)
}
}
return nil
}
},
want: func(t *testing.T, got []*PortInfo) error {
// 验证返回结果
if len(got) != 3 {
return fmt.Errorf("返回的 PortInfo 数量不正确,期望 3得到 %d", len(got))
}
// 验证结果
var gotMap = make(map[int]PortInfo)
for _, port := range got {
if port.Proto != "socks5" {
return fmt.Errorf("期望协议为 http得到 %s", port.Proto)
}
if port.Host != proxy.Host {
return fmt.Errorf("期望主机为 %s得到 %s", proxy.Host, port.Host)
}
gotMap[port.Port] = *port
}
// 验证数据库字段
var channels []*models.Channel
db.Where("user_id = ? and deleted_at is null", userAuth.Payload.Id).Find(&channels)
for _, ch := range channels {
if ch.Protocol != "http" {
return fmt.Errorf("通道协议不正确,期望 http得到 %s", ch.Protocol)
}
if ch.UserID != userAuth.Payload.Id {
return fmt.Errorf("通道用户ID不正确期望 %d得到 %d", userAuth.Payload.Id, ch.UserID)
}
// todo 多代理分配策略,验证 proxy_host
if ch.ProxyID != proxy.ID {
return fmt.Errorf("通道代理ID不正确期望 %d得到 %d", proxy.ID, ch.ProxyID)
}
var info, ok = gotMap[int(ch.ProxyPort)]
if !ok {
return fmt.Errorf("通道端口 %d 不在返回结果中", ch.ProxyPort)
}
if ch.AuthPass != true && ch.AuthIP != false {
return fmt.Errorf("通道认证类型不正确,期望 Pass得到 %v", ch.AuthPass)
}
if ch.Protocol != info.Proto {
return fmt.Errorf("通道协议不正确,期望 %s得到 %s", info.Proto, ch.Protocol)
}
if ch.Username != *info.Username {
return fmt.Errorf("通道用户名不正确,期望 %s得到 %s", *info.Username, ch.Username)
}
if ch.Password != *info.Password {
return fmt.Errorf("通道密码不正确,期望 %s得到 %s", *info.Password, ch.Password)
}
if ch.Expiration.IsZero() {
return fmt.Errorf("通道过期时间不应为空")
}
// 检查Redis缓存中的字段
key := fmt.Sprintf("channel:%d", ch.ID)
if !mr.Exists(key) {
return fmt.Errorf("redis缓存中应有键 %s", key)
}
data, _ := mr.Get(key)
var cache models.Channel
err := json.Unmarshal([]byte(data), &cache)
if err != nil {
return fmt.Errorf("无法解析缓存数据: %v", err)
}
if reflect.DeepEqual(cache, *ch) {
return fmt.Errorf("缓存数据与数据库不匹配: %v", cache)
}
}
// 检查跨天用量更新
var pss models.ResourcePss
db.Where("resource_id = ?", 1).First(&pss)
if pss.DailyUsed != 3 {
return fmt.Errorf("套餐每日用量不正确,期望 3得到 %d", pss.DailyUsed)
}
if pss.DailyLast.IsZero() {
return fmt.Errorf("套餐每日最后更新时间不应为空")
}
if pss.Used != 3 {
return fmt.Errorf("套餐总用量不正确,期望 3得到 %d", pss.Used)
}
return nil
},
},
@@ -443,8 +799,12 @@ func Test_channelService_CreateChannel(t *testing.T) {
authType: ChannelAuthTypeIp,
count: 1,
},
setup: func() {
mr.FlushAll()
clearDb()
},
wantErr: true,
wantErrContains: "套餐不存在",
wantErrContains: "无权限访问",
},
{
name: "套餐没有权限",
@@ -456,25 +816,43 @@ func Test_channelService_CreateChannel(t *testing.T) {
authType: ChannelAuthTypeIp,
count: 1,
},
setup: func() {
mr.FlushAll()
clearDb()
resource2 := &models.Resource{
ID: 2,
UserID: 102,
Active: true,
}
db.Create(resource2)
var resourcePss2 = &models.ResourcePss{
ID: 2,
ResourceID: 2,
Type: 1,
Live: 180,
Expire: time.Now().AddDate(1, 0, 0),
DailyLimit: 10000,
}
db.Create(resourcePss2)
},
wantErr: true,
wantErrContains: "无权限访问",
},
{
name: "套餐配额不足",
args: args{
ctx: ctx,
auth: &AuthContext{
Payload: Payload{
Type: PayloadUser,
Id: 100,
},
},
ctx: ctx,
auth: userAuth,
resourceId: 2,
protocol: ProtocolHTTP,
authType: ChannelAuthTypeIp,
count: 10,
},
setup: func() {
mr.FlushAll()
clearDb()
// 创建一个配额几乎用完的资源包
resource2 := models.Resource{
ID: 2,
@@ -482,8 +860,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
Active: true,
}
resourcePss2 := models.ResourcePss{
ID: 1,
ResourceID: 1,
ID: 2,
ResourceID: 2,
Type: 2,
Quota: 100,
Used: 91,
@@ -506,20 +884,24 @@ func Test_channelService_CreateChannel(t *testing.T) {
count: 1,
},
setup: func() {
mr.FlushAll()
clearDb()
// 创建大量占用端口的通道
for i := 10000; i < 20000; i++ {
channel := models.Channel{
ProxyID: 1,
ProxyPort: int32(i),
UserID: 101,
var channels = make([]models.Channel, 10000)
var expr = time.Now().Add(time.Hour)
for i := range channels {
channels[i] = models.Channel{
ProxyID: 1,
ProxyPort: int32(i + 10000),
UserID: 101,
Expiration: expr,
}
db.Create(&channel)
}
db.CreateInBatches(channels, 1000)
},
wantErr: true,
wantErrContains: "端口数量不足",
wantErrContains: "端口数量到达上限",
},
// todo 跨天用量更新
// todo 多地区混杂条件提取
}
@@ -552,10 +934,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
}
// 使用检查函数验证结果
if tt.want != nil {
if err := tt.want(t, got); err != nil {
t.Errorf("结果验证失败: %v", err)
}
if err := tt.want(t, got); err != nil {
t.Errorf("结果验证失败: %v", err)
}
})
}
@@ -681,9 +1061,10 @@ func Test_channelService_RemoveChannels(t *testing.T) {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.Edge == nil || len(*param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
return fmt.Errorf("边缘节点不符合预期1: %v", param.Edge)
}
}
return nil
case m.Host == proxy2.Host:
for _, param := range params {
if param.Port != 10001 {
@@ -693,9 +1074,10 @@ func Test_channelService_RemoveChannels(t *testing.T) {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.Edge == nil || len(*param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
return fmt.Errorf("边缘节点不符合预期2: %v", param.Edge)
}
}
return nil
}
return fmt.Errorf("代理主机不符合预期: %s", m.Host)
}
@@ -703,8 +1085,8 @@ func Test_channelService_RemoveChannels(t *testing.T) {
switch {
case param.Uuid == proxy.Name:
var edges = []string{"edge1", "edge2", "edge4"}
if !slices.Equal(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
if !testutil.SliceEqual(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期3: %v", param.Edge)
}
if len(param.Config) != 0 {
return 0, fmt.Errorf("配置不符合预期: %v", param.Config)
@@ -712,8 +1094,8 @@ func Test_channelService_RemoveChannels(t *testing.T) {
return len(param.Edge), nil
case param.Uuid == proxy2.Name:
var edges = []string{"edge3"}
if !slices.Equal(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
if !testutil.SliceEqual(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期4: %v", param.Edge)
}
if len(param.Config) != 0 {
return 0, fmt.Errorf("配置不符合预期: %v", param.Config)
@@ -793,9 +1175,10 @@ func Test_channelService_RemoveChannels(t *testing.T) {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.Edge == nil || len(*param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
return fmt.Errorf("边缘节点不符合预期5: %v", param.Edge)
}
}
return nil
case m.Host == proxy2.Host:
for _, param := range params {
if param.Port != 10001 {
@@ -805,9 +1188,10 @@ func Test_channelService_RemoveChannels(t *testing.T) {
return fmt.Errorf("端口状态不符合预期: %v", param.Status)
}
if param.Edge == nil || len(*param.Edge) != 0 {
return fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
return fmt.Errorf("边缘节点不符合预期6: %v", param.Edge)
}
}
return nil
}
return fmt.Errorf("代理主机不符合预期: %s", m.Host)
}
@@ -815,8 +1199,8 @@ func Test_channelService_RemoveChannels(t *testing.T) {
switch {
case param.Uuid == proxy.Name:
var edges = []string{"edge1", "edge2", "edge4"}
if !slices.Equal(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
if !testutil.SliceEqual(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期7: %v", param.Edge)
}
if len(param.Config) != 0 {
return 0, fmt.Errorf("配置不符合预期: %v", param.Config)
@@ -824,8 +1208,8 @@ func Test_channelService_RemoveChannels(t *testing.T) {
return len(param.Edge), nil
case param.Uuid == proxy2.Name:
var edges = []string{"edge3"}
if !slices.Equal(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期: %v", param.Edge)
if !testutil.SliceEqual(edges, param.Edge) {
return 0, fmt.Errorf("边缘节点不符合预期8: %v", param.Edge)
}
if len(param.Config) != 0 {
return 0, fmt.Errorf("配置不符合预期: %v", param.Config)
@@ -911,9 +1295,9 @@ func Test_channelService_RemoveChannels(t *testing.T) {
}
// 检查数据库和缓存是否正确设置
want := tt.want(t)
if tt.want(t) != nil {
t.Errorf("RemoveChannels() 结果验证失败: %v", want)
if err := tt.want(t); err != nil {
t.Errorf("RemoveChannels() 结果验证失败: %v", err)
}
})
}