Skip to content

Commit

Permalink
Fix integration test for ECS
Browse files Browse the repository at this point in the history
  • Loading branch information
r0mdau committed Dec 27, 2024
1 parent 7496221 commit 6212bde
Showing 1 changed file with 82 additions and 24 deletions.
106 changes: 82 additions & 24 deletions extension/cgroupruntimeextension/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package cgroupruntimeextension // import "github.com/open-telemetry/opentelemetr

import (
"context"
"encoding/json"
"fmt"
"math"
"net/http"
Expand All @@ -33,6 +32,7 @@ import (

const (
defaultCgroup2Path = "/sys/fs/cgroup"
ecsMetadataUri = "ECS_CONTAINER_METADATA_URI_V4"
)

// checkCgroupSystem skips the test if is not run in a cgroupv2 system
Expand Down Expand Up @@ -66,19 +66,24 @@ func cgroupMaxCpu(filename string) (quota int64, period uint64, err error) {
return quota, period, err
}

func startMockECSServer() *httptest.Server {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
response := map[string]interface{}{
"DockerID": "container-id",
"Limits": map[string]interface{}{
"CPU": 2.0,
},
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
func testServerECSMetadata(t *testing.T, containerCPU, taskCPU int) *httptest.Server {
t.Helper()

mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
_, err := w.Write([]byte(fmt.Sprintf(`{"Limits":{"CPU":%d},"DockerId":"container-id"}`, containerCPU)))
assert.NoError(t, err)
})
mux.HandleFunc("/task", func(w http.ResponseWriter, _ *http.Request) {
_, err := w.Write([]byte(fmt.Sprintf(
`{"Containers":[{"DockerId":"container-id","Limits":{"CPU":%d}}],"Limits":{"CPU":%d}}`,
containerCPU,
taskCPU,
)))
assert.NoError(t, err)
})

return httptest.NewServer(handler)
return httptest.NewServer(mux)
}

func TestCgroupV2SudoIntegration(t *testing.T) {
Expand Down Expand Up @@ -164,10 +169,11 @@ func TestCgroupV2SudoIntegration(t *testing.T) {
expectedGoMemLimit: 13421772,
},
{
name: "running on AWS ECS with 90% of max cgroup memory and 2 GOMAXPROCS",
cgroupCpuQuota: pointerInt64(-1),
name: "AWS ECS 90% the max cgroup memory and 12 GOMAXPROCS",
cgroupCpuQuota: pointerInt64(100000),
cgroupCpuPeriod: 8000,
cgroupMaxMemory: 134217728, // 128 MB
// 128 Mb
cgroupMaxMemory: 134217728,
config: &Config{
GoMaxProcs: GoMaxProcsConfig{
Enabled: true,
Expand All @@ -177,8 +183,54 @@ func TestCgroupV2SudoIntegration(t *testing.T) {
Ratio: 0.9,
},
},
expectedGoMaxProcs: 22,
expectedGoMemLimit: 120795955, // 134217728 * 0.9
// 100000 / 8000
expectedGoMaxProcs: 12,
// 134217728 * 0.9
expectedGoMemLimit: 120795955,
setECSMetadataURI: true,
},
{
name: "AWS ECS 50% of the max cgroup memory and 1 GOMAXPROCS",
cgroupCpuQuota: pointerInt64(100000),
cgroupCpuPeriod: 100000,
// 128 Mb
cgroupMaxMemory: 134217728,
config: &Config{
GoMaxProcs: GoMaxProcsConfig{
Enabled: true,
},
GoMemLimit: GoMemLimitConfig{
Enabled: true,
Ratio: 0.5,
},
},
// 100000 / 100000
expectedGoMaxProcs: 1,
// 134217728 * 0.5
expectedGoMemLimit: 67108864,
setECSMetadataURI: true,
},
{
name: "AWS ECS 10% of the max cgroup memory, max cpu, default GOMAXPROCS",
cgroupCpuQuota: nil,
cgroupCpuPeriod: 100000,
// 128 Mb
cgroupMaxMemory: 134217728,
config: &Config{
GoMaxProcs: GoMaxProcsConfig{
Enabled: true,
},
GoMemLimit: GoMemLimitConfig{
Enabled: true,
Ratio: 0.1,
},
},
// GOMAXPROCS is set to the value of `cpu.max / cpu.period`
// If cpu.max is set to max, GOMAXPROCS should not be
// modified
expectedGoMaxProcs: runtime.GOMAXPROCS(-1),
// 134217728 * 0.1
expectedGoMemLimit: 13421772,
setECSMetadataURI: true,
},
}
Expand Down Expand Up @@ -235,12 +287,25 @@ func TestCgroupV2SudoIntegration(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// if running in ECS environment, set the ECS metedata URI environment variable
// to get the Cgroup CPU quota from the httptest server
cleanECS := func() {}
if test.setECSMetadataURI {
server := testServerECSMetadata(t, test.expectedGoMaxProcs*1024, test.expectedGoMaxProcs*1024)
os.Setenv(ecsMetadataUri, server.URL)
cleanECS = func() {
server.Close()
os.Unsetenv(ecsMetadataUri)
}
}

// restore startup cgroup initial resource values
t.Cleanup(func() {
debug.SetMemoryLimit(initialGoMem)
runtime.GOMAXPROCS(initialGoProcs)
memoryCgroupCleanUp()
cpuCgroupCleanUp()
cleanECS()
})

err = manager.Update(&cgroup2.Resources{
Expand All @@ -257,13 +322,6 @@ func TestCgroupV2SudoIntegration(t *testing.T) {
})
require.NoError(t, err)

if test.setECSMetadataURI {
server := startMockECSServer()
defer server.Close()
os.Setenv("ECS_CONTAINER_METADATA_URI_V4", server.URL)
defer os.Unsetenv("ECS_CONTAINER_METADATA_URI_V4")
}

factory := NewFactory()
ctx := context.Background()
extension, err := factory.Create(ctx, extensiontest.NewNopSettings(), test.config)
Expand Down

0 comments on commit 6212bde

Please sign in to comment.