1 package labels
2
3 import (
4 "strings"
5 "testing"
6
7 "github.com/google/go-cmp/cmp"
8 "k8s.io/apimachinery/pkg/labels"
9 "k8s.io/apimachinery/pkg/util/validation"
10
11 "github.com/redhat-developer/odo/pkg/version"
12 )
13
14 func Test_getLabels(t *testing.T) {
15 type args struct {
16 componentName string
17 applicationName string
18 additional bool
19 isPartOfComponent bool
20 }
21 tests := []struct {
22 name string
23 args args
24 want labels.Set
25 }{
26 {
27 name: "everything filled",
28 args: args{
29 componentName: "componentname",
30 applicationName: "applicationame",
31 additional: false,
32 },
33 want: labels.Set{
34 kubernetesManagedByLabel: "odo",
35 kubernetesPartOfLabel: "applicationame",
36 kubernetesInstanceLabel: "componentname",
37 "odo.dev/mode": "Dev",
38 },
39 }, {
40 name: "everything with additional",
41 args: args{
42 componentName: "componentname",
43 applicationName: "applicationame",
44 additional: true,
45 },
46 want: labels.Set{
47 kubernetesPartOfLabel: "applicationame",
48 appLabel: "applicationame",
49 kubernetesManagedByLabel: "odo",
50 kubernetesManagedByVersionLabel: version.VERSION,
51 kubernetesInstanceLabel: "componentname",
52 "odo.dev/mode": "Dev",
53 },
54 },
55 {
56 name: "everything with isPartOfComponent",
57 args: args{
58 componentName: "componentname",
59 applicationName: "applicationname",
60 isPartOfComponent: true,
61 },
62 want: labels.Set{
63 kubernetesManagedByLabel: "odo",
64 kubernetesPartOfLabel: "applicationname",
65 kubernetesInstanceLabel: "componentname",
66 "odo.dev/mode": "Dev",
67 componentLabel: "componentname",
68 },
69 },
70 }
71 for _, tt := range tests {
72 t.Run(tt.name, func(t *testing.T) {
73 got := getLabels(tt.args.componentName, tt.args.applicationName, ComponentDevMode, tt.args.additional, tt.args.isPartOfComponent)
74 if diff := cmp.Diff(tt.want, got); diff != "" {
75 t.Errorf("getLabels() mismatch (-want +got):\n%s", diff)
76 }
77 })
78 }
79 }
80
81 func Test_sanitizeLabelValue(t *testing.T) {
82 type args struct {
83 value string
84 }
85 for _, tt := range []struct {
86 name string
87 args args
88 want string
89 }{
90 {
91 name: "valid label",
92 args: args{value: "a-valid-value"},
93 want: "a-valid-value",
94 },
95 {
96 name: "empty value",
97 args: args{value: ""},
98 want: "",
99 },
100 {
101 name: "blank value",
102 args: args{value: " \t"},
103 want: "",
104 },
105 {
106 name: "dot",
107 args: args{value: "."},
108 want: "dot",
109 },
110 {
111 name: "leading dot - upper",
112 args: args{value: ".NET"},
113 want: "DOTNET",
114 },
115 {
116 name: "leading dot - lower",
117 args: args{value: ".net"},
118 want: "dotnet",
119 },
120 {
121 name: "leading dot - mixed",
122 args: args{value: ".NeT"},
123 want: "dotNeT",
124 },
125 {
126 name: "trailing dot - upper",
127 args: args{value: "NET."},
128 want: "NETDOT",
129 },
130 {
131 name: "trailing dot - lower",
132 args: args{value: "net."},
133 want: "netdot",
134 },
135 {
136 name: "trailing dot - mixed",
137 args: args{value: "NeT."},
138 want: "NeTdot",
139 },
140 {
141 name: "leading and trailing dots",
142 args: args{value: ".."},
143 want: "dotdot",
144 },
145 {
146 name: "leading and trailing dots",
147 args: args{value: ".NET."},
148 want: "DOTNETDOT",
149 },
150 {
151 name: "sharp",
152 args: args{value: "#"},
153 want: "sharp",
154 },
155 {
156 name: "sharpdot",
157 args: args{value: "#."},
158 want: "sharpdot",
159 },
160 {
161 name: "dotsharp",
162 args: args{value: ".#"},
163 want: "dotsharp",
164 },
165 {
166 name: "leading sharp - upper",
167 args: args{value: "#NET"},
168 want: "SHARPNET",
169 },
170 {
171 name: "leading sharp - lower",
172 args: args{value: "#net"},
173 want: "sharpnet",
174 },
175 {
176 name: "leading sharp - mixed",
177 args: args{value: "#NeT"},
178 want: "sharpNeT",
179 },
180 {
181 name: "trailing sharp - upper",
182 args: args{value: "C#"},
183 want: "CSHARP",
184 },
185 {
186 name: "trailing sharp - lower",
187 args: args{value: "c#"},
188 want: "csharp",
189 },
190 {
191 name: "trailing sharp - mixed",
192 args: args{value: "NeT#"},
193 want: "NeTsharp",
194 },
195 {
196 name: "leading and trailing sharps",
197 args: args{value: "##"},
198 want: "sharpsharp",
199 },
200 {
201 name: "single invalid character",
202 args: args{value: "?"},
203 want: "",
204 },
205 {
206 name: "leading and trailing sharps with valid character in between",
207 args: args{value: "#C#"},
208 want: "SHARPCSHARP",
209 },
210
211 {
212 name: "leading non alpha-numeric",
213 args: args{value: "-something"},
214 want: "something",
215 },
216 {
217 name: "trailing non alpha-numeric",
218 args: args{value: "some thing-"},
219 want: "some-thing",
220 },
221 {
222 name: "more than 63 characters",
223 args: args{value: "Express.js (a.k.a Express), the de facto standard server framework for Node.js"},
224 want: "Express.js--a.k.a-Express---the-de-facto-standard-server-framew",
225 },
226 {
227 name: "more than 63 characters starting with space",
228 args: args{value: " Express.js (a.k.a Express), the de facto standard server framework for Node.js"},
229 want: "Express.js--a.k.a-Express---the-de-facto-standard-server-framew",
230 },
231 {
232 name: "more than 63 characters where truncating it leads to string ending with non-alphanumeric",
233 args: args{value: " Express.js (a.k.a Express), the de facto standard server frame-work"},
234 want: "Express.js--a.k.a-Express---the-de-facto-standard-server-frame",
235 },
236 {
237 name: "more than 63 characters starting and ending with replacable char should be truncated after replacement",
238 args: args{
239 value: ".NET (Lorem Ipsum Dolor Sit Amet, consectetur adipiscing elit, " +
240 "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.) C#",
241 },
242 want: "dotNET--Lorem-Ipsum-Dolor-Sit-Amet--consectetur-adipiscing-elit",
243 },
244 {
245 name: "more than 63 characters ending with a lot of invalid characters",
246 args: args{value: ".NET" + strings.Repeat(" ", 60)},
247 want: "DOTNET",
248 },
249 {
250 name: "more than 63 invalid-only characters",
251 args: args{value: strings.Repeat("/[@\\", 90)},
252 want: "",
253 },
254 } {
255 t.Run(tt.name, func(t *testing.T) {
256 got := sanitizeLabelValue(openshiftRunTimeLabel, tt.args.value)
257 if got != tt.want {
258 t.Errorf("unexpected value for label. Expected %q, got %q", tt.want, got)
259 }
260 validationErrs := validation.IsValidLabelValue(got)
261 if len(validationErrs) != 0 {
262 t.Errorf("expected result %q to be a valid label value, but got the following errors: %s",
263 got, strings.Join(validationErrs, "; "))
264 }
265 })
266 }
267 }
268
View as plain text