Skip to content

Commit 6e9cb0f

Browse files
committed
Added unit tests for pv_creator.go
1 parent d12ad72 commit 6e9cb0f

File tree

4 files changed

+341
-0
lines changed

4 files changed

+341
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ run-unit-tests: $(GOBUILDDIR) $(SOURCES)
235235
$(REPOPATH)/pkg/apis/storage/v1alpha \
236236
$(REPOPATH)/pkg/deployment/reconcile \
237237
$(REPOPATH)/pkg/deployment/resources \
238+
$(REPOPATH)/pkg/storage \
238239
$(REPOPATH)/pkg/util/k8sutil \
239240
$(REPOPATH)/pkg/util/k8sutil/test \
240241
$(REPOPATH)/pkg/util/probe \
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package mocks
24+
25+
import (
26+
"github.com/stretchr/testify/mock"
27+
)
28+
29+
type MockGetter interface {
30+
AsMock() *mock.Mock
31+
}
32+
33+
// AsMock performs a typeconversion to *Mock.
34+
func AsMock(obj interface{}) *mock.Mock {
35+
return obj.(MockGetter).AsMock()
36+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package mocks
24+
25+
import (
26+
"context"
27+
"fmt"
28+
29+
"github.com/stretchr/testify/mock"
30+
31+
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner"
32+
)
33+
34+
type Provisioner interface {
35+
provisioner.API
36+
MockGetter
37+
}
38+
39+
type provisionerMock struct {
40+
mock.Mock
41+
nodeName string
42+
available, capacity int64
43+
localPaths map[string]struct{}
44+
}
45+
46+
// NewProvisioner returns a new mocked provisioner
47+
func NewProvisioner(nodeName string, available, capacity int64) Provisioner {
48+
return &provisionerMock{
49+
nodeName: nodeName,
50+
available: available,
51+
capacity: capacity,
52+
localPaths: make(map[string]struct{}),
53+
}
54+
}
55+
56+
func (m *provisionerMock) AsMock() *mock.Mock {
57+
return &m.Mock
58+
}
59+
60+
// GetNodeInfo fetches information from the current node.
61+
func (m *provisionerMock) GetNodeInfo(ctx context.Context) (provisioner.NodeInfo, error) {
62+
return provisioner.NodeInfo{
63+
NodeName: m.nodeName,
64+
}, nil
65+
}
66+
67+
// GetInfo fetches information from the filesystem containing
68+
// the given local path on the current node.
69+
func (m *provisionerMock) GetInfo(ctx context.Context, localPath string) (provisioner.Info, error) {
70+
return provisioner.Info{
71+
NodeInfo: provisioner.NodeInfo{
72+
NodeName: m.nodeName,
73+
},
74+
Available: m.available,
75+
Capacity: m.capacity,
76+
}, nil
77+
}
78+
79+
// Prepare a volume at the given local path
80+
func (m *provisionerMock) Prepare(ctx context.Context, localPath string) error {
81+
if _, found := m.localPaths[localPath]; found {
82+
return fmt.Errorf("Path already exists: %s", localPath)
83+
}
84+
m.localPaths[localPath] = struct{}{}
85+
return nil
86+
}
87+
88+
// Remove a volume with the given local path
89+
func (m *provisionerMock) Remove(ctx context.Context, localPath string) error {
90+
if _, found := m.localPaths[localPath]; !found {
91+
return fmt.Errorf("Path not found: %s", localPath)
92+
}
93+
delete(m.localPaths, localPath)
94+
return nil
95+
}

pkg/storage/pv_creator_test.go

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package storage
24+
25+
import (
26+
"context"
27+
"testing"
28+
29+
"github.com/stretchr/testify/assert"
30+
"k8s.io/api/core/v1"
31+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32+
33+
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner"
34+
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner/mocks"
35+
)
36+
37+
// TestCreateValidEndpointList tests createValidEndpointList.
38+
func TestCreateValidEndpointList(t *testing.T) {
39+
tests := []struct {
40+
Input *v1.EndpointsList
41+
Expected []string
42+
}{
43+
{
44+
Input: &v1.EndpointsList{},
45+
Expected: []string{},
46+
},
47+
{
48+
Input: &v1.EndpointsList{
49+
Items: []v1.Endpoints{
50+
v1.Endpoints{
51+
Subsets: []v1.EndpointSubset{
52+
v1.EndpointSubset{
53+
Addresses: []v1.EndpointAddress{
54+
v1.EndpointAddress{
55+
IP: "1.2.3.4",
56+
},
57+
},
58+
},
59+
v1.EndpointSubset{
60+
Addresses: []v1.EndpointAddress{
61+
v1.EndpointAddress{
62+
IP: "5.6.7.8",
63+
},
64+
v1.EndpointAddress{
65+
IP: "9.10.11.12",
66+
},
67+
},
68+
},
69+
},
70+
},
71+
},
72+
},
73+
Expected: []string{
74+
"1.2.3.4:8929",
75+
"5.6.7.8:8929",
76+
"9.10.11.12:8929",
77+
},
78+
},
79+
}
80+
for _, test := range tests {
81+
output := createValidEndpointList(test.Input)
82+
assert.Equal(t, test.Expected, output)
83+
}
84+
}
85+
86+
// TestCreateNodeAffinity tests createNodeAffinity.
87+
func TestCreateNodeAffinity(t *testing.T) {
88+
tests := map[string]string{
89+
"foo": "{\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"kubernetes.io/hostname\",\"operator\":\"In\",\"values\":[\"foo\"]}]}]}}",
90+
"bar": "{\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"kubernetes.io/hostname\",\"operator\":\"In\",\"values\":[\"bar\"]}]}]}}",
91+
}
92+
for input, expected := range tests {
93+
output, err := createNodeAffinity(input)
94+
assert.NoError(t, err)
95+
assert.Equal(t, expected, output, "Input: '%s'", input)
96+
}
97+
}
98+
99+
// TestCreateNodeClientMap tests createNodeClientMap.
100+
func TestCreateNodeClientMap(t *testing.T) {
101+
GB := int64(1024 * 1024 * 1024)
102+
foo := mocks.NewProvisioner("foo", 100*GB, 100*GB)
103+
bar := mocks.NewProvisioner("bar", 100*GB, 100*GB)
104+
tests := []struct {
105+
Input []provisioner.API
106+
Expected map[string]provisioner.API
107+
}{
108+
{
109+
Input: nil,
110+
Expected: map[string]provisioner.API{},
111+
},
112+
{
113+
Input: []provisioner.API{foo, bar},
114+
Expected: map[string]provisioner.API{
115+
"bar": bar,
116+
"foo": foo,
117+
},
118+
},
119+
}
120+
ctx := context.Background()
121+
for _, test := range tests {
122+
output := createNodeClientMap(ctx, test.Input)
123+
assert.Equal(t, test.Expected, output)
124+
}
125+
}
126+
127+
// TestGetDeploymentInfo tests getDeploymentInfo.
128+
func TestGetDeploymentInfo(t *testing.T) {
129+
tests := []struct {
130+
Input v1.PersistentVolumeClaim
131+
ExpectedDeploymentName string
132+
ExpectedRole string
133+
ExpectedEnforceAntiAffinity bool
134+
}{
135+
{
136+
Input: v1.PersistentVolumeClaim{},
137+
ExpectedDeploymentName: "",
138+
ExpectedRole: "",
139+
ExpectedEnforceAntiAffinity: false,
140+
},
141+
{
142+
Input: v1.PersistentVolumeClaim{
143+
ObjectMeta: metav1.ObjectMeta{
144+
Annotations: map[string]string{
145+
"database.arangodb.com/enforce-anti-affinity": "true",
146+
},
147+
Labels: map[string]string{
148+
"arango_deployment": "foo",
149+
"role": "r1",
150+
},
151+
},
152+
},
153+
ExpectedDeploymentName: "foo",
154+
ExpectedRole: "r1",
155+
ExpectedEnforceAntiAffinity: true,
156+
},
157+
{
158+
Input: v1.PersistentVolumeClaim{
159+
ObjectMeta: metav1.ObjectMeta{
160+
Annotations: map[string]string{
161+
"database.arangodb.com/enforce-anti-affinity": "false",
162+
},
163+
Labels: map[string]string{
164+
"arango_deployment": "foo",
165+
"role": "r1",
166+
},
167+
},
168+
},
169+
ExpectedDeploymentName: "foo",
170+
ExpectedRole: "r1",
171+
ExpectedEnforceAntiAffinity: false,
172+
},
173+
{
174+
Input: v1.PersistentVolumeClaim{
175+
ObjectMeta: metav1.ObjectMeta{
176+
Annotations: map[string]string{
177+
"database.arangodb.com/enforce-anti-affinity": "wrong",
178+
},
179+
Labels: map[string]string{
180+
"arango_deployment": "bar",
181+
"role": "r77",
182+
},
183+
},
184+
},
185+
ExpectedDeploymentName: "bar",
186+
ExpectedRole: "r77",
187+
ExpectedEnforceAntiAffinity: false,
188+
},
189+
}
190+
for _, test := range tests {
191+
deploymentName, role, enforceAntiAffinity := getDeploymentInfo(test.Input)
192+
assert.Equal(t, test.ExpectedDeploymentName, deploymentName)
193+
assert.Equal(t, test.ExpectedRole, role)
194+
assert.Equal(t, test.ExpectedEnforceAntiAffinity, enforceAntiAffinity)
195+
}
196+
}
197+
198+
// TestShortHash tests shortHash.
199+
func TestShortHash(t *testing.T) {
200+
tests := map[string]string{
201+
"foo": "0beec7",
202+
"": "da39a3",
203+
"something very very very very very looooooooooooooooooooooooooooooooong": "68ff76",
204+
}
205+
for input, expected := range tests {
206+
output := shortHash(input)
207+
assert.Equal(t, expected, output, "Input: '%s'", input)
208+
}
209+
}

0 commit comments

Comments
 (0)