*
* Copyright (c) 2025 Bocloud Technologies Co., Ltd.
* installer is licensed under 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.
*
*/
package cluster
import (
"fmt"
"net"
"os"
"testing"
"github.com/agiledragon/gomonkey/v2"
"github.com/stretchr/testify/assert"
configv1beta1 "gopkg.openfuyao.cn/cluster-api-provider-bke/api/bkecommon/v1beta1"
yaml2 "sigs.k8s.io/yaml"
)
const (
testFileModeReadOnly = os.FileMode(0644)
testIPv4SegmentA = 192
testIPv4SegmentB = 168
testIPv4SegmentC = 1
testIPv4SegmentD = 100
)
var testIP = net.IPv4(
testIPv4SegmentA,
testIPv4SegmentB,
testIPv4SegmentC,
testIPv4SegmentD,
).String()
func TestNewBKEClusterFromFile(t *testing.T) {
tempFile := t.TempDir() + "/test-cluster.yaml"
validConfig := fmt.Sprintf(`apiVersion: cluster.bocloud.com/v1beta1
kind: BKECluster
metadata:
name: test-cluster
spec:
clusterConfig:
cluster:
imageRepo:
domain: %s
ip: %s
port: %s
prefix: k8s
httpRepo:
domain: %s
ip: %s
port: %s
chartRepo:
domain: %s
ip: %s
port: %s
prefix: charts
ntpServer: pool.ntp.org
`, testRegistryDomain, testRegistryIP, testRegistryPort, testYumDomain, testYumIP, testYumPort, testChartDomain, testChartIP, testChartPort)
err := os.WriteFile(tempFile, []byte(validConfig), testFileModeReadOnly)
assert.NoError(t, err)
tests := []struct {
name string
file string
mockReadFile func(string) ([]byte, error)
mockUnmarshal func([]byte, interface{}) error
expectError bool
}{
{
name: "successful cluster creation from valid file",
file: tempFile,
mockReadFile: func(filename string) ([]byte, error) {
return []byte(validConfig), nil
},
mockUnmarshal: func(data []byte, v interface{}) error {
conf := v.(*configv1beta1.BKECluster)
conf.APIVersion = "cluster.bocloud.com/v1beta1"
conf.Kind = "BKECluster"
conf.Name = "test-cluster"
conf.Spec.ClusterConfig = &configv1beta1.BKEConfig{
Cluster: configv1beta1.Cluster{
ImageRepo: configv1beta1.Repo{
Domain: "registry.example.com",
Ip: testIP,
Port: "5000",
Prefix: "k8s",
},
},
}
return nil
},
expectError: false,
},
{
name: "file read error",
file: "nonexistent-file.yaml",
mockReadFile: func(filename string) ([]byte, error) {
return nil, fmt.Errorf("file not found")
},
expectError: true,
},
{
name: "unmarshal error",
file: tempFile,
mockReadFile: func(filename string) ([]byte, error) {
return []byte("invalid yaml"), nil
},
mockUnmarshal: func(data []byte, v interface{}) error {
return fmt.Errorf("unmarshal error")
},
expectError: true,
},
{
name: "empty cluster config error",
file: tempFile,
mockReadFile: func(filename string) ([]byte, error) {
return []byte(`apiVersion: cluster.bocloud.com/v1beta1
kind: BKECluster
metadata:
name: test-cluster
spec:
clusterConfig: ~
`), nil
},
mockUnmarshal: func(data []byte, v interface{}) error {
conf := v.(*configv1beta1.BKECluster)
conf.Spec.ClusterConfig = nil
return nil
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
patches.ApplyFunc(os.ReadFile, tt.mockReadFile)
if tt.mockUnmarshal != nil {
patches.ApplyFunc(yaml2.Unmarshal, tt.mockUnmarshal)
}
cluster, err := NewBKEClusterFromFile(tt.file)
if tt.expectError {
assert.Error(t, err)
assert.Nil(t, cluster)
} else {
assert.NoError(t, err)
assert.NotNil(t, cluster)
}
})
}
}
func TestNewBKEClusterFromFileEmptyClusterConfig(t *testing.T) {
tempDir := t.TempDir()
tempFile := tempDir + "/empty-config.yaml"
emptyConfig := `apiVersion: cluster.bocloud.com/v1beta1
kind: BKECluster
metadata:
name: empty-test-cluster
spec:
clusterConfig:
`
err := os.WriteFile(tempFile, []byte(emptyConfig), testFileModeReadOnly)
assert.NoError(t, err)
cluster, err := NewBKEClusterFromFile(tempFile)
assert.Error(t, err)
assert.Nil(t, cluster)
assert.Contains(t, err.Error(), "the cluster configuration cannot be empty")
}
func TestNewBKEClusterFromFileInvalidYAML(t *testing.T) {
tempDir := t.TempDir()
tempFile := tempDir + "/invalid.yaml"
invalidYAML := `apiVersion: cluster.bocloud.com/v1beta1
kind: BKECluster
metadata:
name: invalid-test-cluster
spec:
clusterConfig:
cluster:
# Invalid YAML syntax here
imageRepo
domain: registry.example.com
`
err := os.WriteFile(tempFile, []byte(invalidYAML), testFileModeReadOnly)
assert.NoError(t, err)
cluster, err := NewBKEClusterFromFile(tempFile)
assert.Error(t, err)
assert.Nil(t, cluster)
}
func TestNewBKEClusterFromFileNonExistentFile(t *testing.T) {
cluster, err := NewBKEClusterFromFile("non-existent-file.yaml")
assert.Error(t, err)
assert.Nil(t, cluster)
}