Skip to content

Commit

Permalink
add integration tests from docker_driver_integration_tests repo
Browse files Browse the repository at this point in the history
Signed-off-by: Amelia Downs <[email protected]>
Co-authored-by: Amelia Downs <[email protected]>
  • Loading branch information
winkingturtle-vmw and ameowlia committed Aug 14, 2024
1 parent 1d7355b commit fbc30c6
Show file tree
Hide file tree
Showing 10 changed files with 898 additions and 0 deletions.
68 changes: 68 additions & 0 deletions integration/compatibility/compatibility_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package compatibility_test

import (
"encoding/json"
"errors"
"os"
"os/exec"
"strings"
"testing"

"code.cloudfoundry.org/dockerdriver/integration"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
)

type VolumeServiceBrokerBinding struct {
VolumeMounts []struct {
Device struct {
VolumeID string `json:"volume_id"`
MountConfig map[string]interface{} `json:"mount_config"`
} `json:"device"`
} `json:"volume_mounts"`
}

var (
integrationFixtureTemplate = integration.LoadFixtureTemplate()
bindingsFixture = LoadVolumeServiceBrokerBindingsFixture()
session *gexec.Session
)

func TestCompatibility(t *testing.T) {

RegisterFailHandler(Fail)
RunSpecs(t, "Compatibility Suite")
}

var _ = BeforeSuite(func() {
cmd := exec.Command(os.Getenv("DRIVER_CMD"), strings.Split(os.Getenv("DRIVER_OPTS"), ",")...)

var err error
session, err = gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(session.Out).Should(gbytes.Say("driver-server.started"))
})

func LoadVolumeServiceBrokerBindingsFixture() []VolumeServiceBrokerBinding {
var ok bool
var bindingsFile string
if bindingsFile, ok = os.LookupEnv("BINDINGS_FILE"); !ok {
panic(errors.New("BINDINGS_FILE environment variable not set"))
}

bytes, err := os.ReadFile(bindingsFile)
if err != nil {
panic(err.Error())
}

bindings := []VolumeServiceBrokerBinding{}
err = json.Unmarshal(bytes, &bindings)
if err != nil {
panic(err.Error())
}

return bindings
}
220 changes: 220 additions & 0 deletions integration/compatibility/compatibility_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package compatibility_test

import (
"context"
"math/rand"
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
"time"

"code.cloudfoundry.org/dockerdriver"
"code.cloudfoundry.org/dockerdriver/driverhttp"
"code.cloudfoundry.org/lager/v3"
"code.cloudfoundry.org/lager/v3/lagertest"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)

var _ = Describe("Compatibility", func() {
var (
err error

testLogger lager.Logger
testContext context.Context
testEnv dockerdriver.Env
driverClient dockerdriver.Driver
errResponse dockerdriver.ErrorResponse

mountResponse dockerdriver.MountResponse
)

BeforeEach(func() {
testLogger = lagertest.NewTestLogger("CompatibilityTest")
testContext = context.TODO()
testEnv = driverhttp.NewHttpDriverEnv(testLogger, testContext)

driverClient, err = driverhttp.NewRemoteClient(integrationFixtureTemplate.DriverAddress, integrationFixtureTemplate.TLSConfig)
Expect(err).NotTo(HaveOccurred())
})

for _, binding := range bindingsFixture {

options := []string{}

cf := integrationFixtureTemplate
cf.CreateConfig = dockerdriver.CreateRequest{}
cf.CreateConfig.Name = binding.VolumeMounts[0].Device.VolumeID
cf.CreateConfig.Opts = map[string]interface{}{}
cf.CreateConfig.Opts["source"] = integrationFixtureTemplate.CreateConfig.Opts["source"]

if userAuthenticated(integrationFixtureTemplate.CreateConfig.Opts) {
cf.CreateConfig.Opts["username"] = integrationFixtureTemplate.CreateConfig.Opts["username"]
cf.CreateConfig.Opts["password"] = integrationFixtureTemplate.CreateConfig.Opts["password"]
} else {
cf.CreateConfig.Opts["uid"] = integrationFixtureTemplate.CreateConfig.Opts["uid"]
cf.CreateConfig.Opts["gid"] = integrationFixtureTemplate.CreateConfig.Opts["gid"]
}

for k, v := range binding.VolumeMounts[0].Device.MountConfig {
options = append(options, k)

if k == "source" || k == "username" || k == "password" || k == "uid" || k == "gid" {
continue
}

cf.CreateConfig.Opts[k] = v
}

Context("given a created volume", func() {

var certificationFixture = cf

BeforeEach(func() {
testLogger.Info("using fixture", lager.Data{"fixture": certificationFixture})
errResponse = driverClient.Create(testEnv, certificationFixture.CreateConfig)
Expect(errResponse.Err).To(Equal(""))
})

AfterEach(func() {
errResponse = driverClient.Remove(testEnv, dockerdriver.RemoveRequest{
Name: certificationFixture.CreateConfig.Name,
})
Expect(errResponse.Err).To(Equal(""))
})

Context("given a mounted volume with options: "+strings.Join(options, ","), func() {
BeforeEach(func() {
mountResponse = driverClient.Mount(testEnv, dockerdriver.MountRequest{
Name: certificationFixture.CreateConfig.Name,
})
Expect(mountResponse.Err).To(Equal(""))
Expect(mountResponse.Mountpoint).NotTo(Equal(""))

cmd := exec.Command("bash", "-c", "cat /proc/mounts | grep -E '"+mountResponse.Mountpoint+"'")
Expect(cmdRunner(cmd)).To(Equal(0))
})

AfterEach(func() {
errResponse = driverClient.Unmount(testEnv, dockerdriver.UnmountRequest{
Name: certificationFixture.CreateConfig.Name,
})
Expect(errResponse.Err).To(Equal(""))
})

if isReadWrite(certificationFixture.CreateConfig.Opts) {
It("should be able to write a file", func() {
testFileWrite(testLogger, mountResponse)
})
} else {
It("should be a read-only filesystem", func() {
testReadOnly(testLogger, mountResponse)
})
}
})
})
}
})

