mirror of
https://github.com/moby/moby.git
synced 2026-06-24 08:48:23 +00:00
Merge pull request #52096 from deahtstroke/50159-migrate-TestAPIStatsNetworkStats-from-integration-cli
integration/container: Migrate TestAPIStatsNetworkStats to integratio…
This commit is contained in:
@@ -6,9 +6,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -99,83 +96,6 @@ func (s *DockerAPISuite) TestAPIStatsStoppedContainerInGoroutines(c *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerAPISuite) TestAPIStatsNetworkStats(c *testing.T) {
|
||||
skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
|
||||
testRequires(c, testEnv.IsLocalDaemon)
|
||||
|
||||
id := runSleepingContainer(c)
|
||||
cli.WaitRun(c, id)
|
||||
|
||||
// Retrieve the container address
|
||||
net := "bridge"
|
||||
if testEnv.DaemonInfo.OSType == "windows" {
|
||||
net = "nat"
|
||||
}
|
||||
contIP := findContainerIP(c, id, net)
|
||||
numPings := 1
|
||||
|
||||
var preRxPackets uint64
|
||||
var preTxPackets uint64
|
||||
var postRxPackets uint64
|
||||
var postTxPackets uint64
|
||||
|
||||
// Get the container networking stats before and after pinging the container
|
||||
nwStatsPre := getNetworkStats(c, id)
|
||||
for _, v := range nwStatsPre {
|
||||
preRxPackets += v.RxPackets
|
||||
preTxPackets += v.TxPackets
|
||||
}
|
||||
|
||||
countParam := "-c"
|
||||
if runtime.GOOS == "windows" {
|
||||
countParam = "-n" // Ping count parameter is -n on Windows
|
||||
}
|
||||
pingout, err := exec.Command("ping", contIP, countParam, strconv.Itoa(numPings)).CombinedOutput()
|
||||
if err != nil && runtime.GOOS == "linux" {
|
||||
// If it fails then try a work-around, but just for linux.
|
||||
// If this fails too then go back to the old error for reporting.
|
||||
//
|
||||
// The ping will sometimes fail due to an apparmor issue where it
|
||||
// denies access to the libc.so.6 shared library - running it
|
||||
// via /lib64/ld-linux-x86-64.so.2 seems to work around it.
|
||||
pingout2, err2 := exec.Command("/lib64/ld-linux-x86-64.so.2", "/bin/ping", contIP, "-c", strconv.Itoa(numPings)).CombinedOutput()
|
||||
if err2 == nil {
|
||||
pingout = pingout2
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
assert.NilError(c, err)
|
||||
pingouts := string(pingout[:])
|
||||
nwStatsPost := getNetworkStats(c, id)
|
||||
for _, v := range nwStatsPost {
|
||||
postRxPackets += v.RxPackets
|
||||
postTxPackets += v.TxPackets
|
||||
}
|
||||
|
||||
// Verify the stats contain at least the expected number of packets
|
||||
// On Linux, account for ARP.
|
||||
expRxPkts := preRxPackets + uint64(numPings)
|
||||
expTxPkts := preTxPackets + uint64(numPings)
|
||||
if testEnv.DaemonInfo.OSType != "windows" {
|
||||
expRxPkts++
|
||||
expTxPkts++
|
||||
}
|
||||
assert.Assert(c, postTxPackets >= expTxPkts, "Reported less TxPackets than expected. Expected >= %d. Found %d. %s", expTxPkts, postTxPackets, pingouts)
|
||||
assert.Assert(c, postRxPackets >= expRxPkts, "Reported less RxPackets than expected. Expected >= %d. Found %d. %s", expRxPkts, postRxPackets, pingouts)
|
||||
}
|
||||
|
||||
func getNetworkStats(t *testing.T, id string) map[string]container.NetworkStats {
|
||||
_, body, err := request.Get(testutil.GetContext(t), "/containers/"+id+"/stats?stream=false")
|
||||
assert.NilError(t, err)
|
||||
|
||||
var st container.StatsResponse
|
||||
err = json.NewDecoder(body).Decode(&st)
|
||||
assert.NilError(t, err)
|
||||
_ = body.Close()
|
||||
|
||||
return st.Networks
|
||||
}
|
||||
|
||||
func (s *DockerAPISuite) TestAPIStatsNoStreamConnectedContainers(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
containertypes "github.com/moby/moby/api/types/container"
|
||||
@@ -12,6 +17,7 @@ import (
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -93,3 +99,86 @@ func TestStatsContainerNotFound(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatsNetworkStats(t *testing.T) {
|
||||
// FIXME(thaJeztah): Broken on Windows + containerd combination, see https://github.com/moby/moby/pull/41479
|
||||
skip.If(t, testEnv.RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
|
||||
skip.If(t, testEnv.IsRootless() && testEnv.DaemonInfo.CgroupVersion == "1", "Rootless Mode does not support cgroups v1 stats")
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
cID := container.Run(ctx, t, apiClient)
|
||||
|
||||
net := "bridge"
|
||||
if testEnv.DaemonInfo.OSType == "windows" {
|
||||
net = "nat"
|
||||
}
|
||||
|
||||
res, err := apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
|
||||
assert.NilError(t, err)
|
||||
containerIP := res.Container.NetworkSettings.Networks[net].IPAddress.String()
|
||||
|
||||
// Get the container networking stats before pinging the container
|
||||
var preRxPackets, preTxPackets uint64
|
||||
for _, v := range getNetworkStats(ctx, t, apiClient, cID) {
|
||||
preRxPackets += v.RxPackets
|
||||
preTxPackets += v.TxPackets
|
||||
}
|
||||
|
||||
countParam := "-c"
|
||||
if runtime.GOOS == "windows" {
|
||||
countParam = "-n" // Ping count parameter is -n on Windows
|
||||
}
|
||||
|
||||
numPings := 1
|
||||
out, err := exec.Command("ping", containerIP, countParam, strconv.Itoa(numPings)).CombinedOutput()
|
||||
if err != nil && runtime.GOOS == "linux" {
|
||||
// If it fails then try a work-around, but just for linux.
|
||||
// If this fails too then go back to the old error for reporting.
|
||||
//
|
||||
// The ping will sometimes fail due to an apparmor issue where it
|
||||
// denies access to the libc.so.6 shared library - running it
|
||||
// via /lib64/ld-linux-x86-64.so.2 seems to work around it.
|
||||
out, err = exec.Command("/lib64/ld-linux-x86-64.so.2", "/bin/ping", containerIP, countParam, strconv.Itoa(numPings)).CombinedOutput()
|
||||
}
|
||||
pingOutput := string(out)
|
||||
assert.NilError(t, err, pingOutput)
|
||||
|
||||
// Verify the stats contain at least the expected number of packets
|
||||
expRxPkts := preRxPackets + uint64(numPings)
|
||||
expTxPkts := preTxPackets + uint64(numPings)
|
||||
|
||||
// Poll for both PostTxPackets and PostRxPackets until they have the expected quantity
|
||||
poll.WaitOn(t, func(l poll.LogT) poll.Result {
|
||||
var postRxPackets, postTxPackets uint64
|
||||
for _, v := range getNetworkStats(ctx, t, apiClient, cID) {
|
||||
postTxPackets += v.TxPackets
|
||||
postRxPackets += v.RxPackets
|
||||
}
|
||||
|
||||
if postTxPackets < expTxPkts {
|
||||
return poll.Continue("Reported less Tx packets than expected. Expected >= %d. Found %d. %s", expTxPkts, postTxPackets, pingOutput)
|
||||
}
|
||||
|
||||
if postRxPackets < expRxPkts {
|
||||
return poll.Continue("Reported less Rx packets than expected. Expected >= %d. Found %d. %s", expRxPkts, postRxPackets, pingOutput)
|
||||
}
|
||||
|
||||
return poll.Success()
|
||||
}, poll.WithDelay(100*time.Millisecond), poll.WithTimeout(2*time.Second))
|
||||
}
|
||||
|
||||
func getNetworkStats(ctx context.Context, t *testing.T, apiClient client.APIClient, id string) map[string]containertypes.NetworkStats {
|
||||
res, err := apiClient.ContainerStats(ctx, id, client.ContainerStatsOptions{Stream: false})
|
||||
assert.NilError(t, err)
|
||||
|
||||
var st containertypes.StatsResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&st)
|
||||
|
||||
assert.NilError(t, err)
|
||||
_ = res.Body.Close()
|
||||
|
||||
return st.Networks
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user