Skip to content

Commit

Permalink
functional_tests: added windows functional test
Browse files Browse the repository at this point in the history
  • Loading branch information
adnxn committed Oct 3, 2017
1 parent ff162ba commit b208d50
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 27 deletions.
3 changes: 3 additions & 0 deletions agent/api/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,16 @@ func (c *Container) IsRunning() bool {
return c.GetKnownStatus().IsRunning()
}

// IsMetadataFileUpdated() returns true if the metadata file has been once the
// metadata file is ready and will no longer change
func (c *Container) IsMetadataFileUpdated() bool {
c.lock.RLock()
defer c.lock.RUnlock()

return c.MetadataFileUpdated
}

// SetMetadataFileUpdated sets the container's MetadataFileUpdated status to true
func (c *Container) SetMetadataFileUpdated() {
c.lock.Lock()
defer c.lock.Unlock()
Expand Down
3 changes: 2 additions & 1 deletion agent/config/config_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ func DefaultConfig() Config {
},
ReservedPortsUDP: []uint16{},
DataDir: dataDir,
// DataDirOnHost is identical to DataDir for Windows because we do not run on a container
// DataDirOnHost is identical to DataDir for Windows because we do not
// run as a container
DataDirOnHost: dataDir,
// DisableMetrics is set to true on Windows as docker stats does not work
DisableMetrics: true,
Expand Down
15 changes: 6 additions & 9 deletions agent/containermetadata/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ const (
inspectContainerTimeout = 30 * time.Second
metadataFile = "ecs-container-metadata.json"
metadataPerm = 0644
// MetadataInitial is the initial state of the metadata file which
// contains metadata provided by the ECS Agent
MetadataInitial = "INITIAL"
// MetadataReady is the final state of the metadata file which indicates
// it has acquired all the data it needs (Currently from the Agent and Docker)
MetadataReady = "READY"
)

// MetadataStatus specifies the current update status of the metadata file.
Expand All @@ -42,15 +48,6 @@ const (
// statuses should amended/appended accordingly.
type MetadataStatus string

const (
// MetadataInitial is the initial state of the metadata file which
// contains metadata provided by the ECS Agent
MetadataInitial = "INITIAL"
// MetadataReady is the final state of the metadata file which indicates
// it has acquired all the data it needs (Currently from the Agent and Docker)
MetadataReady = "READY"
)

// Manager is an interface that allows us to abstract away the metadata
// operations
type Manager interface {
Expand Down
5 changes: 1 addition & 4 deletions agent/containermetadata/manager_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package containermetadata

import (
"errors"
"testing"

docker "github.com/fsouza/go-dockerclient"
Expand All @@ -35,9 +34,7 @@ func TestCreate(t *testing.T) {

gomock.InOrder(
mockOS.EXPECT().MkdirAll(gomock.Any(), gomock.Any()).Return(nil),
mockOS.EXPECT().OpenFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("err")),
mockOS.EXPECT().IsNotExist(gomock.Any()).Return(true),
mockOS.EXPECT().Create(gomock.Any()).Return(mockFile, nil),
mockOS.EXPECT().OpenFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockFile, nil),
mockFile.EXPECT().Write(gomock.Any()).Return(0, nil),
mockFile.EXPECT().Sync().Return(nil),
mockFile.EXPECT().Close().Return(nil),
Expand Down
11 changes: 3 additions & 8 deletions agent/containermetadata/write_metadata_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,12 @@ func writeToMetadataFile(osWrap oswrapper.OS, ioutilWrap ioutilwrapper.IOUtil, d
}
metadataFileName := filepath.Join(metadataFileDir, metadataFile)

file, err := osWrap.OpenFile(metadataFileName, os.O_WRONLY, metadataPerm)
file, err := osWrap.OpenFile(metadataFileName, os.O_WRONLY|os.O_CREATE, metadataPerm)
if err != nil {
// Retry if file does not exist
if osWrap.IsNotExist(err) {
file, err = osWrap.Create(metadataFileName)
}
if err != nil {
return err
}
return err
}
defer file.Close()

_, err = file.Write(data)
if err != nil {
return err
Expand Down
1 change: 0 additions & 1 deletion agent/containermetadata/write_metadata_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func TestWriteOpenFileFail(t *testing.T) {

gomock.InOrder(
mockOS.EXPECT().OpenFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, mockOpenErr),
mockOS.EXPECT().IsNotExist(mockOpenErr).Return(false),
)

err := writeToMetadataFile(mockOS, nil, mockData, mockTaskARN, mockContainerName, mockDataDir)
Expand Down
6 changes: 3 additions & 3 deletions agent/engine/docker_task_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (engine *DockerTaskEngine) sweepTask(task *api.Task) {
if engine.cfg.ContainerMetadataEnabled {
err := engine.metadataManager.Clean(task.Arn)
if err != nil {
seelog.Errorf("Clean task metadata failed for task %s: %v", task, err)
seelog.Warnf("Clean task metadata failed for task %s: %v", task, err)
}
}
engine.saver.Save()
Expand Down Expand Up @@ -660,7 +660,7 @@ func (engine *DockerTaskEngine) createContainer(task *api.Task, container *api.C
if engine.cfg.ContainerMetadataEnabled && !container.IsInternal() {
mderr := engine.metadataManager.Create(config, hostConfig, task.Arn, container.Name)
if mderr != nil {
seelog.Errorf("Create metadata failed for container %s of task %s: %v", container, task, mderr)
seelog.Warnf("Create metadata failed for container %s of task %s: %v", container, task, mderr)
}
}

Expand Down Expand Up @@ -702,7 +702,7 @@ func (engine *DockerTaskEngine) startContainer(task *api.Task, container *api.Co
go func() {
err := engine.metadataManager.Update(dockerContainer.DockerID, task.Arn, container.Name)
if err != nil {
seelog.Errorf("Update metadata file failed for container %s of task %s: %v", container, task, err)
seelog.Warnf("Update metadata file failed for container %s of task %s: %v", container, task, err)
} else {
container.SetMetadataFileUpdated()
seelog.Debugf("Updated metadata file for container %s of task %s", container, task)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"family": "ecsftest-mdservice-validator",
"networkMode": "none",
"containerDefinitions": [{
"image": "microsoft/windowsservercore:latest",
"name": "mdservice-validator-windows",
"cpu": 100,
"memory": 100,
"entryPoint": ["powershell"],
"command": ["-c", "sleep 10; if($?){if(cat $env:ECS_CONTAINER_METADATA_FILE | Select-String -pattern READY){exit 42}else {exit 1}};"]
}]
}
37 changes: 37 additions & 0 deletions agent/functional_tests/tests/functionaltests_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,40 @@ func taskIamRolesTest(networkMode string, agent *TestAgent, t *testing.T) {
}

}

// TestMetadataServiceValidator Tests that the metadata file can be accessed from the
// container using the ECS_CONTAINER_METADATA_FILE environment variables
func TestMetadataServiceValidator(t *testing.T) {
agentOptions := &AgentOptions{
ExtraEnvironment: map[string]string{
"ECS_ENABLE_CONTAINER_METADATA": "true",
},
}

agent := RunAgent(t, agentOptions)
defer agent.Cleanup()

tdOverride := make(map[string]string)
tdOverride["$$$TEST_REGION$$$"] = *ECS.Config.Region
tdOverride["$$$NETWORK_MODE$$$"] = ""

task, err := agent.StartTaskWithTaskDefinitionOverrides(t, "mdservice-validator-windows", tdOverride)
if err != nil {
t.Fatalf("Error starting mdservice-validator-windows: %v", err)
}

// clean up
err = task.WaitStopped(2 * time.Minute)
require.NoError(t, err, "Error waiting for task to transition to STOPPED")

containerID, err := agent.ResolveTaskDockerID(task, "mdservice-validator-windows")
if err != nil {
t.Fatalf("Error resolving docker id for container in task: %v", err)
}

containerMetaData, err := agent.DockerClient.InspectContainer(containerID)
require.NoError(t, err, "Could not inspect container for task")

exitCode := containerMetaData.State.ExitCode
assert.Equal(t, 42, exitCode, fmt.Sprintf("Expected exit code of 42; got %d", exitCode))
}
10 changes: 10 additions & 0 deletions agent/functional_tests/util/utils_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ func (agent *TestAgent) StopAgent() error {
}

func (agent *TestAgent) StartAgent() error {
if agent.Options != nil {
for k, v := range agent.Options.ExtraEnvironment {
os.Setenv(k, v)
}
}
agentInvoke := exec.Command(".\\agent.exe")
if TestDirectory := os.Getenv("ECS_WINDOWS_TEST_DIR"); TestDirectory != "" {
agentInvoke.Dir = TestDirectory
Expand All @@ -130,6 +135,11 @@ func (agent *TestAgent) StartAgent() error {
}

func (agent *TestAgent) Cleanup() {
if agent.Options != nil {
for k, _ := range agent.Options.ExtraEnvironment {
os.Unsetenv(k)
}
}
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Amazon\ECS Agent\State File`, registry.ALL_ACCESS)
if err != nil {
return
Expand Down
2 changes: 1 addition & 1 deletion agent/statemanager/state_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const (
// b) Add 'ContainerResourcesProvisioned' as a new 'ContainerStatus' enum
// c) Add 'SteadyStateStatus' field to 'Container' struct
// d) Add 'ENIAttachments' struct
// e) Add 'MetadataUpdated' field to 'api.Container'
// e) Add 'MetadataUpdated' field to 'api.Container'
ECSDataVersion = 6

// ecsDataFile specifies the filename in the ECS_DATADIR
Expand Down

0 comments on commit b208d50

Please sign in to comment.