Skip to content

Commit 62ecd08

Browse files
committed
implement tests and mock client for Utho cloud provider functionality
1 parent 9089329 commit 62ecd08

File tree

3 files changed

+457
-0
lines changed

3 files changed

+457
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package utho
18+
19+
import (
20+
"context"
21+
"errors"
22+
"strings"
23+
"testing"
24+
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
"github.com/uthoplatforms/utho-go/utho"
28+
apiv1 "k8s.io/api/core/v1"
29+
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
30+
)
31+
32+
// Helper function to set up mock ListNodePools
33+
func setupMockListNodePools(client *uthoClientMock, ctx context.Context, clusterID string, nodePools []utho.NodepoolDetails, err error) {
34+
client.On("ListNodePools", ctx, clusterID, nil).Return(nodePools, &utho.Meta{}, err).Once()
35+
}
36+
37+
func TestCloudProvider_NewCloudProvider_Success(t *testing.T) {
38+
config := `{"token": "123-456", "cluster_id": "111"}`
39+
40+
manager, err := newManager(strings.NewReader(config))
41+
require.NoError(t, err)
42+
43+
client := &uthoClientMock{}
44+
ctx := context.Background()
45+
46+
setupMockListNodePools(client, ctx, "123", []utho.NodepoolDetails{
47+
{ID: "1234", AutoScale: true, MinNodes: 1, MaxNodes: 2},
48+
{ID: "4567", AutoScale: true, MinNodes: 5, MaxNodes: 8},
49+
{ID: "9876", AutoScale: false, MinNodes: 5, MaxNodes: 8},
50+
}, nil)
51+
52+
manager.client = client
53+
54+
_ = newUthoCloudProvider(manager, &cloudprovider.ResourceLimiter{})
55+
}
56+
57+
func TestUthoCloudProvider_NewNodeGroup_Success(t *testing.T) {
58+
config := `{"token": "123-456", "cluster_id": "111"}`
59+
60+
manager, err := newManager(strings.NewReader(config))
61+
require.NoError(t, err)
62+
63+
client := &uthoClientMock{}
64+
ctx := context.Background()
65+
66+
setupMockListNodePools(client, ctx, manager.clusterID, []utho.NodepoolDetails{
67+
{ID: "1234", AutoScale: true, MinNodes: 1, MaxNodes: 2},
68+
{ID: "4567", AutoScale: true, MinNodes: 5, MaxNodes: 8},
69+
{ID: "9876", AutoScale: false, MinNodes: 5, MaxNodes: 8},
70+
}, nil)
71+
72+
manager.client = client
73+
provider := newUthoCloudProvider(manager, &cloudprovider.ResourceLimiter{})
74+
75+
err = provider.Refresh()
76+
assert.NoError(t, err)
77+
78+
nodes := provider.NodeGroups()
79+
assert.Equal(t, 2, len(nodes), "number of nodes do not match")
80+
}
81+
82+
func TestUthoCloudProvider_NodeGroupForNode_Success(t *testing.T) {
83+
config := `{"token": "123-456", "cluster_id": "111"}`
84+
85+
manager, err := newManager(strings.NewReader(config))
86+
require.NoError(t, err)
87+
88+
client := &uthoClientMock{}
89+
ctx := context.Background()
90+
91+
setupMockListNodePools(client, ctx, manager.clusterID, []utho.NodepoolDetails{
92+
{
93+
ID: "pool-123",
94+
AutoScale: true,
95+
Workers: []utho.WorkerNode{
96+
{
97+
ID: 1234,
98+
Status: "Active",
99+
},
100+
},
101+
MinNodes: 1,
102+
MaxNodes: 2,
103+
},
104+
{
105+
ID: "pool-456",
106+
AutoScale: true,
107+
Workers: []utho.WorkerNode{
108+
{
109+
ID: 456,
110+
Status: "Active",
111+
},
112+
},
113+
MinNodes: 5,
114+
MaxNodes: 8,
115+
},
116+
}, nil)
117+
118+
manager.client = client
119+
provider := newUthoCloudProvider(manager, &cloudprovider.ResourceLimiter{})
120+
121+
err = provider.Refresh()
122+
assert.NoError(t, err)
123+
124+
node := &apiv1.Node{Spec: apiv1.NodeSpec{ProviderID: toProviderID("1234")}}
125+
nodeGroup, err := provider.NodeGroupForNode(node)
126+
require.NoError(t, err)
127+
128+
require.NotNil(t, nodeGroup)
129+
require.Equal(t, "pool-123", nodeGroup.Id(), "nodegroup IDs do not match")
130+
131+
}
132+
133+
func TestUthoCloudProvider_Name_ReturnsCorrectName(t *testing.T) {
134+
config := `{"token": "123-456", "cluster_id": "111"}`
135+
136+
manager, err := newManager(strings.NewReader(config))
137+
require.NoError(t, err)
138+
139+
p := newUthoCloudProvider(manager, &cloudprovider.ResourceLimiter{})
140+
assert.Equal(t, cloudprovider.UthoProviderName, p.Name(), "provider name doesn't match")
141+
}
142+
143+
func TestUthoCloudProvider_Refresh_EmptyNodePools(t *testing.T) {
144+
config := `{"token": "123-456", "cluster_id": "111"}`
145+
146+
manager, err := newManager(strings.NewReader(config))
147+
require.NoError(t, err)
148+
149+
client := &uthoClientMock{}
150+
ctx := context.Background()
151+
152+
setupMockListNodePools(client, ctx, manager.clusterID, []utho.NodepoolDetails{}, nil)
153+
154+
manager.client = client
155+
provider := newUthoCloudProvider(manager, &cloudprovider.ResourceLimiter{})
156+
157+
err = provider.Refresh()
158+
assert.NoError(t, err)
159+
160+
nodes := provider.NodeGroups()
161+
assert.Equal(t, 0, len(nodes), "expected no node groups")
162+
163+
}
164+
165+
func TestUthoCloudProvider_Refresh_ErrorFromAPI(t *testing.T) {
166+
config := `{"token": "123-456", "cluster_id": "111"}`
167+
168+
manager, err := newManager(strings.NewReader(config))
169+
require.NoError(t, err)
170+
171+
client := &uthoClientMock{}
172+
ctx := context.Background()
173+
174+
setupMockListNodePools(client, ctx, manager.clusterID, nil, errors.New("mock error"))
175+
176+
manager.client = client
177+
provider := newUthoCloudProvider(manager, &cloudprovider.ResourceLimiter{})
178+
179+
err = provider.Refresh()
180+
assert.Error(t, err, "expected an error from ListNodePools")
181+
182+
}

0 commit comments

Comments
 (0)