Revision 5273a46cf7288144d3ccac825725cf024b40b565 authored by André Martins on 18 June 2024, 14:59:12 UTC, committed by André Martins on 20 June 2024, 19:00:01 UTC
The builder image is used to generate Kubernetes manifests and some Go code
for Kubernetes clients. Currently, Docker run commands are executed as the
root user inside the container, resulting in files being created with the
root UID. This prevents the user who executed the Docker run command from
managing these files.

Running the Docker container with the executing user's UID causes "go run"
commands to fail due to insufficient permissions to write to the /.cache
directory. To resolve this, we need to create a /.cache directory with write
permissions for all users.

Signed-off-by: André Martins <andre@cilium.io>
1 parent 6f461ea
Raw File
bpf_ct_list_test.go
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package cmd

import (
	"bytes"
	"encoding/json"
	"io"
	"os"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/cilium/cilium/pkg/byteorder"
	"github.com/cilium/cilium/pkg/command"
	"github.com/cilium/cilium/pkg/maps/ctmap"
	"github.com/cilium/cilium/pkg/testutils/mockmaps"
	"github.com/cilium/cilium/pkg/tuple"
	"github.com/cilium/cilium/pkg/types"
)

var (
	ctKey4 = ctmap.CtKey4{
		TupleKey4: tuple.TupleKey4{
			DestAddr:   types.IPv4{10, 10, 10, 1},
			SourceAddr: types.IPv4{10, 10, 10, 2},
			DestPort:   byteorder.HostToNetwork16(80),
			SourcePort: byteorder.HostToNetwork16(13579),
			NextHeader: 6,
			Flags:      123,
		},
	}
	ctKey6 = ctmap.CtKey6{
		TupleKey6: tuple.TupleKey6{
			DestAddr:   types.IPv6{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
			SourceAddr: types.IPv6{1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 121, 98, 219, 61},
			DestPort:   byteorder.HostToNetwork16(443),
			SourcePort: byteorder.HostToNetwork16(7878),
			NextHeader: 17,
			Flags:      31,
		},
	}
	ctValue = ctmap.CtEntry{
		Packets:          4 + 1,
		Bytes:            2048 + 512,
		Lifetime:         12345,
		Flags:            3,
		RevNAT:           byteorder.HostToNetwork16(27),
		TxFlagsSeen:      88,
		RxFlagsSeen:      99,
		SourceSecurityID: 6789,
		LastTxReport:     0,
		LastRxReport:     7777,
	}
)

type ctRecord4 struct {
	Key   tuple.TupleKey4
	Value ctmap.CtEntry
}

type ctRecord6 struct {
	Key   tuple.TupleKey6
	Value ctmap.CtEntry
}

func dumpAndRead[T any](t *testing.T, maps []T, dump func([]T, ...interface{}), args ...interface{}) string {
	// dumpCt() prints to standard output. Let's redirect it to a pipe, and
	// read the dump from there.
	stdout := os.Stdout
	readEnd, writeEnd, err := os.Pipe()
	require.NoError(t, err, "failed to create pipe: '%s'", err)
	os.Stdout = writeEnd
	defer func() { os.Stdout = stdout }()

	command.ForceJSON()
	dump(maps, args...)

	channel := make(chan string)
	go func() {
		var buf bytes.Buffer
		_, err = io.Copy(&buf, readEnd)
		channel <- buf.String()
	}()

	writeEnd.Close()
	// Even though we have a defer, restore os.Stdout already if we can
	// (for the assert)
	os.Stdout = stdout
	rawDump := <-channel
	require.NoError(t, err, "failed to read data: '%s'", err)

	return rawDump
}

func TestDumpCt4(t *testing.T) {
	ctMaps := []ctmap.CtMap{
		mockmaps.NewCtMockMap(
			[]ctmap.CtMapRecord{
				{
					Key:   &ctKey4,
					Value: ctValue,
				},
				{
					Key:   &ctKey4,
					Value: ctValue,
				},
			},
		),
		mockmaps.NewCtMockMap(
			[]ctmap.CtMapRecord{
				{
					Key:   &ctKey4,
					Value: ctValue,
				},
			},
		),
	}

	rawDump := dumpAndRead(t, ctMaps, dumpCt, "")

	var ctDump []ctRecord4
	err := json.Unmarshal([]byte(rawDump), &ctDump)
	require.NoError(t, err, "invalid JSON output: '%s', '%s'", err, rawDump)

	// JSON output may reorder the entries, but in our case they are all
	// the same.
	ctRecordDump := ctmap.CtMapRecord{
		Key:   &ctmap.CtKey4{TupleKey4: ctDump[0].Key},
		Value: ctDump[0].Value,
	}
	require.Equal(t, ctRecordDump, ctMaps[0].(*mockmaps.CtMockMap).Entries[0])
}

func TestDumpCt6(t *testing.T) {
	ctMaps := []ctmap.CtMap{
		mockmaps.NewCtMockMap(
			[]ctmap.CtMapRecord{
				{
					Key:   &ctKey6,
					Value: ctValue,
				},
				{
					Key:   &ctKey6,
					Value: ctValue,
				},
			},
		),
		mockmaps.NewCtMockMap(
			[]ctmap.CtMapRecord{
				{
					Key:   &ctKey6,
					Value: ctValue,
				},
			},
		),
	}

	rawDump := dumpAndRead(t, ctMaps, dumpCt, "")

	var ctDump []ctRecord6
	err := json.Unmarshal([]byte(rawDump), &ctDump)
	require.NoError(t, err, "invalid JSON output: '%s', '%s'", err, rawDump)

	// JSON output may reorder the entries, but in our case they are all
	// the same.
	ctRecordDump := ctmap.CtMapRecord{
		Key:   &ctmap.CtKey6{TupleKey6: ctDump[0].Key},
		Value: ctDump[0].Value,
	}
	require.Equal(t, ctRecordDump, ctMaps[0].(*mockmaps.CtMockMap).Entries[0])
}
back to top