Skip to content

Commit

Permalink
add unit for ovn-nb-logical_router_route.go (#4672)
Browse files Browse the repository at this point in the history
Signed-off-by: zcq98 <[email protected]>
  • Loading branch information
Congqi Zhao authored Oct 29, 2024
1 parent bc2eb2b commit 535048d
Show file tree
Hide file tree
Showing 2 changed files with 309 additions and 11 deletions.
308 changes: 297 additions & 11 deletions pkg/ovs/ovn-nb-logical_router_route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ func (suite *OvnClientTestSuite) testCreateLogicalRouterStaticRoutes() {

require.Contains(t, lr.StaticRoutes, route.UUID)
}

// create logical router static routes for non-exist logical router
err = nbClient.CreateLogicalRouterStaticRoutes("non-exist-lrName", append(routes, nil)...)
require.ErrorContains(t, err, "generate operations for adding static routes to logical router")
}

func (suite *OvnClientTestSuite) testAddLogicalRouterStaticRoute() {
Expand Down Expand Up @@ -85,6 +89,13 @@ func (suite *OvnClientTestSuite) testAddLogicalRouterStaticRoute() {
}
})

t.Run("create route for non-exist logical router", func(t *testing.T) {
for i := range ipPrefixes {
err = nbClient.AddLogicalRouterStaticRoute("non-exist-lrName", routeTable, "", ipPrefixes[i], nil, nexthops[i])
require.ErrorContains(t, err, "not found logical router")
}
})

