Add aci volumes e2e test

Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
This commit is contained in:
Ulysses Souza 2020-10-01 16:03:22 +02:00 committed by Guillaume Tardif
parent 0cea91c555
commit f8a3aec64d
6 changed files with 112 additions and 31 deletions

2
go.mod
View File

@ -48,6 +48,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/runc v0.1.1 // indirect github.com/opencontainers/runc v0.1.1 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/tsdb v0.7.1
github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b
github.com/sirupsen/logrus v1.6.0 github.com/sirupsen/logrus v1.6.0
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
@ -62,6 +63,7 @@ require (
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.61.0 gopkg.in/ini.v1 v1.61.0
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
gotest.tools/v3 v3.0.2 gotest.tools/v3 v3.0.2
) )

1
go.sum
View File

@ -404,6 +404,7 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=

View File

@ -20,10 +20,13 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/prometheus/tsdb/fileutil"
"io/ioutil"
"math/rand" "math/rand"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
@ -31,6 +34,9 @@ import (
"testing" "testing"
"time" "time"
"github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types"
"gopkg.in/yaml.v3"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/icmd" "gotest.tools/v3/icmd"
@ -133,16 +139,27 @@ func getTestLocation() string {
return location[n] return location[n]
} }
func TestContainerRunVolume(t *testing.T) { func uploadTestFile(t *testing.T, aciContext store.AciContext, accountName string, fileshareName string, testFileName string, testFileContent string) {
c := NewParallelE2eCLI(t, binDir) storageLogin := login.StorageLoginImpl{AciContext: aciContext}
sID, rg, location := setupTestResourceGroup(t, c) key, err := storageLogin.GetAzureStorageAccountKey(context.TODO(), accountName)
assert.NilError(t, err)
cred, err := azfile.NewSharedKeyCredential(accountName, key)
assert.NilError(t, err)
u, _ := url.Parse(fmt.Sprintf("https://%s.file.core.windows.net/%s", accountName, fileshareName))
uploadFile(t, *cred, u.String(), testFileName, testFileContent)
}
const fileshareName = "dockertestshare"
func TestRunVolume(t *testing.T) {
const ( const (
fileshareName = "dockertestshare"
testFileContent = "Volume mounted successfully!" testFileContent = "Volume mounted successfully!"
testFileName = "index.html" testFileName = "index.html"
) )
c := NewParallelE2eCLI(t, binDir)
sID, rg, location := setupTestResourceGroup(t, c)
// Bootstrap volume // Bootstrap volume
aciContext := store.AciContext{ aciContext := store.AciContext{
SubscriptionID: sID, SubscriptionID: sID,
@ -180,8 +197,8 @@ func TestContainerRunVolume(t *testing.T) {
t.Run("create volumes", func(t *testing.T) { t.Run("create volumes", func(t *testing.T) {
c.RunDockerCmd("volume", "create", "--storage-account", accountName, fileshareName) c.RunDockerCmd("volume", "create", "--storage-account", accountName, fileshareName)
}) })
volumeID = accountName + "/" + fileshareName
volumeID = accountName + "/" + fileshareName
t.Cleanup(func() { t.Cleanup(func() {
c.RunDockerCmd("volume", "rm", volumeID) c.RunDockerCmd("volume", "rm", volumeID)
res := c.RunDockerCmd("volume", "ls") res := c.RunDockerCmd("volume", "ls")
@ -215,14 +232,7 @@ func TestContainerRunVolume(t *testing.T) {
}) })
t.Run("upload file", func(t *testing.T) { t.Run("upload file", func(t *testing.T) {
storageLogin := login.StorageLoginImpl{AciContext: aciContext} uploadTestFile(t, aciContext, accountName, fileshareName, testFileName, testFileContent)
key, err := storageLogin.GetAzureStorageAccountKey(context.TODO(), accountName)
assert.NilError(t, err)
cred, err := azfile.NewSharedKeyCredential(accountName, key)
assert.NilError(t, err)
u, _ := url.Parse(fmt.Sprintf("https://%s.file.core.windows.net/%s", accountName, fileshareName))
uploadFile(t, *cred, u.String(), testFileName, testFileContent)
}) })
t.Run("run", func(t *testing.T) { t.Run("run", func(t *testing.T) {
@ -465,24 +475,73 @@ func TestContainerRunAttached(t *testing.T) {
}) })
} }
func TestComposeUpUpdate(t *testing.T) { func overwriteFileStorageAccount(t *testing.T, absComposefileName string, storageAccount string) {
c := NewParallelE2eCLI(t, binDir) data, err := ioutil.ReadFile(absComposefileName)
_, groupID, location := setupTestResourceGroup(t, c) m, err := loader.ParseYAML(data)
assert.NilError(t, err)
p, err := loader.Load(types.ConfigDetails{ConfigFiles: []types.ConfigFile{{Config: m}}})
p.Volumes["mydata"].DriverOpts["storage_account_name"] = storageAccount
out, err := yaml.Marshal(p)
assert.NilError(t, err)
// FIXME(ulyssessouza): Change `compose-go` to omit `WorkingDir` and `Name` on YAML serialization
outBytes := []byte(strings.Join(strings.Split(string(out), "\n")[2:], "\n")) // Removes the first 2 lines
err = ioutil.WriteFile(absComposefileName, outBytes, 0644)
assert.NilError(t, err)
}
func TestUpUpdate(t *testing.T) {
const ( const (
composeFile = "../composefiles/aci-demo/aci_demo_port.yaml"
composeFileMultiplePorts = "../composefiles/aci-demo/aci_demo_multi_port.yaml"
composeProjectName = "acidemo" composeProjectName = "acidemo"
serverContainer = composeProjectName + "_web" serverContainer = composeProjectName + "_web"
wordsContainer = composeProjectName + "_words" wordsContainer = composeProjectName + "_words"
dbContainer = composeProjectName + "_db" dbContainer = composeProjectName + "_db"
) )
var (
singlePortVolumesComposefile = "aci_demo_port_volumes.yaml"
multiPortVolumesComposefile = "aci_demo_multiport_volumes.yaml"
)
c := NewParallelE2eCLI(t, binDir)
sID, groupID, location := setupTestResourceGroup(t, c)
composeAccountName := groupID + "-sa"
composeAccountName = strings.ReplaceAll(composeAccountName, "-", "")
composeAccountName = strings.ToLower(composeAccountName)
dstDir := filepath.Join(os.TempDir(), "e2e-aci-volume-"+composeAccountName)
err := fileutil.CopyDirs("../composefiles/aci-demo/", dstDir)
assert.NilError(t, err)
t.Cleanup(func() {
assert.NilError(t, os.RemoveAll(dstDir))
})
singlePortVolumesComposefile = filepath.Join(dstDir, singlePortVolumesComposefile)
overwriteFileStorageAccount(t, singlePortVolumesComposefile, composeAccountName)
multiPortVolumesComposefile = filepath.Join(dstDir, multiPortVolumesComposefile)
t.Run("compose up", func(t *testing.T) { t.Run("compose up", func(t *testing.T) {
const (
testFileName = "msg.txt"
testFileContent = "VOLUME_OK"
)
c.RunDockerCmd("volume", "create", "--storage-account", composeAccountName, fileshareName)
volumeID := composeAccountName + "/" + fileshareName
t.Cleanup(func() {
c.RunDockerCmd("volume", "rm", volumeID)
})
// Bootstrap volume
aciContext := store.AciContext{
SubscriptionID: sID,
Location: location,
ResourceGroup: groupID,
}
uploadTestFile(t, aciContext, composeAccountName, fileshareName, testFileName, testFileContent)
dnsLabelName := "nginx-" + groupID dnsLabelName := "nginx-" + groupID
fqdn := dnsLabelName + "." + location + ".azurecontainer.io" fqdn := dnsLabelName + "." + location + ".azurecontainer.io"
// Name of Compose project is taken from current folder "acie2e" // Name of Compose project is taken from current folder "acie2e"
c.RunDockerCmd("compose", "up", "-f", composeFile, "--domainname", dnsLabelName) c.RunDockerCmd("compose", "up", "-f", singlePortVolumesComposefile, "--domainname", dnsLabelName, "--project-name", "acidemo")
res := c.RunDockerCmd("ps") res := c.RunDockerCmd("ps")
out := lines(res.Stdout()) out := lines(res.Stdout())
@ -495,7 +554,7 @@ func TestComposeUpUpdate(t *testing.T) {
strings.Contains(l, ":80->80/tcp") strings.Contains(l, ":80->80/tcp")
} }
} }
assert.Assert(t, webRunning, "web container not running") assert.Assert(t, webRunning, "web container not running ; ps:\n" + res.Stdout())
res = c.RunDockerCmd("inspect", serverContainer) res = c.RunDockerCmd("inspect", serverContainer)
@ -510,6 +569,9 @@ func TestComposeUpUpdate(t *testing.T) {
endpoint = fmt.Sprintf("http://%s:%d", fqdn, containerInspect.Ports[0].HostPort) endpoint = fmt.Sprintf("http://%s:%d", fqdn, containerInspect.Ports[0].HostPort)
HTTPGetWithRetry(t, endpoint+"/words/noun", http.StatusOK, 2*time.Second, 20*time.Second) HTTPGetWithRetry(t, endpoint+"/words/noun", http.StatusOK, 2*time.Second, 20*time.Second)
body := HTTPGetWithRetry(t, endpoint+"/volume_test/"+testFileName, http.StatusOK, 2*time.Second, 20*time.Second)
assert.Assert(t, strings.Contains(body, testFileContent))
}) })
t.Run("compose ps", func(t *testing.T) { t.Run("compose ps", func(t *testing.T) {
@ -553,7 +615,7 @@ func TestComposeUpUpdate(t *testing.T) {
}) })
t.Run("update", func(t *testing.T) { t.Run("update", func(t *testing.T) {
c.RunDockerCmd("compose", "up", "-f", composeFileMultiplePorts, "--project-name", composeProjectName) c.RunDockerCmd("compose", "up", "-f", multiPortVolumesComposefile, "--project-name", composeProjectName)
res := c.RunDockerCmd("ps") res := c.RunDockerCmd("ps")
out := lines(res.Stdout()) out := lines(res.Stdout())
// Check three containers are running // Check three containers are running
@ -645,7 +707,7 @@ func TestRunEnvVars(t *testing.T) {
func setupTestResourceGroup(t *testing.T, c *E2eCLI) (string, string, string) { func setupTestResourceGroup(t *testing.T, c *E2eCLI) (string, string, string) {
startTime := strconv.Itoa(int(time.Now().Unix())) startTime := strconv.Itoa(int(time.Now().Unix()))
rg := "E2E-" + t.Name() + "-" + startTime rg := "E2E-" + t.Name() + "-" + startTime[5:]
azureLogin(t, c) azureLogin(t, c)
sID := getSubscriptionID(t) sID := getSubscriptionID(t)
location := getTestLocation() location := getTestLocation()

View File

@ -0,0 +1,16 @@
services:
db:
build: db
image: gtardif/sentences-db
words:
build: words
image: gtardif/sentences-api
ports:
- "8080:8080"
web:
build: web
image: gtardif/sentences-web
ports:
- "80:80"

View File

@ -13,11 +13,11 @@ services:
ports: ports:
- "80:80" - "80:80"
volumes: volumes:
- mydata:/mount/testvolumes - mydata:/static/volume_test
volumes: volumes:
mydata: mydata:
driver: azure_file driver: azure_file
driver_opts: driver_opts:
share_name: minecraft-volume share_name: dockertestshare
storage_account_name: minecraftdocker storage_account_name: dockertestvolumeaccount

View File

@ -142,7 +142,7 @@ func CopyFile(sourceFile string, destinationFile string) error {
return nil return nil
} }
// NewCmd creates a cmd object configured with the test environment set // NewCmd creates a cmd object configured with the Test environment set
func (c *E2eCLI) NewCmd(command string, args ...string) icmd.Cmd { func (c *E2eCLI) NewCmd(command string, args ...string) icmd.Cmd {
env := append(os.Environ(), env := append(os.Environ(),
"DOCKER_CONFIG="+c.ConfigDir, "DOCKER_CONFIG="+c.ConfigDir,
@ -173,7 +173,7 @@ func (c *E2eCLI) RunDockerCmd(args ...string) *icmd.Result {
return res return res
} }
// PathEnvVar returns path (os sensitive) for running test // PathEnvVar returns path (os sensitive) for running Test
func (c *E2eCLI) PathEnvVar() string { func (c *E2eCLI) PathEnvVar() string {
path := c.BinDir + ":" + os.Getenv("PATH") path := c.BinDir + ":" + os.Getenv("PATH")
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {