/* Copyright(C) 2022. Huawei Technologies Co.,Ltd. All rights reserved.
   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 common a series of common function
package common

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"testing"
	"time"

	"github.com/agiledragon/gomonkey/v2"
	"github.com/fsnotify/fsnotify"
	"github.com/smartystreets/goconvey/convey"
	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/sets"
	"k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1"

	"ascend-common/api"
	"ascend-common/common-utils/hwlog"
	"ascend-common/common-utils/utils"
)

const (
	num3 = 3
	num5 = 5
)

type mockFileInfo struct {
	mode os.FileMode
	sys  interface{}
}

func (m *mockFileInfo) Name() string       { return "mock" }
func (m *mockFileInfo) Size() int64        { return 0 }
func (m *mockFileInfo) Mode() os.FileMode  { return m.mode }
func (m *mockFileInfo) ModTime() time.Time { return time.Now() }
func (m *mockFileInfo) IsDir() bool        { return false }
func (m *mockFileInfo) Sys() interface{}   { return m.sys }

func init() {
	hwLogConfig := hwlog.LogConfig{
		OnlyToStdout: true,
	}
	hwlog.InitRunLogger(&hwLogConfig, context.Background())
}

// TestLockAllDeviceInfo for test LockAllDeviceInfo
func TestLockAllDeviceInfo(t *testing.T) {
	convey.Convey("test LockAllDeviceInfo", t, func() {
		convey.Convey("LockAllDeviceInfo success", func() {
			LockAllDeviceInfo()
			UnlockAllDeviceInfo()
		})
	})
}

// TestSetAscendRuntimeEnv for test SetAscendRuntimeEnv
func TestSetAscendRuntimeEnv(t *testing.T) {
	convey.Convey("test SetAscendRuntimeEnv", t, func() {
		id := 100
		devices := []int{id}
		SetAscendRuntimeEnv(devices, "", nil)
		ParamOption.RealCardType = api.Ascend310B
		resp := v1beta1.ContainerAllocateResponse{}
		SetAscendRuntimeEnv(devices, "", &resp)
		convey.So(resp.Envs[ascendAllowLinkEnv], convey.ShouldEqual, "True")
		convey.So(resp.Envs[AscendVisibleDevicesEnv], convey.ShouldEqual, strconv.Itoa(id))
	})
}

// TestMakeDataHash for test MakeDataHash
func TestMakeDataHash(t *testing.T) {
	convey.Convey("test MakeDataHash", t, func() {
		convey.Convey("h.Write success", func() {
			DeviceInfo := NodeDeviceInfo{DeviceList: map[string]string{HuaweiUnHealthAscend910: "Ascend910-0"}}
			ret := MakeDataHash(DeviceInfo)
			convey.So(ret, convey.ShouldNotBeEmpty)
		})
		convey.Convey("json.Marshal failed", func() {
			mockMarshal := gomonkey.ApplyFunc(json.Marshal, func(v interface{}) ([]byte, error) {
				return nil, fmt.Errorf("err")
			})
			defer mockMarshal.Reset()
			DeviceInfo := NodeDeviceInfo{DeviceList: map[string]string{HuaweiUnHealthAscend910: "Ascend910-0"}}
			ret := MakeDataHash(DeviceInfo)
			convey.So(ret, convey.ShouldBeEmpty)
		})
	})
}

// TestMapDeepCopy for test MapDeepCopy
func TestMapDeepCopy(t *testing.T) {
	convey.Convey("test MapDeepCopy", t, func() {
		convey.Convey("input nil", func() {
			ret := MapDeepCopy(nil)
			convey.So(ret, convey.ShouldNotBeNil)
		})
		convey.Convey("h.Write success", func() {
			devices := map[string]string{"100": DefaultDeviceIP}
			ret := MapDeepCopy(devices)
			convey.So(len(ret), convey.ShouldEqual, len(devices))
		})
	})
}

// TestGetDeviceFromPodAnnotation for test GetDeviceFromPodAnnotation
func TestGetDeviceFromPodAnnotation(t *testing.T) {
	convey.Convey("test GetDeviceFromPodAnnotation", t, func() {
		convey.Convey("input invalid pod", func() {
			_, err := GetDeviceFromPodAnnotation(nil, api.Ascend910)
			convey.So(err, convey.ShouldNotBeNil)
		})
		convey.Convey("annotationTag not exist", func() {
			_, err := GetDeviceFromPodAnnotation(&v1.Pod{}, api.Ascend910)
			convey.So(err, convey.ShouldNotBeNil)
		})
		convey.Convey("annotationTag exist", func() {
			pod := v1.Pod{}
			pod.Annotations = map[string]string{api.ResourceNamePrefix + api.Ascend910: "Ascend910-0"}
			_, err := GetDeviceFromPodAnnotation(&pod, api.Ascend910)
			convey.So(err, convey.ShouldBeNil)
		})
	})
}

func createFile(filePath string) error {
	f, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer f.Close()
	if err := f.Chmod(SocketChmod); err != nil {
		return err
	}
	return nil
}

// TestGetDefaultDevices2 for GetDefaultDevices
func TestGetDefaultDevices2(t *testing.T) {
	convey.Convey("test TestGetDefaultDevices2", t, func() {
		mockStat := gomonkey.ApplyFunc(getDavinciManagerPath, func() (string, error) {
			return HiAIManagerDevice, nil
		})
		defer mockStat.Reset()
		ParamOption = Option{
			ProductTypes: []string{Atlas200ISoc},
		}
		defer func() {
			ParamOption = Option{}
		}()
		convey.Convey("set200SocDefaultDevices return err", func() {
			patch := gomonkey.ApplyFunc(set200SocDefaultDevices, func() ([]string, error) {
				return []string{Atlas200ISocVPC}, fmt.Errorf("err")
			})
			defer patch.Reset()
			_, err := GetDefaultDevices(true)
			convey.So(err, convey.ShouldNotBeNil)
		})
		convey.Convey("set200SocDefaultDevices return nil", func() {
			patch := gomonkey.ApplyFunc(set200SocDefaultDevices, func() ([]string, error) {
				return []string{Atlas200ISocVPC}, nil
			})
			defer patch.Reset()
			_, err := GetDefaultDevices(true)
			convey.So(err, convey.ShouldBeNil)
		})
	})
}

// TestGetDefaultDevices for GetDefaultDevices
func TestGetDefaultDevices(t *testing.T) {
	convey.Convey("pods is nil", t, func() {
		mockStat := gomonkey.ApplyFunc(os.Stat, func(name string) (os.FileInfo, error) {
			return nil, fmt.Errorf("err")
		})
		defer mockStat.Reset()
		_, err := GetDefaultDevices(true)
		convey.So(err, convey.ShouldNotBeNil)
	})
	if _, err := os.Stat(HiAIHDCDevice); err != nil {
		if err = createFile(HiAIHDCDevice); err != nil {
			t.Fatal("TestGetDefaultDevices Run Failed")
		}
	}

	if _, err := os.Stat(HiAIManagerDevice); err != nil {
		if err = createFile(HiAIManagerDevice); err != nil {
			t.Fatal("TestGetDefaultDevices Run Failed")
		}
	}

	if _, err := os.Stat(HiAISVMDevice); err != nil {
		if err = createFile(HiAISVMDevice); err != nil {
			t.Fatal("TestGetDefaultDevices Run Failed")
		}
	}

	if _, err := os.Stat(DvppCmdlistDevice); err != nil {
		if err = createFile(DvppCmdlistDevice); err != nil {
			t.Fatal("TestGetDefaultDevices Run Failed")
		}
	}

	defaultDevices, err := GetDefaultDevices(true)
	if err != nil {
		t.Errorf("TestGetDefaultDevices Run Failed")
	}
	defaultMap := make(map[string]string)
	defaultMap[HiAIHDCDevice] = ""
	defaultMap[HiAIManagerDevice] = ""
	defaultMap[HiAISVMDevice] = ""
	defaultMap[HiAi200RCEventSched] = ""
	defaultMap[HiAi200RCHiDvpp] = ""
	defaultMap[HiAi200RCLog] = ""
	defaultMap[HiAi200RCMemoryBandwidth] = ""
	defaultMap[HiAi200RCSVM0] = ""
	defaultMap[HiAi200RCTsAisle] = ""
	defaultMap[HiAi200RCUpgrade] = ""
	defaultMap[DvppCmdlistDevice] = ""

	for _, str := range defaultDevices {
		if _, ok := defaultMap[str]; !ok {
			t.Errorf("TestGetDefaultDevices Run Failed")
		}
	}
	t.Logf("TestGetDefaultDevices Run Pass")
}

// TestSet200SocDefaultDevices for test set200SocDefaultDevices
func TestSet200SocDefaultDevices(t *testing.T) {
	convey.Convey("test set200SocDefaultDevices", t, func() {
		convey.Convey("os.Stat err", func() {
			mockStat := gomonkey.ApplyFuncReturn(os.Stat, nil, errors.New("failed"))
			defer mockStat.Reset()
			_, err := set200SocDefaultDevices()
			convey.So(err, convey.ShouldNotBeNil)
		})
		convey.Convey("device is exist", func() {
			mockStat := gomonkey.ApplyFunc(os.Stat, func(name string) (os.FileInfo, error) {
				if name == HiAi200RCEventSched {
					return nil, fmt.Errorf("err")
				}
				return nil, nil
			})
			defer mockStat.Reset()
			ret, err := set200SocDefaultDevices()
			convey.So(ret, convey.ShouldNotBeNil)
			convey.So(err, convey.ShouldBeNil)
		})
	})
}

// TestSet310BDefaultDevices for test set310BDefaultDevices
func TestSet310BDefaultDevices(t *testing.T) {
	convey.Convey("test set310BDefaultDevices", t, func() {
		convey.Convey("os.Stat err", func() {
			mockStat := gomonkey.ApplyFuncReturn(os.Stat, nil, errors.New("failed"))
			defer mockStat.Reset()
			convey.So(len(set310BDefaultDevices()), convey.ShouldEqual, 0)
		})
		convey.Convey("device is exist", func() {
			mockStat := gomonkey.ApplyFuncReturn(os.Stat, nil, nil)
			defer mockStat.Reset()
			convey.So(len(set310BDefaultDevices()), convey.ShouldNotEqual, 0)
		})
	})
}

func TestFilterPods1(t *testing.T) {
	convey.Convey("test FilterPods part1", t, func() {
		convey.Convey("The number of container exceeds the upper limit", func() {
			pods := []v1.Pod{{Spec: v1.PodSpec{Containers: make([]v1.Container, MaxContainerLimit+1)}}}
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("annotationTag not exist", func() {
			pods := []v1.Pod{{Spec: v1.PodSpec{Containers: []v1.Container{{Resources: v1.
				ResourceRequirements{Limits: v1.ResourceList{}}}}}}}
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("annotationTag exist, device is virtual", func() {
			limits := resource.NewQuantity(1, resource.DecimalExponent)
			pods := []v1.Pod{{Spec: v1.PodSpec{Containers: []v1.Container{{Resources: v1.
				ResourceRequirements{Limits: v1.ResourceList{api.ResourceNamePrefix + Ascend910vir2: *limits}}}}}}}
			res := FilterPods(pods, Ascend910vir2, nil)
			convey.So(len(res), convey.ShouldEqual, 1)
		})
		convey.Convey("limitsDevNum exceeds the upper limit", func() {
			limits := resource.NewQuantity(MaxDevicesNum*MaxAICoreNum+1, resource.DecimalExponent)
			pods := []v1.Pod{{Spec: v1.PodSpec{Containers: []v1.Container{{Resources: v1.
				ResourceRequirements{Limits: v1.ResourceList{api.ResourceNamePrefix + Ascend910vir2: *limits}}}}}}}
			res := FilterPods(pods, Ascend910vir2, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("no assigned flag", func() {
			limits := resource.NewQuantity(1, resource.DecimalExponent)
			pods := []v1.Pod{
				{Spec: v1.PodSpec{Containers: []v1.Container{{Resources: v1.ResourceRequirements{Limits: v1.
					ResourceList{api.ResourceNamePrefix + api.Ascend910: *limits}}}}}}}
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("had assigned flag", func() {
			limits := resource.NewQuantity(1, resource.DecimalExponent)
			pods := []v1.Pod{
				{Spec: v1.PodSpec{Containers: []v1.Container{{Resources: v1.ResourceRequirements{Limits: v1.
					ResourceList{api.HuaweiAscend910: *limits}}}}},
					ObjectMeta: metav1.ObjectMeta{Name: "test3", Namespace: "test3",
						Annotations: map[string]string{
							PodPredicateTime: "1", api.HuaweiAscend910: api.Ascend910 + "-1"}},
				},
			}
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(len(res), convey.ShouldEqual, 1)
		})
	})
}

func TestFilterPods2(t *testing.T) {
	convey.Convey("test FilterPods part2", t, func() {
		limits := resource.NewQuantity(1, resource.DecimalExponent)
		pods := []v1.Pod{
			{Spec: v1.PodSpec{Containers: []v1.Container{{Resources: v1.ResourceRequirements{Limits: v1.
				ResourceList{api.HuaweiAscend910: *limits}}}}},
				ObjectMeta: metav1.ObjectMeta{Name: "test3", Namespace: "test3",
					Annotations: map[string]string{
						PodPredicateTime: "1", api.HuaweiAscend910: api.Ascend910 + "-1"},
					DeletionTimestamp: &metav1.Time{}},
				Status: v1.PodStatus{ContainerStatuses: make([]v1.ContainerStatus, 1),
					Reason: "UnexpectedAdmissionError"},
			},
		}
		convey.Convey("DeletionTimestamp is not nil", func() {
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		pods[0].DeletionTimestamp = nil
		convey.Convey("The number of container status exceeds the upper limit", func() {
			pods[0].Status.ContainerStatuses = make([]v1.ContainerStatus, 1)
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("Waiting.Message is not nil", func() {
			pods[0].Status.ContainerStatuses = []v1.ContainerStatus{{State: v1.ContainerState{Waiting: &v1.
				ContainerStateWaiting{Message: "PreStartContainer check failed"}}}}
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("pod.Status.Reason is UnexpectedAdmissionError", func() {
			pods[0].Status = v1.PodStatus{ContainerStatuses: []v1.ContainerStatus{},
				Reason: "UnexpectedAdmissionError"}
			res := FilterPods(pods, api.Ascend910, nil)
			convey.So(res, convey.ShouldBeEmpty)
		})
		convey.Convey("conditionFunc return false", func() {
			pods[0].Status = v1.PodStatus{}
			mockConitionFunc := func(pod *v1.Pod) bool {
				return false
			}
			res := FilterPods(pods, api.Ascend910, mockConitionFunc)
			convey.So(res, convey.ShouldBeEmpty)
		})
	})
}

// TestVerifyPath for VerifyPath
func TestVerifyPath(t *testing.T) {
	convey.Convey("TestVerifyPath", t, func() {
		convey.Convey("filepath.Abs failed", func() {
			mock := gomonkey.ApplyFunc(filepath.Abs, func(path string) (string, error) {
				return "", fmt.Errorf("err")
			})
			defer mock.Reset()
			_, ret := VerifyPathAndPermission("", 0)
			convey.So(ret, convey.ShouldBeFalse)
		})
		convey.Convey("os.Stat failed", func() {
			mock := gomonkey.ApplyFunc(os.Stat, func(name string) (os.FileInfo, error) {
				return nil, fmt.Errorf("err")
			})
			defer mock.Reset()
			_, ret := VerifyPathAndPermission("./", 0)
			convey.So(ret, convey.ShouldBeFalse)
		})
		convey.Convey("filepath.EvalSymlinks failed", func() {
			mock := gomonkey.ApplyFunc(filepath.EvalSymlinks, func(path string) (string, error) {
				return "", fmt.Errorf("err")
			})
			defer mock.Reset()
			_, ret := VerifyPathAndPermission("./", 0)
			convey.So(ret, convey.ShouldBeFalse)
		})
	})
}

// TestCheckPodNameAndSpace for test CheckPodNameAndSpace
func TestCheckPodNameAndSpace(t *testing.T) {
	convey.Convey("test CheckPodNameAndSpace", t, func() {
		convey.Convey("beyond max length", func() {
			podPara, maxLength := "abc", 1
			convey.So(CheckPodNameAndSpace(podPara, maxLength), convey.ShouldNotBeNil)
		})
		convey.Convey("device is exist", func() {
			podPara, maxLength := "abc", PodNameMaxLength
			convey.So(CheckPodNameAndSpace(podPara, maxLength), convey.ShouldBeNil)
			podPara = "abc_d"
			convey.So(CheckPodNameAndSpace(podPara, maxLength), convey.ShouldNotBeNil)
		})
	})
}

// TestWatchFile for test watchFile
func TestWatchFile(t *testing.T) {
	convey.Convey("TestWatchFile", t, func() {
		convey.Convey("fsnotify.NewWatcher ok", func() {
			watcher, err := NewFileWatch()
			convey.So(err, convey.ShouldBeNil)
			convey.So(watcher, convey.ShouldNotBeNil)
		})
		convey.Convey("fsnotify.NewWatcher failed", func() {
			mock := gomonkey.ApplyFunc(fsnotify.NewWatcher, func() (*fsnotify.Watcher, error) {
				return nil, fmt.Errorf("error")
			})
			defer mock.Reset()
			watcher, err := NewFileWatch()
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(watcher, convey.ShouldBeNil)
		})
		watcher, _ := NewFileWatch()
		convey.Convey("stat failed", func() {
			convey.So(watcher, convey.ShouldNotBeNil)
			mock := gomonkey.ApplyFunc(os.Stat, func(name string) (os.FileInfo, error) {
				return nil, fmt.Errorf("err")
			})
			defer mock.Reset()
			err := watcher.WatchFile("")
			convey.So(err, convey.ShouldNotBeNil)
		})
		mockStat := gomonkey.ApplyFunc(os.Stat, func(name string) (os.FileInfo, error) {
			return nil, nil
		})
		defer mockStat.Reset()
		convey.Convey("Add failed", func() {
			convey.So(watcher, convey.ShouldNotBeNil)
			mockWatchFile := gomonkey.ApplyMethod(reflect.TypeOf(new(fsnotify.Watcher)), "Add",
				func(_ *fsnotify.Watcher, name string) error { return fmt.Errorf("err") })
			defer mockWatchFile.Reset()
			err := watcher.WatchFile("")
			convey.So(err, convey.ShouldNotBeNil)
		})
		convey.Convey("Add ok", func() {
			convey.So(watcher, convey.ShouldNotBeNil)
			mockWatchFile := gomonkey.ApplyMethod(reflect.TypeOf(new(fsnotify.Watcher)), "Add",
				func(_ *fsnotify.Watcher, name string) error { return nil })
			defer mockWatchFile.Reset()
			err := watcher.WatchFile("")
			convey.So(err, convey.ShouldBeNil)
		})
	})
}

// TestGetDeviceListID for test GetDeviceListID
func TestGetDeviceListID(t *testing.T) {
	convey.Convey("TestGetDeviceListID", t, func() {
		convey.Convey("device num excceed max num", func() {
			devices := make([]string, MaxDevicesNum+1)
			_, _, ret := GetDeviceListID(devices, "")
			convey.So(ret, convey.ShouldNotBeNil)
		})
		convey.Convey("device name is invalid", func() {
			devices := []string{"Ascend910"}
			_, _, ret := GetDeviceListID(devices, "")
			convey.So(ret, convey.ShouldNotBeNil)
		})
		convey.Convey("physical device", func() {
			devices := []string{"Ascend910-0"}
			_, ascendVisibleDevices, ret := GetDeviceListID(devices, "")
			convey.So(ret, convey.ShouldBeNil)
			convey.So(len(ascendVisibleDevices), convey.ShouldEqual, 1)
		})
		convey.Convey("virtual device", func() {
			devices := []string{"Ascend910-2c-100-0"}
			_, ascendVisibleDevices, ret := GetDeviceListID(devices, VirtualDev)
			convey.So(ret, convey.ShouldBeNil)
			convey.So(len(ascendVisibleDevices), convey.ShouldEqual, 1)
		})
	})
}

// TestGetPodConfiguration for test GetPodConfiguration
func TestGetPodConfiguration(t *testing.T) {
	convey.Convey("TestGetPodConfiguration", t, func() {
		convey.Convey("Marshal failed", func() {
			mockMarshal := gomonkey.ApplyFunc(json.Marshal, func(v interface{}) ([]byte, error) {
				return nil, fmt.Errorf("err")
			})
			defer mockMarshal.Reset()
			devices := map[int]string{100: DefaultDeviceIP}
			phyDevMapVirtualDev := map[int]int{100: 0}
			deviceType := "Ascend910-2c"
			superPodID := int32(1)
			info := ServerInfo{
				ServerID:   DefaultDeviceIP,
				DeviceType: deviceType,
				SuperPodID: superPodID,
			}
			ret := GetPodConfiguration(phyDevMapVirtualDev, devices, "pod-name", info, nil)
			convey.So(ret, convey.ShouldBeEmpty)
		})
		convey.Convey("Marshal ok", func() {
			devices := map[int]string{100: DefaultDeviceIP}
			phyDevMapVirtualDev := map[int]int{100: 0}
			deviceType := "Ascend910-2c"
			superPodID := int32(1)
			info := ServerInfo{
				ServerID:   DefaultDeviceIP,
				DeviceType: deviceType,
				SuperPodID: superPodID,
			}
			ret := GetPodConfiguration(phyDevMapVirtualDev, devices, "pod-name", info, nil)
			convey.So(ret, convey.ShouldNotBeEmpty)
		})
	})
}

// TestNewSignWatcher for test NewSignWatcher
func TestNewSignWatcher(t *testing.T) {
	convey.Convey("TestNewSignWatcher", t, func() {
		signChan := NewSignWatcher(syscall.SIGHUP)
		convey.So(signChan, convey.ShouldNotBeNil)
	})
}

// TestCheckFileUserSameWithProcess for test CheckFileUserSameWithProcess
func TestCheckFileUserSameWithProcess(t *testing.T) {
	convey.Convey("CheckFileUserSameWithProcess", t, func() {
		var testMode os.FileMode = 0660
		loggerPath := "/home/test"
		convey.Convey("user is root", func() {
			mockFunc := gomonkey.ApplyFuncReturn(os.Getuid, RootUID)
			defer mockFunc.Reset()
			convey.So(CheckFileUserSameWithProcess(loggerPath), convey.ShouldBeTrue)
		})
		convey.Convey("user is not root, logger path is unavailable", func() {
			mockFunc := gomonkey.ApplyFuncReturn(os.Getuid, 1).
				ApplyFuncReturn(os.Lstat, &mockFileInfo{}, fmt.Errorf("get path stat failed"))
			defer mockFunc.Reset()
			convey.So(CheckFileUserSameWithProcess(loggerPath), convey.ShouldBeFalse)
		})
		convey.Convey("user is not root, logger file is unavailable", func() {
			mockFunc := gomonkey.ApplyFuncReturn(os.Getuid, 1).
				ApplyFuncReturn(os.Lstat, &mockFileInfo{mode: testMode, sys: "invalid-type"}, nil)
			defer mockFunc.Reset()
			convey.So(CheckFileUserSameWithProcess(loggerPath), convey.ShouldBeFalse)
		})
		convey.Convey("user is not root, logger file stat uid or gid is not equal curUid", func() {
			mockFunc := gomonkey.ApplyFuncReturn(os.Getuid, 1).
				ApplyFuncReturn(os.Lstat, &mockFileInfo{mode: testMode, sys: &syscall.Stat_t{Uid: RootUID}}, nil)
			defer mockFunc.Reset()
			convey.So(CheckFileUserSameWithProcess(loggerPath), convey.ShouldBeFalse)
		})
		convey.Convey("user is not root, both logger file stat uid and gid are equal curUid", func() {
			mockFunc := gomonkey.ApplyFuncReturn(os.Getuid, 1).
				ApplyFuncReturn(os.Lstat, &mockFileInfo{mode: testMode, sys: &syscall.Stat_t{Uid: 1, Gid: 1}}, nil)
			defer mockFunc.Reset()
			convey.So(CheckFileUserSameWithProcess(loggerPath), convey.ShouldBeTrue)
		})
	})
}

// TestIsContainAtlas300IDuo for test IsContainAtlas300IDuo
func TestIsContainAtlas300IDuo(t *testing.T) {
	convey.Convey("IsContainAtlas300IDuo", t, func() {
		convey.Convey("IsContainAtlas300IDuo success", func() {
			ParamOption.ProductTypes = nil
			convey.So(IsContainAtlas300IDuo(), convey.ShouldBeFalse)
			ParamOption.ProductTypes = []string{Atlas300IDuo}
			convey.So(IsContainAtlas300IDuo(), convey.ShouldBeTrue)
		})
	})
}

// TestRecordFaultInfoList for test RecordFaultInfoList
func TestRecordFaultInfoList(t *testing.T) {
	convey.Convey("test RecordFaultInfoList success", t, func() {
		RecordFaultInfoList([]*TaskDevInfo{{}})
	})
}

// TestInt32Join for test Int32Join
func TestInt32Join(t *testing.T) {
	convey.Convey("test Int32Join success", t, func() {
		convey.So(Int32Join([]int32{0, 1}, ","), convey.ShouldEqual, "0,1")
	})
}

// TestGetDeviceRunMode for test GetDeviceRunMode
func TestGetDeviceRunMode(t *testing.T) {
	convey.Convey("test GetDeviceRunMode", t, func() {
		convey.Convey("device mode is Ascend310", func() {
			ParamOption.RealCardType = api.Ascend310
			ret, err := GetDeviceRunMode()
			convey.So(ret, convey.ShouldEqual, api.Ascend310)
			convey.So(err, convey.ShouldBeNil)
		})
		convey.Convey("device mode is Ascend910, when card real type is Ascend910", func() {
			ParamOption.RealCardType = api.Ascend910
			ret, err := GetDeviceRunMode()
			convey.So(ret, convey.ShouldEqual, api.Ascend910)
			convey.So(err, convey.ShouldBeNil)
		})
		convey.Convey("device mode is Ascend910, when card real type is Ascend910B", func() {
			ParamOption.RealCardType = api.Ascend910B
			ret, err := GetDeviceRunMode()
			convey.So(ret, convey.ShouldEqual, api.Ascend910)
			convey.So(err, convey.ShouldBeNil)
		})
		convey.Convey("device mode is Ascend910, when card real type is Atlas A3", func() {
			ParamOption.RealCardType = api.Ascend910A3
			ret, err := GetDeviceRunMode()
			convey.So(ret, convey.ShouldEqual, api.Ascend910)
			convey.So(err, convey.ShouldBeNil)
		})
		convey.Convey("device mode is Ascend310P", func() {
			ParamOption.RealCardType = api.Ascend310P
			ret, err := GetDeviceRunMode()
			convey.So(ret, convey.ShouldEqual, api.Ascend310P)
			convey.So(err, convey.ShouldBeNil)
		})
		convey.Convey("device mode is invalid", func() {
			ParamOption.RealCardType = ""
			_, err := GetDeviceRunMode()
			convey.So(err, convey.ShouldNotBeNil)
		})
	})
}

// TestCheckDeviceName for test CheckDeviceName
func TestCheckDeviceName(t *testing.T) {
	originalRealCardType := ParamOption.RealCardType
	defer func() { ParamOption.RealCardType = originalRealCardType }()

	convey.Convey("test CheckDeviceName", t, func() {
		convey.Convey("device name is valid", func() {
			convey.So(CheckDeviceName(api.Ascend910+"-0", api.Ascend910), convey.ShouldBeTrue)
		})
		convey.Convey("device name is invalid", func() {
			convey.So(CheckDeviceName("", api.Ascend910), convey.ShouldBeFalse)
		})
		convey.Convey("npu-x format should be valid for Atlas 950", func() {
			ParamOption.RealCardType = api.Ascend910A5
			convey.So(CheckDeviceName(api.NPULowerCase+"-0", api.Ascend910), convey.ShouldBeTrue)
			convey.So(CheckDeviceName(api.NPULowerCase+"-3", api.Ascend910), convey.ShouldBeTrue)
		})
		convey.Convey("Ascend910-x format should still be valid for Atlas 950", func() {
			ParamOption.RealCardType = api.Ascend910A5
			convey.So(CheckDeviceName(api.Ascend910+"-0", api.Ascend910), convey.ShouldBeTrue)
		})
		convey.Convey("npu-x format should be invalid for old device type", func() {
			ParamOption.RealCardType = api.Ascend910A
			convey.So(CheckDeviceName(api.NPULowerCase+"-0", api.Ascend910), convey.ShouldBeFalse)
		})
	})
}

// newTestPod creates a test Pod instance with specified labels
func newTestPod(labels map[string]string) *v1.Pod {
	return &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Labels: labels,
		},
	}
}

// TestGetJobNameOfPod
func TestGetJobNameOfPod(t *testing.T) {
	convey.Convey("Test GetJobNameOfPod function", t, func() {
		const fakeJobName = "job1"
		convey.Convey("Pod pointer is nil", func() {
			res := GetJobNameOfPod(nil)
			convey.So(res, convey.ShouldEqual, "")
		})

		convey.Convey("Label ResetTaskNameKey exists (highest priority)", func() {
			pod := newTestPod(map[string]string{ResetTaskNameKey: fakeJobName})
			res := GetJobNameOfPod(pod)
			convey.So(res, convey.ShouldEqual, fakeJobName)
		})

		convey.Convey("Label ResetTaskNameKeyInLabel exists (second priority)", func() {
			pod := newTestPod(map[string]string{ResetTaskNameKeyInLabel: fakeJobName})
			res := GetJobNameOfPod(pod)
			convey.So(res, convey.ShouldEqual, fakeJobName)
		})

		convey.Convey("Label DeploymentNameKeyInLabel exists (lowest priority)", func() {
			pod := newTestPod(map[string]string{DeploymentNameKeyInLabel: fakeJobName})
			res := GetJobNameOfPod(pod)
			convey.So(res, convey.ShouldEqual, fakeJobName)
		})

		convey.Convey("Multiple target labels exist, verify priority rule", func() {
			pod := newTestPod(map[string]string{
				ResetTaskNameKey:         fakeJobName,
				ResetTaskNameKeyInLabel:  "other-job",
				DeploymentNameKeyInLabel: "other-job2",
			})
			res := GetJobNameOfPod(pod)
			convey.So(res, convey.ShouldEqual, fakeJobName)
		})

		convey.Convey("No target labels exist, return empty string", func() {
			pod := newTestPod(map[string]string{"other-label": "val"})
			res := GetJobNameOfPod(pod)
			convey.So(res, convey.ShouldEqual, "")
		})

		convey.Convey("Pod has empty label map, return empty string", func() {
			pod := newTestPod(map[string]string{})
			res := GetJobNameOfPod(pod)
			convey.So(res, convey.ShouldEqual, "")
		})
	})
}

// TestCheckDeviceName for test GetSyncMapLen
func TestGetSyncMapLen(t *testing.T) {
	t.Run("TestGetSyncMapLen", func(t *testing.T) {
		m := &sync.Map{}
		m.Store("key1", "value1")
		m.Store("key2", "value2")
		if got := GetSyncMapLen(m); got != 2 {
			t.Errorf("GetSyncMapLen() = %v, want %v", got, 2)
		}
	})
}

// TestObjToString for test ObjToString
func TestObjToString(t *testing.T) {
	t.Run("TestObjToString", func(t *testing.T) {
		mp := map[string]string{"hello": "world"}
		want := `{"hello":"world"}`
		if got := ObjToString(mp); got != want {
			t.Errorf("ObjToString failed")
		}
	})
}

// TestKeys for test Keys
func TestKeys(t *testing.T) {
	t.Run("TestKeys", func(t *testing.T) {
		mp := map[string]string{"key": "value"}
		want := "key"
		if got := Keys(mp); got[0] != want {
			t.Errorf("Keys() = %v, want %v", got[0], want)
		}
	})
}

// TestSetDeviceByPathWhen200RC for test setDeviceByPathWhen200RC
func TestSetDeviceByPathWhen200RC(t *testing.T) {
	convey.Convey("test setDeviceByPathWhen200RC", t, func() {
		// 01-stub os.Stat, set device success, devices should be updated
		mockStat := gomonkey.ApplyFunc(os.Stat, func(name string) (os.FileInfo, error) {
			return nil, nil
		})
		defer mockStat.Reset()
		devices := []string{}
		setDeviceByPathWhen200RC(&devices)
		convey.So(len(devices), convey.ShouldEqual, 7)
		convey.So(devices[0], convey.ShouldEqual, HiAi200RCEventSched)
		if len(devices) >= 7 {
			convey.So(devices[6], convey.ShouldEqual, HiAi200RCUpgrade)
		}
	})
}

// TestGetPodNameFromEnv for test GetPodNameFromEnv
func TestGetPodNameFromEnv(t *testing.T) {
	convey.Convey("test getPodNameFromEnv", t, func() {
		convey.Convey("01-check pod name and space failed, should return error", func() {
			mockGetEnv := gomonkey.ApplyFuncReturn(os.Getenv, "master-1")
			defer mockGetEnv.Reset()
			mockCheck := gomonkey.ApplyFuncReturn(CheckPodNameAndSpace, errors.New("failed"))
			defer mockCheck.Reset()
			_, err := GetPodNameFromEnv()
			convey.So(err, convey.ShouldNotBeNil)
		})
		convey.Convey("02-check pod name and space success, should return nil", func() {
			mockGetEnv := gomonkey.ApplyFuncReturn(os.Getenv, "master-1")
			defer mockGetEnv.Reset()
			podName, err := GetPodNameFromEnv()
			convey.So(err, convey.ShouldBeNil)
			convey.So(podName == "master-1", convey.ShouldBeTrue)
		})
	})
}

// TestIsContainAll300IDuo for test IsContainAll300IDuo
func TestIsContainAll300IDuo(t *testing.T) {
	convey.Convey("test IsContainAll300IDuo", t, func() {
		convey.Convey("01-productType length is zero, should return false", func() {
			mockParam := gomonkey.ApplyGlobalVar(&ParamOption, Option{})
			defer mockParam.Reset()
			convey.So(IsContainAll300IDuo(), convey.ShouldBeFalse)
		})
		convey.Convey("02-productType has Atlas300IDuo, should return true", func() {
			mockParam := gomonkey.ApplyGlobalVar(&ParamOption, Option{ProductTypes: []string{Atlas300IDuo}})
			defer mockParam.Reset()
			convey.So(IsContainAll300IDuo(), convey.ShouldBeTrue)
		})
		convey.Convey("03-productType has other type, should return false", func() {
			mockParam := gomonkey.ApplyGlobalVar(&ParamOption, Option{ProductTypes: []string{Atlas300IDuo, "other type"}})
			defer mockParam.Reset()
			convey.So(IsContainAll300IDuo(), convey.ShouldBeFalse)
		})
	})
}

// TestIntInList for test IntInList
func TestIntInList(t *testing.T) {
	convey.Convey("test intInList", t, func() {
		list := []int32{1, 2, 3}
		// 01-list has target number, should return true
		convey.So(IntInList(2, list), convey.ShouldBeTrue)
		// 01-list has not target number, should return false
		convey.So(IntInList(4, list), convey.ShouldBeFalse)
	})
}

// TestCompareStringSetMap for test CompareStringSetMap
func TestCompareStringSetMap(t *testing.T) {
	tests := []struct {
		name     string
		map1     map[string]sets.String
		map2     map[string]sets.String
		expected bool
	}{
		{name: "Both maps are nil, should return true", map1: nil, map2: nil, expected: true},
		{name: "One map is nil and the other is not, should return false",
			map1: nil, map2: map[string]sets.String{}, expected: false},
		{name: "Maps have different lengths, should return false",
			map1: map[string]sets.String{"key1": sets.NewString("subKey1")},
			map2: map[string]sets.String{"key1": sets.NewString("subKey1"),
				"key2": sets.NewString("subKey1")}, expected: false},
		{name: "Maps have different keys, should return false",
			map1: map[string]sets.String{"key1": sets.NewString("subKey1")},
			map2: map[string]sets.String{"key2": sets.NewString("subKey1")}, expected: false},
		{name: "Maps have different values, should return false",
			map1: map[string]sets.String{"key": sets.NewString("subKey1")},
			map2: map[string]sets.String{"key": sets.NewString("subKey2")}, expected: false},
		{name: "Maps are identical, should return true",
			map1: map[string]sets.String{"key": sets.NewString("subKey")},
			map2: map[string]sets.String{"key": sets.NewString("subKey")}, expected: true},
		{name: "Maps have same keys and values but different order, should return true",
			map1: map[string]sets.String{"key": sets.NewString("subKey1", "subKey2")},
			map2: map[string]sets.String{"key": sets.NewString("subKey2", "subKey1")}, expected: true},
		{name: "Both maps are empty, should return true",
			map1: map[string]sets.String{}, map2: map[string]sets.String{}, expected: true},
	}

	convey.Convey("Test CompareStringSetMap function", t, func() {
		for _, tc := range tests {
			convey.Convey(tc.name, func() {
				res := CompareStringSetMap(tc.map1, tc.map2)
				convey.So(res, convey.ShouldEqual, tc.expected)
			})
		}
	})
}

// getDeviceFromAllDeviceInfo tests getDeviceFromBaseNpuInfo
func TestGetDeviceFromAllDeviceInfo(t *testing.T) {
	convey.Convey("test getDeviceFromAllDeviceInfo", t, func() {
		convey.Convey("01. should return device for given device Id and allDevices", func() {
			deviceId := 0
			devices := map[int]string{0: "DefaultDeviceIP"}
			allDevs := []NpuDevice{
				{
					SuperDeviceID: 1,
					LevelList: []api.RankLevel{
						{Level: 0, Info: make(map[string]api.LevelElement)},
					},
				},
			}
			dev := getDeviceFromAllDeviceInfo(deviceId, devices, allDevs)
			convey.So(reflect.DeepEqual(dev, Device{
				DeviceID:      "0",
				DeviceIP:      "DefaultDeviceIP",
				SuperDeviceID: "1",
				LevelList: []api.RankLevel{
					{Level: 0, Info: make(map[string]api.LevelElement)},
				},
			}), convey.ShouldBeTrue)
		})
		convey.Convey("02. should return abnormal device when allDevices contains no device Id", func() {
			deviceId := 0
			devices := map[int]string{0: "DefaultDeviceIP"}
			dev := getDeviceFromAllDeviceInfo(deviceId, devices, nil)
			convey.So(dev.SuperDeviceID, convey.ShouldEqual, strconv.Itoa(SdIdAbnormal))
			convey.So(dev.LevelList, convey.ShouldBeNil)
		})
	})
}

func TestTriggerUpdate(t *testing.T) {
	convey.Convey("trigger update success", t, func() {
		verifyUpdateTrigger(t)
		TriggerUpdate("test trigger update")
		convey.So(verifyUpdateTrigger(t), convey.ShouldBeTrue)
	})
	convey.Convey("not trigger update", t, func() {
		verifyUpdateTrigger(t)
		if updateTriggerChan == nil {
			t.Error("updateTriggerChan is nil")
		}
		updateTriggerChan <- struct{}{}
		TriggerUpdate("test trigger update")
		convey.So(verifyUpdateTrigger(t), convey.ShouldBeTrue)
	})
}

func verifyUpdateTrigger(t *testing.T) bool {
	if updateTriggerChan == nil {
		t.Error("updateTriggerChan is nil")
	}
	select {
	case <-updateTriggerChan:
		return true
	default:
		return false
	}
}

type testCase struct {
	name          string
	pod           *v1.Pod
	deviceType    string
	expectedAnnot string
	expectedErr   string
}

func getAnnotationTag(deviceType string) string {
	return fmt.Sprintf("%s%s", api.ResourceNamePrefix, deviceType)
}

func createNilPodTestCase() testCase {
	return testCase{
		name:          "Pod is nil",
		pod:           nil,
		deviceType:    "gpu",
		expectedAnnot: "",
		expectedErr:   "invalid pod",
	}
}

func createAnnotationNotFoundTestCase() testCase {
	return testCase{
		name: "Annotation not found",
		pod: &v1.Pod{
			ObjectMeta: metav1.ObjectMeta{
				Name: "test-pod",
				Annotations: map[string]string{
					"other-annotation": "some-value",
				},
			},
		},
		deviceType:    "gpu",
		expectedAnnot: "",
		expectedErr:   "cannot find the annotation",
	}
}

func createAnnotationTooLongTestCase() testCase {
	return testCase{
		name: "Annotation too long",
		pod: &v1.Pod{
			ObjectMeta: metav1.ObjectMeta{
				Name: "test-pod",
				Annotations: map[string]string{
					getAnnotationTag("gpu"): strings.Repeat("a", PodAnnotationMaxLength+1),
				},
			},
		},
		deviceType:    "gpu",
		expectedAnnot: "",
		expectedErr:   "pod annotation size out of memory",
	}
}

func createSuccessfulGetAnnotationTestCase() testCase {
	return testCase{
		name: "Successfully get annotation",
		pod: &v1.Pod{
			ObjectMeta: metav1.ObjectMeta{
				Name: "test-pod",
				Annotations: map[string]string{
					getAnnotationTag("gpu"): "gpu-resource-info",
					"other-annotation":      "other-value",
				},
			},
		},
		deviceType:    "gpu",
		expectedAnnot: "gpu-resource-info",
		expectedErr:   "",
	}
}

func TestGetPodAnnotationByDeviceType(t *testing.T) {
	convey.Convey("Testing GetPodAnnotationByDeviceType function", t, func() {
		testCases := []testCase{
			createNilPodTestCase(),
			createAnnotationNotFoundTestCase(),
			createAnnotationTooLongTestCase(),
			createSuccessfulGetAnnotationTestCase(),
		}
		for _, tc := range testCases {
			convey.Convey(tc.name, func() {
				annot, err := GetPodAnnotationByDeviceType(tc.pod, tc.deviceType)
				convey.So(tc.expectedAnnot, convey.ShouldEqual, annot)
				if tc.expectedErr != "" {
					convey.So(err, convey.ShouldNotBeNil)
				} else {
					convey.So(err, convey.ShouldBeNil)
				}
			})
		}
	})
}

type isSoftShareDevJobTestCase struct {
	name     string
	pod      *v1.Pod
	expected bool
}

func createIsSoftShareDevJobTestCase() []isSoftShareDevJobTestCase {
	return []isSoftShareDevJobTestCase{
		{
			name:     "Pod is nil",
			pod:      nil,
			expected: false,
		},
		{
			name: "Pod.Annotations is nil",
			pod: &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Annotations: nil,
				},
			},
			expected: false,
		},
		{
			name: "Missing SchedulerSoftShareDevPolicyKey",
			pod: &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Annotations: map[string]string{
						api.SchedulerSoftShareDevAicoreQuotaKey: "10",
						api.SchedulerSoftShareDevHbmQuotaKey:    "20",
					},
				},
			},
			expected: false,
		},
		{
			name: "All required keys present",
			pod: &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Annotations: map[string]string{
						api.SchedulerSoftShareDevPolicyKey:      "policy-value",
						api.SchedulerSoftShareDevAicoreQuotaKey: "10",
						api.SchedulerSoftShareDevHbmQuotaKey:    "20",
					},
				},
			},
			expected: true,
		},
	}
}

func TestIsSoftShareDevJob(t *testing.T) {
	tests := createIsSoftShareDevJobTestCase()
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := IsSoftShareDevJob(tt.pod)
			if result != tt.expected {
				t.Errorf("IsSoftShareDevJob() = %v, want %v", result, tt.expected)
			}
		})
	}
}

func TestConvertSchedulingPolicyToIntStr(t *testing.T) {
	convey.Convey("Testing ConvertSchedulingPolicyToIntStr function", t, func() {
		testCases := []struct {
			name           string
			input          string
			expectedOutput string
		}{
			{
				name:           "TC001 - Empty input",
				input:          "",
				expectedOutput: "",
			},
			{
				name:           "TC002 - Valid input 'fixed-share'",
				input:          "fixed-share",
				expectedOutput: "1",
			},
			{
				name:           "TC003 - Valid input 'elastic'",
				input:          "elastic",
				expectedOutput: "2",
			},
			{
				name:           "TC004 - Valid input 'best-effort'",
				input:          "best-effort",
				expectedOutput: "3",
			},
			{
				name:           "TC005 - Invalid input 'unknown-policy'",
				input:          "unknown-policy",
				expectedOutput: "",
			},
		}
		for _, tc := range testCases {
			convey.Convey(tc.name, func() {
				result := ConvertSchedulingPolicyToIntStr(tc.input)
				convey.So(tc.expectedOutput, convey.ShouldEqual, result)
			})
		}
	})
}

type getDeviceFromPodAnnotationTestCase struct {
	name               string
	mockRealCardType   string
	mockStatDockerPath func() (os.FileInfo, error)
	mockStatDevicePath func() (os.FileInfo, error)
	expectedPath       string
	expectedErr        error
}

func buildGetDeviceFromPodAnnotationTestCases() []getDeviceFromPodAnnotationTestCase {
	testErrFileNotExist := errors.New("stat /dev/hiai_manager: no such file or directory")
	return []getDeviceFromPodAnnotationTestCase{
		{
			name:               "Ascend310B card + docker path exists",
			mockRealCardType:   api.Ascend310B,
			mockStatDockerPath: func() (os.FileInfo, error) { return nil, nil },
			mockStatDevicePath: func() (os.FileInfo, error) { return nil, nil },
			expectedPath:       HiAIManagerDeviceDocker,
			expectedErr:        nil,
		},
		{
			name:               "Ascend310B card + docker path not exist + device path exists",
			mockRealCardType:   api.Ascend310B,
			mockStatDockerPath: func() (os.FileInfo, error) { return nil, testErrFileNotExist },
			mockStatDevicePath: func() (os.FileInfo, error) { return nil, nil },
			expectedPath:       HiAIManagerDevice,
			expectedErr:        nil,
		},
		{
			name:               "non-Ascend310B card + device path exists",
			mockRealCardType:   api.Ascend910,
			mockStatDockerPath: func() (os.FileInfo, error) { return nil, nil },
			mockStatDevicePath: func() (os.FileInfo, error) { return nil, nil },
			expectedPath:       HiAIManagerDevice,
			expectedErr:        nil,
		},
		{
			name:               "device path not exist",
			mockRealCardType:   api.Ascend910,
			mockStatDockerPath: func() (os.FileInfo, error) { return nil, nil },
			mockStatDevicePath: func() (os.FileInfo, error) { return nil, testErrFileNotExist },
			expectedPath:       "",
			expectedErr:        testErrFileNotExist,
		},
	}
}

func TestGetDavinciManagerPath(t *testing.T) {
	convey.Convey("Test getDavinciManagerPath", t, func() {
		tests := buildGetDeviceFromPodAnnotationTestCases()
		for _, tt := range tests {
			convey.Convey(tt.name, func() {
				patchCardType := gomonkey.ApplyGlobalVar(&ParamOption, Option{RealCardType: tt.mockRealCardType})
				defer patchCardType.Reset()
				patchStat := gomonkey.ApplyFunc(os.Stat,
					func(path string) (os.FileInfo, error) {
						switch path {
						case HiAIManagerDeviceDocker:
							return tt.mockStatDockerPath()
						case HiAIManagerDevice:
							return tt.mockStatDevicePath()
						default:
							return nil, os.ErrNotExist
						}
					})
				defer patchStat.Reset()
				gotPath, gotErr := getDavinciManagerPath()
				convey.So(gotPath, convey.ShouldEqual, tt.expectedPath)

				if tt.expectedErr == nil {
					convey.So(gotErr, convey.ShouldBeNil)
				} else {
					convey.So(gotErr, convey.ShouldNotBeNil)
				}
			})
		}
	})
}

func TestGetMaxVirtualIDByPhysicalID(t *testing.T) {
	convey.Convey("Test GetMaxVirtualIDByPhysicalID", t, func() {
		convey.Convey("When getNPUInfoConfigBaseDir returns error", func() {
			patches := gomonkey.ApplyFuncReturn(getNPUInfoConfigBaseDir, "", errors.New("dir not exist"))
			defer patches.Reset()

			maxVID, err := GetMaxVirtualIDByPhysicalID(0)
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(maxVID, convey.ShouldEqual, MinVirtualID)
		})
		convey.Convey("When collectMatchedVirtualIDs returns error", func() {
			patches := gomonkey.ApplyFuncReturn(getNPUInfoConfigBaseDir, SoftShareDevNPUInfoConfigParentDirPath, nil)
			patches.ApplyFuncReturn(collectMatchedVirtualIDs, nil, errors.New("read dir failed"))
			defer patches.Reset()

			maxVID, err := GetMaxVirtualIDByPhysicalID(0)
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(maxVID, convey.ShouldEqual, MinVirtualID)
		})
		convey.Convey("When all steps success, return max VirtualID", func() {
			patches := gomonkey.ApplyFuncReturn(getNPUInfoConfigBaseDir, SoftShareDevNPUInfoConfigParentDirPath, nil)
			patches.ApplyFuncReturn(collectMatchedVirtualIDs, []int{1, num5, num3}, nil)
			patches.ApplyFuncReturn(calculateMaxVirtualID, num5)
			defer patches.Reset()

			maxVID, err := GetMaxVirtualIDByPhysicalID(0)
			convey.So(err, convey.ShouldBeNil)
			convey.So(maxVID, convey.ShouldEqual, num5)
		})
		convey.Convey("When no matched VirtualID, return -1", func() {
			patches := gomonkey.ApplyFuncReturn(getNPUInfoConfigBaseDir, SoftShareDevNPUInfoConfigParentDirPath, nil)
			patches.ApplyFuncReturn(collectMatchedVirtualIDs, []int{}, nil)
			defer patches.Reset()

			maxVID, err := GetMaxVirtualIDByPhysicalID(0)
			convey.So(err, convey.ShouldBeNil)
			convey.So(maxVID, convey.ShouldEqual, -1)
		})
	})
}

func TestGetNPUInfoConfigBaseDir(t *testing.T) {
	convey.Convey("Test getNPUInfoConfigBaseDir", t, func() {
		convey.Convey("When RealDirChecker returns error", func() {
			patches := gomonkey.ApplyFuncReturn(utils.RealDirChecker, "", errors.New("dir not exist"))
			defer patches.Reset()
			dirPath, err := getNPUInfoConfigBaseDir()
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(dirPath, convey.ShouldBeEmpty)
			convey.So(err.Error(), convey.ShouldContainSubstring, "stat npu info config dir")
		})
		convey.Convey("When RealDirChecker success", func() {
			patches := gomonkey.ApplyFuncReturn(utils.RealDirChecker, SoftShareDevNPUInfoConfigParentDirPath, nil)
			defer patches.Reset()
			dirPath, err := getNPUInfoConfigBaseDir()
			convey.So(err, convey.ShouldBeNil)
			convey.So(dirPath, convey.ShouldEqual, SoftShareDevNPUInfoConfigParentDirPath)
		})
	})
}

func TestCollectMatchedVirtualIDs(t *testing.T) {
	convey.Convey("Test collectMatchedVirtualIDs", t, func() {
		convey.Convey("When os.ReadDir base dir returns error", func() {
			patches := gomonkey.ApplyFuncReturn(os.ReadDir, nil, errors.New("permission denied"))
			defer patches.Reset()
			vidList, err := collectMatchedVirtualIDs(SoftShareDevNPUInfoConfigParentDirPath, 0)
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(vidList, convey.ShouldBeNil)
			convey.So(err.Error(), convey.ShouldContainSubstring, "read base dir")
		})

		convey.Convey("When os.ReadDir sub dir returns error", func() {
			patches := gomonkey.ApplyFuncReturn(os.ReadDir, nil, errors.New("dir not exist"))
			defer patches.Reset()
			vidList, err := collectMatchedVirtualIDs(SoftShareDevNPUInfoConfigParentDirPath, 0)
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(vidList, convey.ShouldBeEmpty)
		})
	})
}

func TestParseVirtualIDFromDirName(t *testing.T) {
	convey.Convey("Test parseVirtualIDFromDirName", t, func() {
		physicalIDStr := strconv.Itoa(0)
		convey.Convey("When dir name format is invalid", func() {
			vid, err := parseVirtualIDFromDirName("100", physicalIDStr)
			convey.So(err, convey.ShouldNotBeNil)
			convey.So(vid, convey.ShouldEqual, -1)
			convey.So(err.Error(), convey.ShouldContainSubstring, "invalid dir name format")
		})

		convey.Convey("When PhysicalID not match", func() {
			vid, err := parseVirtualIDFromDirName("200_5", physicalIDStr)
			convey.So(err, convey.ShouldBeNil)
			convey.So(vid, convey.ShouldEqual, -1)
		})

		convey.Convey("When parse success", func() {
			vid, err := parseVirtualIDFromDirName("0_1", physicalIDStr)
			convey.So(err, convey.ShouldBeNil)
			convey.So(vid, convey.ShouldEqual, 1)
		})
	})
}

func TestCalculateMaxVirtualID(t *testing.T) {
	convey.Convey("Test calculateMaxVirtualID", t, func() {
		convey.Convey("When virtualIDs is empty", func() {
			maxVID := calculateMaxVirtualID([]int{})
			convey.So(maxVID, convey.ShouldEqual, -1)
		})
		convey.Convey("When virtualIDs has multiple elements", func() {
			maxVID := calculateMaxVirtualID([]int{1, num5, num3})
			convey.So(maxVID, convey.ShouldEqual, num5)
		})
	})
}

func TestSliceEqual(t *testing.T) {
	convey.Convey("Test SliceEqual", t, func() {
		convey.Convey("When two slices are equal, should return true", func() {
			convey.So(SliceEqual[int]([]int{1, 2, 3}, []int{1, 2, 3}), convey.ShouldBeTrue)
		})
		convey.Convey("When two slices are both empty, should return true", func() {
			convey.So(SliceEqual[int]([]int{}, []int{}), convey.ShouldBeTrue)
		})
		convey.Convey("When lengths differ, should return false", func() {
			convey.So(SliceEqual[int]([]int{1, 2}, []int{1, 2, 3}), convey.ShouldBeFalse)
		})
		convey.Convey("When same length but different elements, should return false", func() {
			convey.So(SliceEqual[int]([]int{1, 2, 3}, []int{1, 2, 4}), convey.ShouldBeFalse)
		})
	})
}