Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions test/e2e/framework/ovn_address_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ const (
)

var (
ovnnbAddrOnce sync.Once
ovnnbAddrErr error
ovnnbAddr string
ovnnbAddrOnce sync.Once
ovnnbAddrErr error
ovnnbAddr string
ovnnbClientOnce sync.Once
ovnnbClientErr error
ovnnbCachedNbCli *ovs.OVNNbClient
ovnnbCachedModel map[string]model.Model
)

func validateModelStructure(model model.Model, table string, expectedFields map[string]reflect.Type) {
Expand All @@ -61,8 +65,6 @@ func WaitForAddressSetCondition(condition func(rows any) (bool, error)) {
ginkgo.GinkgoHelper()

client, models := getOVNNbClient(ovnnb.AddressSetTable)
defer client.Close()

model := models[ovnnb.AddressSetTable]
validateModelStructure(model, ovnnb.AddressSetTable, map[string]reflect.Type{
"Name": reflect.TypeFor[string](),
Expand All @@ -76,7 +78,10 @@ func WaitForAddressSetCondition(condition func(rows any) (bool, error)) {

result := reflect.New(reflect.SliceOf(reflect.TypeOf(model).Elem())).Interface()
if err := client.List(ctx, result); err != nil {
return false, err
// Transient errors (e.g. "not connected" during leader failover)
// should be retried rather than immediately failing the poll.
Logf("Failed to list address sets (will retry): %v", err)
return false, nil
}

return condition(result)
Expand Down Expand Up @@ -176,16 +181,18 @@ func getOVNNbClient(tables ...string) (*ovs.OVNNbClient, map[string]model.Model)
})
ExpectNoError(ovnnbAddrErr)

client, models, err := ovs.NewDynamicOvnNbClient(
ovnnbAddr,
ovnNbTimeoutSeconds,
ovsdbConnTimeout,
ovsdbInactivityTimeout,
tables...,
)
ExpectNoError(err)
ovnnbClientOnce.Do(func() {
ovnnbCachedNbCli, ovnnbCachedModel, ovnnbClientErr = ovs.NewDynamicOvnNbClient(
ovnnbAddr,
ovnNbTimeoutSeconds,
ovsdbConnTimeout,
ovsdbInactivityTimeout,
tables...,
)
})
Comment on lines +184 to +192
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation of client caching has a potential flaw. The tables... argument is captured by the closure inside ovnnbClientOnce.Do, which means the OVSDB client will only be initialized to monitor the tables from the first call to getOVNNbClient.

Subsequent calls with a different set of tables will receive the cached client, which is not monitoring the newly requested tables. This will likely lead to unexpected behavior or test failures.

While this might work for the current usage within this file (where it's always called with ovnnb.AddressSetTable), it makes the function fragile and unsafe for general use in a framework.

Consider one of the following fixes:

  1. Rename the function to be more specific (e.g., getAddrSetOVNNbClient) and hardcode the table name, removing the tables argument. This makes its limited scope clear.
  2. Add a check to ensure all callers use the same set of tables, and fail the test otherwise.
  3. Implement a more robust caching mechanism that can handle multiple sets of tables (though this might be overly complex for this context).

ExpectNoError(ovnnbClientErr)

return client, models
return ovnnbCachedNbCli, ovnnbCachedModel
}

func resolveOVNNbConnection() (string, error) {
Expand Down
Loading