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 }