1
+package rdverb
2
+
3
+import (
4
+ "bytes"
5
+ "testing"
6
+
7
+ rdsec "gosuda.org/portal/portal/core/proto/rdsec"
8
+)
9
+
10
+// TestPacket_MarshalVT_UnmarshalVT tests round-trip serialization for Packet
11
+func TestPacket_MarshalVT_UnmarshalVT(t *testing.T) {
12
+ tests := []struct {
13
+ name string
14
+ input *Packet
15
+ wantErr bool
16
+ }{
17
+ {
18
+ name: "empty",
19
+ input: &Packet{},
20
+ wantErr: false,
21
+ },
22
+ {
23
+ name: "full",
24
+ input: &Packet{
25
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
26
+ Payload: []byte{0x01, 0x02, 0x03, 0x04},
27
+ },
28
+ wantErr: false,
29
+ },
30
+ {
31
+ name: "type only",
32
+ input: &Packet{
33
+ Type: PacketType_PACKET_TYPE_LEASE_UPDATE_REQUEST,
34
+ },
35
+ wantErr: false,
36
+ },
37
+ {
38
+ name: "payload only",
39
+ input: &Packet{
40
+ Payload: []byte("test payload"),
41
+ },
42
+ wantErr: false,
43
+ },
44
+ }
45
+
46
+ for _, tt := range tests {
47
+ t.Run(tt.name, func(t *testing.T) {
48
+ data, err := tt.input.MarshalVT()
49
+ if (err != nil) != tt.wantErr {
50
+ t.Errorf("MarshalVT() error = %v, wantErr %v", err, tt.wantErr)
51
+ return
52
+ }
53
+
54
+ got := &Packet{}
55
+ err = got.UnmarshalVT(data)
56
+ if (err != nil) != tt.wantErr {
57
+ t.Errorf("UnmarshalVT() error = %v, wantErr %v", err, tt.wantErr)
58
+ return
59
+ }
60
+
61
+ if !tt.input.EqualVT(got) {
62
+ t.Errorf("roundtrip mismatch")
63
+ }
64
+ })
65
+ }
66
+}
67
+
68
+// TestPacket_AllPacketTypes tests serialization of all packet types
69
+func TestPacket_AllPacketTypes(t *testing.T) {
70
+ packetTypes := []PacketType{
71
+ PacketType_PACKET_TYPE_RELAY_INFO_REQUEST,
72
+ PacketType_PACKET_TYPE_RELAY_INFO_RESPONSE,
73
+ PacketType_PACKET_TYPE_LEASE_UPDATE_REQUEST,
74
+ PacketType_PACKET_TYPE_LEASE_UPDATE_RESPONSE,
75
+ PacketType_PACKET_TYPE_LEASE_DELETE_REQUEST,
76
+ PacketType_PACKET_TYPE_LEASE_DELETE_RESPONSE,
77
+ PacketType_PACKET_TYPE_CONNECTION_REQUEST,
78
+ PacketType_PACKET_TYPE_CONNECTION_RESPONSE,
79
+ }
80
+
81
+ for _, pt := range packetTypes {
82
+ t.Run(pt.String(), func(t *testing.T) {
83
+ msg := &Packet{
84
+ Type: pt,
85
+ Payload: []byte("test payload"),
86
+ }
87
+
88
+ data, err := msg.MarshalVT()
89
+ if err != nil {
90
+ t.Fatalf("MarshalVT() error = %v", err)
91
+ }
92
+
93
+ got := &Packet{}
94
+ if err := got.UnmarshalVT(data); err != nil {
95
+ t.Fatalf("UnmarshalVT() error = %v", err)
96
+ }
97
+
98
+ if !msg.EqualVT(got) {
99
+ t.Errorf("roundtrip mismatch for %v", pt)
100
+ }
101
+ })
102
+ }
103
+}
104
+
105
+// TestRelayInfo_MarshalVT_UnmarshalVT tests round-trip serialization
106
+func TestRelayInfo_MarshalVT_UnmarshalVT(t *testing.T) {
107
+ tests := []struct {
108
+ name string
109
+ input *RelayInfo
110
+ wantErr bool
111
+ }{
112
+ {
113
+ name: "empty",
114
+ input: &RelayInfo{},
115
+ wantErr: false,
116
+ },
117
+ {
118
+ name: "full",
119
+ input: &RelayInfo{
120
+ Identity: &rdsec.Identity{
121
+ Id: "relay-id",
122
+ PublicKey: []byte{0x01, 0x02},
123
+ },
124
+ Address: []string{"addr1.example.com:8080", "addr2.example.com:8080"},
125
+ Leases: []*Lease{
126
+ {
127
+ Identity: &rdsec.Identity{Id: "lease1-id"},
128
+ Expires: 1234567890,
129
+ Name: "lease1",
130
+ Alpn: []string{"h2", "http/1.1"},
131
+ Metadata: "metadata1",
132
+ },
133
+ {
134
+ Identity: &rdsec.Identity{Id: "lease2-id"},
135
+ Expires: 9876543210,
136
+ Name: "lease2",
137
+ Alpn: []string{"h2"},
138
+ },
139
+ },
140
+ },
141
+ wantErr: false,
142
+ },
143
+ {
144
+ name: "with identity only",
145
+ input: &RelayInfo{
146
+ Identity: &rdsec.Identity{Id: "test-relay"},
147
+ },
148
+ wantErr: false,
149
+ },
150
+ {
151
+ name: "with multiple addresses",
152
+ input: &RelayInfo{
153
+ Identity: &rdsec.Identity{Id: "multi-addr"},
154
+ Address: []string{"addr1:8080", "addr2:8080", "addr3:8080"},
155
+ },
156
+ wantErr: false,
157
+ },
158
+ }
159
+
160
+ for _, tt := range tests {
161
+ t.Run(tt.name, func(t *testing.T) {
162
+ data, err := tt.input.MarshalVT()
163
+ if (err != nil) != tt.wantErr {
164
+ t.Errorf("MarshalVT() error = %v, wantErr %v", err, tt.wantErr)
165
+ return
166
+ }
167
+
168
+ got := &RelayInfo{}
169
+ err = got.UnmarshalVT(data)
170
+ if (err != nil) != tt.wantErr {
171
+ t.Errorf("UnmarshalVT() error = %v, wantErr %v", err, tt.wantErr)
172
+ return
173
+ }
174
+
175
+ if !tt.input.EqualVT(got) {
176
+ t.Errorf("roundtrip mismatch")
177
+ }
178
+ })
179
+ }
180
+}
181
+
182
+// TestRelayInfo_WithMultipleLeases tests array handling for leases
183
+func TestRelayInfo_WithMultipleLeases(t *testing.T) {
184
+ leases := []*Lease{
185
+ {Identity: &rdsec.Identity{Id: "l1"}, Expires: 100, Name: "lease1"},
186
+ {Identity: &rdsec.Identity{Id: "l2"}, Expires: 200, Name: "lease2"},
187
+ {Identity: &rdsec.Identity{Id: "l3"}, Expires: 300, Name: "lease3"},
188
+ {Identity: &rdsec.Identity{Id: "l4"}, Expires: 400, Name: "lease4"},
189
+ {Identity: &rdsec.Identity{Id: "l5"}, Expires: 500, Name: "lease5"},
190
+ }
191
+
192
+ msg := &RelayInfo{
193
+ Identity: &rdsec.Identity{Id: "relay"},
194
+ Leases: leases,
195
+ }
196
+
197
+ data, err := msg.MarshalVT()
198
+ if err != nil {
199
+ t.Fatalf("MarshalVT() error = %v", err)
200
+ }
201
+
202
+ got := &RelayInfo{}
203
+ if err := got.UnmarshalVT(data); err != nil {
204
+ t.Fatalf("UnmarshalVT() error = %v", err)
205
+ }
206
+
207
+ if len(got.Leases) != len(leases) {
208
+ t.Fatalf("got %d leases, want %d", len(got.Leases), len(leases))
209
+ }
210
+
211
+ for i, want := range leases {
212
+ if got.Leases[i].Name != want.Name {
213
+ t.Errorf("lease[%d].Name = %v, want %v", i, got.Leases[i].Name, want.Name)
214
+ }
215
+ }
216
+}
217
+
218
+// TestLease_MarshalVT_UnmarshalVT tests round-trip serialization
219
+func TestLease_MarshalVT_UnmarshalVT(t *testing.T) {
220
+ tests := []struct {
221
+ name string
222
+ input *Lease
223
+ wantErr bool
224
+ }{
225
+ {
226
+ name: "empty",
227
+ input: &Lease{},
228
+ wantErr: false,
229
+ },
230
+ {
231
+ name: "full",
232
+ input: &Lease{
233
+ Identity: &rdsec.Identity{
234
+ Id: "lease-id",
235
+ PublicKey: []byte{0x01, 0x02},
236
+ },
237
+ Expires: 1234567890,
238
+ Name: "my-lease",
239
+ Alpn: []string{"h2", "http/1.1"},
240
+ Metadata: "some metadata",
241
+ },
242
+ wantErr: false,
243
+ },
244
+ {
245
+ name: "with alpn",
246
+ input: &Lease{
247
+ Identity: &rdsec.Identity{Id: "alpn-test"},
248
+ Alpn: []string{"h2", "grpc"},
249
+ },
250
+ wantErr: false,
251
+ },
252
+ }
253
+
254
+ for _, tt := range tests {
255
+ t.Run(tt.name, func(t *testing.T) {
256
+ data, err := tt.input.MarshalVT()
257
+ if (err != nil) != tt.wantErr {
258
+ t.Errorf("MarshalVT() error = %v, wantErr %v", err, tt.wantErr)
259
+ return
260
+ }
261
+
262
+ got := &Lease{}
263
+ err = got.UnmarshalVT(data)
264
+ if (err != nil) != tt.wantErr {
265
+ t.Errorf("UnmarshalVT() error = %v, wantErr %v", err, tt.wantErr)
266
+ return
267
+ }
268
+
269
+ if !tt.input.EqualVT(got) {
270
+ t.Errorf("roundtrip mismatch")
271
+ }
272
+ })
273
+ }
274
+}
275
+
276
+// TestLeaseUpdateRequest_MarshalVT_UnmarshalVT tests round-trip serialization
277
+func TestLeaseUpdateRequest_MarshalVT_UnmarshalVT(t *testing.T) {
278
+ lease := &Lease{
279
+ Identity: &rdsec.Identity{Id: "update-lease"},
280
+ Expires: 1234567890,
281
+ Name: "lease-name",
282
+ }
283
+
284
+ tests := []struct {
285
+ name string
286
+ input *LeaseUpdateRequest
287
+ wantErr bool
288
+ }{
289
+ {
290
+ name: "full",
291
+ input: &LeaseUpdateRequest{
292
+ Lease: lease,
293
+ Nonce: []byte{0x01, 0x02, 0x03, 0x04},
294
+ Timestamp: 9876543210,
295
+ },
296
+ wantErr: false,
297
+ },
298
+ {
299
+ name: "empty",
300
+ input: &LeaseUpdateRequest{},
301
+ wantErr: false,
302
+ },
303
+ }
304
+
305
+ for _, tt := range tests {
306
+ t.Run(tt.name, func(t *testing.T) {
307
+ data, err := tt.input.MarshalVT()
308
+ if (err != nil) != tt.wantErr {
309
+ t.Errorf("MarshalVT() error = %v, wantErr %v", err, tt.wantErr)
310
+ return
311
+ }
312
+
313
+ got := &LeaseUpdateRequest{}
314
+ err = got.UnmarshalVT(data)
315
+ if (err != nil) != tt.wantErr {
316
+ t.Errorf("UnmarshalVT() error = %v, wantErr %v", err, tt.wantErr)
317
+ return
318
+ }
319
+
320
+ if !tt.input.EqualVT(got) {
321
+ t.Errorf("roundtrip mismatch")
322
+ }
323
+ })
324
+ }
325
+}
326
+
327
+// TestResponseCode_AllValues tests all response code values
328
+func TestResponseCode_AllValues(t *testing.T) {
329
+ codes := []ResponseCode{
330
+ ResponseCode_RESPONSE_CODE_UNKNOWN,
331
+ ResponseCode_RESPONSE_CODE_ACCEPTED,
332
+ ResponseCode_RESPONSE_CODE_INVALID_EXPIRES,
333
+ ResponseCode_RESPONSE_CODE_INVALID_IDENTITY,
334
+ ResponseCode_RESPONSE_CODE_INVALID_NAME,
335
+ ResponseCode_RESPONSE_CODE_INVALID_ALPN,
336
+ ResponseCode_RESPONSE_CODE_REJECTED,
337
+ }
338
+
339
+ for _, code := range codes {
340
+ t.Run(code.String(), func(t *testing.T) {
341
+ msg := &LeaseUpdateResponse{Code: code}
342
+
343
+ data, err := msg.MarshalVT()
344
+ if err != nil {
345
+ t.Fatalf("MarshalVT() error = %v", err)
346
+ }
347
+
348
+ got := &LeaseUpdateResponse{}
349
+ if err := got.UnmarshalVT(data); err != nil {
350
+ t.Fatalf("UnmarshalVT() error = %v", err)
351
+ }
352
+
353
+ if got.Code != code {
354
+ t.Errorf("Code = %v, want %v", got.Code, code)
355
+ }
356
+ })
357
+ }
358
+}
359
+
360
+// TestLeaseDeleteRequest_MarshalVT_UnmarshalVT tests round-trip serialization
361
+func TestLeaseDeleteRequest_MarshalVT_UnmarshalVT(t *testing.T) {
362
+ tests := []struct {
363
+ name string
364
+ input *LeaseDeleteRequest
365
+ wantErr bool
366
+ }{
367
+ {
368
+ name: "full",
369
+ input: &LeaseDeleteRequest{
370
+ Identity: &rdsec.Identity{Id: "delete-id", PublicKey: []byte{0x01}},
371
+ Nonce: []byte{0x01, 0x02, 0x03},
372
+ Timestamp: 1234567890,
373
+ },
374
+ wantErr: false,
375
+ },
376
+ {
377
+ name: "empty",
378
+ input: &LeaseDeleteRequest{},
379
+ wantErr: false,
380
+ },
381
+ }
382
+
383
+ for _, tt := range tests {
384
+ t.Run(tt.name, func(t *testing.T) {
385
+ data, err := tt.input.MarshalVT()
386
+ if (err != nil) != tt.wantErr {
387
+ t.Errorf("MarshalVT() error = %v, wantErr %v", err, tt.wantErr)
388
+ return
389
+ }
390
+
391
+ got := &LeaseDeleteRequest{}
392
+ err = got.UnmarshalVT(data)
393
+ if (err != nil) != tt.wantErr {
394
+ t.Errorf("UnmarshalVT() error = %v, wantErr %v", err, tt.wantErr)
395
+ return
396
+ }
397
+
398
+ if !tt.input.EqualVT(got) {
399
+ t.Errorf("roundtrip mismatch")
400
+ }
401
+ })
402
+ }
403
+}
404
+
405
+// TestConnectionRequest_MarshalVT_UnmarshalVT tests round-trip serialization
406
+func TestConnectionRequest_MarshalVT_UnmarshalVT(t *testing.T) {
407
+ tests := []struct {
408
+ name string
409
+ input *ConnectionRequest
410
+ wantErr bool
411
+ }{
412
+ {
413
+ name: "full",
414
+ input: &ConnectionRequest{
415
+ LeaseId: "lease-123",
416
+ ClientIdentity: &rdsec.Identity{Id: "client-id", PublicKey: []byte{0xAA, 0xBB}},
417
+ },
418
+ wantErr: false,
419
+ },
420
+ {
421
+ name: "empty",
422
+ input: &ConnectionRequest{},
423
+ wantErr: false,
424
+ },
425
+ {
426
+ name: "lease id only",
427
+ input: &ConnectionRequest{
428
+ LeaseId: "lease-only",
429
+ },
430
+ wantErr: false,
431
+ },
432
+ }
433
+
434
+ for _, tt := range tests {
435
+ t.Run(tt.name, func(t *testing.T) {
436
+ data, err := tt.input.MarshalVT()
437
+ if (err != nil) != tt.wantErr {
438
+ t.Errorf("MarshalVT() error = %v, wantErr %v", err, tt.wantErr)
439
+ return
440
+ }
441
+
442
+ got := &ConnectionRequest{}
443
+ err = got.UnmarshalVT(data)
444
+ if (err != nil) != tt.wantErr {
445
+ t.Errorf("UnmarshalVT() error = %v, wantErr %v", err, tt.wantErr)
446
+ return
447
+ }
448
+
449
+ if !tt.input.EqualVT(got) {
450
+ t.Errorf("roundtrip mismatch")
451
+ }
452
+ })
453
+ }
454
+}
455
+
456
+// TestRelayInfoRequest_MarshalVT_UnmarshalVT tests empty message
457
+func TestRelayInfoRequest_MarshalVT_UnmarshalVT(t *testing.T) {
458
+ msg := &RelayInfoRequest{}
459
+
460
+ data, err := msg.MarshalVT()
461
+ if err != nil {
462
+ t.Fatalf("MarshalVT() error = %v", err)
463
+ }
464
+
465
+ got := &RelayInfoRequest{}
466
+ err = got.UnmarshalVT(data)
467
+ if err != nil {
468
+ t.Fatalf("UnmarshalVT() error = %v", err)
469
+ }
470
+
471
+ if !msg.EqualVT(got) {
472
+ t.Error("roundtrip mismatch for empty RelayInfoRequest")
473
+ }
474
+}
475
+
476
+// TestRelayInfoResponse_MarshalVT_UnmarshalVT tests with RelayInfo
477
+func TestRelayInfoResponse_MarshalVT_UnmarshalVT(t *testing.T) {
478
+ relayInfo := &RelayInfo{
479
+ Identity: &rdsec.Identity{Id: "response-relay"},
480
+ Address: []string{"addr1:8080"},
481
+ Leases: []*Lease{
482
+ {Identity: &rdsec.Identity{Id: "l1"}, Name: "lease1"},
483
+ },
484
+ }
485
+
486
+ msg := &RelayInfoResponse{RelayInfo: relayInfo}
487
+
488
+ data, err := msg.MarshalVT()
489
+ if err != nil {
490
+ t.Fatalf("MarshalVT() error = %v", err)
491
+ }
492
+
493
+ got := &RelayInfoResponse{}
494
+ err = got.UnmarshalVT(data)
495
+ if err != nil {
496
+ t.Fatalf("UnmarshalVT() error = %v", err)
497
+ }
498
+
499
+ if !msg.EqualVT(got) {
500
+ t.Error("roundtrip mismatch")
501
+ }
502
+}
503
+
504
+// TestCloneVT tests cloning creates independent copies
505
+func TestCloneVT(t *testing.T) {
506
+ t.Run("Packet", func(t *testing.T) {
507
+ original := &Packet{
508
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
509
+ Payload: []byte{0x01, 0x02, 0x03},
510
+ }
511
+ cloned := original.CloneVT()
512
+
513
+ cloned.Type = PacketType_PACKET_TYPE_LEASE_UPDATE_REQUEST
514
+ cloned.Payload[0] = 0xFF
515
+
516
+ if original.Type != PacketType_PACKET_TYPE_CONNECTION_REQUEST {
517
+ t.Error("original.Type was modified")
518
+ }
519
+ if original.Payload[0] != 0x01 {
520
+ t.Error("original.Payload was modified")
521
+ }
522
+ })
523
+
524
+ t.Run("RelayInfo", func(t *testing.T) {
525
+ original := &RelayInfo{
526
+ Identity: &rdsec.Identity{Id: "test"},
527
+ Address: []string{"addr1"},
528
+ Leases: []*Lease{
529
+ {Identity: &rdsec.Identity{Id: "l1"}, Name: "lease1"},
530
+ },
531
+ }
532
+ cloned := original.CloneVT()
533
+
534
+ cloned.Identity.Id = "modified"
535
+ cloned.Address[0] = "modified-addr"
536
+ cloned.Leases[0].Name = "modified-lease"
537
+
538
+ if original.Identity.Id != "test" {
539
+ t.Error("original.Identity.Id was modified")
540
+ }
541
+ if original.Address[0] != "addr1" {
542
+ t.Error("original.Address was modified")
543
+ }
544
+ if original.Leases[0].Name != "lease1" {
545
+ t.Error("original.Leases[0].Name was modified")
546
+ }
547
+ })
548
+
549
+ t.Run("Lease", func(t *testing.T) {
550
+ original := &Lease{
551
+ Identity: &rdsec.Identity{Id: "lease-clone"},
552
+ Expires: 12345,
553
+ Name: "clone-lease",
554
+ Alpn: []string{"h2"},
555
+ }
556
+ cloned := original.CloneVT()
557
+
558
+ cloned.Identity.Id = "modified"
559
+ cloned.Expires = 99999
560
+ cloned.Name = "modified"
561
+ cloned.Alpn[0] = "modified"
562
+
563
+ if original.Identity.Id != "lease-clone" {
564
+ t.Error("original.Identity.Id was modified")
565
+ }
566
+ if original.Expires != 12345 {
567
+ t.Error("original.Expires was modified")
568
+ }
569
+ if original.Name != "clone-lease" {
570
+ t.Error("original.Name was modified")
571
+ }
572
+ if original.Alpn[0] != "h2" {
573
+ t.Error("original.Alpn was modified")
574
+ }
575
+ })
576
+}
577
+
578
+// TestEqualVT tests equality comparison
579
+func TestEqualVT(t *testing.T) {
580
+ t.Run("Packet", func(t *testing.T) {
581
+ a := &Packet{Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST, Payload: []byte{0x01}}
582
+ b := &Packet{Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST, Payload: []byte{0x01}}
583
+ c := &Packet{Type: PacketType_PACKET_TYPE_LEASE_UPDATE_REQUEST, Payload: []byte{0x01}}
584
+
585
+ if !a.EqualVT(b) {
586
+ t.Error("Equal packets should be equal")
587
+ }
588
+ if a.EqualVT(c) {
589
+ t.Error("Different packet types should not be equal")
590
+ }
591
+ if a.EqualVT(nil) {
592
+ t.Error("Packet should not equal nil")
593
+ }
594
+ if !(*Packet)(nil).EqualVT(nil) {
595
+ t.Error("nil should equal nil")
596
+ }
597
+ })
598
+
599
+ t.Run("Lease", func(t *testing.T) {
600
+ identity := &rdsec.Identity{Id: "test"}
601
+ a := &Lease{Identity: identity, Expires: 123, Name: "test"}
602
+ b := &Lease{Identity: identity, Expires: 123, Name: "test"}
603
+ c := &Lease{Identity: identity, Expires: 456, Name: "test"}
604
+
605
+ if !a.EqualVT(b) {
606
+ t.Error("Equal leases should be equal")
607
+ }
608
+ if a.EqualVT(c) {
609
+ t.Error("Leases with different Expires should not be equal")
610
+ }
611
+ })
612
+}
613
+
614
+// TestSizeVT tests size calculation accuracy
615
+func TestSizeVT(t *testing.T) {
616
+ t.Run("Packet", func(t *testing.T) {
617
+ msg := &Packet{
618
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
619
+ Payload: []byte("test payload"),
620
+ }
621
+
622
+ size := msg.SizeVT()
623
+ data, err := msg.MarshalVT()
624
+ if err != nil {
625
+ t.Fatalf("MarshalVT() error = %v", err)
626
+ }
627
+
628
+ if size != len(data) {
629
+ t.Errorf("SizeVT() = %v, MarshalVT() produced %v bytes", size, len(data))
630
+ }
631
+ })
632
+
633
+ t.Run("RelayInfo", func(t *testing.T) {
634
+ msg := &RelayInfo{
635
+ Identity: &rdsec.Identity{Id: "size-test"},
636
+ Address: []string{"addr1:8080", "addr2:8080"},
637
+ Leases: []*Lease{
638
+ {Identity: &rdsec.Identity{Id: "l1"}, Name: "lease1"},
639
+ },
640
+ }
641
+
642
+ size := msg.SizeVT()
643
+ data, err := msg.MarshalVT()
644
+ if err != nil {
645
+ t.Fatalf("MarshalVT() error = %v", err)
646
+ }
647
+
648
+ if size != len(data) {
649
+ t.Errorf("SizeVT() = %v, MarshalVT() produced %v bytes", size, len(data))
650
+ }
651
+ })
652
+
653
+ t.Run("Lease", func(t *testing.T) {
654
+ msg := &Lease{
655
+ Identity: &rdsec.Identity{Id: "size-lease"},
656
+ Expires: 1234567890,
657
+ Name: "size-test",
658
+ Alpn: []string{"h2", "http/1.1"},
659
+ Metadata: "size metadata",
660
+ }
661
+
662
+ size := msg.SizeVT()
663
+ data, err := msg.MarshalVT()
664
+ if err != nil {
665
+ t.Fatalf("MarshalVT() error = %v", err)
666
+ }
667
+
668
+ if size != len(data) {
669
+ t.Errorf("SizeVT() = %v, MarshalVT() produced %v bytes", size, len(data))
670
+ }
671
+ })
672
+}
673
+
674
+// TestReset tests Reset clears all fields
675
+func TestReset(t *testing.T) {
676
+ t.Run("Packet", func(t *testing.T) {
677
+ p := &Packet{Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST, Payload: []byte{0x01}}
678
+ p.Reset()
679
+ if p.Type != 0 || p.Payload != nil {
680
+ t.Error("Packet not properly reset")
681
+ }
682
+ })
683
+
684
+ t.Run("Lease", func(t *testing.T) {
685
+ l := &Lease{
686
+ Identity: &rdsec.Identity{Id: "test"},
687
+ Expires: 123,
688
+ Name: "test-name",
689
+ Alpn: []string{"h2"},
690
+ Metadata: "meta",
691
+ }
692
+ l.Reset()
693
+ if l.Identity != nil || l.Expires != 0 || l.Name != "" || l.Alpn != nil || l.Metadata != "" {
694
+ t.Error("Lease not properly reset")
695
+ }
696
+ })
697
+}
698
+
699
+// TestGetters tests getter methods
700
+func TestGetters(t *testing.T) {
701
+ t.Run("Packet", func(t *testing.T) {
702
+ p := &Packet{
703
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
704
+ Payload: []byte{0x01, 0x02},
705
+ }
706
+
707
+ if p.GetType() != PacketType_PACKET_TYPE_CONNECTION_REQUEST {
708
+ t.Error("GetType() returned wrong value")
709
+ }
710
+ if !bytes.Equal(p.GetPayload(), []byte{0x01, 0x02}) {
711
+ t.Error("GetPayload() returned wrong value")
712
+ }
713
+ })
714
+
715
+ t.Run("Lease", func(t *testing.T) {
716
+ identity := &rdsec.Identity{Id: "lease-id", PublicKey: []byte{0x01}}
717
+ l := &Lease{
718
+ Identity: identity,
719
+ Expires: 12345,
720
+ Name: "lease-name",
721
+ Alpn: []string{"h2", "grpc"},
722
+ Metadata: "lease-metadata",
723
+ }
724
+
725
+ if l.GetIdentity() != identity {
726
+ t.Error("GetIdentity() returned wrong value")
727
+ }
728
+ if l.GetExpires() != 12345 {
729
+ t.Error("GetExpires() returned wrong value")
730
+ }
731
+ if l.GetName() != "lease-name" {
732
+ t.Error("GetName() returned wrong value")
733
+ }
734
+ if len(l.GetAlpn()) != 2 {
735
+ t.Error("GetAlpn() returned wrong value")
736
+ }
737
+ if l.GetMetadata() != "lease-metadata" {
738
+ t.Error("GetMetadata() returned wrong value")
739
+ }
740
+ })
741
+
742
+ t.Run("nil Lease", func(t *testing.T) {
743
+ var l *Lease
744
+ if l.GetIdentity() != nil {
745
+ t.Error("GetIdentity() on nil should return nil")
746
+ }
747
+ if l.GetExpires() != 0 {
748
+ t.Error("GetExpires() on nil should return 0")
749
+ }
750
+ if l.GetName() != "" {
751
+ t.Error("GetName() on nil should return empty string")
752
+ }
753
+ if l.GetAlpn() != nil {
754
+ t.Error("GetAlpn() on nil should return nil")
755
+ }
756
+ if l.GetMetadata() != "" {
757
+ t.Error("GetMetadata() on nil should return empty string")
758
+ }
759
+ })
760
+}
761
+
762
+// TestNilHandling tests nil message handling
763
+func TestNilHandling(t *testing.T) {
764
+ testCases := []struct {
765
+ name string
766
+ test func(t *testing.T)
767
+ }{
768
+ {"Packet", func(t *testing.T) {
769
+ var msg *Packet
770
+ if data, err := msg.MarshalVT(); err != nil || data != nil {
771
+ t.Errorf("MarshalVT() on nil Packet = (%v, %v), want (nil, nil)", data, err)
772
+ }
773
+ if msg.CloneVT() != nil {
774
+ t.Error("CloneVT() on nil Packet should return nil")
775
+ }
776
+ if msg.SizeVT() != 0 {
777
+ t.Error("SizeVT() on nil Packet should return 0")
778
+ }
779
+ }},
780
+ {"RelayInfo", func(t *testing.T) {
781
+ var msg *RelayInfo
782
+ if msg.CloneVT() != nil {
783
+ t.Error("CloneVT() on nil RelayInfo should return nil")
784
+ }
785
+ }},
786
+ {"Lease", func(t *testing.T) {
787
+ var msg *Lease
788
+ if msg.CloneVT() != nil {
789
+ t.Error("CloneVT() on nil Lease should return nil")
790
+ }
791
+ }},
792
+ {"LeaseUpdateRequest", func(t *testing.T) {
793
+ var msg *LeaseUpdateRequest
794
+ if msg.CloneVT() != nil {
795
+ t.Error("CloneVT() on nil LeaseUpdateRequest should return nil")
796
+ }
797
+ }},
798
+ {"LeaseUpdateResponse", func(t *testing.T) {
799
+ var msg *LeaseUpdateResponse
800
+ if msg.CloneVT() != nil {
801
+ t.Error("CloneVT() on nil LeaseUpdateResponse should return nil")
802
+ }
803
+ }},
804
+ {"LeaseDeleteRequest", func(t *testing.T) {
805
+ var msg *LeaseDeleteRequest
806
+ if msg.CloneVT() != nil {
807
+ t.Error("CloneVT() on nil LeaseDeleteRequest should return nil")
808
+ }
809
+ }},
810
+ {"LeaseDeleteResponse", func(t *testing.T) {
811
+ var msg *LeaseDeleteResponse
812
+ if msg.CloneVT() != nil {
813
+ t.Error("CloneVT() on nil LeaseDeleteResponse should return nil")
814
+ }
815
+ }},
816
+ {"ConnectionRequest", func(t *testing.T) {
817
+ var msg *ConnectionRequest
818
+ if msg.CloneVT() != nil {
819
+ t.Error("CloneVT() on nil ConnectionRequest should return nil")
820
+ }
821
+ }},
822
+ {"ConnectionResponse", func(t *testing.T) {
823
+ var msg *ConnectionResponse
824
+ if msg.CloneVT() != nil {
825
+ t.Error("CloneVT() on nil ConnectionResponse should return nil")
826
+ }
827
+ }},
828
+ }
829
+
830
+ for _, tc := range testCases {
831
+ t.Run(tc.name, tc.test)
832
+ }
833
+}
834
+
835
+// TestMarshalVTStrict tests strict marshaling
836
+func TestMarshalVTStrict(t *testing.T) {
837
+ msg := &Packet{
838
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
839
+ Payload: []byte{0x01, 0x02, 0x03},
840
+ }
841
+
842
+ data, err := msg.MarshalVTStrict()
843
+ if err != nil {
844
+ t.Fatalf("MarshalVTStrict() error = %v", err)
845
+ }
846
+
847
+ got := &Packet{}
848
+ err = got.UnmarshalVT(data)
849
+ if err != nil {
850
+ t.Fatalf("UnmarshalVT() error = %v", err)
851
+ }
852
+
853
+ if !msg.EqualVT(got) {
854
+ t.Error("MarshalVTStrict roundtrip mismatch")
855
+ }
856
+}
857
+
858
+// TestUnmarshalVTUnsafe tests unsafe unmarshaling
859
+func TestUnmarshalVTUnsafe(t *testing.T) {
860
+ msg := &ConnectionRequest{
861
+ LeaseId: "unsafe-test",
862
+ ClientIdentity: &rdsec.Identity{Id: "unsafe-client", PublicKey: []byte{0xAA, 0xBB}},
863
+ }
864
+
865
+ data, err := msg.MarshalVT()
866
+ if err != nil {
867
+ t.Fatalf("MarshalVT() error = %v", err)
868
+ }
869
+
870
+ got := &ConnectionRequest{}
871
+ err = got.UnmarshalVTUnsafe(data)
872
+ if err != nil {
873
+ t.Fatalf("UnmarshalVTUnsafe() error = %v", err)
874
+ }
875
+
876
+ if !msg.EqualVT(got) {
877
+ t.Error("UnmarshalVTUnsafe roundtrip mismatch")
878
+ }
879
+}
880
+
881
+// TestEmptyResponseMessages tests response messages
882
+func TestEmptyResponseMessages(t *testing.T) {
883
+ responses := []ResponseCode{
884
+ ResponseCode_RESPONSE_CODE_UNKNOWN,
885
+ ResponseCode_RESPONSE_CODE_ACCEPTED,
886
+ ResponseCode_RESPONSE_CODE_INVALID_EXPIRES,
887
+ ResponseCode_RESPONSE_CODE_INVALID_IDENTITY,
888
+ ResponseCode_RESPONSE_CODE_INVALID_NAME,
889
+ ResponseCode_RESPONSE_CODE_INVALID_ALPN,
890
+ ResponseCode_RESPONSE_CODE_REJECTED,
891
+ }
892
+
893
+ for _, code := range responses {
894
+ t.Run(code.String(), func(t *testing.T) {
895
+ updateResp := &LeaseUpdateResponse{Code: code}
896
+ data, err := updateResp.MarshalVT()
897
+ if err != nil {
898
+ t.Fatalf("MarshalVT() error = %v", err)
899
+ }
900
+
901
+ got := &LeaseUpdateResponse{}
902
+ if err := got.UnmarshalVT(data); err != nil {
903
+ t.Fatalf("UnmarshalVT() error = %v", err)
904
+ }
905
+
906
+ if got.Code != code {
907
+ t.Errorf("Code = %v, want %v", got.Code, code)
908
+ }
909
+ })
910
+ }
911
+}
912
+
913
+// TestComplexRelayInfo tests complex RelayInfo with multiple nested elements
914
+func TestComplexRelayInfo(t *testing.T) {
915
+ // Create a complex RelayInfo with multiple addresses and leases
916
+ msg := &RelayInfo{
917
+ Identity: &rdsec.Identity{
918
+ Id: "complex-relay",
919
+ PublicKey: bytes.Repeat([]byte{0xAA}, 32),
920
+ },
921
+ Address: []string{
922
+ "relay1.example.com:443",
923
+ "relay2.example.com:443",
924
+ "relay3.example.com:443",
925
+ },
926
+ Leases: []*Lease{
927
+ {
928
+ Identity: &rdsec.Identity{
929
+ Id: "lease-1",
930
+ PublicKey: bytes.Repeat([]byte{0x01}, 32),
931
+ },
932
+ Expires: 1000000000,
933
+ Name: "service-1",
934
+ Alpn: []string{"h2", "grpc"},
935
+ Metadata: "production service 1",
936
+ },
937
+ {
938
+ Identity: &rdsec.Identity{
939
+ Id: "lease-2",
940
+ PublicKey: bytes.Repeat([]byte{0x02}, 32),
941
+ },
942
+ Expires: 2000000000,
943
+ Name: "service-2",
944
+ Alpn: []string{"h2"},
945
+ Metadata: "production service 2",
946
+ },
947
+ },
948
+ }
949
+
950
+ data, err := msg.MarshalVT()
951
+ if err != nil {
952
+ t.Fatalf("MarshalVT() error = %v", err)
953
+ }
954
+
955
+ got := &RelayInfo{}
956
+ err = got.UnmarshalVT(data)
957
+ if err != nil {
958
+ t.Fatalf("UnmarshalVT() error = %v", err)
959
+ }
960
+
961
+ if !msg.EqualVT(got) {
962
+ t.Error("complex RelayInfo roundtrip mismatch")
963
+ }
964
+
965
+ // Verify all fields
966
+ if len(got.Address) != 3 {
967
+ t.Errorf("got %d addresses, want 3", len(got.Address))
968
+ }
969
+ if len(got.Leases) != 2 {
970
+ t.Errorf("got %d leases, want 2", len(got.Leases))
971
+ }
972
+}
973
+
974
+// BenchmarkPacket_MarshalVT benchmarks packet marshaling
975
+func BenchmarkPacket_MarshalVT(b *testing.B) {
976
+ msg := &Packet{
977
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
978
+ Payload: bytes.Repeat([]byte{0x01}, 1024),
979
+ }
980
+
981
+ b.ResetTimer()
982
+ for i := 0; i < b.N; i++ {
983
+ _, _ = msg.MarshalVT()
984
+ }
985
+}
986
+
987
+// BenchmarkPacket_UnmarshalVT benchmarks packet unmarshaling
988
+func BenchmarkPacket_UnmarshalVT(b *testing.B) {
989
+ msg := &Packet{
990
+ Type: PacketType_PACKET_TYPE_CONNECTION_REQUEST,
991
+ Payload: bytes.Repeat([]byte{0x01}, 1024),
992
+ }
993
+
994
+ data, _ := msg.MarshalVT()
995
+
996
+ b.ResetTimer()
997
+ for i := 0; i < b.N; i++ {
998
+ got := &Packet{}
999
+ _ = got.UnmarshalVT(data)
1000
+ }
1001
+}
1002
+
1003
+// BenchmarkRelayInfo_MarshalVT benchmarks complex relay info marshaling
1004
+func BenchmarkRelayInfo_MarshalVT(b *testing.B) {
1005
+ msg := &RelayInfo{
1006
+ Identity: &rdsec.Identity{
1007
+ Id: "benchmark-relay",
1008
+ PublicKey: bytes.Repeat([]byte{0xAA}, 32),
1009
+ },
1010
+ Address: []string{"addr1:8080", "addr2:8080", "addr3:8080"},
1011
+ Leases: []*Lease{
1012
+ {
1013
+ Identity: &rdsec.Identity{Id: "l1", PublicKey: bytes.Repeat([]byte{0x01}, 32)},
1014
+ Expires: 1234567890,
1015
+ Name: "lease1",
1016
+ Alpn: []string{"h2", "grpc"},
1017
+ },
1018
+ {
1019
+ Identity: &rdsec.Identity{Id: "l2", PublicKey: bytes.Repeat([]byte{0x02}, 32)},
1020
+ Expires: 9876543210,
1021
+ Name: "lease2",
1022
+ Alpn: []string{"h2"},
1023
+ },
1024
+ },
1025
+ }
1026
+
1027
+ b.ResetTimer()
1028
+ for i := 0; i < b.N; i++ {
1029
+ _, _ = msg.MarshalVT()
1030
+ }
1031
+}
1032
+
1033
+// BenchmarkLease_MarshalVT benchmarks lease marshaling
1034
+func BenchmarkLease_MarshalVT(b *testing.B) {
1035
+ msg := &Lease{
1036
+ Identity: &rdsec.Identity{
1037
+ Id: "benchmark-lease",
1038
+ PublicKey: bytes.Repeat([]byte{0xBB}, 32),
1039
+ },
1040
+ Expires: 1234567890,
1041
+ Name: "benchmark-lease",
1042
+ Alpn: []string{"h2", "grpc", "http/1.1"},
1043
+ Metadata: "benchmark metadata",
1044
+ }
1045
+
1046
+ b.ResetTimer()
1047
+ for i := 0; i < b.N; i++ {
1048
+ _, _ = msg.MarshalVT()
1049
+ }
1050
+}
1051
+
1052
+// TestPacketType_String tests enum String method
1053
+func TestPacketType_String(t *testing.T) {
1054
+ tests := []struct {
1055
+ name string
1056
+ enum PacketType
1057
+ want string
1058
+ }{
1059
+ {"PACKET_TYPE_RELAY_INFO_REQUEST", PacketType_PACKET_TYPE_RELAY_INFO_REQUEST, "PACKET_TYPE_RELAY_INFO_REQUEST"},
1060
+ {"PACKET_TYPE_RELAY_INFO_RESPONSE", PacketType_PACKET_TYPE_RELAY_INFO_RESPONSE, "PACKET_TYPE_RELAY_INFO_RESPONSE"},
1061
+ {"PACKET_TYPE_LEASE_UPDATE_REQUEST", PacketType_PACKET_TYPE_LEASE_UPDATE_REQUEST, "PACKET_TYPE_LEASE_UPDATE_REQUEST"},
1062
+ {"PACKET_TYPE_LEASE_UPDATE_RESPONSE", PacketType_PACKET_TYPE_LEASE_UPDATE_RESPONSE, "PACKET_TYPE_LEASE_UPDATE_RESPONSE"},
1063
+ {"PACKET_TYPE_LEASE_DELETE_REQUEST", PacketType_PACKET_TYPE_LEASE_DELETE_REQUEST, "PACKET_TYPE_LEASE_DELETE_REQUEST"},
1064
+ {"PACKET_TYPE_LEASE_DELETE_RESPONSE", PacketType_PACKET_TYPE_LEASE_DELETE_RESPONSE, "PACKET_TYPE_LEASE_DELETE_RESPONSE"},
1065
+ {"PACKET_TYPE_CONNECTION_REQUEST", PacketType_PACKET_TYPE_CONNECTION_REQUEST, "PACKET_TYPE_CONNECTION_REQUEST"},
1066
+ {"PACKET_TYPE_CONNECTION_RESPONSE", PacketType_PACKET_TYPE_CONNECTION_RESPONSE, "PACKET_TYPE_CONNECTION_RESPONSE"},
1067
+ }
1068
+
1069
+ for _, tt := range tests {
1070
+ t.Run(tt.name, func(t *testing.T) {
1071
+ if got := tt.enum.String(); got != tt.want {
1072
+ t.Errorf("PacketType.String() = %v, want %v", got, tt.want)
1073
+ }
1074
+ })
1075
+ }
1076
+}
1077
+
1078
+// TestPacketType_Enum tests Enum method
1079
+func TestPacketType_Enum(t *testing.T) {
1080
+ if PacketType_PACKET_TYPE_CONNECTION_REQUEST.Enum() != nil && *PacketType_PACKET_TYPE_CONNECTION_REQUEST.Enum() != 6 {
1081
+ t.Error("PacketType.Enum() returned wrong value")
1082
+ }
1083
+ if PacketType_PACKET_TYPE_RELAY_INFO_REQUEST.Enum() != nil && *PacketType_PACKET_TYPE_RELAY_INFO_REQUEST.Enum() != 0 {
1084
+ t.Error("PACKET_TYPE_RELAY_INFO_REQUEST.Enum() should be 0")
1085
+ }
1086
+}
1087
+
1088
+// TestResponseCode_String tests enum String method
1089
+func TestResponseCode_String(t *testing.T) {
1090
+ tests := []struct {
1091
+ name string
1092
+ enum ResponseCode
1093
+ want string
1094
+ }{
1095
+ {"RESPONSE_CODE_UNKNOWN", ResponseCode_RESPONSE_CODE_UNKNOWN, "RESPONSE_CODE_UNKNOWN"},
1096
+ {"RESPONSE_CODE_ACCEPTED", ResponseCode_RESPONSE_CODE_ACCEPTED, "RESPONSE_CODE_ACCEPTED"},
1097
+ {"RESPONSE_CODE_INVALID_EXPIRES", ResponseCode_RESPONSE_CODE_INVALID_EXPIRES, "RESPONSE_CODE_INVALID_EXPIRES"},
1098
+ {"RESPONSE_CODE_INVALID_IDENTITY", ResponseCode_RESPONSE_CODE_INVALID_IDENTITY, "RESPONSE_CODE_INVALID_IDENTITY"},
1099
+ {"RESPONSE_CODE_INVALID_NAME", ResponseCode_RESPONSE_CODE_INVALID_NAME, "RESPONSE_CODE_INVALID_NAME"},
1100
+ {"RESPONSE_CODE_INVALID_ALPN", ResponseCode_RESPONSE_CODE_INVALID_ALPN, "RESPONSE_CODE_INVALID_ALPN"},
1101
+ {"RESPONSE_CODE_REJECTED", ResponseCode_RESPONSE_CODE_REJECTED, "RESPONSE_CODE_REJECTED"},
1102
+ }
1103
+
1104
+ for _, tt := range tests {
1105
+ t.Run(tt.name, func(t *testing.T) {
1106
+ if got := tt.enum.String(); got != tt.want {
1107
+ t.Errorf("ResponseCode.String() = %v, want %v", got, tt.want)
1108
+ }
1109
+ })
1110
+ }
1111
+}
1112
+
1113
+// TestResponseCode_Enum tests Enum method
1114
+func TestResponseCode_Enum(t *testing.T) {
1115
+ if ResponseCode_RESPONSE_CODE_ACCEPTED.Enum() != nil && *ResponseCode_RESPONSE_CODE_ACCEPTED.Enum() != 1 {
1116
+ t.Error("ResponseCode.Enum() returned wrong value")
1117
+ }
1118
+ if ResponseCode_RESPONSE_CODE_UNKNOWN.Enum() != nil && *ResponseCode_RESPONSE_CODE_UNKNOWN.Enum() != 0 {
1119
+ t.Error("RESPONSE_CODE_UNKNOWN.Enum() should be 0")
1120
+ }
1121
+}
1122
+
1123
+// TestRelayInfo_Getters tests all getter methods
1124
+func TestRelayInfo_Getters(t *testing.T) {
1125
+ identity := &rdsec.Identity{Id: "relay-test", PublicKey: []byte{0xAA}}
1126
+ msg := &RelayInfo{
1127
+ Identity: identity,
1128
+ Address: []string{"addr1:8080", "addr2:8080"},
1129
+ Leases: []*Lease{{Name: "lease1"}},
1130
+ }
1131
+
1132
+ if got := msg.GetIdentity(); got == nil || got.Id != "relay-test" {
1133
+ t.Errorf("GetIdentity() = %v, want Id='relay-test'", got)
1134
+ }
1135
+ if got := msg.GetAddress(); len(got) != 2 {
1136
+ t.Errorf("GetAddress() length = %v, want 2", len(got))
1137
+ }
1138
+ if got := msg.GetLeases(); len(got) != 1 {
1139
+ t.Errorf("GetLeases() length = %v, want 1", len(got))
1140
+ }
1141
+
1142
+ // Test nil defaults
1143
+ empty := &RelayInfo{}
1144
+ if got := empty.GetIdentity(); got != nil {
1145
+ t.Errorf("empty GetIdentity() = %v, want nil", got)
1146
+ }
1147
+ if got := empty.GetAddress(); got != nil {
1148
+ t.Errorf("empty GetAddress() = %v, want nil", got)
1149
+ }
1150
+ if got := empty.GetLeases(); got != nil {
1151
+ t.Errorf("empty GetLeases() = %v, want nil", got)
1152
+ }
1153
+}
1154
+
1155
+// TestRelayInfo_Reset tests Reset method
1156
+func TestRelayInfo_Reset(t *testing.T) {
1157
+ msg := &RelayInfo{
1158
+ Identity: &rdsec.Identity{Id: "test"},
1159
+ Address: []string{"addr1"},
1160
+ Leases: []*Lease{{Name: "lease1"}},
1161
+ }
1162
+
1163
+ msg.Reset()
1164
+
1165
+ if msg.Identity != nil {
1166
+ t.Error("Reset() did not clear Identity")
1167
+ }
1168
+ if msg.Address != nil {
1169
+ t.Error("Reset() did not clear Address")
1170
+ }
1171
+ if msg.Leases != nil {
1172
+ t.Error("Reset() did not clear Leases")
1173
+ }
1174
+}
1175
+
1176
+// TestRelayInfoRequest_Reset tests Reset method
1177
+func TestRelayInfoRequest_Reset(t *testing.T) {
1178
+ msg := &RelayInfoRequest{}
1179
+ msg.Reset() // Should not panic
1180
+}
1181
+
1182
+// TestRelayInfoResponse_Getters tests all getter methods
1183
+func TestRelayInfoResponse_Getters(t *testing.T) {
1184
+ relay := &RelayInfo{Identity: &rdsec.Identity{Id: "response-test"}}
1185
+ msg := &RelayInfoResponse{
1186
+ RelayInfo: relay,
1187
+ }
1188
+
1189
+ if got := msg.GetRelayInfo(); got == nil || got.Identity.Id != "response-test" {
1190
+ t.Errorf("GetRelayInfo() = %v, want Id='response-test'", got)
1191
+ }
1192
+
1193
+ // Test nil defaults
1194
+ empty := &RelayInfoResponse{}
1195
+ if got := empty.GetRelayInfo(); got != nil {
1196
+ t.Errorf("empty GetRelayInfo() = %v, want nil", got)
1197
+ }
1198
+}
1199
+
1200
+// TestRelayInfoResponse_Reset tests Reset method
1201
+func TestRelayInfoResponse_Reset(t *testing.T) {
1202
+ msg := &RelayInfoResponse{
1203
+ RelayInfo: &RelayInfo{Identity: &rdsec.Identity{Id: "test"}},
1204
+ }
1205
+
1206
+ msg.Reset()
1207
+
1208
+ if msg.RelayInfo != nil {
1209
+ t.Error("Reset() did not clear RelayInfo")
1210
+ }
1211
+}
1212
+
1213
+// TestLeaseUpdateRequest_Getters tests all getter methods
1214
+func TestLeaseUpdateRequest_Getters(t *testing.T) {
1215
+ lease := &Lease{Name: "update-lease"}
1216
+ msg := &LeaseUpdateRequest{
1217
+ Lease: lease,
1218
+ Nonce: []byte{0x01, 0x02},
1219
+ Timestamp: 1234567890,
1220
+ }
1221
+
1222
+ if got := msg.GetLease(); got == nil || got.Name != "update-lease" {
1223
+ t.Errorf("GetLease() = %v, want Name='update-lease'", got)
1224
+ }
1225
+ if got := msg.GetNonce(); !bytes.Equal(got, []byte{0x01, 0x02}) {
1226
+ t.Errorf("GetNonce() = %v, want [1 2]", got)
1227
+ }
1228
+ if got := msg.GetTimestamp(); got != 1234567890 {
1229
+ t.Errorf("GetTimestamp() = %v, want 1234567890", got)
1230
+ }
1231
+
1232
+ // Test nil defaults
1233
+ empty := &LeaseUpdateRequest{}
1234
+ if got := empty.GetLease(); got != nil {
1235
+ t.Errorf("empty GetLease() = %v, want nil", got)
1236
+ }
1237
+ if got := empty.GetNonce(); got != nil {
1238
+ t.Errorf("empty GetNonce() = %v, want nil", got)
1239
+ }
1240
+}
1241
+
1242
+// TestLeaseUpdateRequest_Reset tests Reset method
1243
+func TestLeaseUpdateRequest_Reset(t *testing.T) {
1244
+ msg := &LeaseUpdateRequest{
1245
+ Lease: &Lease{Name: "test"},
1246
+ Nonce: []byte{0x01},
1247
+ Timestamp: 123,
1248
+ }
1249
+
1250
+ msg.Reset()
1251
+
1252
+ if msg.Lease != nil {
1253
+ t.Error("Reset() did not clear Lease")
1254
+ }
1255
+ if msg.Nonce != nil {
1256
+ t.Error("Reset() did not clear Nonce")
1257
+ }
1258
+ if msg.Timestamp != 0 {
1259
+ t.Error("Reset() did not clear Timestamp")
1260
+ }
1261
+}
1262
+
1263
+// TestLeaseUpdateResponse_Reset tests Reset method
1264
+func TestLeaseUpdateResponse_Reset(t *testing.T) {
1265
+ msg := &LeaseUpdateResponse{
1266
+ Code: ResponseCode_RESPONSE_CODE_ACCEPTED,
1267
+ }
1268
+
1269
+ msg.Reset()
1270
+
1271
+ if msg.Code != ResponseCode_RESPONSE_CODE_UNKNOWN {
1272
+ t.Error("Reset() did not clear Code to default")
1273
+ }
1274
+}
1275
+
1276
+// TestLeaseDeleteRequest_Reset tests Reset method
1277
+func TestLeaseDeleteRequest_Reset(t *testing.T) {
1278
+ msg := &LeaseDeleteRequest{
1279
+ Identity: &rdsec.Identity{Id: "delete-test"},
1280
+ }
1281
+
1282
+ msg.Reset()
1283
+
1284
+ if msg.Identity != nil {
1285
+ t.Error("Reset() did not clear Identity")
1286
+ }
1287
+}
1288
+
1289
+// TestLeaseDeleteResponse_Reset tests Reset method
1290
+func TestLeaseDeleteResponse_Reset(t *testing.T) {
1291
+ msg := &LeaseDeleteResponse{
1292
+ Code: ResponseCode_RESPONSE_CODE_ACCEPTED,
1293
+ }
1294
+
1295
+ msg.Reset()
1296
+
1297
+ if msg.Code != ResponseCode_RESPONSE_CODE_UNKNOWN {
1298
+ t.Error("Reset() did not clear Code to default")
1299
+ }
1300
+}