2024-09-23 02:16:57 +00:00
|
|
|
From eaa82db55dbc543f9911e3c5ef4dd550711deb63 Mon Sep 17 00:00:00 2001
|
2023-06-19 07:12:03 +00:00
|
|
|
From: jingxiaolu <lujingxiao@huawei.com>
|
|
|
|
|
Date: Mon, 12 Jun 2023 23:12:37 +0800
|
2024-09-23 02:16:57 +00:00
|
|
|
Subject: [PATCH 03/13] rubik: test coverage for PSI Manager
|
2023-06-19 07:12:03 +00:00
|
|
|
|
|
|
|
|
Adding test cases for PSI Manager
|
|
|
|
|
|
|
|
|
|
Signed-off-by: jingxiaolu <lujingxiao@huawei.com>
|
|
|
|
|
---
|
|
|
|
|
Makefile | 3 +
|
|
|
|
|
pkg/config/config_test.go | 29 ++++++++
|
|
|
|
|
pkg/services/psi/psi.go | 14 ++--
|
|
|
|
|
pkg/services/psi/psi_test.go | 126 +++++++++++++++++++++++++++++++++++
|
|
|
|
|
pkg/services/service_test.go | 4 ++
|
|
|
|
|
5 files changed, 169 insertions(+), 7 deletions(-)
|
|
|
|
|
create mode 100644 pkg/services/psi/psi_test.go
|
|
|
|
|
|
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
|
|
|
index 7a92d12..bd66147 100644
|
|
|
|
|
--- a/Makefile
|
|
|
|
|
+++ b/Makefile
|
|
|
|
|
@@ -54,6 +54,7 @@ help:
|
|
|
|
|
@echo "make test-unit # run unit test"
|
|
|
|
|
@echo "make cover # generate coverage report"
|
|
|
|
|
@echo "make install # install files to /var/lib/rubik"
|
|
|
|
|
+ @echo "make clean" # clean built files and test logs
|
|
|
|
|
|
|
|
|
|
prepare:
|
|
|
|
|
mkdir -p $(TMP_DIR) $(BUILD_DIR)
|
|
|
|
|
@@ -101,3 +102,5 @@ install:
|
|
|
|
|
cp -f $(BUILD_DIR)/* $(INSTALL_DIR)
|
|
|
|
|
cp -f $(BUILD_DIR)/rubik.service /lib/systemd/system/
|
|
|
|
|
|
|
|
|
|
+clean:
|
|
|
|
|
+ rm -rf build/* cover.* unit_test_log
|
|
|
|
|
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
|
|
|
|
|
index dbbd2e4..03ff4ca 100644
|
|
|
|
|
--- a/pkg/config/config_test.go
|
|
|
|
|
+++ b/pkg/config/config_test.go
|
|
|
|
|
@@ -53,6 +53,35 @@ var rubikConfig string = `
|
|
|
|
|
"mid": 30,
|
|
|
|
|
"high": 50
|
|
|
|
|
}
|
|
|
|
|
+ },
|
|
|
|
|
+ "ioCost": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "nodeName": "k8s-single",
|
|
|
|
|
+ "config": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "dev": "sdb",
|
|
|
|
|
+ "enable": true,
|
|
|
|
|
+ "model": "linear",
|
|
|
|
|
+ "param": {
|
|
|
|
|
+ "rbps": 10000000,
|
|
|
|
|
+ "rseqiops": 10000000,
|
|
|
|
|
+ "rrandiops": 10000000,
|
|
|
|
|
+ "wbps": 10000000,
|
|
|
|
|
+ "wseqiops": 10000000,
|
|
|
|
|
+ "wrandiops": 10000000
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "psi": {
|
|
|
|
|
+ "interval": 10,
|
|
|
|
|
+ "resource": [
|
|
|
|
|
+ "cpu",
|
|
|
|
|
+ "memory",
|
|
|
|
|
+ "io"
|
|
|
|
|
+ ],
|
|
|
|
|
+ "avg10Threshold": 5.0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`
|
|
|
|
|
diff --git a/pkg/services/psi/psi.go b/pkg/services/psi/psi.go
|
|
|
|
|
index 1c70255..a55922e 100644
|
|
|
|
|
--- a/pkg/services/psi/psi.go
|
|
|
|
|
+++ b/pkg/services/psi/psi.go
|
|
|
|
|
@@ -37,19 +37,19 @@ const (
|
|
|
|
|
minThreshold float64 = 5.0
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
-// Factory is the QuotaTurbo factory class
|
|
|
|
|
+// Factory is the PSI Manager factory class
|
|
|
|
|
type Factory struct {
|
|
|
|
|
ObjName string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Name returns the factory class name
|
|
|
|
|
-func (i Factory) Name() string {
|
|
|
|
|
- return "Factory"
|
|
|
|
|
+func (f Factory) Name() string {
|
|
|
|
|
+ return "PSIFactory"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-// NewObj returns a QuotaTurbo object
|
|
|
|
|
-func (i Factory) NewObj() (interface{}, error) {
|
|
|
|
|
- return NewManager(i.ObjName), nil
|
|
|
|
|
+// NewObj returns a Manager object
|
|
|
|
|
+func (f Factory) NewObj() (interface{}, error) {
|
|
|
|
|
+ return NewManager(f.ObjName), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Config is PSI service configuration
|
|
|
|
|
@@ -130,7 +130,7 @@ func (m *Manager) SetConfig(f helper.ConfigHandler) error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsRunner returns true that tells other Manager is a persistent service
|
|
|
|
|
-func (qt *Manager) IsRunner() bool {
|
|
|
|
|
+func (m *Manager) IsRunner() bool {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
diff --git a/pkg/services/psi/psi_test.go b/pkg/services/psi/psi_test.go
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000..2036aa1
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/pkg/services/psi/psi_test.go
|
|
|
|
|
@@ -0,0 +1,126 @@
|
|
|
|
|
+// Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
|
|
|
|
|
+// rubik licensed under the Mulan PSL v2.
|
|
|
|
|
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
|
|
|
+// You may obtain a copy of Mulan PSL v2 at:
|
|
|
|
|
+// http://license.coscl.org.cn/MulanPSL2
|
|
|
|
|
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
|
|
|
+// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
|
|
|
+// PURPOSE.
|
|
|
|
|
+// See the Mulan PSL v2 for more details.
|
|
|
|
|
+// Author: Jingxiao Lu
|
|
|
|
|
+// Date: 2023-06-12
|
|
|
|
|
+// Description: This file is used for testing psi.go
|
|
|
|
|
+
|
|
|
|
|
+package psi
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "context"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "testing"
|
|
|
|
|
+ "time"
|
|
|
|
|
+
|
|
|
|
|
+ "isula.org/rubik/pkg/api"
|
|
|
|
|
+ "isula.org/rubik/pkg/core/typedef"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// TestNewManagerObj tests NewObj() for Factory
|
|
|
|
|
+func TestNewManagerObj(t *testing.T) {
|
|
|
|
|
+ var fact = Factory{
|
|
|
|
|
+ ObjName: "psi",
|
|
|
|
|
+ }
|
|
|
|
|
+ nm, err := fact.NewObj()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("New PSI Manager failed: %v", err)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ fmt.Printf("New PSI Manager %s is %#v", fact.Name(), nm)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// TestConfigValidate tests Config Validate
|
|
|
|
|
+func TestConfigValidate(t *testing.T) {
|
|
|
|
|
+ var tests = []struct {
|
|
|
|
|
+ name string
|
|
|
|
|
+ conf *Config
|
|
|
|
|
+ wantErr bool
|
|
|
|
|
+ }{
|
|
|
|
|
+ {
|
|
|
|
|
+ name: "TC1 - Default Config",
|
|
|
|
|
+ conf: NewConfig(),
|
|
|
|
|
+ wantErr: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: "TC2 - Wrong Interval value",
|
|
|
|
|
+ conf: &Config{
|
|
|
|
|
+ Interval: minInterval - 1,
|
|
|
|
|
+ },
|
|
|
|
|
+ wantErr: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: "TC3 - Wrong Threshold value",
|
|
|
|
|
+ conf: &Config{
|
|
|
|
|
+ Interval: minInterval,
|
|
|
|
|
+ Avg10Threshold: minThreshold - 1,
|
|
|
|
|
+ },
|
|
|
|
|
+ wantErr: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: "TC4 - No resource type specified",
|
|
|
|
|
+ conf: &Config{
|
|
|
|
|
+ Interval: minInterval,
|
|
|
|
|
+ Avg10Threshold: minThreshold,
|
|
|
|
|
+ },
|
|
|
|
|
+ wantErr: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: "TC5 - Wrong resource type cpuacct - cpuacct is for psi subsystem, not for resource type",
|
|
|
|
|
+ conf: &Config{
|
|
|
|
|
+ Interval: minInterval,
|
|
|
|
|
+ Avg10Threshold: minThreshold,
|
|
|
|
|
+ Resource: []string{"cpu", "memory", "io", "cpuacct"},
|
|
|
|
|
+ },
|
|
|
|
|
+ wantErr: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: "TC6 - Success case - trully end",
|
|
|
|
|
+ conf: &Config{
|
|
|
|
|
+ Interval: minInterval,
|
|
|
|
|
+ Avg10Threshold: minThreshold,
|
|
|
|
|
+ Resource: []string{"cpu", "memory", "io"},
|
|
|
|
|
+ },
|
|
|
|
|
+ wantErr: false,
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+ for _, tc := range tests {
|
|
|
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
+ if err := tc.conf.Validate(); (err != nil) != tc.wantErr {
|
|
|
|
|
+ t.Errorf("Config.Validate() error = %v, wantErr %v", err, tc.wantErr)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type FakeManager struct{}
|
|
|
|
|
+
|
|
|
|
|
+func (m *FakeManager) ListContainersWithOptions(options ...api.ListOption) map[string]*typedef.ContainerInfo {
|
|
|
|
|
+ return make(map[string]*typedef.ContainerInfo)
|
|
|
|
|
+}
|
|
|
|
|
+func (m *FakeManager) ListPodsWithOptions(options ...api.ListOption) map[string]*typedef.PodInfo {
|
|
|
|
|
+ return make(map[string]*typedef.PodInfo, 1)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// TestManagerRun creates a fake manager and runs it
|
|
|
|
|
+func TestManagerRun(t *testing.T) {
|
|
|
|
|
+ nm := NewManager("psi")
|
|
|
|
|
+ nm.conf.Interval = 1
|
|
|
|
|
+ nm.PreStart(&FakeManager{})
|
|
|
|
|
+ nm.SetConfig(func(configName string, d interface{}) error { return nil })
|
|
|
|
|
+ if !nm.IsRunner() {
|
|
|
|
|
+ t.Fatalf("FakeManager is not a runner!")
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
|
+ go nm.Run(ctx)
|
|
|
|
|
+ time.Sleep(time.Second)
|
|
|
|
|
+ cancel()
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/pkg/services/service_test.go b/pkg/services/service_test.go
|
|
|
|
|
index a6e0298..537d0b3 100644
|
|
|
|
|
--- a/pkg/services/service_test.go
|
|
|
|
|
+++ b/pkg/services/service_test.go
|
|
|
|
|
@@ -36,6 +36,10 @@ var defaultFeature = []FeatureSpec{
|
|
|
|
|
Name: feature.QuotaTurboFeature,
|
|
|
|
|
Default: true,
|
|
|
|
|
},
|
|
|
|
|
+ {
|
|
|
|
|
+ Name: feature.PSIFeature,
|
|
|
|
|
+ Default: true,
|
|
|
|
|
+ },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestErrorInitServiceComponents(t *testing.T) {
|
|
|
|
|
--
|
2024-09-23 02:16:57 +00:00
|
|
|
2.41.0
|
2023-06-19 07:12:03 +00:00
|
|
|
|