Skip to content

Commit 1a94fc0

Browse files
committed
add test cases for scheduler
1 parent 18e6f6b commit 1a94fc0

File tree

16 files changed

+411
-46
lines changed

16 files changed

+411
-46
lines changed

cloud/scheduler/framework/cycle_state.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
type CycleState struct {
99
completed bool
1010
err error
11+
messages map[string]string
1112
result SchedulerResult
1213
}
1314

@@ -18,7 +19,7 @@ type SchedulerResult struct {
1819
}
1920

2021
func NewCycleState() CycleState {
21-
return CycleState{completed: false, err: nil}
22+
return CycleState{completed: false, err: nil, messages: map[string]string{}}
2223
}
2324

2425
func (c *CycleState) SetComplete() {
@@ -37,6 +38,14 @@ func (c *CycleState) Error() error {
3738
return c.err
3839
}
3940

41+
func (c *CycleState) SetMessage(pluginName, message string) {
42+
c.messages[pluginName] = message
43+
}
44+
45+
func (c *CycleState) Messages() map[string]string {
46+
return c.messages
47+
}
48+
4049
func (c *CycleState) QEMU() *api.VirtualMachine {
4150
return c.result.instance.VM
4251
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package framework_test
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
"github.com/sp-yduck/proxmox-go/proxmox"
10+
logf "sigs.k8s.io/controller-runtime/pkg/log"
11+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
12+
)
13+
14+
var (
15+
proxmoxSvc *proxmox.Service
16+
)
17+
18+
func TestFrameworks(t *testing.T) {
19+
RegisterFailHandler(Fail)
20+
RunSpecs(t, "Scheduler Framework Suite")
21+
}
22+
23+
var _ = BeforeSuite(func() {
24+
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
25+
26+
if GinkgoLabelFilter() != "unit" {
27+
By("setup proxmox client to do integration test")
28+
url := os.Getenv("PROXMOX_URL")
29+
user := os.Getenv("PROXMOX_USER")
30+
password := os.Getenv("PROXMOX_PASSWORD")
31+
tokenid := os.Getenv("PROXMOX_TOKENID")
32+
secret := os.Getenv("PROXMOX_SECRET")
33+
34+
authConfig := proxmox.AuthConfig{
35+
Username: user,
36+
Password: password,
37+
TokenID: tokenid,
38+
Secret: secret,
39+
}
40+
param := proxmox.NewParams(url, authConfig, proxmox.ClientConfig{InsecureSkipVerify: true})
41+
var err error
42+
proxmoxSvc, err = proxmox.GetOrCreateService(param)
43+
Expect(err).NotTo(HaveOccurred())
44+
}
45+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package framework_test
2+
3+
import (
4+
"context"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
9+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/framework"
10+
)
11+
12+
var _ = Describe("GetNodeInfoList", Label("integration", "framework"), func() {
13+
ctx := context.Background()
14+
15+
It("should not error", func() {
16+
nodes, err := framework.GetNodeInfoList(ctx, proxmoxSvc)
17+
Expect(err).To(BeNil())
18+
Expect(len(nodes)).ToNot(Equal(0))
19+
})
20+
21+
})

cloud/scheduler/framework/utils.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import "context"
44

55
type CtxKey string
66

7-
// bind map's key-value to context key-value
7+
// bind map's key-value to context key-value.
8+
// type of key is translated to CtxKey type
89
func ContextWithMap(ctx context.Context, m map[string]string) context.Context {
910
for key, value := range m {
1011
ctx = context.WithValue(ctx, CtxKey(key), value)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package framework_test
2+
3+
import (
4+
"context"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
9+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/framework"
10+
)
11+
12+
var _ = Describe("ContextWithMap", Label("unit", "framework"), func() {
13+
c := context.Background()
14+
15+
Context("input empty map", func() {
16+
It("should not panic", func() {
17+
m := map[string]string{}
18+
ctx := framework.ContextWithMap(c, m)
19+
Expect(ctx).To(Equal(c))
20+
})
21+
})
22+
23+
Context("input nil", func() {
24+
It("should not panic", func() {
25+
ctx := framework.ContextWithMap(c, nil)
26+
Expect(ctx).To(Equal(c))
27+
})
28+
})
29+
30+
Context("input random map", func() {
31+
It("should get map's key-value", func() {
32+
m := map[string]string{}
33+
m["abc"] = "ABC"
34+
ctx := framework.ContextWithMap(c, m)
35+
Expect(ctx.Value("abc")).ToNot(Equal("ABC"))
36+
Expect(ctx.Value(framework.CtxKey("abc"))).To(Equal("ABC"))
37+
})
38+
})
39+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package idrange
2+
3+
import "context"
4+
5+
func FindVMIDRange(ctx context.Context) (int, int, error) {
6+
return findVMIDRange(ctx)
7+
}

cloud/scheduler/plugins/idrange/idrange.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ func (pl *Range) PluginKey() framework.CtxKey {
3131

3232
// select minimum id being not used in specified range
3333
// range is specified in ctx value (key=vmid.qemu-scheduler/range)
34-
func (pl *Range) Select(ctx context.Context, state *framework.CycleState, config api.VirtualMachineCreateOptions, nextid int, usedID map[int]bool) (int, error) {
34+
func (pl *Range) Select(ctx context.Context, state *framework.CycleState, _ api.VirtualMachineCreateOptions, nextid int, usedID map[int]bool) (int, error) {
3535
start, end, err := findVMIDRange(ctx)
3636
if err != nil {
37-
return 0, nil
37+
state.SetMessage(pl.Name(), "no idrange is specified, use nextid.")
38+
return nextid, nil
3839
}
3940
for i := start; i <= end; i++ {
4041
_, used := usedID[i]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package idrange_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
10+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/framework"
11+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/plugins/idrange"
12+
)
13+
14+
func TestIDRange(t *testing.T) {
15+
RegisterFailHandler(Fail)
16+
RunSpecs(t, "idrange plugin")
17+
}
18+
19+
var _ = Describe("findVMIDRange", Label("unit", "plugins"), func() {
20+
ctx := context.Background()
21+
22+
Context("no 'vmid.qemu-scheduler/range' key in the context", func() {
23+
It("should error", func() {
24+
start, end, err := idrange.FindVMIDRange(ctx)
25+
Expect(start).To(Equal(0))
26+
Expect(end).To(Equal(0))
27+
Expect(err.Error()).To(Equal("no vmid range is specified"))
28+
})
29+
})
30+
31+
Context("specify invalid range (start)", func() {
32+
It("should error", func() {
33+
c := context.WithValue(ctx, framework.CtxKey(idrange.VMIDRangeKey), "a-10")
34+
start, end, err := idrange.FindVMIDRange(c)
35+
Expect(start).To(Equal(0))
36+
Expect(end).To(Equal(0))
37+
Expect(err.Error()).To(ContainSubstring("invalid range is specified"))
38+
})
39+
})
40+
41+
Context("specify invalid range (end)", func() {
42+
It("should error", func() {
43+
c := context.WithValue(ctx, framework.CtxKey(idrange.VMIDRangeKey), "10-b")
44+
start, end, err := idrange.FindVMIDRange(c)
45+
Expect(start).To(Equal(0))
46+
Expect(end).To(Equal(0))
47+
Expect(err.Error()).To(ContainSubstring("invalid range is specified"))
48+
})
49+
})
50+
51+
Context("specify valid range", func() {
52+
It("should not error", func() {
53+
c := context.WithValue(ctx, framework.CtxKey(idrange.VMIDRangeKey), "10-20")
54+
start, end, err := idrange.FindVMIDRange(c)
55+
Expect(start).To(Equal(10))
56+
Expect(end).To(Equal(20))
57+
Expect(err).ToNot(HaveOccurred())
58+
})
59+
})
60+
})

cloud/scheduler/plugins/random/random.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ func (pl *Random) Name() string {
2323
return Name
2424
}
2525

26-
// return random score: 0 <= n < 100
26+
// return random score: 0 <= n < 100.
27+
// just a sample plugin
2728
func (pl *Random) Score(ctx context.Context, state *framework.CycleState, config api.VirtualMachineCreateOptions, nodeInfo *framework.NodeInfo) (int64, *framework.Status) {
2829
src := rand.NewSource(time.Now().Unix())
2930
r := rand.New(src)

cloud/scheduler/plugins/regex/node_regex.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ func (pl *NodeRegex) Name() string {
2525
}
2626

2727
// regex is specified in ctx value (key=node.qemu-scheduler/regex)
28-
func (pl *NodeRegex) Filter(ctx context.Context, _ *framework.CycleState, config api.VirtualMachineCreateOptions, nodeInfo *framework.NodeInfo) *framework.Status {
28+
func (pl *NodeRegex) Filter(ctx context.Context, state *framework.CycleState, config api.VirtualMachineCreateOptions, nodeInfo *framework.NodeInfo) *framework.Status {
2929
reg, err := findNodeRegex(ctx)
3030
if err != nil {
31-
31+
state.SetMessage(pl.Name(), "no valid regex is specified, skip")
3232
return &framework.Status{}
3333
}
3434
if !reg.MatchString(nodeInfo.Node().Node) {

0 commit comments

Comments
 (0)