Skip to content

Commit

Permalink
windows: adding functional test for cpu percent
Browse files Browse the repository at this point in the history
  • Loading branch information
Peng Yin committed Nov 17, 2017
1 parent 68f7fea commit 6df5ef3
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
"family": "ecsftest-telemetry-windows",
"family": "ecsftest-windows-telemetry",
"containerDefinitions": [{
"image": "microsoft/iis:latest",
"name": "http_server",
"cpu": 100,
"memory": 500,
"command": ["powershell", "-c", "New-Item -Path C:\\inetpub\\wwwroot\\index.html -Type file -Value '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p>'; C:\\ServiceMonitor.exe w3svc"]
"image": "amazon/amazon-ecs-windows-cpupercent-test:make",
"name": "windows-cpu-percent",
"cpu": $$$$CPUSHARE$$$$,
"memory": 500
}]
}
12 changes: 6 additions & 6 deletions agent/functional_tests/tests/functionaltests_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,11 @@ func TestTelemetry(t *testing.T) {
time.Sleep(waitMetricsInCloudwatchDuration)

cwclient := cloudwatch.New(session.New(), aws.NewConfig().WithRegion(*ECS.Config.Region))
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Before task running, verify metrics for CPU utilization failed")

params.MetricName = aws.String("MemoryUtilization")
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Before task running, verify metrics for memory utilization failed")

testTask, err := agent.StartTask(t, "telemetry")
Expand All @@ -400,11 +400,11 @@ func TestTelemetry(t *testing.T) {
params.EndTime = aws.Time(RoundTimeUp(time.Now(), time.Minute).UTC())
params.StartTime = aws.Time((*params.EndTime).Add(-waitMetricsInCloudwatchDuration).UTC())
params.MetricName = aws.String("CPUUtilization")
err = VerifyMetrics(cwclient, params, false)
err, _ = VerifyMetrics(cwclient, params, false)
assert.NoError(t, err, "Task is running, verify metrics for CPU utilization failed")

params.MetricName = aws.String("MemoryUtilization")
err = VerifyMetrics(cwclient, params, false)
err, _ = VerifyMetrics(cwclient, params, false)
assert.NoError(t, err, "Task is running, verify metrics for memory utilization failed")

err = testTask.Stop()
Expand All @@ -417,11 +417,11 @@ func TestTelemetry(t *testing.T) {
params.EndTime = aws.Time(RoundTimeUp(time.Now(), time.Minute).UTC())
params.StartTime = aws.Time((*params.EndTime).Add(-waitMetricsInCloudwatchDuration).UTC())
params.MetricName = aws.String("CPUUtilization")
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Task stopped: verify metrics for CPU utilization failed")

params.MetricName = aws.String("MemoryUtilization")
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Task stopped, verify metrics for memory utilization failed")
}

Expand Down
25 changes: 18 additions & 7 deletions agent/functional_tests/tests/functionaltests_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package functional_tests
import (
"fmt"
"os"
"runtime"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -266,14 +268,20 @@ func TestTelemetry(t *testing.T) {
time.Sleep(waitMetricsInCloudwatchDuration)

cwclient := cloudwatch.New(session.New(), aws.NewConfig().WithRegion(*ECS.Config.Region))
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Before task running, verify metrics for CPU utilization failed")

params.MetricName = aws.String("MemoryUtilization")
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Before task running, verify metrics for memory utilization failed")

testTask, err := agent.StartTask(t, "telemetry-windows")
cpuNum := runtime.NumCPU()

tdOverrides := make(map[string]string)
// Set the container cpu percentage 25%
tdOverrides["$$$$CPUSHARE$$$$"] = strconv.Itoa(cpuNum * 1024 / 4)

testTask, err := agent.StartTaskWithTaskDefinitionOverrides(t, "telemetry-windows", tdOverrides)
require.NoError(t, err, "Failed to start telemetry task")
// Wait for the task to run and the agent to send back metrics
err = testTask.WaitRunning(waitTaskStateChangeDuration)
Expand All @@ -283,11 +291,14 @@ func TestTelemetry(t *testing.T) {
params.EndTime = aws.Time(RoundTimeUp(time.Now(), time.Minute).UTC())
params.StartTime = aws.Time((*params.EndTime).Add(-waitMetricsInCloudwatchDuration).UTC())
params.MetricName = aws.String("CPUUtilization")
err = VerifyMetrics(cwclient, params, false)
err, metrics := VerifyMetrics(cwclient, params, false)
assert.NoError(t, err, "Task is running, verify metrics for CPU utilization failed")
// Also verify the cpu usage is around 25%
assert.True(t, *metrics.Average < 0.3)
assert.True(t, *metrics.Average > 0.2)

params.MetricName = aws.String("MemoryUtilization")
err = VerifyMetrics(cwclient, params, false)
err, _ = VerifyMetrics(cwclient, params, false)
assert.NoError(t, err, "Task is running, verify metrics for memory utilization failed")

err = testTask.Stop()
Expand All @@ -300,10 +311,10 @@ func TestTelemetry(t *testing.T) {
params.EndTime = aws.Time(RoundTimeUp(time.Now(), time.Minute).UTC())
params.StartTime = aws.Time((*params.EndTime).Add(-waitMetricsInCloudwatchDuration).UTC())
params.MetricName = aws.String("CPUUtilization")
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Task stopped: verify metrics for CPU utilization failed")

params.MetricName = aws.String("MemoryUtilization")
err = VerifyMetrics(cwclient, params, true)
err, _ = VerifyMetrics(cwclient, params, true)
assert.NoError(t, err, "Task stopped, verify metrics for memory utilization failed")
}
16 changes: 8 additions & 8 deletions agent/functional_tests/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,36 +266,36 @@ func DeleteCluster(t *testing.T, clusterName string) {

// VerifyMetrics whether the response is as expected
// the expected value can be 0 or positive
func VerifyMetrics(cwclient *cloudwatch.CloudWatch, params *cloudwatch.GetMetricStatisticsInput, idleCluster bool) error {
func VerifyMetrics(cwclient *cloudwatch.CloudWatch, params *cloudwatch.GetMetricStatisticsInput, idleCluster bool) (error, *cloudwatch.Datapoint) {
resp, err := cwclient.GetMetricStatistics(params)
if err != nil {
return fmt.Errorf("Error getting metrics of cluster: %v", err)
return fmt.Errorf("Error getting metrics of cluster: %v", err), nil
}

if resp == nil || resp.Datapoints == nil {
return fmt.Errorf("Cloudwatch get metrics failed, returned null")
return fmt.Errorf("Cloudwatch get metrics failed, returned null"), nil
}
metricsCount := len(resp.Datapoints)
if metricsCount == 0 {
return fmt.Errorf("No datapoints returned")
return fmt.Errorf("No datapoints returned"), nil
}

datapoint := resp.Datapoints[metricsCount-1]
// Samplecount is always expected to be "1" for cluster metrics
if *datapoint.SampleCount != 1.0 {
return fmt.Errorf("Incorrect SampleCount %f, expected 1", *datapoint.SampleCount)
return fmt.Errorf("Incorrect SampleCount %f, expected 1", *datapoint.SampleCount), nil
}

if idleCluster {
if *datapoint.Average != 0.0 {
return fmt.Errorf("non-zero utilization for idle cluster")
return fmt.Errorf("non-zero utilization for idle cluster"), nil
}
} else {
if *datapoint.Average == 0.0 {
return fmt.Errorf("utilization is zero for non-idle cluster")
return fmt.Errorf("utilization is zero for non-idle cluster"), nil
}
}
return nil
return nil, datapoint
}

// ResolveTaskDockerID determines the Docker ID for a container within a given
Expand Down
14 changes: 14 additions & 0 deletions misc/windows-cpupercent/build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

docker build -t "amazon/amazon-ecs-windows-cpupercent-test:make" -f "${PSScriptRoot}/windows.dockerfile" ${PSScriptRoot}
24 changes: 24 additions & 0 deletions misc/windows-cpupercent/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"crypto/md5"
"flag"
"fmt"
)

func main() {
concurrency := flag.Int("concurrency", 1, "amount of concurrency")
flag.Parse()
neverdie := make(chan struct{})

fmt.Printf("Hogging CPU with concurrency %d\n", *concurrency)
for i := 0; i < *concurrency; i++ {
go func() {
md5hash := md5.New()
for {
md5hash.Write([]byte{0})
}
}()
}
<-neverdie
}
18 changes: 18 additions & 0 deletions misc/windows-cpupercent/windows.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.
FROM golang:nanoserver

WORKDIR /gopath
COPY main.go .

CMD ["go", "run", "main.go", "-concurrency", "1000"]
1 change: 1 addition & 0 deletions scripts/run-functional-tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

Invoke-Expression "${PSScriptRoot}\..\misc\windows-iam\Setup_Iam.ps1"
Invoke-Expression "${PSScriptRoot}\..\misc\windows-listen80\Setup_Listen80.ps1"
Invoke-Expression "${PSScriptRoot}\..\misc\windows-cpupercent\build.ps1"

# Run the tests
$cwd = (pwd).Path
Expand Down

0 comments on commit 6df5ef3

Please sign in to comment.