|
|
@@ -18,14 +18,9 @@ package convert
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
- "fmt"
|
|
|
- "io/ioutil"
|
|
|
"os"
|
|
|
- "path"
|
|
|
"testing"
|
|
|
|
|
|
- "github.com/stretchr/testify/mock"
|
|
|
-
|
|
|
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
|
|
|
"github.com/Azure/go-autorest/autorest/to"
|
|
|
"github.com/compose-spec/compose-go/types"
|
|
|
@@ -209,181 +204,6 @@ func TestComposeSingleContainerGroupToContainerNoDnsSideCarSide(t *testing.T) {
|
|
|
assert.Equal(t, *(*group.Containers)[0].Image, "image1")
|
|
|
}
|
|
|
|
|
|
-func TestComposeVolumes(t *testing.T) {
|
|
|
- ctx := context.TODO()
|
|
|
- accountName := "myAccount"
|
|
|
- mockStorageHelper.On("GetAzureStorageAccountKey", ctx, accountName).Return("123456", nil)
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- },
|
|
|
- },
|
|
|
- Volumes: types.Volumes{
|
|
|
- "vol1": types.VolumeConfig{
|
|
|
- Driver: "azure_file",
|
|
|
- DriverOpts: map[string]string{
|
|
|
- "share_name": "myFileshare",
|
|
|
- "storage_account_name": accountName,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- group, err := ToContainerGroup(ctx, convertCtx, project, mockStorageHelper)
|
|
|
- assert.NilError(t, err)
|
|
|
-
|
|
|
- assert.Assert(t, is.Len(*group.Containers, 1))
|
|
|
- assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
|
|
- expectedGroupVolume := containerinstance.Volume{
|
|
|
- Name: to.StringPtr("vol1"),
|
|
|
- AzureFile: &containerinstance.AzureFileVolume{
|
|
|
- ShareName: to.StringPtr("myFileshare"),
|
|
|
- StorageAccountName: &accountName,
|
|
|
- StorageAccountKey: to.StringPtr("123456"),
|
|
|
- ReadOnly: to.BoolPtr(false),
|
|
|
- },
|
|
|
- }
|
|
|
- assert.Equal(t, len(*group.Volumes), 1)
|
|
|
- assert.DeepEqual(t, (*group.Volumes)[0], expectedGroupVolume)
|
|
|
-}
|
|
|
-
|
|
|
-func TestComposeVolumesRO(t *testing.T) {
|
|
|
- ctx := context.TODO()
|
|
|
- accountName := "myAccount"
|
|
|
- mockStorageHelper.On("GetAzureStorageAccountKey", ctx, accountName).Return("123456", nil)
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- },
|
|
|
- },
|
|
|
- Volumes: types.Volumes{
|
|
|
- "vol1": types.VolumeConfig{
|
|
|
- Driver: "azure_file",
|
|
|
- DriverOpts: map[string]string{
|
|
|
- "share_name": "myFileshare",
|
|
|
- "storage_account_name": accountName,
|
|
|
- "read_only": "true",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- group, err := ToContainerGroup(ctx, convertCtx, project, mockStorageHelper)
|
|
|
- assert.NilError(t, err)
|
|
|
-
|
|
|
- assert.Assert(t, is.Len(*group.Containers, 1))
|
|
|
- assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
|
|
- expectedGroupVolume := containerinstance.Volume{
|
|
|
- Name: to.StringPtr("vol1"),
|
|
|
- AzureFile: &containerinstance.AzureFileVolume{
|
|
|
- ShareName: to.StringPtr("myFileshare"),
|
|
|
- StorageAccountName: &accountName,
|
|
|
- StorageAccountKey: to.StringPtr("123456"),
|
|
|
- ReadOnly: to.BoolPtr(true),
|
|
|
- },
|
|
|
- }
|
|
|
- assert.Equal(t, len(*group.Volumes), 1)
|
|
|
- assert.DeepEqual(t, (*group.Volumes)[0], expectedGroupVolume)
|
|
|
-}
|
|
|
-
|
|
|
-type mockStorageLogin struct {
|
|
|
- mock.Mock
|
|
|
-}
|
|
|
-
|
|
|
-func (s *mockStorageLogin) GetAzureStorageAccountKey(ctx context.Context, accountName string) (string, error) {
|
|
|
- args := s.Called(ctx, accountName)
|
|
|
- return args.String(0), args.Error(1)
|
|
|
-}
|
|
|
-
|
|
|
-func TestComposeSingleContainerRestartPolicy(t *testing.T) {
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- Deploy: &types.DeployConfig{
|
|
|
- RestartPolicy: &types.RestartPolicy{
|
|
|
- Condition: "on-failure",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
|
|
- assert.NilError(t, err)
|
|
|
-
|
|
|
- assert.Assert(t, is.Len(*group.Containers, 1))
|
|
|
- assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
|
|
- assert.Equal(t, group.RestartPolicy, containerinstance.OnFailure)
|
|
|
-}
|
|
|
-
|
|
|
-func TestComposeMultiContainerRestartPolicy(t *testing.T) {
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- Deploy: &types.DeployConfig{
|
|
|
- RestartPolicy: &types.RestartPolicy{
|
|
|
- Condition: "on-failure",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- {
|
|
|
- Name: "service2",
|
|
|
- Image: "image2",
|
|
|
- Deploy: &types.DeployConfig{
|
|
|
- RestartPolicy: &types.RestartPolicy{
|
|
|
- Condition: "on-failure",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
|
|
- assert.NilError(t, err)
|
|
|
-
|
|
|
- assert.Assert(t, is.Len(*group.Containers, 3))
|
|
|
- assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
|
|
- assert.Equal(t, group.RestartPolicy, containerinstance.OnFailure)
|
|
|
- assert.Equal(t, *(*group.Containers)[1].Name, "service2")
|
|
|
- assert.Equal(t, group.RestartPolicy, containerinstance.OnFailure)
|
|
|
-}
|
|
|
-
|
|
|
-func TestComposeInconsistentMultiContainerRestartPolicy(t *testing.T) {
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- Deploy: &types.DeployConfig{
|
|
|
- RestartPolicy: &types.RestartPolicy{
|
|
|
- Condition: "any",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- {
|
|
|
- Name: "service2",
|
|
|
- Image: "image2",
|
|
|
- Deploy: &types.DeployConfig{
|
|
|
- RestartPolicy: &types.RestartPolicy{
|
|
|
- Condition: "on-failure",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- _, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
|
|
- assert.Error(t, err, "ACI integration does not support specifying different restart policies on services in the same compose application")
|
|
|
-}
|
|
|
-
|
|
|
func TestLabelsErrorMessage(t *testing.T) {
|
|
|
project := types.Project{
|
|
|
Services: []types.ServiceConfig{
|
|
|
@@ -401,71 +221,6 @@ func TestLabelsErrorMessage(t *testing.T) {
|
|
|
assert.Error(t, err, "ACI integration does not support labels in compose applications")
|
|
|
}
|
|
|
|
|
|
-func TestComposeSingleContainerGroupToContainerDefaultRestartPolicy(t *testing.T) {
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
|
|
- assert.NilError(t, err)
|
|
|
-
|
|
|
- assert.Assert(t, is.Len(*group.Containers, 1))
|
|
|
- assert.Equal(t, *(*group.Containers)[0].Name, "service1")
|
|
|
- assert.Equal(t, group.RestartPolicy, containerinstance.Always)
|
|
|
-}
|
|
|
-
|
|
|
-func TestComposeContainerGroupToContainerMultiplePorts(t *testing.T) {
|
|
|
- project := types.Project{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: "service1",
|
|
|
- Image: "image1",
|
|
|
- Ports: []types.ServicePortConfig{
|
|
|
- {
|
|
|
- Published: 80,
|
|
|
- Target: 80,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- {
|
|
|
- Name: "service2",
|
|
|
- Image: "image2",
|
|
|
- Ports: []types.ServicePortConfig{
|
|
|
- {
|
|
|
- Published: 8080,
|
|
|
- Target: 8080,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
|
|
- assert.NilError(t, err)
|
|
|
- assert.Assert(t, is.Len(*group.Containers, 3))
|
|
|
-
|
|
|
- container1 := (*group.Containers)[0]
|
|
|
- assert.Equal(t, *container1.Name, "service1")
|
|
|
- assert.Equal(t, *container1.Image, "image1")
|
|
|
- assert.Equal(t, *(*container1.Ports)[0].Port, int32(80))
|
|
|
-
|
|
|
- container2 := (*group.Containers)[1]
|
|
|
- assert.Equal(t, *container2.Name, "service2")
|
|
|
- assert.Equal(t, *container2.Image, "image2")
|
|
|
- assert.Equal(t, *(*container2.Ports)[0].Port, int32(8080))
|
|
|
-
|
|
|
- groupPorts := *group.IPAddress.Ports
|
|
|
- assert.Assert(t, is.Len(groupPorts, 2))
|
|
|
- assert.Equal(t, *groupPorts[0].Port, int32(80))
|
|
|
- assert.Equal(t, *groupPorts[1].Port, int32(8080))
|
|
|
- assert.Assert(t, group.IPAddress.DNSNameLabel == nil)
|
|
|
-}
|
|
|
-
|
|
|
func TestComposeContainerGroupToContainerWithDomainName(t *testing.T) {
|
|
|
project := types.Project{
|
|
|
Services: []types.ServiceConfig{
|
|
|
@@ -691,20 +446,6 @@ func TestComposeContainerGroupToContainerenvVar(t *testing.T) {
|
|
|
assert.Assert(t, is.Contains(envVars, containerinstance.EnvironmentVariable{Name: to.StringPtr("key2"), Value: to.StringPtr("value2")}))
|
|
|
}
|
|
|
|
|
|
-func TestConvertToAciRestartPolicyCondition(t *testing.T) {
|
|
|
- assert.Equal(t, toAciRestartPolicy("none"), containerinstance.Never)
|
|
|
- assert.Equal(t, toAciRestartPolicy("always"), containerinstance.Always)
|
|
|
- assert.Equal(t, toAciRestartPolicy("on-failure"), containerinstance.OnFailure)
|
|
|
- assert.Equal(t, toAciRestartPolicy("on-failure:5"), containerinstance.Always)
|
|
|
-}
|
|
|
-
|
|
|
-func TestConvertToDockerRestartPolicyCondition(t *testing.T) {
|
|
|
- assert.Equal(t, toContainerRestartPolicy(containerinstance.Never), "none")
|
|
|
- assert.Equal(t, toContainerRestartPolicy(containerinstance.Always), "any")
|
|
|
- assert.Equal(t, toContainerRestartPolicy(containerinstance.OnFailure), "on-failure")
|
|
|
- assert.Equal(t, toContainerRestartPolicy(""), "any")
|
|
|
-}
|
|
|
-
|
|
|
func TestConvertContainerGroupStatus(t *testing.T) {
|
|
|
assert.Equal(t, "Running", GetStatus(container(to.StringPtr("Running")), group(to.StringPtr("Started"))))
|
|
|
assert.Equal(t, "Terminated", GetStatus(container(to.StringPtr("Terminated")), group(to.StringPtr("Stopped"))))
|
|
|
@@ -715,157 +456,6 @@ func TestConvertContainerGroupStatus(t *testing.T) {
|
|
|
assert.Equal(t, "Unknown", GetStatus(container(nil), group(nil)))
|
|
|
}
|
|
|
|
|
|
-func TestConvertSecrets(t *testing.T) {
|
|
|
- serviceName := "testservice"
|
|
|
- secretName := "testsecret"
|
|
|
- absBasePath := "/home/user"
|
|
|
- tmpFile, err := ioutil.TempFile(os.TempDir(), "TestConvertProjectSecrets-")
|
|
|
- assert.NilError(t, err)
|
|
|
- _, err = tmpFile.Write([]byte("test content"))
|
|
|
- assert.NilError(t, err)
|
|
|
- t.Cleanup(func() {
|
|
|
- _ = os.Remove(tmpFile.Name())
|
|
|
- })
|
|
|
-
|
|
|
- t.Run("mix default and absolute", func(t *testing.T) {
|
|
|
- pSquashedDefaultAndAbs := projectAciHelper{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: serviceName,
|
|
|
- Secrets: []types.ServiceSecretConfig{
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: "some_target1",
|
|
|
- },
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- },
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: path.Join(defaultSecretsPath, "some_target2"),
|
|
|
- },
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: path.Join(absBasePath, "some_target3"),
|
|
|
- },
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: path.Join(absBasePath, "some_target4"),
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- Secrets: map[string]types.SecretConfig{
|
|
|
- secretName: {
|
|
|
- File: tmpFile.Name(),
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
- volumes, err := pSquashedDefaultAndAbs.getAciSecretVolumes()
|
|
|
- assert.NilError(t, err)
|
|
|
- assert.Equal(t, len(volumes), 2)
|
|
|
-
|
|
|
- defaultVolumeName := getServiceSecretKey(serviceName, defaultSecretsPath)
|
|
|
- homeVolumeName := getServiceSecretKey(serviceName, absBasePath)
|
|
|
- // random order since this was created from a map...
|
|
|
- for _, vol := range volumes {
|
|
|
- switch *vol.Name {
|
|
|
- case defaultVolumeName:
|
|
|
- assert.Equal(t, len(vol.Secret), 3)
|
|
|
- case homeVolumeName:
|
|
|
- assert.Equal(t, len(vol.Secret), 2)
|
|
|
- default:
|
|
|
- assert.Assert(t, false, "unexpected volume name: "+*vol.Name)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- s := serviceConfigAciHelper(pSquashedDefaultAndAbs.Services[0])
|
|
|
- vms, err := s.getAciSecretsVolumeMounts()
|
|
|
- assert.NilError(t, err)
|
|
|
- assert.Equal(t, len(vms), 2)
|
|
|
-
|
|
|
- assert.Equal(t, *vms[0].Name, defaultVolumeName)
|
|
|
- assert.Equal(t, *vms[0].MountPath, defaultSecretsPath)
|
|
|
-
|
|
|
- assert.Equal(t, *vms[1].Name, homeVolumeName)
|
|
|
- assert.Equal(t, *vms[1].MountPath, absBasePath)
|
|
|
- })
|
|
|
-
|
|
|
- t.Run("convert invalid target", func(t *testing.T) {
|
|
|
- targetName := "some/invalid/relative/path/target"
|
|
|
- pInvalidRelativePathTarget := projectAciHelper{
|
|
|
- Services: []types.ServiceConfig{
|
|
|
- {
|
|
|
- Name: serviceName,
|
|
|
- Secrets: []types.ServiceSecretConfig{
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: targetName,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- Secrets: map[string]types.SecretConfig{
|
|
|
- secretName: {
|
|
|
- File: tmpFile.Name(),
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
- _, err := pInvalidRelativePathTarget.getAciSecretVolumes()
|
|
|
- assert.Equal(t, err.Error(),
|
|
|
- fmt.Sprintf(`in service %q, secret with source %q cannot have a relative path as target. Only absolute paths are allowed. Found %q`,
|
|
|
- serviceName, secretName, targetName))
|
|
|
- })
|
|
|
-
|
|
|
- t.Run("convert colliding default targets", func(t *testing.T) {
|
|
|
- targetName1 := path.Join(defaultSecretsPath, "target1")
|
|
|
- targetName2 := path.Join(defaultSecretsPath, "sub/folder/target2")
|
|
|
-
|
|
|
- service := serviceConfigAciHelper{
|
|
|
- Name: serviceName,
|
|
|
- Secrets: []types.ServiceSecretConfig{
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: targetName1,
|
|
|
- },
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: targetName2,
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- _, err := service.getAciSecretsVolumeMounts()
|
|
|
- assert.Equal(t, err.Error(),
|
|
|
- fmt.Sprintf(`mount paths %q and %q collide. A volume mount cannot include another one.`,
|
|
|
- path.Dir(targetName1), path.Dir(targetName2)))
|
|
|
- })
|
|
|
-
|
|
|
- t.Run("convert colliding absolute targets", func(t *testing.T) {
|
|
|
- targetName1 := path.Join(absBasePath, "target1")
|
|
|
- targetName2 := path.Join(absBasePath, "sub/folder/target2")
|
|
|
-
|
|
|
- service := serviceConfigAciHelper{
|
|
|
- Name: serviceName,
|
|
|
- Secrets: []types.ServiceSecretConfig{
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: targetName1,
|
|
|
- },
|
|
|
- {
|
|
|
- Source: secretName,
|
|
|
- Target: targetName2,
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- _, err := service.getAciSecretsVolumeMounts()
|
|
|
- assert.Equal(t, err.Error(),
|
|
|
- fmt.Sprintf(`mount paths %q and %q collide. A volume mount cannot include another one.`,
|
|
|
- path.Dir(targetName1), path.Dir(targetName2)))
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
func container(status *string) containerinstance.Container {
|
|
|
var state *containerinstance.ContainerState = nil
|
|
|
if status != nil {
|