Skip to content

Commit b6bfd5d

Browse files
committed
apiutil: add tests for UnmarshalSRSegments nil Flags and round-trip
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
1 parent b22177e commit b6bfd5d

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

pkg/apiutil/attribute_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/osrg/gobgp/v4/api"
2626
"github.com/osrg/gobgp/v4/pkg/packet/bgp"
2727
"github.com/stretchr/testify/assert"
28+
"github.com/stretchr/testify/require"
2829
)
2930

3031
func Test_OriginAttribute(t *testing.T) {
@@ -1563,6 +1564,118 @@ func TestFullCyclePrefixSID(t *testing.T) {
15631564
}
15641565
}
15651566

1567+
func TestUnmarshalSRSegments_NilFlags(t *testing.T) {
1568+
// Flags is an optional protobuf sub-message. A caller that builds
1569+
// api.SegmentTypeA or api.SegmentTypeB without setting Flags must
1570+
// not cause a nil pointer dereference; the result should be all-zero
1571+
// flag bits.
1572+
t.Run("SegmentTypeA_nil_flags", func(t *testing.T) {
1573+
segs := []*api.TunnelEncapSubTLVSRSegmentList_Segment{
1574+
{Segment: &api.TunnelEncapSubTLVSRSegmentList_Segment_A{
1575+
A: &api.SegmentTypeA{Label: 100},
1576+
// Flags intentionally omitted (nil)
1577+
}},
1578+
}
1579+
result, err := UnmarshalSRSegments(segs)
1580+
assert.NoError(t, err)
1581+
require.Len(t, result, 1)
1582+
seg, ok := result[0].(*bgp.SegmentTypeA)
1583+
require.True(t, ok)
1584+
assert.Equal(t, uint32(100), seg.Label)
1585+
assert.Equal(t, uint8(0), seg.Flags)
1586+
})
1587+
1588+
t.Run("SegmentTypeB_nil_flags", func(t *testing.T) {
1589+
sid := []byte{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
1590+
segs := []*api.TunnelEncapSubTLVSRSegmentList_Segment{
1591+
{Segment: &api.TunnelEncapSubTLVSRSegmentList_Segment_B{
1592+
B: &api.SegmentTypeB{Sid: sid},
1593+
// Flags intentionally omitted (nil)
1594+
}},
1595+
}
1596+
result, err := UnmarshalSRSegments(segs)
1597+
assert.NoError(t, err)
1598+
require.Len(t, result, 1)
1599+
seg, ok := result[0].(*bgp.SegmentTypeB)
1600+
require.True(t, ok)
1601+
assert.Equal(t, sid, seg.SID)
1602+
assert.Equal(t, uint8(0), seg.Flags)
1603+
})
1604+
}
1605+
1606+
func TestUnmarshalSRSegments_RoundTrip(t *testing.T) {
1607+
t.Run("SegmentTypeA", func(t *testing.T) {
1608+
orig := []bgp.TunnelEncapSubTLVInterface{
1609+
&bgp.SegmentTypeA{
1610+
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{Type: bgp.EncapSubTLVType(bgp.TypeA), Length: 6},
1611+
Label: 200,
1612+
Flags: 0x80 | 0x10, // VFlag + BFlag
1613+
},
1614+
}
1615+
marshaled, err := MarshalSRSegments(orig)
1616+
require.NoError(t, err)
1617+
result, err := UnmarshalSRSegments(marshaled)
1618+
require.NoError(t, err)
1619+
require.Len(t, result, 1)
1620+
seg, ok := result[0].(*bgp.SegmentTypeA)
1621+
require.True(t, ok)
1622+
assert.Equal(t, uint32(200), seg.Label)
1623+
assert.Equal(t, uint8(0x80|0x10), seg.Flags)
1624+
})
1625+
1626+
t.Run("SegmentTypeB", func(t *testing.T) {
1627+
sid := []byte{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
1628+
orig := []bgp.TunnelEncapSubTLVInterface{
1629+
&bgp.SegmentTypeB{
1630+
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{Type: bgp.EncapSubTLVType(bgp.TypeB), Length: 18},
1631+
SID: sid,
1632+
Flags: 0x40 | 0x20, // AFlag + SFlag
1633+
},
1634+
}
1635+
marshaled, err := MarshalSRSegments(orig)
1636+
require.NoError(t, err)
1637+
result, err := UnmarshalSRSegments(marshaled)
1638+
require.NoError(t, err)
1639+
require.Len(t, result, 1)
1640+
seg, ok := result[0].(*bgp.SegmentTypeB)
1641+
require.True(t, ok)
1642+
assert.Equal(t, sid, seg.SID)
1643+
assert.Equal(t, uint8(0x40|0x20), seg.Flags)
1644+
})
1645+
1646+
t.Run("SegmentTypeB_with_SRv6EBS", func(t *testing.T) {
1647+
sid := []byte{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
1648+
orig := []bgp.TunnelEncapSubTLVInterface{
1649+
&bgp.SegmentTypeB{
1650+
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{Type: bgp.EncapSubTLVType(bgp.TypeB), Length: 18},
1651+
SID: sid,
1652+
Flags: 0x80,
1653+
SRv6EBS: &bgp.SRv6EndpointBehaviorStructure{
1654+
Behavior: bgp.END,
1655+
BlockLen: 40,
1656+
NodeLen: 24,
1657+
FuncLen: 16,
1658+
ArgLen: 0,
1659+
},
1660+
},
1661+
}
1662+
marshaled, err := MarshalSRSegments(orig)
1663+
require.NoError(t, err)
1664+
result, err := UnmarshalSRSegments(marshaled)
1665+
require.NoError(t, err)
1666+
require.Len(t, result, 1)
1667+
seg, ok := result[0].(*bgp.SegmentTypeB)
1668+
require.True(t, ok)
1669+
assert.Equal(t, sid, seg.SID)
1670+
assert.Equal(t, uint8(0x80), seg.Flags)
1671+
require.NotNil(t, seg.SRv6EBS)
1672+
assert.Equal(t, bgp.END, seg.SRv6EBS.Behavior)
1673+
assert.Equal(t, uint8(40), seg.SRv6EBS.BlockLen)
1674+
assert.Equal(t, uint8(24), seg.SRv6EBS.NodeLen)
1675+
assert.Equal(t, uint8(16), seg.SRv6EBS.FuncLen)
1676+
})
1677+
}
1678+
15661679
func TestFullCycleSRv6SIDStructureSubSubTLV(t *testing.T) {
15671680
tests := []struct {
15681681
name string

0 commit comments

Comments
 (0)