Add e2e-aci tests for volumes

Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
This commit is contained in:
Ulysses Souza 2020-05-19 11:29:48 +02:00
parent b25a6b4bd6
commit d28e5fd742
7 changed files with 273 additions and 24 deletions

View File

@ -257,11 +257,14 @@ func getContainerClient(subscriptionID string) (containerinstance.ContainerClien
return containerClient, nil
}
func getSubscriptionsClient() subscription.SubscriptionsClient {
func getSubscriptionsClient() (subscription.SubscriptionsClient, error) {
subc := subscription.NewSubscriptionsClient()
authorizer, _ := login.NewAuthorizerFromLogin()
authorizer, err := login.NewAuthorizerFromLogin()
if err != nil {
return subscription.SubscriptionsClient{}, err
}
subc.Authorizer = authorizer
return subc
return subc, nil
}
// GetGroupsClient ...
@ -274,7 +277,10 @@ func GetGroupsClient(subscriptionID string) resources.GroupsClient {
// GetSubscriptionID ...
func GetSubscriptionID(ctx context.Context) (string, error) {
c := getSubscriptionsClient()
c, err := getSubscriptionsClient()
if err != nil {
return "", err
}
res, err := c.List(ctx)
if err != nil {
return "", err

76
azure/storage/storage.go Normal file
View File

@ -0,0 +1,76 @@
package storage
import (
"context"
"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/storage/mgmt/storage"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
"github.com/docker/api/azure/login"
"github.com/docker/api/context/store"
)
// CreateStorageAccount creates a new storage account.
func CreateStorageAccount(ctx context.Context, aciContext store.AciContext, accountName string) (storage.Account, error) {
storageAccountsClient := getStorageAccountsClient(aciContext)
result, err := storageAccountsClient.CheckNameAvailability(
ctx,
storage.AccountCheckNameAvailabilityParameters{
Name: to.StringPtr(accountName),
Type: to.StringPtr("Microsoft.Storage/storageAccounts"),
})
if err != nil {
return storage.Account{}, err
}
if !*result.NameAvailable {
return storage.Account{}, err
}
future, err := storageAccountsClient.Create(
ctx,
aciContext.ResourceGroup,
accountName,
storage.AccountCreateParameters{
Sku: &storage.Sku{
Name: storage.StandardLRS,
},
Location: to.StringPtr(aciContext.Location),
AccountPropertiesCreateParameters: &storage.AccountPropertiesCreateParameters{}})
if err != nil {
return storage.Account{}, err
}
err = future.WaitForCompletionRef(ctx, storageAccountsClient.Client)
if err != nil {
return storage.Account{}, err
}
return future.Result(storageAccountsClient)
}
// DeleteStorageAccount deletes a given storage account
func DeleteStorageAccount(ctx context.Context, aciContext store.AciContext, accountName string) (autorest.Response, error) {
storageAccountsClient := getStorageAccountsClient(aciContext)
response, err := storageAccountsClient.Delete(ctx, aciContext.ResourceGroup, accountName)
if err != nil {
return autorest.Response{}, err
}
return response, err
}
// ListKeys lists the storage account keys
func ListKeys(ctx context.Context, aciContext store.AciContext, accountName string) (storage.AccountListKeysResult, error) {
storageAccountsClient := getStorageAccountsClient(aciContext)
keys, err := storageAccountsClient.ListKeys(ctx, aciContext.ResourceGroup, accountName)
if err != nil {
return storage.AccountListKeysResult{}, err
}
return keys, nil
}
func getStorageAccountsClient(aciContext store.AciContext) storage.AccountsClient {
storageAccountsClient := storage.NewAccountsClient(aciContext.SubscriptionID)
autho, _ := login.NewAuthorizerFromLogin()
storageAccountsClient.Authorizer = autho
return storageAccountsClient
}

View File

@ -0,0 +1,67 @@
package storage
import (
"context"
"fmt"
"net/url"
"testing"
"github.com/Azure/azure-storage-file-go/azfile"
. "github.com/onsi/gomega"
"github.com/docker/api/azure"
"github.com/docker/api/context/store"
)
const (
resourceGroupName = "rgulyssessouza"
location = "westeurope"
testAccountName = "dockertestaccountname"
testShareName = "dockertestsharename"
testContent = "test content!"
)
func TestGetContainerName(t *testing.T) {
RegisterTestingT(t)
subscriptionID, err := azure.GetSubscriptionID(context.TODO())
Expect(err).To(BeNil())
aciContext := store.AciContext{
SubscriptionID: subscriptionID,
Location: location,
ResourceGroup: resourceGroupName,
}
storageAccount, err := CreateStorageAccount(context.TODO(), aciContext, testAccountName)
Expect(err).To(BeNil())
Expect(*storageAccount.Name).To(Equal(testAccountName))
list, err := ListKeys(context.TODO(), aciContext, *storageAccount.Name)
Expect(err).To(BeNil())
firstKey := *(*list.Keys)[0].Value
// Create a ShareURL object that wraps a soon-to-be-created share's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.file.core.windows.net/%s", testAccountName, testShareName))
credential, err := azfile.NewSharedKeyCredential(testAccountName, firstKey)
Expect(err).To(BeNil())
shareURL := azfile.NewShareURL(*u, azfile.NewPipeline(credential, azfile.PipelineOptions{}))
_, err = shareURL.Create(context.TODO(), azfile.Metadata{}, 0)
Expect(err).To(BeNil())
fURL, err := url.Parse(u.String() + "/testfile")
Expect(err).To(BeNil())
fileURL := azfile.NewFileURL(*fURL, azfile.NewPipeline(credential, azfile.PipelineOptions{}))
err = azfile.UploadBufferToAzureFile(context.TODO(), []byte(testContent), fileURL, azfile.UploadToAzureFileOptions{})
Expect(err).To(BeNil())
b := make([]byte, len(testContent))
_, err = azfile.DownloadAzureFileToBuffer(context.TODO(), fileURL, b, azfile.DownloadFromAzureFileOptions{})
Expect(err).To(BeNil())
Expect(string(b)).To(Equal(testContent))
_, err = DeleteStorageAccount(context.TODO(), aciContext, testAccountName)
Expect(err).To(BeNil())
}

View File

@ -31,10 +31,11 @@ func (r *Opts) ToContainerConfig(image string) (containers.ContainerConfig, erro
}
return containers.ContainerConfig{
ID: r.Name,
Image: image,
Ports: publish,
Labels: labels,
ID: r.Name,
Image: image,
Ports: publish,
Labels: labels,
Volumes: r.Volumes,
}, nil
}

3
go.mod
View File

@ -3,10 +3,13 @@ module github.com/docker/api
go 1.14
require (
github.com/Azure/azure-pipeline-go v0.2.1
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible
github.com/Azure/azure-storage-file-go v0.7.0
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/Azure/go-autorest/autorest v0.10.0
github.com/Azure/go-autorest/autorest/adal v0.8.2
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1
github.com/Azure/go-autorest/autorest/date v0.2.0
github.com/Azure/go-autorest/autorest/to v0.3.0

16
go.sum
View File

@ -1,15 +1,26 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo=
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible h1:yz6sFf5bHZ+gEOQVuK5JhPqTTAmv+OvSLSaqgzqaCwY=
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-storage-file-go v0.7.0 h1:yWoV0MYwzmoSgWACcVkdPolvAULFPNamcQLpIvS/Et4=
github.com/Azure/azure-storage-file-go v0.7.0/go.mod h1:3w3mufGcMjcOJ3w+4Gs+5wsSgkT7xDwWWqMMIrXtW4c=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v1.1.1 h1:4G9tVCqooRY3vDTB2bA1Z01PlSALtnUbji0AfzthUSs=
github.com/Azure/go-autorest v14.1.0+incompatible h1:qROrS0rWxAXGfFdNOI33we8553d7T8v78jXf/8tjLBM=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY=
github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest v0.10.1 h1:uaB8A32IZU9YKs9v50+/LWIWTDHJk2vlGzbfd7FfESI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk=
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
@ -151,9 +162,12 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149 h1:HfxbT6/JcvIljmERptWhwa8XzP7H3T+Z2N26gTsaDaA=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@ -270,6 +284,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
@ -288,6 +303,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=

View File

@ -2,14 +2,22 @@ package main
import (
"context"
"fmt"
"log"
"net/url"
"strings"
"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
"github.com/Azure/go-autorest/autorest/to"
azure_storage "github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/storage/mgmt/storage"
"github.com/Azure/azure-storage-file-go/azfile"
. "github.com/onsi/gomega"
"github.com/docker/api/azure"
"github.com/docker/api/azure/storage"
"github.com/docker/api/context/store"
. "github.com/docker/api/tests/framework"
)
@ -44,9 +52,11 @@ func main() {
Expect(output).To(ContainSubstring("default *"))
})
var subscriptionID string
It("creates a new aci context for tests", func() {
setupTestResourceGroup(resourceGroupName)
subscriptionID, err := azure.GetSubscriptionID(context.TODO())
var err error
subscriptionID, err = azure.GetSubscriptionID(context.TODO())
Expect(err).To(BeNil())
NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie()
@ -68,21 +78,7 @@ func main() {
})
It("runs nginx on port 80", func() {
output := NewDockerCommand("run", "nginx", "-p", "80:80", "--name", testContainerName).ExecOrDie()
Expect(output).To(Equal(testContainerName + "\n"))
output = NewDockerCommand("ps").ExecOrDie()
lines := Lines(output)
Expect(len(lines)).To(Equal(2))
containerFields := Columns(lines[1])
Expect(containerFields[1]).To(Equal("nginx"))
Expect(containerFields[2]).To(Equal("Running"))
exposedIP := containerFields[3]
Expect(exposedIP).To(ContainSubstring(":80->80/tcp"))
url := strings.ReplaceAll(exposedIP, "->80/tcp", "")
output = NewCommand("curl", url).ExecOrDie()
Expect(output).To(ContainSubstring("Welcome to nginx!"))
runTest(subscriptionID)
})
It("removes container nginx", func() {
@ -136,6 +132,90 @@ func main() {
})
}
const (
testStorageAccountName = "dockertestaccountname"
testShareName = "dockertestsharename"
testFileContent = "Volume mounted with success!"
testFileName = "index.html"
)
func createStorageAccount(aciContext store.AciContext, accountName string) azure_storage.Account {
storageAccount, err := storage.CreateStorageAccount(context.TODO(), aciContext, accountName)
Expect(err).To(BeNil())
Expect(*storageAccount.Name).To(Equal(accountName))
return storageAccount
}
func getStorageKeys(aciContext store.AciContext, storageAccountName string) []azure_storage.AccountKey {
list, err := storage.ListKeys(context.TODO(), aciContext, storageAccountName)
Expect(err).To(BeNil())
Expect(list.Keys).ToNot(BeNil())
Expect(len(*list.Keys)).To(BeNumerically(">", 0))
return *list.Keys
}
func deleteStorageAccount(aciContext store.AciContext) {
_, err := storage.DeleteStorageAccount(context.TODO(), aciContext, testStorageAccountName)
Expect(err).To(BeNil())
}
func createFileShare(key, shareName string) (azfile.SharedKeyCredential, url.URL) {
// Create a ShareURL object that wraps a soon-to-be-created share's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.file.core.windows.net/%s", testStorageAccountName, shareName))
credential, err := azfile.NewSharedKeyCredential(testStorageAccountName, key)
Expect(err).To(BeNil())
shareURL := azfile.NewShareURL(*u, azfile.NewPipeline(credential, azfile.PipelineOptions{}))
_, err = shareURL.Create(context.TODO(), azfile.Metadata{}, 0)
Expect(err).To(BeNil())
return *credential, *u
}
func uploadFile(credential azfile.SharedKeyCredential, baseURL, fileName, fileContent string) {
fURL, err := url.Parse(baseURL + "/" + fileName)
Expect(err).To(BeNil())
fileURL := azfile.NewFileURL(*fURL, azfile.NewPipeline(&credential, azfile.PipelineOptions{}))
err = azfile.UploadBufferToAzureFile(context.TODO(), []byte(testFileContent), fileURL, azfile.UploadToAzureFileOptions{})
Expect(err).To(BeNil())
}
func runTest(subscriptionID string) {
aciContext := store.AciContext{
SubscriptionID: subscriptionID,
Location: location,
ResourceGroup: resourceGroupName,
}
createStorageAccount(aciContext, testStorageAccountName)
defer deleteStorageAccount(aciContext)
keys := getStorageKeys(aciContext, testStorageAccountName)
firstKey := *keys[0].Value
credential, u := createFileShare(firstKey, testShareName)
uploadFile(credential, u.String(), testFileName, testFileContent)
mountTarget := "/usr/share/nginx/html"
output := NewDockerCommand("run", "nginx",
"-v", fmt.Sprintf("%s:%s@%s:%s",
testStorageAccountName, firstKey, testShareName, mountTarget),
"-p", "80:80",
"--name", testContainerName).ExecOrDie()
Expect(output).To(Equal(testContainerName + "\n"))
output = NewDockerCommand("ps").ExecOrDie()
lines := Lines(output)
Expect(len(lines)).To(Equal(2))
containerFields := Columns(lines[1])
Expect(containerFields[1]).To(Equal("nginx"))
Expect(containerFields[2]).To(Equal("Running"))
exposedIP := containerFields[3]
Expect(exposedIP).To(ContainSubstring(":80->80/tcp"))
publishedURL := strings.ReplaceAll(exposedIP, "->80/tcp", "")
output = NewCommand("curl", publishedURL).ExecOrDie()
Expect(output).To(ContainSubstring(testFileContent))
}
func setupTestResourceGroup(groupName string) {
log.Println("Creating resource group " + resourceGroupName)
ctx := context.TODO()