Skip to content

Commit

Permalink
v3 metadata bridge mode tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sharanyad committed Feb 8, 2019
1 parent 4f85a1d commit e9df282
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 19 deletions.
9 changes: 9 additions & 0 deletions agent/dockerclient/dockerapi/docker_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,9 @@ func TestMetadataFromContainer(t *testing.T) {
NetworkSettingsBase: types.NetworkSettingsBase{
Ports: ports,
},
DefaultNetworkSettings: types.DefaultNetworkSettings{
IPAddress: "17.0.0.3",
},
},
ContainerJSONBase: &types.ContainerJSONBase{
ID: "1234",
Expand All @@ -1434,6 +1437,9 @@ func TestMetadataFromContainer(t *testing.T) {
StartedAt: started,
FinishedAt: finished,
},
HostConfig: &dockercontainer.HostConfig{
NetworkMode: dockercontainer.NetworkMode("bridge"),
},
},
Config: &dockercontainer.Config{
Labels: labels,
Expand All @@ -1446,6 +1452,9 @@ func TestMetadataFromContainer(t *testing.T) {
assert.Equal(t, volumes, metadata.Volumes)
assert.Equal(t, labels, metadata.Labels)
assert.Len(t, metadata.PortBindings, 1)
assert.Equal(t, "bridge", metadata.NetworkMode)
assert.NotNil(t, metadata.NetworkSettings)
assert.Equal(t, "17.0.0.3", metadata.NetworkSettings.IPAddress)

// Need to convert both strings to same format to be able to compare. Parse and Format are not inverses.
createdTimeSDK, _ := time.Parse(time.RFC3339, dockerContainer.Created)
Expand Down
150 changes: 150 additions & 0 deletions agent/handlers/task_server_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ const (
associationName = "dev1"
associationEncoding = "base64"
associationValue = "val"
bridgeMode = "bridge"
bridgeIPAddr = "17.0.0.3"
)

var (
Expand Down Expand Up @@ -192,10 +194,99 @@ var (
Associations: []string{associationName},
}
expectedAssociationResponse = associationValue

bridgeTask = &apitask.Task{
Arn: taskARN,
Associations: []apitask.Association{association},
Family: family,
Version: version,
DesiredStatusUnsafe: apitaskstatus.TaskRunning,
KnownStatusUnsafe: apitaskstatus.TaskRunning,
CPU: cpu,
Memory: memory,
PullStartedAtUnsafe: now,
PullStoppedAtUnsafe: now,
ExecutionStoppedAtUnsafe: now,
}
container1 = &apicontainer.Container{
Name: containerName,
Image: imageName,
ImageID: imageID,
DesiredStatusUnsafe: apicontainerstatus.ContainerRunning,
KnownStatusUnsafe: apicontainerstatus.ContainerRunning,
CPU: cpu,
Memory: memory,
Type: apicontainer.ContainerNormal,
Ports: []apicontainer.PortBinding{
{
ContainerPort: containerPort,
Protocol: apicontainer.TransportProtocolTCP,
},
},
NetworkModeUnsafe: bridgeMode,
NetworkSettingsUnsafe: &types.NetworkSettings{
DefaultNetworkSettings: types.DefaultNetworkSettings{
IPAddress: bridgeIPAddr,
},
},
}
bridgeContainer = &apicontainer.DockerContainer{
DockerID: containerID,
DockerName: containerName,
Container: container1,
}
containerNameToBridgeContainer = map[string]*apicontainer.DockerContainer{
taskARN: bridgeContainer,
}
expectedBridgeContainerResponse = v2.ContainerResponse{
ID: containerID,
Name: containerName,
DockerName: containerName,
Image: imageName,
ImageID: imageID,
DesiredStatus: statusRunning,
KnownStatus: statusRunning,
Limits: v2.LimitsResponse{
CPU: aws.Float64(cpu),
Memory: aws.Int64(memory),
},
Type: containerType,
Labels: labels,
Ports: []v1.PortResponse{
{
ContainerPort: containerPort,
Protocol: containerPortProtocol,
},
},
Networks: []containermetadata.Network{
{
NetworkMode: bridgeMode,
IPv4Addresses: []string{bridgeIPAddr},
},
},
}
expectedBridgeTaskResponse = v2.TaskResponse{
Cluster: clusterName,
TaskARN: taskARN,
Family: family,
Revision: version,
DesiredStatus: statusRunning,
KnownStatus: statusRunning,
Containers: []v2.ContainerResponse{expectedBridgeContainerResponse},
Limits: &v2.LimitsResponse{
CPU: aws.Float64(cpu),
Memory: aws.Int64(memory),
},
PullStartedAt: aws.Time(now.UTC()),
PullStoppedAt: aws.Time(now.UTC()),
ExecutionStoppedAt: aws.Time(now.UTC()),
AvailabilityZone: availabilityzone,
}
)

func init() {
container.SetLabels(labels)
container1.SetLabels(labels)
}

// TestInvalidPath tests if HTTP status code 404 is returned when invalid path is queried.
Expand Down Expand Up @@ -680,6 +771,65 @@ func TestV3TaskMetadata(t *testing.T) {
assert.Equal(t, expectedTaskResponse, taskResponse)
}

func TestV3BridgeTaskMetadata(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

state := mock_dockerstate.NewMockTaskEngineState(ctrl)
auditLog := mock_audit.NewMockAuditLogger(ctrl)
statsEngine := mock_stats.NewMockEngine(ctrl)
ecsClient := mock_api.NewMockECSClient(ctrl)

gomock.InOrder(
state.EXPECT().TaskARNByV3EndpointID(v3EndpointID).Return(taskARN, true),
state.EXPECT().TaskByArn(taskARN).Return(bridgeTask, true),
state.EXPECT().ContainerMapByArn(taskARN).Return(containerNameToBridgeContainer, true),
state.EXPECT().TaskByArn(taskARN).Return(bridgeTask, true),
state.EXPECT().ContainerByID(containerID).Return(bridgeContainer, true),
)
server := taskServerSetup(credentials.NewManager(), auditLog, state, ecsClient, clusterName, statsEngine,
config.DefaultTaskMetadataSteadyStateRate, config.DefaultTaskMetadataBurstRate, availabilityzone, containerInstanceArn)
recorder := httptest.NewRecorder()
req, _ := http.NewRequest("GET", v3BasePath+v3EndpointID+"/task", nil)
server.Handler.ServeHTTP(recorder, req)
res, err := ioutil.ReadAll(recorder.Body)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, recorder.Code)
var taskResponse v2.TaskResponse
err = json.Unmarshal(res, &taskResponse)
assert.NoError(t, err)
assert.Equal(t, expectedBridgeTaskResponse, taskResponse)
}

func TestV3BridgeContainerMetadata(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

state := mock_dockerstate.NewMockTaskEngineState(ctrl)
auditLog := mock_audit.NewMockAuditLogger(ctrl)
statsEngine := mock_stats.NewMockEngine(ctrl)
ecsClient := mock_api.NewMockECSClient(ctrl)

gomock.InOrder(
state.EXPECT().DockerIDByV3EndpointID(v3EndpointID).Return(containerID, true),
state.EXPECT().ContainerByID(containerID).Return(bridgeContainer, true),
state.EXPECT().TaskByID(containerID).Return(bridgeTask, true),
state.EXPECT().ContainerByID(containerID).Return(bridgeContainer, true),
)
server := taskServerSetup(credentials.NewManager(), auditLog, state, ecsClient, clusterName, statsEngine,
config.DefaultTaskMetadataSteadyStateRate, config.DefaultTaskMetadataBurstRate, "", containerInstanceArn)
recorder := httptest.NewRecorder()
req, _ := http.NewRequest("GET", v3BasePath+v3EndpointID, nil)
server.Handler.ServeHTTP(recorder, req)
res, err := ioutil.ReadAll(recorder.Body)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, recorder.Code)
var containerResponse v2.ContainerResponse
err = json.Unmarshal(res, &containerResponse)
assert.NoError(t, err)
assert.Equal(t, expectedBridgeContainerResponse, containerResponse)
}

