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 devmgr
import (
"errors"
"fmt"
"sort"
"testing"
"github.com/agiledragon/gomonkey/v2"
"github.com/gogo/protobuf/sortkeys"
"github.com/smartystreets/goconvey/convey"
"ascend-common/api"
"ascend-common/devmanager"
ascommon "ascend-common/devmanager/common"
"container-manager/pkg/common"
)
func TestHwDevMgrBasicMethod(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'GetDevType' success", t, func() {
devType := mockDevMgr.GetDevType()
convey.So(devType, convey.ShouldEqual, mockDevMgr.devType)
})
convey.Convey("test method 'GetDevUsage' success", t, func() {
devUsage := mockDevMgr.GetDevUsage()
convey.So(devUsage, convey.ShouldEqual, mockDevMgr.devUsage)
})
convey.Convey("test method 'GetDevNum' success", t, func() {
devNum := mockDevMgr.GetDevNum()
convey.So(devNum, convey.ShouldEqual, len(mockDevMgr.npuInfos))
})
convey.Convey("test method 'GetDevNum' success", t, func() {
phyIds := mockDevMgr.GetPhyIds()
sortkeys.Int32s(phyIds)
expPhyIds := []int32{dev0, dev1, dev2, dev3, dev4, dev5, dev6, dev7}
sortkeys.Int32s(expPhyIds)
convey.So(phyIds, convey.ShouldResemble, expPhyIds)
})
}
func TestSetDeviceUsage(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'setDeviceUsage' success, devType is 310", t, func() {
mockDevMgr.devType = api.Ascend310
err := mockDevMgr.setDeviceUsage(0)
convey.So(err, convey.ShouldBeNil)
convey.So(mockDevMgr.devUsage, convey.ShouldEqual, common.Infer)
})
convey.Convey("test method 'setDeviceUsage' success, usage is infer", t, func() {
mockDevMgr.devType = api.Ascend910B
mockDevMgr.boardId = common.A800IA2NoneHccsBoardIdOld
err := mockDevMgr.setDeviceUsage(0)
convey.So(err, convey.ShouldBeNil)
convey.So(mockDevMgr.devUsage, convey.ShouldEqual, common.Infer)
mockDevMgr.devType = api.Ascend910
err = mockDevMgr.setDeviceUsage(0)
convey.So(err, convey.ShouldBeNil)
convey.So(mockDevMgr.devUsage, convey.ShouldEqual, common.Train)
})
convey.Convey("test method 'setDeviceUsage' failed, get board id error", t, func() {
var patches = gomonkey.ApplyMethodReturn(&HwDevMgr{}, "GetBoardId", uint32(0), testErr)
defer patches.Reset()
mockDevMgr.devType = api.Ascend910
err := mockDevMgr.setDeviceUsage(0)
expErr := fmt.Errorf("get board id failed")
convey.So(err, convey.ShouldResemble, expErr)
})
}
func TestSetRingInfo(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'setRingInfo' success", t, func() {
err := mockDevMgr.setRingInfo()
convey.So(err, convey.ShouldBeNil)
convey.So(mockDevMgr.npuInfos[dev0].DevsOnRing, convey.ShouldResemble,
[]int32{dev0, dev1, dev2, dev3, dev4, dev5, dev6, dev7})
})
convey.Convey("test method 'setRingInfo' failed, GetBoardId error", t, func() {
var patches = gomonkey.ApplyMethodReturn(&HwDevMgr{}, "GetBoardId", uint32(0), testErr)
defer patches.Reset()
err := mockDevMgr.setRingInfo()
expErr := errors.New("get board id failed")
convey.So(err, convey.ShouldResemble, expErr)
})
}
func TestSetBoardId(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'setBoardId' success", t, func() {
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBoardInfo",
ascommon.BoardInfo{}, nil)
defer patches.Reset()
err := mockDevMgr.setBoardId(0)
convey.So(err, convey.ShouldBeNil)
convey.So(mockDevMgr.boardId, convey.ShouldEqual, int32(0))
})
convey.Convey("test method 'setBoardId' failed, GetBoardInfo error", t, func() {
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBoardInfo",
ascommon.BoardInfo{}, testErr)
defer patches.Reset()
err := mockDevMgr.setBoardId(0)
expErr := errors.New("get board id failed")
convey.So(err, convey.ShouldResemble, expErr)
})
}
func TestGetBoardId(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'GetBoardId' success", t, func() {
boardId, err := mockDevMgr.GetBoardId(0)
convey.So(err, convey.ShouldBeNil)
convey.So(boardId, convey.ShouldEqual, mockDevMgr.boardId)
})
convey.Convey("test method 'GetBoardId' failed, GetBoardInfo error", t, func() {
mockDevMgr.boardId = common.EmptyBoardId
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBoardInfo",
ascommon.BoardInfo{}, testErr)
defer patches.Reset()
boardId, err := mockDevMgr.GetBoardId(0)
expErr := fmt.Errorf("get board info failed, error: %v", testErr)
convey.So(err, convey.ShouldResemble, expErr)
convey.So(boardId, convey.ShouldEqual, common.EmptyBoardId)
})
convey.Convey("test method 'GetBoardId' success, GetBoardInfo success", t, func() {
mockDevMgr.boardId = common.EmptyBoardId
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBoardInfo",
ascommon.BoardInfo{BoardId: 0}, nil)
defer patches.Reset()
boardId, err := mockDevMgr.GetBoardId(0)
convey.So(err, convey.ShouldBeNil)
convey.So(boardId, convey.ShouldEqual, 0)
})
}
func TestGetNodeNPUInfo(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'GetNodeNPUInfo' success", t, func() {
var patches = gomonkey.ApplyMethod(&devmanager.DeviceManagerMock{}, "GetPhysicIDFromLogicID",
func(_ *devmanager.DeviceManagerMock, logicID int32) (int32, error) {
return logicID, nil
}).ApplyMethod(&devmanager.DeviceManagerMock{}, "GetCardIDDeviceID",
func(_ *devmanager.DeviceManagerMock, logicID int32) (int32, int32, error) {
return logicID, logicID, nil
}).ApplyMethod(&devmanager.DeviceManagerMock{}, "GetChipInfo",
func(_ *devmanager.DeviceManagerMock, logicID int32) (*ascommon.ChipInfo, error) {
return &ascommon.ChipInfo{
Name: api.Ascend910,
}, nil
}).ApplyMethod(&devmanager.DeviceManagerMock{}, "GetDeviceIPAddress",
func(_ *devmanager.DeviceManagerMock, logicID int32, ipType int32) (string, error) {
return defaultDeviceIP, nil
})
defer patches.Reset()
logicIds := []int32{dev0, dev1, dev2, dev3, dev4, dev5, dev6, dev7}
npuInfo, err := mockDevMgr.setNodeNPUInfo(logicIds, len8)
convey.So(err, convey.ShouldBeNil)
convey.So(len(npuInfo), convey.ShouldEqual, len8)
})
convey.Convey("test method 'GetNodeNPUInfo' failed, devNum too large", t, func() {
const invalidDevNum = 200
_, err := mockDevMgr.setNodeNPUInfo(nil, invalidDevNum)
expErr := fmt.Errorf("invalid device num: %d", invalidDevNum)
convey.So(err, convey.ShouldResemble, expErr)
})
}
func TestSubscribeFaultEvent(t *testing.T) {
convey.Convey("test method 'SubscribeFaultEvent' success", t, func() {
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "SetFaultEventCallFunc", nil)
defer patches.Reset()
callback := func(devFaultInfo ascommon.DevFaultInfo) {}
err := mockDevMgr.SubscribeFaultEvent(callback)
convey.So(err, convey.ShouldBeNil)
})
}
func TestGetFaultCodesMap(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'GetFaultCodesMap' success", t, func() {
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetDeviceAllErrorCode",
int32(0), []int64{123456789, 987654321}, nil)
defer patches.Reset()
codesMap := mockDevMgr.GetFaultCodesMap()
convey.So(len(codesMap), convey.ShouldEqual, len8)
convey.So(codesMap[0], convey.ShouldResemble, []int64{123456789, 987654321})
})
convey.Convey("test method 'GetFaultCodesMap' failed, GetDeviceAllErrorCode error", t, func() {
var patches = gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetDeviceAllErrorCode",
int32(0), []int64{0}, testErr)
defer patches.Reset()
codesMap := mockDevMgr.GetFaultCodesMap()
convey.So(len(codesMap), convey.ShouldEqual, 0)
})
}
func TestGetPhyIdOnRing(t *testing.T) {
resetDevMgr()
testAtlas300IDuoScenarios(t)
testDevicesWithoutRingScenario(t)
testAscend910A3Scenario(t)
testAscend910RingScenario(t)
testGetDevNumPerRingFailScenario(t)
}
func testAtlas300IDuoScenarios(t *testing.T) {
convey.Convey("test method 'GetPhyIdOnRing' for Atlas 300I Duo", t, func() {
testAtlas300IDuoSuccess(t)
})
}
func testAtlas300IDuoSuccess(t *testing.T) {
convey.Convey("should return coupled phy ids when product type is Atlas 300I Duo", func() {
patches := gomonkey.ApplyMethod(&HwDevMgr{}, "GetLogicIdByPhyId",
func(_ *HwDevMgr, phyId int32) int32 {
return 0
})
defer patches.Reset()
patches.ApplyPrivateMethod(&HwDevMgr{}, "isAtlas300IDuo",
func(_ *HwDevMgr, logicId int32) bool {
return true
})
patches.ApplyPrivateMethod(&HwDevMgr{}, "getCoupledPhyIdsFrom310pDuo",
func(_ *HwDevMgr, phyId int32) ([]int32, error) {
return []int32{0, 1}, nil
})
result, err := mockDevMgr.GetPhyIdOnRing(0)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldResemble, []int32{0, 1})
})
}
func testDevicesWithoutRingScenario(t *testing.T) {
convey.Convey("test method 'GetPhyIdOnRing' for devices without ring", t, func() {
patches := gomonkey.ApplyMethod(&HwDevMgr{}, "GetLogicIdByPhyId",
func(_ *HwDevMgr, phyId int32) int32 {
return 0
})
defer patches.Reset()
patches.ApplyPrivateMethod(&HwDevMgr{}, "isAtlas300IDuo",
func(_ *HwDevMgr, logicID int32) bool {
return false
})
patches.ApplyMethodReturn(&HwDevMgr{}, "GetDevNumPerRing", common.NoRingNum, nil)
result, err := mockDevMgr.GetPhyIdOnRing(0)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldResemble, []int32{0})
})
}
func testAscend910A3Scenario(t *testing.T) {
convey.Convey("test method 'GetPhyIdOnRing' for Ascend910A3", t, func() {
patches := gomonkey.ApplyMethod(&HwDevMgr{}, "GetLogicIdByPhyId",
func(_ *HwDevMgr, phyId int32) int32 {
return 0
})
defer patches.Reset()
patches.ApplyPrivateMethod(&HwDevMgr{}, "isAtlas300IDuo",
func(_ *HwDevMgr, logicID int32) bool {
return false
})
patches.ApplyMethodReturn(&HwDevMgr{}, "GetDevNumPerRing", common.Ascend910RingsNum, nil)
patches.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetDevType", api.Ascend910A3)
patches.ApplyPrivateMethod(&HwDevMgr{}, "getPhyIdOn910A3Ring",
func(phyId, logicID int32) ([]int32, error) {
return []int32{0, 1, 2, 3}, nil
})
result, err := mockDevMgr.GetPhyIdOnRing(0)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldResemble, []int32{0, 1, 2, 3})
})
}
func testAscend910RingScenario(t *testing.T) {
convey.Convey("test method 'GetPhyIdOnRing' for Ascend910 ring", t, func() {
patches := gomonkey.ApplyMethod(&HwDevMgr{}, "GetLogicIdByPhyId",
func(_ *HwDevMgr, phyId int32) int32 {
return 0
})
defer patches.Reset()
patches.ApplyPrivateMethod(&HwDevMgr{}, "isAtlas300IDuo",
func(_ *HwDevMgr, logicID int32) bool {
return false
})
patches.ApplyMethodReturn(&HwDevMgr{}, "GetDevNumPerRing", common.Ascend910BRingsNumTrain, nil)
patches.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetDevType", api.Ascend910)
patches.ApplyPrivateMethod(&HwDevMgr{}, "getPhyIdOn910Ring",
func(phyId, devNumPerRing int32) ([]int32, error) {
return []int32{0, 1, 2, 3, 4, 5, 6, 7}, nil
})
result, err := mockDevMgr.GetPhyIdOnRing(0)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldResemble, []int32{0, 1, 2, 3, 4, 5, 6, 7})
})
}
func testGetDevNumPerRingFailScenario(t *testing.T) {
convey.Convey("test method 'GetPhyIdOnRing' should return error when GetDevNumPerRing fails", t, func() {
patches := gomonkey.ApplyMethod(&HwDevMgr{}, "GetLogicIdByPhyId",
func(_ *HwDevMgr, phyId int32) int32 {
return 0
})
defer patches.Reset()
patches.ApplyPrivateMethod(&HwDevMgr{}, "isAtlas300IDuo",
func(_ *HwDevMgr, logicID int32) bool {
return false
})
patches.ApplyMethodReturn(&HwDevMgr{}, "GetDevNumPerRing", 0, testErr)
result, err := mockDevMgr.GetPhyIdOnRing(0)
convey.So(err, convey.ShouldResemble, testErr)
convey.So(result, convey.ShouldBeNil)
})
}
func TestIsAtlas300IDuo(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'isAtlas300IDuo'", t, func() {
convey.Convey("should return true when product type is Atlas 300I Duo", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetProductType",
common.ProductTypeAtlas300IDuo, nil)
defer patches.Reset()
result := mockDevMgr.isAtlas300IDuo(0)
convey.So(result, convey.ShouldBeTrue)
})
convey.Convey("should return false when product type is not Atlas 300I Duo", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetProductType",
"OtherProduct", nil)
defer patches.Reset()
result := mockDevMgr.isAtlas300IDuo(0)
convey.So(result, convey.ShouldBeFalse)
})
convey.Convey("should return false when GetProductType fails", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetProductType",
"", testErr)
defer patches.Reset()
result := mockDevMgr.isAtlas300IDuo(0)
convey.So(result, convey.ShouldBeFalse)
})
})
}
func TestGetCoupledPhyIdsFrom310pDuo(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'getCoupledPhyIdsFrom310pDuo'", t, func() {
convey.Convey("should return coupled phy ids successfully", func() {
mockDevMgr.npuInfos = map[int32]*common.NPUInfo{
0: {PhyID: 0, LogicID: 0, CardID: 0},
1: {PhyID: 1, LogicID: 1, CardID: 0},
2: {PhyID: 2, LogicID: 2, CardID: 1},
}
result, err := mockDevMgr.getCoupledPhyIdsFrom310pDuo(0)
var sortSlice []int
for _, val := range result {
sortSlice = append(sortSlice, int(val))
}
sort.Ints(sortSlice)
convey.So(err, convey.ShouldBeNil)
convey.So(sortSlice, convey.ShouldResemble, []int{0, 1})
})
convey.Convey("should return error when npuInfos is nil", func() {
mockDevMgr.npuInfos = nil
result, err := mockDevMgr.getCoupledPhyIdsFrom310pDuo(0)
convey.So(err, convey.ShouldResemble, errors.New("npuInfos is nil"))
convey.So(result, convey.ShouldBeNil)
})
convey.Convey("should return error when phyId not found in npuInfos", func() {
mockDevMgr.npuInfos = map[int32]*common.NPUInfo{
1: {PhyID: 1, LogicID: 1, CardID: 0},
}
result, err := mockDevMgr.getCoupledPhyIdsFrom310pDuo(0)
convey.So(err, convey.ShouldResemble, errors.New("npuInfos is nil"))
convey.So(result, convey.ShouldBeNil)
})
})
}
func TestGetPhyIdOn910A3Ring(t *testing.T) {
resetDevMgr()
convey.Convey("test method 'getPhyIdOn910A3Ring'", t, func() {
testSuccessScenario(t)
testGetBrotherCardIDFail(t)
testGetDeviceLogicIDFailForDevice0(t)
testGetDeviceLogicIDFailForDevice1(t)
testGetDeviceLogicIDFailForOtherDevice(t)
})
}
func testSuccessScenario(t *testing.T) {
convey.Convey("should return phy ids on 910A3 ring successfully", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBrotherCardID",
int32(1), nil)
defer patches.Reset()
patches.ApplyMethodSeq(&devmanager.DeviceManagerMock{}, "GetDeviceLogicID",
[]gomonkey.OutputCell{
{Values: gomonkey.Params{int32(10), nil}},
{Values: gomonkey.Params{int32(11), nil}},
{Values: gomonkey.Params{int32(12), nil}},
})
patches.ApplyMethod(&HwDevMgr{}, "GetPhyIdByLogicId",
func(_ *HwDevMgr, logicId int32) int32 {
return logicId
})
result, err := mockDevMgr.getPhyIdOn910A3Ring(0, 0)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldResemble, []int32{0, 12, 10, 11})
})
}
func testGetBrotherCardIDFail(t *testing.T) {
convey.Convey("should return error when GetBrotherCardID fails", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBrotherCardID",
int32(0), testErr)
defer patches.Reset()
result, err := mockDevMgr.getPhyIdOn910A3Ring(0, 0)
convey.So(err, convey.ShouldResemble, testErr)
convey.So(result, convey.ShouldBeNil)
})
}
func testGetDeviceLogicIDFailForDevice0(t *testing.T) {
convey.Convey("should return error when GetDeviceLogicID for device 0 fails", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBrotherCardID",
int32(1), nil)
defer patches.Reset()
patches.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetDeviceLogicID",
int32(0), testErr)
result, err := mockDevMgr.getPhyIdOn910A3Ring(0, 0)
convey.So(err, convey.ShouldResemble, testErr)
convey.So(result, convey.ShouldBeNil)
})
}
func testGetDeviceLogicIDFailForDevice1(t *testing.T) {
convey.Convey("should return error when GetDeviceLogicID for device 1 fails", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBrotherCardID",
int32(1), nil)
defer patches.Reset()
patches.ApplyMethodSeq(&devmanager.DeviceManagerMock{}, "GetDeviceLogicID",
[]gomonkey.OutputCell{
{Values: gomonkey.Params{int32(10), nil}},
{Values: gomonkey.Params{int32(0), testErr}},
})
result, err := mockDevMgr.getPhyIdOn910A3Ring(0, 0)
convey.So(err, convey.ShouldResemble, testErr)
convey.So(result, convey.ShouldBeNil)
})
}
func testGetDeviceLogicIDFailForOtherDevice(t *testing.T) {
convey.Convey("should return error when GetDeviceLogicID for other device fails", func() {
patches := gomonkey.ApplyMethodReturn(&devmanager.DeviceManagerMock{}, "GetBrotherCardID",
int32(1), nil)
defer patches.Reset()
patches.ApplyMethodSeq(&devmanager.DeviceManagerMock{}, "GetDeviceLogicID",
[]gomonkey.OutputCell{
{Values: gomonkey.Params{int32(10), nil}},
{Values: gomonkey.Params{int32(11), nil}},
{Values: gomonkey.Params{int32(0), testErr}},
})
result, err := mockDevMgr.getPhyIdOn910A3Ring(0, 0)
convey.So(err, convey.ShouldResemble, testErr)
convey.So(result, convey.ShouldBeNil)
})
}