github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/bandwidth/ops_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package bandwidth
     5  
     6  import (
     7  	"context"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  	"github.com/vishvananda/netlink"
    12  
    13  	"github.com/cilium/hive/hivetest"
    14  	"github.com/cilium/statedb/reconciler"
    15  
    16  	"github.com/cilium/cilium/pkg/datapath/tables"
    17  	"github.com/cilium/cilium/pkg/testutils"
    18  	"github.com/cilium/cilium/pkg/testutils/netns"
    19  )
    20  
    21  func TestOps(t *testing.T) {
    22  	testutils.PrivilegedTest(t)
    23  	log := hivetest.Logger(t)
    24  
    25  	var nlh *netlink.Handle
    26  	var err error
    27  
    28  	ns := netns.NewNetNS(t)
    29  	require.NoError(t, ns.Do(func() error {
    30  		nlh, err = netlink.NewHandle()
    31  		return err
    32  	}))
    33  
    34  	// Create a dummy device to test with
    35  	err = nlh.LinkAdd(
    36  		&netlink.Dummy{
    37  			LinkAttrs: netlink.LinkAttrs{
    38  				Name: "dummy0",
    39  			},
    40  		},
    41  	)
    42  	require.NoError(t, err, "LinkAdd")
    43  	link, err := nlh.LinkByName("dummy0")
    44  	require.NoError(t, err, "LinkByName")
    45  	require.NoError(t, err, nlh.LinkSetUp(link))
    46  	index := link.Attrs().Index
    47  	name := link.Attrs().Name
    48  
    49  	t.Logf("created %s (index %d)", name, index)
    50  
    51  	// Check that the default qdisc is
    52  	qdiscs, err := nlh.QdiscList(link)
    53  	require.NoError(t, err, "QdiscList")
    54  	require.Len(t, qdiscs, 1)
    55  	t.Logf("qdiscs before: %+v", qdiscs)
    56  	require.Equal(t, "noqueue", qdiscs[0].Type()) // the default for dummys
    57  
    58  	ops := &ops{
    59  		log:       log,
    60  		isEnabled: func() bool { return true },
    61  	}
    62  	ctx := context.TODO()
    63  
    64  	// Initial Update()
    65  	err = ns.Do(func() error {
    66  		return ops.Update(ctx, nil, &tables.BandwidthQDisc{
    67  			LinkIndex: index,
    68  			LinkName:  name,
    69  			FqHorizon: FqDefaultHorizon,
    70  			FqBuckets: FqDefaultBuckets,
    71  			Status:    reconciler.StatusPending(),
    72  		})
    73  	})
    74  	require.NoError(t, err, "expected no error from initial update")
    75  
    76  	// qdisc should now have changed from "noqueue" to mq (or fq if mq not supported)
    77  	qdiscs, err = nlh.QdiscList(link)
    78  	require.NoError(t, err, "QdiscList")
    79  	require.Greater(t, len(qdiscs), 0)
    80  	t.Logf("qdiscs after: %+v", qdiscs)
    81  
    82  	if qdiscs[0].Type() != "mq" {
    83  		require.Equal(t, "fq", qdiscs[0].Type())
    84  	} else {
    85  		require.Equal(t, "mq", qdiscs[0].Type())
    86  	}
    87  
    88  	// Second Update() should not do anything.
    89  	err = ns.Do(func() error {
    90  		return ops.Update(ctx, nil, &tables.BandwidthQDisc{
    91  			LinkIndex: index,
    92  			LinkName:  name,
    93  			FqHorizon: FqDefaultHorizon,
    94  			FqBuckets: FqDefaultBuckets,
    95  			Status:    reconciler.StatusPending(),
    96  		})
    97  	})
    98  	require.NoError(t, err, "expected no error from second update")
    99  
   100  	// Non-existing devices return an error.
   101  	err = ns.Do(func() error {
   102  		return ops.Update(ctx, nil, &tables.BandwidthQDisc{
   103  			LinkIndex: 1234,
   104  			LinkName:  name,
   105  			FqHorizon: FqDefaultHorizon,
   106  			FqBuckets: FqDefaultBuckets,
   107  			Status:    reconciler.StatusPending(),
   108  		})
   109  	})
   110  	require.Error(t, err, "expected no error from update of non-existing device")
   111  }