t.Run("update route", func(t *testing.T) {
updatedNexthops := [...]string{"192.168.30.254", "fd00:100:64::fe"}
for i := range ipPrefixes {
Expand Down Expand Up @@ -167,6 +178,20 @@ func (suite *OvnClientTestSuite) testDeleteLogicalRouterStaticRoute() {

_, err = nbClient.GetLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, false)
require.ErrorContains(t, err, "not found")

// delete non-exist route
ipPrefix = "192.168.40.0/24"
nexthop = "192.168.40.1"
err = nbClient.DeleteLogicalRouterStaticRoute(lrName, &routeTable, &policy, ipPrefix, nexthop)
require.NoError(t, err)
})

t.Run("delete static route for non-exist logical router", func(t *testing.T) {
ipPrefix := "192.168.30.0/24"
nexthop := "192.168.30.1"

err := nbClient.DeleteLogicalRouterStaticRoute("non-exist-lrName", &routeTable, nil, ipPrefix, nexthop)
require.NoError(t, err)
})

t.Run("ecmp policy route", func(t *testing.T) {
Expand Down Expand Up @@ -252,6 +277,10 @@ func (suite *OvnClientTestSuite) testClearLogicalRouterStaticRoute() {
lr, err = nbClient.GetLogicalRouter(lrName, false)
require.NoError(t, err)
require.Empty(t, lr.StaticRoutes)

// clear logical router static route for non-exist logical router
err = nbClient.ClearLogicalRouterStaticRoute("non-exist-lrName")
require.ErrorContains(t, err, "not found logical router")
}

func (suite *OvnClientTestSuite) testGetLogicalRouterStaticRoute() {
Expand Down Expand Up @@ -321,30 +350,74 @@ func (suite *OvnClientTestSuite) testListLogicalRouterStaticRoutes() {
t.Parallel()

nbClient := suite.ovnNBClient
lrName := "test-list-routes-lr"
lrName := "test-list-routes-filters-lr"
routeTable := util.MainRouteTable
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefixes := []string{"192.168.30.0/24", "192.168.40.0/24", "192.168.50.0/24"}
nexthops := []string{"192.168.30.1", "192.168.40.1", "192.168.50.1"}
routes := make([]*ovnnb.LogicalRouterStaticRoute, 0, 5)
routes := make([]*ovnnb.LogicalRouterStaticRoute, 0)

err := nbClient.CreateLogicalRouter(lrName)
require.NoError(t, err)

for i, ipPrefix := range ipPrefixes {
route, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthops[i], nil)
require.NoError(t, err)
// Create test routes with different external IDs
testData := []struct {
ipPrefix string
nexthop string
externalIDs map[string]string
}{
{"192.168.60.0/24", "192.168.60.1", map[string]string{"key1": "value1", "key2": "value2"}},
{"192.168.70.0/24", "192.168.70.1", map[string]string{"key1": "value1"}},
{"192.168.80.0/24", "192.168.80.1", map[string]string{"key2": "value2"}},
{"192.168.90.0/24", "192.168.90.1", map[string]string{}},
}

for _, data := range testData {
route, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, data.ipPrefix, data.nexthop, nil)
require.NoError(t, err)
route.ExternalIDs = data.externalIDs
routes = append(routes, route)
}

err = nbClient.CreateLogicalRouterStaticRoutes(lrName, append(routes, nil)...)
err = nbClient.CreateLogicalRouterStaticRoutes(lrName, routes...)
require.NoError(t, err)

t.Run("include same router routes", func(t *testing.T) {
out, err := nbClient.ListLogicalRouterStaticRoutes(lrName, nil, nil, "", nil)
t.Run("filter by external IDs with multiple keys", func(t *testing.T) {
result, err := nbClient.ListLogicalRouterStaticRoutes(lrName, nil, nil, "", map[string]string{"key1": "value1", "key2": "value2"})
require.NoError(t, err)
require.Len(t, result, 1)
require.Equal(t, "192.168.60.0/24", result[0].IPPrefix)
})

t.Run("filter by external IDs key existence only", func(t *testing.T) {
result, err := nbClient.ListLogicalRouterStaticRoutes(lrName, nil, nil, "", map[string]string{"key1": ""})
require.NoError(t, err)
require.Len(t, result, 2)
})

t.Run("filter by route table and external IDs", func(t *testing.T) {
customTable := "custom"
result, err := nbClient.ListLogicalRouterStaticRoutes(lrName, &customTable, nil, "", map[string]string{"key1": "value1"})
require.NoError(t, err)
require.Len(t, out, 3)
require.Empty(t, result)
})

t.Run("filter with non-matching external IDs", func(t *testing.T) {
result, err := nbClient.ListLogicalRouterStaticRoutes(lrName, nil, nil, "", map[string]string{"nonexistent": "value"})
require.NoError(t, err)
require.Empty(t, result)
})

t.Run("filter with policy and external IDs", func(t *testing.T) {
srcPolicy := ovnnb.LogicalRouterStaticRoutePolicySrcIP
result, err := nbClient.ListLogicalRouterStaticRoutes(lrName, nil, &srcPolicy, "", map[string]string{"key1": "value1"})
require.NoError(t, err)
require.Empty(t, result)
})

t.Run("filter with IP prefix and external IDs", func(t *testing.T) {
result, err := nbClient.ListLogicalRouterStaticRoutes(lrName, nil, nil, "192.168.70.0/24", map[string]string{"key1": "value1"})
require.NoError(t, err)
require.Len(t, result, 1)
require.Equal(t, "192.168.70.0/24", result[0].IPPrefix)
})
}

Expand Down Expand Up @@ -373,4 +446,217 @@ func (suite *OvnClientTestSuite) testNewLogicalRouterStaticRoute() {
require.NoError(t, err)
expect.UUID = route.UUID
require.Equal(t, expect, route)

t.Run("with custom options", func(t *testing.T) {
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefix := "192.168.100.0/24"
nexthop := "192.168.100.1"

customOption := func(route *ovnnb.LogicalRouterStaticRoute) {
route.Options = map[string]string{
"ecmp_symmetric_reply": "true",
"method": "redirect",
}
}

route, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, nil, customOption)
require.NoError(t, err)
require.Equal(t, "true", route.Options["ecmp_symmetric_reply"])
require.Equal(t, "redirect", route.Options["method"])
})

t.Run("with multiple options and bfd", func(t *testing.T) {
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefix := "192.168.110.0/24"
nexthop := "192.168.110.1"
bfdID := "test-bfd"

option1 := func(route *ovnnb.LogicalRouterStaticRoute) {
route.ExternalIDs = map[string]string{"key1": "value1"}
}
option2 := func(route *ovnnb.LogicalRouterStaticRoute) {
if route.Options == nil {
route.Options = make(map[string]string)
}
route.Options["test"] = "value"
}

route, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, &bfdID, option1, option2)
require.NoError(t, err)
require.Equal(t, "value1", route.ExternalIDs["key1"])
require.Equal(t, "value", route.Options["test"])
require.Equal(t, "true", route.Options[util.StaticRouteBfdEcmp])
require.Equal(t, &bfdID, route.BFD)
})

t.Run("with empty policy and existing route", func(t *testing.T) {
ipPrefix := "192.168.120.0/24"
nexthop := "192.168.120.1"

route1, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, "", ipPrefix, nexthop, nil)
require.NoError(t, err)
err = nbClient.CreateLogicalRouterStaticRoutes(lrName, route1)
require.NoError(t, err)

route2, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, "", ipPrefix, nexthop, nil)
require.Nil(t, route2)
require.NoError(t, err)
})

t.Run("with bfd but no options", func(t *testing.T) {
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefix := "192.168.130.0/24"
nexthop := "192.168.130.1"
bfdID := "test-bfd-2"

route, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, &bfdID)
require.NoError(t, err)
require.Equal(t, "true", route.Options[util.StaticRouteBfdEcmp])
require.Equal(t, &bfdID, route.BFD)
})

t.Run("with empty logical switch name", func(t *testing.T) {
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefix := "192.168.130.0/24"
nexthop := "192.168.130.1"
bfdID := "test-bfd-2"

route, err := nbClient.newLogicalRouterStaticRoute("", routeTable, policy, ipPrefix, nexthop, &bfdID)
require.ErrorContains(t, err, "the logical router name is required")
require.Nil(t, route)
})
}

