Describe the bug
If batchLookupCmd returns ErrKeyNotExist in batchLookup, the unmarshalling of valuesOut is skipped.
My expectation is that the unmarshalling of valuesOut is called for the last batch as well. Just like it happens for keysOut.
How to reproduce
The batch size should be chosen in a way so the last batch is less than batch size and ErrKeyNotExist is returned.
package ebpf_test
import (
"errors"
"testing"
"github.com/cilium/ebpf"
)
var (
keysMockCalled int
valuesMockCalled int
)
type keysMock []any
func (u keysMock) UnmarshalBinary(data []byte) error {
keysMockCalled++
return nil
}
type valuesMock []any
func (u valuesMock) UnmarshalBinary(data []byte) error {
valuesMockCalled++
return nil
}
func TestLastBatchUnmarshalValuesNotCalled(t *testing.T) {
// Choose batch size in a way that last batch returns ErrKeyNotExist.
var maxEntries, batchSize uint32 = 4, 3
m, err := ebpf.NewMap(&ebpf.MapSpec{
Type: ebpf.Array,
MaxEntries: maxEntries,
KeySize: 4,
ValueSize: 4,
})
if err != nil {
t.Fatalf("create map: %v", err)
}
var (
cursor ebpf.MapBatchCursor
keysOut = make(keysMock, batchSize)
valuesOut = make(valuesMock, batchSize)
)
_, err = m.BatchLookup(&cursor, keysOut, valuesOut, nil)
if err != nil {
t.Fatalf("first batch lookup failed: %v", err)
}
_, err = m.BatchLookup(&cursor, keysOut, valuesOut, nil)
if !errors.Is(err, ebpf.ErrKeyNotExist) {
t.Fatalf("second batch lookup must return ErrKeyNotExist, got %v", err)
}
if keysMockCalled != 2 {
t.Errorf("keys mock calls: got %d, want %d", keysMockCalled, 2)
}
// This fails unexpectedly. It should be 2 (called for both batches), but
// is 1 (not called for last batch).
if valuesMockCalled != 2 {
t.Errorf("values mock calls: got %d, want %d", valuesMockCalled, 2)
}
}
This fails with:
=== RUN TestLastBatchUnmarshalValuesNotCalled
main_test.go:66: values mock calls: got 1, want 2
--- FAIL: TestLastBatchUnmarshalValuesNotCalled (0.00s)
FAIL
Version information
github.com/cilium/ebpf v0.18.0
Describe the bug
If
batchLookupCmdreturnsErrKeyNotExistinbatchLookup, the unmarshalling ofvaluesOutis skipped.My expectation is that the unmarshalling of
valuesOutis called for the last batch as well. Just like it happens forkeysOut.How to reproduce
The batch size should be chosen in a way so the last batch is less than batch size and
ErrKeyNotExistis returned.This fails with:
Version information
github.com/cilium/ebpf v0.18.0