Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions api/Control.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ func (i *InstHandler) DeleteVM(w http.ResponseWriter, r *http.Request) {
i.Logger.Error("failed to delete domain", zap.String("uuid", param.UUID), zap.Error(ERR))
return
}
// stat.( map[domainStatus.SourceType]int )[domainStatus.CPU]
// interface{}로 반환하다보니 좀 못생겨졌는데, 나중에 타입 결정하고 변경하면 될 거 같음, 일단은 이렇게 구현
i.DomainControl.DeleteDomain(domain.Domain, param.UUID, int(stat.(map[domainStatus.SourceType]int)[domainStatus.CPU]))

resp.ResponseWriteOK(w, nil)
Expand Down
4 changes: 2 additions & 2 deletions api/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ func (i *InstHandler) ReturnStatusUUID(w http.ResponseWriter, r *http.Request) {
resp.ResponseWriteErr(w, virerr.ErrorJoin(err, errors.New("error returning status from uuid")), http.StatusInternalServerError)
}

DomainDetail := status.DomainDetailFactory(outputStruct, dom)
DomainDetail := status.DomainDetailFactory(outputStruct, dom.Domain)

if err := outputStruct.GetInfo(dom); err != nil {
if err := outputStruct.GetInfo(dom.Domain); err != nil {
resp.ResponseWriteErr(w, err, http.StatusInternalServerError)
return
}
Expand Down
7 changes: 3 additions & 4 deletions vm/service/status/Status.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package status

import (
domCon "github.com/easy-cloud-Knet/KWS_Core/DomCon"
domStatus "github.com/easy-cloud-Knet/KWS_Core/DomCon/domainList_status"
"libvirt.org/go/libvirt"
)
Expand Down Expand Up @@ -87,7 +86,7 @@ type InstDetail struct {
}

type InstDataTypeHandler interface {
GetAllinstInfo(LibvirtInst *libvirt.Connect) error
GetAllinstInfo(LibvirtInst Connect) error
}

const (
Expand Down Expand Up @@ -128,10 +127,10 @@ type DomainInfo struct {
}

type DataTypeHandler interface {
GetInfo(*domCon.Domain) error
GetInfo(Domain) error
}

type DomainDetail struct {
DataHandle DataTypeHandler
Domain *domCon.Domain
Domain Domain
}
17 changes: 17 additions & 0 deletions vm/service/status/domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package status

import "libvirt.org/go/libvirt"

// Domain is a minimal interface over *libvirt.Domain for status service.
// *libvirt.Domain satisfies this via structural typing.
type Domain interface {
GetInfo() (*libvirt.DomainInfo, error)
GetState() (libvirt.DomainState, int, error)
GetUUID() ([]byte, error)
GetGuestInfo(types libvirt.DomainGuestInfoTypes, flags uint32) (*libvirt.DomainGuestInfo, error)
}

// Connect is a minimal interface over *libvirt.Connect for listing all domains.
type Connect interface {
ListAllDomains(flags libvirt.ConnectListAllDomainsFlags) ([]libvirt.Domain, error)
}
15 changes: 7 additions & 8 deletions vm/service/status/domain_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import (
"errors"
"fmt"

domCon "github.com/easy-cloud-Knet/KWS_Core/DomCon"
virerr "github.com/easy-cloud-Knet/KWS_Core/error"
"github.com/google/uuid"
"libvirt.org/go/libvirt"
)

func (DI *DomainInfo) GetInfo(domain *domCon.Domain) error {
info, err := domain.Domain.GetInfo()
func (DI *DomainInfo) GetInfo(domain Domain) error {
info, err := domain.GetInfo()
if err != nil {
return virerr.ErrorGen(virerr.DomainStatusError, err)
}
Expand All @@ -24,14 +23,14 @@ func (DI *DomainInfo) GetInfo(domain *domCon.Domain) error {
return nil
}

func (DP *DomainState) GetInfo(domain *domCon.Domain) error {
info, _, err := domain.Domain.GetState()
func (DP *DomainState) GetInfo(domain Domain) error {
info, _, err := domain.GetState()
//searching for coresponding second parameter, "Reason"
if err != nil {
return virerr.ErrorGen(virerr.DomainStatusError, err)
}

uuidBytes, err := domain.Domain.GetUUID()
uuidBytes, err := domain.GetUUID()
if err != nil {
return virerr.ErrorGen(virerr.InvalidUUID, err)
}
Expand All @@ -42,15 +41,15 @@ func (DP *DomainState) GetInfo(domain *domCon.Domain) error {

DP.DomainState = info
DP.UUID = string(uuidParsed.String())
userInfo, err := domain.Domain.GetGuestInfo(libvirt.DOMAIN_GUEST_INFO_USERS, 0)
userInfo, err := domain.GetGuestInfo(libvirt.DOMAIN_GUEST_INFO_USERS, 0)
if err != nil {
return virerr.ErrorGen(virerr.DomainStatusError, fmt.Errorf("error retreving guest info: %w", err))
}
DP.Users = userInfo.Users
return nil
}

func DomainDetailFactory(Handler DataTypeHandler, dom *domCon.Domain) *DomainDetail {
func DomainDetailFactory(Handler DataTypeHandler, dom Domain) *DomainDetail {
return &DomainDetail{
DataHandle: Handler,
Domain: dom,
Expand Down
5 changes: 2 additions & 3 deletions vm/service/status/instStatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import (
"fmt"

virerr "github.com/easy-cloud-Knet/KWS_Core/error"
"libvirt.org/go/libvirt"
)

func (AII *AllInstInfo) GetAllinstInfo(LibvirtInst *libvirt.Connect) error {
func (AII *AllInstInfo) GetAllinstInfo(LibvirtInst Connect) error {

domains, err := LibvirtInst.ListAllDomains(0) //alldomain
if err != nil {
Expand Down Expand Up @@ -41,7 +40,7 @@ func InstDataTypeRouter(types InstDataType) (InstDataTypeHandler, error) {
return nil, virerr.ErrorGen(virerr.InvalidParameter, fmt.Errorf("unsupported type"))
}

func InstDetailFactory(handler InstDataTypeHandler, LibvirtInst *libvirt.Connect) (*InstDetail, error) {
func InstDetailFactory(handler InstDataTypeHandler, LibvirtInst Connect) (*InstDetail, error) {
if err := handler.GetAllinstInfo(LibvirtInst); err != nil {
return nil, err
}
Expand Down
159 changes: 159 additions & 0 deletions vm/service/status/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package status

import (
"errors"
"fmt"
"testing"

virerr "github.com/easy-cloud-Knet/KWS_Core/error"
"libvirt.org/go/libvirt"
)

// mockDomain implements Domain interface
type mockDomain struct {
infoResult *libvirt.DomainInfo
infoErr error
stateResult libvirt.DomainState
stateErr error
uuidResult []byte
uuidErr error
guestInfoResult *libvirt.DomainGuestInfo
guestInfoErr error
}

func (m *mockDomain) GetInfo() (*libvirt.DomainInfo, error) {
return m.infoResult, m.infoErr
}
func (m *mockDomain) GetState() (libvirt.DomainState, int, error) {
return m.stateResult, 0, m.stateErr
}
func (m *mockDomain) GetUUID() ([]byte, error) {
return m.uuidResult, m.uuidErr
}
func (m *mockDomain) GetGuestInfo(types libvirt.DomainGuestInfoTypes, flags uint32) (*libvirt.DomainGuestInfo, error) {
return m.guestInfoResult, m.guestInfoErr
}

// mockConnect implements Connect interface
type mockConnect struct {
domains []libvirt.Domain
err error
}

func (m *mockConnect) ListAllDomains(flags libvirt.ConnectListAllDomainsFlags) ([]libvirt.Domain, error) {
return m.domains, m.err
}

// valid 16-byte UUID for testing
var testUUIDBytes = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

func TestDomainInfo_GetInfo_Success(t *testing.T) {
mock := &mockDomain{
infoResult: &libvirt.DomainInfo{
State: 1,
MaxMem: 2048,
Memory: 1024,
NrVirtCpu: 2,
CpuTime: 100,
},
}
di := &DomainInfo{}
if err := di.GetInfo(mock); err != nil {
t.Fatalf("expected nil, got %v", err)
}
if di.MaxMem != 2048 || di.NrVirtCpu != 2 {
t.Errorf("fields not populated correctly: %+v", di)
}
}

func TestDomainInfo_GetInfo_Error(t *testing.T) {
mock := &mockDomain{infoErr: fmt.Errorf("libvirt error")}
err := (&DomainInfo{}).GetInfo(mock)
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, virerr.DomainStatusError) {
t.Errorf("expected DomainStatusError, got %v", err)
}
}

func TestDomainState_GetInfo_Success(t *testing.T) {
mock := &mockDomain{
stateResult: libvirt.DomainState(1),
uuidResult: testUUIDBytes,
guestInfoResult: &libvirt.DomainGuestInfo{},
}
ds := &DomainState{}
if err := ds.GetInfo(mock); err != nil {
t.Fatalf("expected nil, got %v", err)
}
if ds.UUID == "" {
t.Error("UUID not populated")
}
}

func TestDomainState_GetInfo_StateError(t *testing.T) {
mock := &mockDomain{stateErr: fmt.Errorf("state error")}
err := (&DomainState{}).GetInfo(mock)
if !errors.Is(err, virerr.DomainStatusError) {
t.Errorf("expected DomainStatusError, got %v", err)
}
}

func TestDomainState_GetInfo_UUIDError(t *testing.T) {
mock := &mockDomain{
stateResult: libvirt.DomainState(1),
uuidErr: fmt.Errorf("uuid error"),
}
err := (&DomainState{}).GetInfo(mock)
if !errors.Is(err, virerr.InvalidUUID) {
t.Errorf("expected InvalidUUID, got %v", err)
}
}

func TestDomainState_GetInfo_GuestInfoError(t *testing.T) {
mock := &mockDomain{
stateResult: libvirt.DomainState(1),
uuidResult: testUUIDBytes,
guestInfoErr: fmt.Errorf("guest info error"),
}
err := (&DomainState{}).GetInfo(mock)
if !errors.Is(err, virerr.DomainStatusError) {
t.Errorf("expected DomainStatusError, got %v", err)
}
}

func TestAllInstInfo_GetAllinstInfo_ListError(t *testing.T) {
mock := &mockConnect{err: fmt.Errorf("libvirt error")}
err := (&AllInstInfo{}).GetAllinstInfo(mock)
if !errors.Is(err, virerr.HostStatusError) {
t.Errorf("expected HostStatusError, got %v", err)
}
}

func TestAllInstInfo_GetAllinstInfo_EmptyList(t *testing.T) {
mock := &mockConnect{domains: []libvirt.Domain{}}
aii := &AllInstInfo{}
if err := aii.GetAllinstInfo(mock); err != nil {
t.Fatalf("expected nil, got %v", err)
}
if aii.Totalmaxmem != 0 || aii.TotalVCpu != 0 {
t.Errorf("expected zeros, got %+v", aii)
}
}

func TestDataTypeRouter_ValidTypes(t *testing.T) {
cases := []DomainDataType{DomState, BasicInfo, GuestInfoUser, GuestInfoOS, GuestInfoFS, GuestInfoDisk}
for _, c := range cases {
if _, err := DataTypeRouter(c); err != nil {
t.Errorf("DataTypeRouter(%d) returned error: %v", c, err)
}
}
}

func TestDataTypeRouter_InvalidType(t *testing.T) {
_, err := DataTypeRouter(DomainDataType(99))
if !errors.Is(err, virerr.InvalidParameter) {
t.Errorf("expected InvalidParameter, got %v", err)
}
}
Loading