func (suite *OvnClientTestSuite) testListLogicalRouterStaticRoutesByOption() {
t := suite.T()
t.Parallel()

nbClient := suite.ovnNBClient
lrName := "test-list-routes-by-option-lr"
routeTable := util.MainRouteTable
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefixes := []string{"192.168.30.0/24", "192.168.40.0/24", "192.168.50.0/24"}
nexthops := []string{"192.168.30.1", "192.168.40.1", "192.168.50.1"}
routes := make([]*ovnnb.LogicalRouterStaticRoute, 0, 5)

err := nbClient.CreateLogicalRouter(lrName)
require.NoError(t, err)

for i, ipPrefix := range ipPrefixes {
var bfdID *string
if ipPrefixes[i] == "192.168.30.0/24" {
bfdIDValue := "bfd-id"
bfdID = &bfdIDValue
}
route, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthops[i], bfdID)
require.NoError(t, err)

routes = append(routes, route)
}

err = nbClient.CreateLogicalRouterStaticRoutes(lrName, append(routes, nil)...)
require.NoError(t, err)

t.Run("match single route with option", func(t *testing.T) {
result, err := nbClient.ListLogicalRouterStaticRoutesByOption(lrName, "", util.StaticRouteBfdEcmp, "true")
require.NoError(t, err)
require.Len(t, result, 1)
require.Equal(t, "192.168.30.0/24", result[0].IPPrefix)
})
}