// Test API calls for propagating Tags to Task Metadata
func TestV3TaskMetadataWithTags(t *testing.T) {
ctrl := gomock.NewController(t)
Expand Down
43 changes: 24 additions & 19 deletions misc/v3-task-endpoint-validator/v3-task-endpoint-validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"time"

"github.com/docker/docker/api/types"
"github.com/pkg/errors"
)

const (
Expand All @@ -32,6 +33,7 @@ const (

var isAWSVPCNetworkMode bool
var checkContainerInstanceTags bool
var networkModes map[string]bool

// TaskResponse defines the schema for the task response JSON object
type TaskResponse struct {
Expand Down Expand Up @@ -264,7 +266,7 @@ func verifyContainerMetadataResponse(containerMetadataRawMsg json.RawMessage) er
"Type": "NORMAL",
}

taskExpectedFieldNotEmptyArray := []string{"DockerId", "DockerName", "ImageID", "Limits", "CreatedAt", "StartedAt", "Health"}
taskExpectedFieldNotEmptyArray := []string{"DockerId", "DockerName", "ImageID", "Limits", "CreatedAt", "StartedAt", "Health", "Networks"}

for fieldName, fieldVal := range containerExpectedFieldEqualMap {
if err = fieldEqual(containerMetadataResponseMap, fieldName, fieldVal); err != nil {
Expand Down Expand Up @@ -308,10 +310,6 @@ func verifyLimitResponse(limitRawMsg json.RawMessage) error {
}

func verifyNetworksResponse(networksRawMsg json.RawMessage) error {
// host and bridge network mode
if networksRawMsg == nil {
return nil
}

var err error

Expand All @@ -322,23 +320,28 @@ func verifyNetworksResponse(networksRawMsg json.RawMessage) error {
networkResponseMap := make(map[string]json.RawMessage)
json.Unmarshal(networksResponseArray[0], &networkResponseMap)

if err = fieldEqual(networkResponseMap, "NetworkMode", "awsvpc"); err != nil {
return err
}
var actualFieldVal interface{}
json.Unmarshal(networkResponseMap["NetworkMode"], &actualFieldVal)

if err = fieldNotEmpty(networkResponseMap, "IPv4Addresses"); err != nil {
return err
if _, ok := networkModes[actualFieldVal.(string)]; !ok {
return errors.Errorf("network mode is incorrect: %s", actualFieldVal)
}

var ipv4AddressesResponseArray []json.RawMessage
json.Unmarshal(networkResponseMap["IPv4Addresses"], &ipv4AddressesResponseArray)

if len(ipv4AddressesResponseArray) != 1 {
return fmt.Errorf("incorrect number of IPv4Addresses, expected 1, received %d",
len(ipv4AddressesResponseArray))
if actualFieldVal != "host" {
if err = fieldNotEmpty(networkResponseMap, "IPv4Addresses"); err != nil {
return err
}

var ipv4AddressesResponseArray []json.RawMessage
json.Unmarshal(networkResponseMap["IPv4Addresses"], &ipv4AddressesResponseArray)

if len(ipv4AddressesResponseArray) != 1 {
return fmt.Errorf("incorrect number of IPv4Addresses, expected 1, received %d",
len(ipv4AddressesResponseArray))
}
}
if actualFieldVal == "awsvpc" {
isAWSVPCNetworkMode = true
}

isAWSVPCNetworkMode = true
} else {
return fmt.Errorf("incorrect number of networks, expected 1, received %d",
len(networksResponseArray))
Expand Down Expand Up @@ -415,6 +418,8 @@ func main() {
Timeout: 5 * time.Second,
}

networkModes = map[string]bool{"awsvpc": true, "bridge": true, "host": true, "default": true}

// If the image is built with option to check Tags
argsWithoutProg := os.Args[1:]
if len(argsWithoutProg) > 0 {
Expand Down

0 comments on commit e9df282

Please sign in to comment.