func userAuthenticated(opts map[string]interface{}) bool {
if _, ok := opts["username"]; ok {
return true
} else {
return false
}

}

func testFileWrite(logger lager.Logger, mountResponse dockerdriver.MountResponse) {
logger = logger.Session("test-file-write")
logger.Info("start")
defer logger.Info("end")

fileName := "certtest-" + randomString(10)

logger.Info("writing-test-file", lager.Data{"mountpoint": mountResponse.Mountpoint})
testFile := path.Join(mountResponse.Mountpoint, fileName)
logger.Info("writing-test-file", lager.Data{"filepath": testFile})
err := os.WriteFile(testFile, []byte("hello persi"), 0644)
Expect(err).NotTo(HaveOccurred())

matches, err := filepath.Glob(mountResponse.Mountpoint + "/" + fileName)
Expect(err).NotTo(HaveOccurred())
Expect(len(matches)).To(Equal(1))

bytes, err := os.ReadFile(mountResponse.Mountpoint + "/" + fileName)
Expect(err).NotTo(HaveOccurred())
Expect(bytes).To(Equal([]byte("hello persi")))

err = os.Remove(testFile)
Expect(err).NotTo(HaveOccurred())

matches, err = filepath.Glob(path.Join(mountResponse.Mountpoint, fileName))
Expect(err).NotTo(HaveOccurred())
Expect(len(matches)).To(Equal(0))
}

func isReadWrite(opts map[string]interface{}) bool {
if _, ok := opts["readonly"]; ok {
return false
} else if _, ok := opts["ro"]; ok {
return false
} else {
return true
}
}

func testReadOnly(logger lager.Logger, mountResponse dockerdriver.MountResponse) {
logger = logger.Session("test-read-only")
logger.Info("start")
defer logger.Info("end")

fileName := "certtest-" + randomString(10)

logger.Info("writing-test-file", lager.Data{"mountpoint": mountResponse.Mountpoint})
testFile := path.Join(mountResponse.Mountpoint, fileName)
logger.Info("writing-test-file", lager.Data{"filepath": testFile})
err := os.WriteFile(testFile, []byte("hello persi"), 0644)
if errorCheckReadOnlyMounts() {
Expect(err.Error()).To(ContainSubstring("read-only file system"))
}
}

func errorCheckReadOnlyMounts() bool {
if val, ok := os.LookupEnv("ERROR_CHECK_READONLY_MOUNTS"); ok {
errorCheckReadOnlyMounts, err := strconv.ParseBool(val)
if err != nil {
return false
}
return errorCheckReadOnlyMounts
} else {
return true
}
}

var isSeeded = false

func randomString(n int) string {
if !isSeeded {
rand.Seed(time.Now().UnixNano())
isSeeded = true
}
runes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

b := make([]rune, n)
for i := range b {
b[i] = runes[rand.Intn(len(runes))]
}
return string(b)
}