func (suite *OvnClientTestSuite) testUpdateLogicalRouterStaticRoute() {
t := suite.T()
t.Parallel()

nbClient := suite.ovnNBClient
lrName := "test-update-route-lr"
routeTable := util.MainRouteTable
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP
ipPrefix := "192.168.30.0/24"
nexthop := "192.168.30.1"

err := nbClient.CreateLogicalRouter(lrName)
require.NoError(t, err)

t.Run("update nil route", func(t *testing.T) {
err := nbClient.UpdateLogicalRouterStaticRoute(nil)
require.Error(t, err)
require.Contains(t, err.Error(), "route is nil")
})

t.Run("update route fields", func(t *testing.T) {
err := nbClient.AddLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nil, nexthop)
require.NoError(t, err)

route, err := nbClient.GetLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, false)
require.NoError(t, err)

newPolicy := ovnnb.LogicalRouterStaticRoutePolicySrcIP
route.Policy = &newPolicy
newNexthop := "192.168.30.254"
route.Nexthop = newNexthop

err = nbClient.UpdateLogicalRouterStaticRoute(route, &route.Policy, &route.Nexthop)
require.NoError(t, err)

updatedRoute, err := nbClient.GetLogicalRouterStaticRoute(lrName, routeTable, newPolicy, ipPrefix, newNexthop, false)
require.NoError(t, err)
require.Equal(t, newPolicy, *updatedRoute.Policy)
require.Equal(t, newNexthop, updatedRoute.Nexthop)
})
}

func (suite *OvnClientTestSuite) testGetLogicalRouterStaticRouteEdgeCases() {
t := suite.T()
t.Parallel()

nbClient := suite.ovnNBClient
lrName := "test-get-route-edge-lr"
routeTable := util.MainRouteTable
policy := ovnnb.LogicalRouterStaticRoutePolicyDstIP

err := nbClient.CreateLogicalRouter(lrName)
require.NoError(t, err)

t.Run("empty logical router name", func(t *testing.T) {
_, err := nbClient.GetLogicalRouterStaticRoute("", routeTable, policy, "192.168.1.0/24", "192.168.1.1", false)
require.Error(t, err)
require.Contains(t, err.Error(), "the logical router name is required")
})

t.Run("duplicate routes", func(t *testing.T) {
ipPrefix := "192.168.2.0/24"
nexthop := "192.168.2.1"

route1, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, nil)
require.NoError(t, err)
route2, err := nbClient.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, nil)
require.NoError(t, err)

err = nbClient.CreateLogicalRouterStaticRoutes(lrName, route1, route2)
require.NoError(t, err)

_, err = nbClient.GetLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, false)
require.Error(t, err)
require.Contains(t, err.Error(), "more than one static route")
})

t.Run("ignore not found true", func(t *testing.T) {
route, err := nbClient.GetLogicalRouterStaticRoute(lrName, routeTable, policy, "192.168.3.0/24", "192.168.3.1", true)
require.NoError(t, err)
require.Nil(t, route)
})

t.Run("empty route table", func(t *testing.T) {
ipPrefix := "192.168.4.0/24"
nexthop := "192.168.4.1"

err := nbClient.AddLogicalRouterStaticRoute(lrName, "", policy, ipPrefix, nil, nexthop)
require.NoError(t, err)

route, err := nbClient.GetLogicalRouterStaticRoute(lrName, "", policy, ipPrefix, nexthop, false)
require.NoError(t, err)
require.Equal(t, "", route.RouteTable)
})
}
12 changes: 12 additions & 0 deletions pkg/ovs/ovn-nb-suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,18 @@ func (suite *OvnClientTestSuite) Test_newLogicalRouterStaticRoute() {
suite.testNewLogicalRouterStaticRoute()
}

func (suite *OvnClientTestSuite) Test_ListLogicalRouterStaticRoutesByOption() {
suite.testListLogicalRouterStaticRoutesByOption()
}

func (suite *OvnClientTestSuite) Test_UpdateLogicalRouterStaticRoute() {
suite.testUpdateLogicalRouterStaticRoute()
}

func (suite *OvnClientTestSuite) Test_GetLogicalRouterStaticRouteEdgeCases() {
suite.testGetLogicalRouterStaticRouteEdgeCases()
}

/* dhcp options unit test */
func (suite *OvnClientTestSuite) Test_UpdateDHCPOptions() {
suite.testUpdateDHCPOptions()
Expand Down

0 comments on commit 535048d

Please sign in to comment.