Skip to content

Commit

Permalink
Adding ballooning support
Browse files Browse the repository at this point in the history
  • Loading branch information
Janos Bonic committed May 25, 2022
1 parent 8dc9ff2 commit 624b600
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 36 deletions.
6 changes: 4 additions & 2 deletions util_test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"math/rand"
"os"
"strings"
"regexp"
"testing"
"time"

Expand Down Expand Up @@ -436,8 +436,10 @@ type testHelper struct {
username string
}

var resourceNameRe = regexp.MustCompile(`[^a-zA-Z\d_.-]`)

func (t *testHelper) GenerateTestResourceName(test *testing.T) string {
return strings.ReplaceAll(fmt.Sprintf("%s-%s", test.Name(), t.GenerateRandomID(5)), "/", "_")
return resourceNameRe.ReplaceAllString(fmt.Sprintf("%s-%s", test.Name(), t.GenerateRandomID(5)), "_")
}

func (t *testHelper) GetUsername() string {
Expand Down
72 changes: 54 additions & 18 deletions vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,8 @@ type VMData interface {
CPU() VMCPU
// Memory return the Memory of a VM in Bytes.
Memory() int64
// MemoryPolicy returns the memory policy set on the VM, if any. The second parameter returned is true if the
// memory policy is set.
MemoryPolicy() (MemoryPolicy, bool)
// MemoryPolicy returns the memory policy set on the VM.
MemoryPolicy() MemoryPolicy
// TagIDs returns a list of tags for this VM.
TagIDs() []TagID
// HugePages returns the hugepage settings for the VM, if any.
Expand Down Expand Up @@ -1120,6 +1119,7 @@ func (v vmPlacementPolicyParameters) MustWithHostIDs(hostIDs []HostID) Buildable
type MemoryPolicyParameters interface {
Guaranteed() *int64
Max() *int64
Ballooning() *bool
}

// BuildableMemoryPolicyParameters is a buildable version of MemoryPolicyParameters.
Expand All @@ -1131,6 +1131,9 @@ type BuildableMemoryPolicyParameters interface {

WithMax(max int64) (BuildableMemoryPolicyParameters, error)
MustWithMax(max int64) BuildableMemoryPolicyParameters

WithBallooning(ballooning bool) (BuildableMemoryPolicyParameters, error)
MustWithBallooning(ballooning bool) BuildableMemoryPolicyParameters
}

// NewMemoryPolicyParameters creates a new instance of BuildableMemoryPolicyParameters.
Expand All @@ -1141,6 +1144,24 @@ func NewMemoryPolicyParameters() BuildableMemoryPolicyParameters {
type memoryPolicyParameters struct {
guaranteed *int64
max *int64
ballooning *bool
}

func (m *memoryPolicyParameters) Ballooning() *bool {
return m.ballooning
}

func (m *memoryPolicyParameters) WithBallooning(ballooning bool) (BuildableMemoryPolicyParameters, error) {
m.ballooning = &ballooning
return m, nil
}

func (m *memoryPolicyParameters) MustWithBallooning(ballooning bool) BuildableMemoryPolicyParameters {
builder, err := m.WithBallooning(ballooning)
if err != nil {
panic(err)
}
return builder
}

func (m *memoryPolicyParameters) MustWithGuaranteed(guaranteed int64) BuildableMemoryPolicyParameters {
Expand Down Expand Up @@ -1183,11 +1204,18 @@ type MemoryPolicy interface {
Guaranteed() *int64
// Max returns the maximum amount of memory given to the VM.
Max() *int64
// Ballooning returns true if the VM can give back the memory it is not using to the host OS.
Ballooning() bool
}

type memoryPolicy struct {
guaranteed *int64
max *int64
ballooning bool
}

func (m memoryPolicy) Ballooning() bool {
return m.ballooning
}

func (m memoryPolicy) Max() *int64 {
Expand Down Expand Up @@ -1806,8 +1834,8 @@ func (v *vm) PlacementPolicy() (VMPlacementPolicy, bool) {
return v.placementPolicy, v.placementPolicy != nil
}

func (v *vm) MemoryPolicy() (MemoryPolicy, bool) {
return v.memoryPolicy, v.memoryPolicy != nil
func (v *vm) MemoryPolicy() MemoryPolicy {
return v.memoryPolicy
}

func (v *vm) WaitForIPAddresses(params VMIPSearchParams, retries ...RetryStrategy) (map[string][]net.IP, error) {
Expand Down Expand Up @@ -2080,21 +2108,29 @@ func vmInstanceTypeIDConverter(object *ovirtsdk.Vm, v *vm) error {
}

func vmMemoryPolicyConverter(object *ovirtsdk.Vm, v *vm) error {
if memPolicy, ok := object.MemoryPolicy(); ok {
resultMemPolicy := &memoryPolicy{}
if guaranteed, ok := memPolicy.Guaranteed(); ok {
if guaranteed < -1 {
return newError(
EBug,
"the engine returned a negative guaranteed memory value for VM %s (%d)",
object.MustId(),
guaranteed,
)
}
resultMemPolicy.guaranteed = &guaranteed
memPolicy, ok := object.MemoryPolicy()
if !ok {
return newFieldNotFound("vm", "memory policy")
}
resultMemPolicy := &memoryPolicy{}
if guaranteed, ok := memPolicy.Guaranteed(); ok {
if guaranteed < -1 {
return newError(
EBug,
"the engine returned a negative guaranteed memory value for VM %s (%d)",
object.MustId(),
guaranteed,
)
}
v.memoryPolicy = resultMemPolicy
resultMemPolicy.guaranteed = &guaranteed
}
if max, ok := memPolicy.Max(); ok {
resultMemPolicy.max = &max
}
if ballooning, ok := memPolicy.Ballooning(); ok {
resultMemPolicy.ballooning = ballooning
}
v.memoryPolicy = resultMemPolicy
return nil
}

Expand Down
20 changes: 12 additions & 8 deletions vm_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ func vmBuilderMemoryPolicy(params OptionalVMParameters, builder *ovirtsdk.VmBuil
if max := (*memPolicyParams).Max(); max != nil {
memoryPolicyBuilder.Max(*max)
}
if ballooning := (*memPolicyParams).Ballooning(); ballooning != nil {
memoryPolicyBuilder.Ballooning(*ballooning)
}
builder.MemoryPolicyBuilder(memoryPolicyBuilder)
}
}
Expand Down Expand Up @@ -412,19 +415,20 @@ func (m *mockClient) createVMMemory(params OptionalVMParameters) int64 {
}

func (m *mockClient) createVMMemoryPolicy(params OptionalVMParameters) *memoryPolicy {
var memPolicy *memoryPolicy
memPolicy := &memoryPolicy{
ballooning: true,
}
if memoryPolicyParams := params.MemoryPolicy(); memoryPolicyParams != nil {
var guaranteed *int64
if guaranteedMemory := (*memoryPolicyParams).Guaranteed(); guaranteedMemory != nil {
guaranteed = guaranteedMemory
memPolicy.guaranteed = guaranteedMemory
}
var max *int64

if maxMemory := (*memoryPolicyParams).Max(); maxMemory != nil {
max = maxMemory
memPolicy.max = maxMemory
}
memPolicy = &memoryPolicy{
guaranteed,
max,

if memBallooning := (*memoryPolicyParams).Ballooning(); memBallooning != nil {
memPolicy.ballooning = *memBallooning
}
}
return memPolicy
Expand Down
78 changes: 70 additions & 8 deletions vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,22 @@ func TestVMCreationWithSparseDisks(t *testing.T) {
)
}

func TestMemoryPolicyDefaults(t *testing.T) {
helper := getHelper(t)
vm := assertCanCreateVM(
t,
helper,
helper.GenerateTestResourceName(t),
nil,
)
// Test if memory policy is correctly set
memoryPolicy := vm.MemoryPolicy()
if memoryPolicy == nil {
t.Fatalf("Memory policy was not set.")
}

}

func TestGuaranteedMemory(t *testing.T) {
helper := getHelper(t)
expectedGuaranteed := int64(2 * 1024 * 1024 * 1024)
Expand All @@ -486,10 +502,7 @@ func TestGuaranteedMemory(t *testing.T) {
MustWithGuaranteed(expectedGuaranteed),
).MustWithMemory(expectedGuaranteed),
)
memoryPolicy, ok := vm.MemoryPolicy()
if !ok {
t.Fatalf("Memory policy is not set on VM.")
}
memoryPolicy := vm.MemoryPolicy()
guaranteed := memoryPolicy.Guaranteed()
if guaranteed == nil {
t.Fatalf("Guaranteed memory is not set on VM.")
Expand All @@ -514,10 +527,7 @@ func TestMaxMemory(t *testing.T) {
MustWithMax(expectedMax),
).MustWithMemory(expectedMax),
)
memoryPolicy, ok := vm.MemoryPolicy()
if !ok {
t.Fatalf("Memory policy is not set on VM.")
}
memoryPolicy := vm.MemoryPolicy()
max := memoryPolicy.Max()
if max == nil {
t.Fatalf("Guaranteed memory is not set on VM.")
Expand All @@ -527,6 +537,58 @@ func TestMaxMemory(t *testing.T) {
}
}

func TestBallooning(t *testing.T) {
truePointer := true
falsePointer := false
testCases := []struct {
name string
set *bool
expected bool
}{
{
"empty",
nil,
true,
},
{
"true",
&truePointer,
true,
},
{
"false",
&falsePointer,
false,
},
}

for _, testCase := range testCases {
t.Run(fmt.Sprintf("ballooning=%s", testCase.name), func(t *testing.T) {
helper := getHelper(t)
params := ovirtclient.NewCreateVMParams()
if testCase.set != nil {
params = params.WithMemoryPolicy(
ovirtclient.
NewMemoryPolicyParameters().
MustWithBallooning(*testCase.set),
)
}
vm := assertCanCreateVM(
t,
helper,
helper.GenerateTestResourceName(t),
params,
)
memoryPolicy := vm.MemoryPolicy()
ballooning := memoryPolicy.Ballooning()
if ballooning != testCase.expected {
t.Fatalf("Incorrect ballooning value")
}
})
}

}

func checkVMDiskSparseness(t *testing.T, checkVM ovirtclient.VM, sparse bool, message string) {
t.Helper()
diskAttachments, err := checkVM.ListDiskAttachments()
Expand Down

0 comments on commit 624b600

Please sign in to comment.