@@ -63,6 +63,17 @@ func TestRead(t *testing.T) {
6363 },
6464 },
6565 },
66+ {
67+ name : "read key with colon in name" ,
68+ respValue : "test_value" ,
69+ req : & pb.ReadRequest {
70+ Location : & pb.Location {
71+ File : path ,
72+ Section : "backup_agent" ,
73+ Key : "the:key:with:colon" ,
74+ },
75+ },
76+ },
6677 } {
6778 tc := tc
6879 t .Run (tc .name , func (t * testing.T ) {
@@ -124,9 +135,11 @@ cluster_file = /etc/foundatindb/fdb.cluster`)
124135
125136 client := pb .NewConfClient (conn )
126137 for _ , tc := range []struct {
127- name string
128- req * pb.WriteRequest
129- expected string
138+ name string
139+ req * pb.WriteRequest
140+ expected string
141+ expectErr bool
142+ expectErrString string
130143 }{
131144 {
132145 name : "write cluster_file to general" ,
@@ -157,10 +170,124 @@ test = badcoffee`,
157170 Value : "badcoffee" ,
158171 },
159172 },
173+ {
174+ name : "write key with colon in key name" ,
175+ expected : `[general]
176+ cluster_file = /tmp/fdb.cluster
177+
178+ [backup.1]
179+ test = badcoffee
180+
181+ [backup_agent]
182+ the:key:with:colon = test_value` ,
183+ req : & pb.WriteRequest {
184+ Location : & pb.Location {
185+ File : name ,
186+ Section : "backup_agent" ,
187+ Key : "the:key:with:colon" ,
188+ },
189+ Value : "test_value" ,
190+ },
191+ },
192+ {
193+ name : "write key containing colon in value" ,
194+ expected : `[general]
195+ cluster_file = /tmp/fdb.cluster
196+
197+ [backup.1]
198+ test = badcoffee
199+
200+ [backup_agent]
201+ the:key:with:colon = test_value
202+
203+ [network]
204+ listen_address = 127.0.0.1:4500` ,
205+ req : & pb.WriteRequest {
206+ Location : & pb.Location {
207+ File : name ,
208+ Section : "network" ,
209+ Key : "listen_address" ,
210+ },
211+ Value : "127.0.0.1:4500" ,
212+ },
213+ },
214+ {
215+ name : "write key with multiple colons in key name" ,
216+ expected : `[general]
217+ cluster_file = /tmp/fdb.cluster
218+
219+ [backup.1]
220+ test = badcoffee
221+
222+ [backup_agent]
223+ the:key:with:colon = test_value
224+
225+ [network]
226+ listen_address = 127.0.0.1:4500
227+
228+ [cluster]
229+ database:connection:string:key = "connection://host:port/db"` ,
230+ req : & pb.WriteRequest {
231+ Location : & pb.Location {
232+ File : name ,
233+ Section : "cluster" ,
234+ Key : "database:connection:string:key" ,
235+ },
236+ Value : `"connection://host:port/db"` ,
237+ },
238+ },
239+ {
240+ name : "empty section name" ,
241+ req : & pb.WriteRequest {
242+ Location : & pb.Location {
243+ File : name ,
244+ Section : "" ,
245+ Key : "test_key" ,
246+ },
247+ Value : "test_value" ,
248+ },
249+ expectErr : true ,
250+ expectErrString : "section name can not be empty" ,
251+ },
252+ {
253+ name : "empty key name" ,
254+ req : & pb.WriteRequest {
255+ Location : & pb.Location {
256+ File : name ,
257+ Section : "test_section" ,
258+ Key : "" ,
259+ },
260+ Value : "test_value" ,
261+ },
262+ expectErr : true ,
263+ expectErrString : "key name can not be empty" ,
264+ },
265+ {
266+ name : "empty key value" ,
267+ req : & pb.WriteRequest {
268+ Location : & pb.Location {
269+ File : name ,
270+ Section : "test_section" ,
271+ Key : "test_key" ,
272+ },
273+ Value : "" ,
274+ },
275+ expectErr : true ,
276+ expectErrString : "key value can not be empty" ,
277+ },
160278 } {
161279 tc := tc
162280 t .Run (tc .name , func (t * testing.T ) {
163281 resp , err := client .Write (ctx , tc .req )
282+ if tc .expectErr {
283+ if err == nil {
284+ t .Fatal ("expected error but got none" )
285+ }
286+ if ! strings .Contains (err .Error (), tc .expectErrString ) {
287+ t .Errorf ("expected error to contain %q, got %q" , tc .expectErrString , err .Error ())
288+ }
289+ return
290+ }
164291 testutil .FatalOnErr (fmt .Sprintf ("%v - resp %v" , tc .name , resp ), err , t )
165292 got , err := os .ReadFile (name )
166293 testutil .FatalOnErr ("failed reading config file" , err , t )
@@ -193,9 +320,13 @@ cluster_file = /etc/foundatindb/fdb.cluster
193320
194321[foo.1]
195322bar = baz
323+ the:key:with:colon = test_value
196324
197325[foo.2]
198- bar = baz` )
326+ bar = baz
327+
328+ [backup_agent]
329+ database:connection:string:key = "connection://host:port/db"` )
199330 testutil .FatalOnErr ("WriteString" , err , t )
200331 name := f1 .Name ()
201332 err = f1 .Close ()
@@ -223,9 +354,13 @@ bar = baz`)
223354cluster_file = /etc/foundatindb/fdb.cluster
224355
225356[foo.1]
226- bar = baz
357+ bar = baz
358+ the:key:with:colon = test_value
359+
360+ [foo.2]
227361
228- [foo.2]` ,
362+ [backup_agent]
363+ database:connection:string:key = "connection://host:port/db"` ,
229364 },
230365 {
231366 name : "delete empty section" ,
@@ -236,7 +371,11 @@ bar = baz
236371cluster_file = /etc/foundatindb/fdb.cluster
237372
238373[foo.1]
239- bar = baz` ,
374+ bar = baz
375+ the:key:with:colon = test_value
376+
377+ [backup_agent]
378+ database:connection:string:key = "connection://host:port/db"` ,
240379 },
241380 {
242381 name : "delete section that doesnt exist" ,
@@ -247,17 +386,74 @@ bar = baz`,
247386cluster_file = /etc/foundatindb/fdb.cluster
248387
249388[foo.1]
250- bar = baz` ,
389+ bar = baz
390+ the:key:with:colon = test_value
391+
392+ [backup_agent]
393+ database:connection:string:key = "connection://host:port/db"` ,
251394 expectErr : true ,
252395 expectErrString : "section foo.42 does not exist" ,
253396 },
397+ {
398+ name : "delete key with colon in key name" ,
399+ req : & pb.DeleteRequest {
400+ Location : & pb.Location {File : name , Section : "foo.1" , Key : "the:key:with:colon" },
401+ },
402+ expected : `[general]
403+ cluster_file = /etc/foundatindb/fdb.cluster
404+
405+ [foo.1]
406+ bar = baz
407+
408+ [backup_agent]
409+ database:connection:string:key = "connection://host:port/db"` ,
410+ },
411+ {
412+ name : "delete key with multiple colons in key name" ,
413+ req : & pb.DeleteRequest {
414+ Location : & pb.Location {File : name , Section : "backup_agent" , Key : "database:connection:string:key" },
415+ },
416+ expected : `[general]
417+ cluster_file = /etc/foundatindb/fdb.cluster
418+
419+ [foo.1]
420+ bar = baz
421+
422+ [backup_agent]` ,
423+ },
254424 {
255425 name : "delete whole section with keys" ,
256426 req : & pb.DeleteRequest {
257427 Location : & pb.Location {File : name , Section : "foo.1" , Key : "" },
258428 },
259429 expected : `[general]
260- cluster_file = /etc/foundatindb/fdb.cluster` ,
430+ cluster_file = /etc/foundatindb/fdb.cluster
431+
432+ [backup_agent]` ,
433+ },
434+ {
435+ name : "empty section name" ,
436+ req : & pb.DeleteRequest {
437+ Location : & pb.Location {
438+ File : name ,
439+ Section : "" ,
440+ Key : "test_key" ,
441+ },
442+ },
443+ expectErr : true ,
444+ expectErrString : "section name can not be empty" ,
445+ },
446+ {
447+ name : "non-existent section" ,
448+ req : & pb.DeleteRequest {
449+ Location : & pb.Location {
450+ File : name ,
451+ Section : "nonexistent" ,
452+ Key : "test_key" ,
453+ },
454+ },
455+ expectErr : true ,
456+ expectErrString : "section nonexistent does not exist" ,
261457 },
262458 } {
263459 tc := tc
0 commit comments