func cmdRunner(cmd *exec.Cmd) int {
session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())
Eventually(session, 10).Should(Exit())
return session.ExitCode()
}
13 changes: 13 additions & 0 deletions integration/compatibility/nfs-bindings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{"volume_mounts":[{"device":{"volume_id":"12345-10-0-1ad06d3de7d0314627b1b1a3fc9b72ed","mount_config":{"auto_cache":"true","gid":"9999","source":"nfs://foo/bar","uid":"9999"}}}]},
{"volume_mounts":[{"device":{"volume_id":"12345-10-2-be3238b54e3a4ea93a680ab4eed0b3ad","mount_config":{"auto_cache":"true","gid":"9999","readonly":true,"source":"nfs://foo/bar","uid":"9999"}}}]},
{"volume_mounts":[{"device":{"volume_id":"12345-12-1-caceeff3b764be6a18ae2d421305f492","mount_config":{"auto_cache":"true","password":"pass","source":"nfs://foo/bar","username":"user"}}}]},
{"volume_mounts":[{"device":{"volume_id":"11eadd9a-fa4a-4365-9e20-36ee41d014eb-0-062bf7105a789b74a1b16807fcb7e3f2","mount_config":{"auto_cache":"true","experimental":true,"gid":"9999","source":"nfs://foo/bar","uid":"9999"}}}]},
{"volume_mounts":[{"device":{"volume_id":"11eadd9a-fa4a-4365-9e20-36ee41d014eb-2-f94814dc88e25ffd52606511ceeaee00","mount_config":{"auto_cache":"true","experimental":true,"gid":"9999","readonly":true,"source":"nfs://foo/bar","uid":"9999"}}}]},
{"volume_mounts":[{"device":{"volume_id":"2-1-251ae2aad55809572edd0d74d371ee52","mount_config":{"auto_cache":"true","experimental":true,"password":"pass","source":"nfs://foo/bar","username":"user"}}}]},
{"volume_mounts":[{"device":{"volume_id":"9b1da18c-f64d-4b3a-9ed7-009fa299f223-2-c4b90cf4c0c9569e040d6a458c8b4d43","mount_config":{"auto_cache":"true","gid":"9999","readonly":"true","source":"nfs://foo/bar","uid":"9999"}}}]},
{"volume_mounts":[{"device":{"volume_id":"39a8c397-c767-4715-a2aa-271eb3e60a69-3-4c59e41d22fac501359e18542944f510","mount_config":{"auto_cache":"true","gid":"9999","mount":"/foo/bar","source":"nfs://foo/bar","uid":"9999"}}}]},
{"volume_mounts":[{"device":{"volume_id":"5f0cab5a-8e3d-4828-ae1d-1c9cef594359-22-5d8b7c2c3876d618f12ca4bde6991016","mount_config":{"auto_cache":"true","experimental":true,"gid":"9999","source":"nfs://foo/bar","uid":"9999","version":"4"}}}]},
{"volume_mounts":[{"device":{"volume_id":"2bea6bce-9365-458a-90db-acc639a25380-23-8cc69710d4bac8978242fab37daa23c0","mount_config":{"auto_cache":"true","gid":"9999","mount":"/foo/bar","source":"nfs://foo/bar","uid":"9999","version":"4.1"}}}]},
{"volume_mounts":[{"device":{"volume_id":"2dd69eef-f121-44d0-953e-8a33d5243030","mount_config":{"auto_cache":"true","gid":"9999","mount":"/foo/bar","source":"nfs://foo/bar","uid":"9999","cache" : "true"}}}]}
]
12 changes: 12 additions & 0 deletions integration/compatibility/smb-bindings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{"volume_mounts":[{"device":{"volume_id":"1","mount_config":{"domain":null,"password":"b","source":"foo/bar","username":"a"}}}]},
{"volume_mounts":[{"device":{"volume_id":"2","mount_config":{"domain":null,"password":"b","readonly":true,"source":"foo/bar","username":"a"}}}]},
{"volume_mounts":[{"device":{"volume_id":"3","mount_config":{"password":"b","ro":"true","source":"foo/bar","username":"a"}}}]},
{"volume_mounts":[{"device":{"volume_id":"4","mount_config":{"mount":"/foo/bar","password":"b","source":"foo/bar","username":"a"}}}]},
{"volume_mounts":[{"device":{"volume_id":"5","mount_config":{"password":"b","source":"foo/bar","username":"a"}}}]},
{"volume_mounts":[{"device":{"volume_id":"6","mount_config":{"password":"b","source":"foo/bar","username":"a","version": "1.0"}}}]},
{"volume_mounts":[{"device":{"volume_id":"7","mount_config":{"password":"b","source":"foo/bar","username":"a","version": "2.0"}}}]},
{"volume_mounts":[{"device":{"volume_id":"8","mount_config":{"password":"b","source":"foo/bar","username":"a","version": "2.1"}}}]},
{"volume_mounts":[{"device":{"volume_id":"9","mount_config":{"password":"b","source":"foo/bar","username":"a","version": "3.0"}}}]},
{"volume_mounts":[{"device":{"volume_id":"10","mount_config":{"password":"b","source":"foo/bar","username":"a","mfsymlinks": "true"}}}]}
]
Loading

0 comments on commit fbc30c6

Please sign in to comment.