diff --git a/integrationtests/chrome_test.go b/integrationtests/chrome_test.go index 2280d770..ccb4dff9 100644 --- a/integrationtests/chrome_test.go +++ b/integrationtests/chrome_test.go @@ -3,7 +3,10 @@ package integrationtests import ( "fmt" "io" + "io/ioutil" "net/http" + "os" + "path/filepath" "github.com/tebeka/selenium" @@ -133,6 +136,30 @@ var _ = Describe("Chrome tests", func() { Eventually(func() int { return getDownloadSize("data") }, 90, 0.5).Should(Equal(dataLongLen)) Expect(getDownloadMD5("data")).To(Equal(dataMan.GetMD5())) }, 100) + + It("uploads a small file", func() { + dataMan.GenerateData(dataLen) + data := dataMan.GetData() + dir, err := ioutil.TempDir("", "quic-upload-src") + Expect(err).ToNot(HaveOccurred()) + defer os.RemoveAll(dir) + tmpfn := filepath.Join(dir, "data.dat") + err = ioutil.WriteFile(tmpfn, data, 0777) + Expect(err).ToNot(HaveOccurred()) + copyFileToDocker(tmpfn) + + err = wd.Get("https://quic.clemente.io/uploadform") + Expect(err).NotTo(HaveOccurred()) + elem, err := wd.FindElement(selenium.ByCSSSelector, "#upload") + Expect(err).ToNot(HaveOccurred()) + err = elem.SendKeys("/home/seluser/data.dat") + Expect(err).ToNot(HaveOccurred()) + Eventually(func() error { return elem.Submit() }, 30, 0.1).ShouldNot(HaveOccurred()) + + file := filepath.Join(uploadDir, "data.dat") + Expect(getFileSize(file)).To(Equal(dataLen)) + Expect(getFileMD5(file)).To(Equal(dataMan.GetMD5())) + }) }) } }) diff --git a/integrationtests/integrationtests_suite_test.go b/integrationtests/integrationtests_suite_test.go index ca9829e2..73588ce1 100644 --- a/integrationtests/integrationtests_suite_test.go +++ b/integrationtests/integrationtests_suite_test.go @@ -2,12 +2,16 @@ package integrationtests import ( "bytes" + "crypto/md5" "encoding/hex" "fmt" "io" + "io/ioutil" "net" "net/http" + "os" "os/exec" + "path" "strconv" "time" @@ -30,9 +34,10 @@ const ( ) var ( - server *h2quic.Server - dataMan dataManager - port string + server *h2quic.Server + dataMan dataManager + port string + uploadDir string docker *gexec.Session ) @@ -58,6 +63,10 @@ var _ = AfterSuite(func() { func setupHTTPHandlers() { defer GinkgoRecover() + var err error + uploadDir, err = ioutil.TempDir("", "quic-upload-dest") + Expect(err).ToNot(HaveOccurred()) + http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { defer GinkgoRecover() _, err := io.WriteString(w, "Hello, World!\n") @@ -77,6 +86,35 @@ func setupHTTPHandlers() { _, err := io.Copy(w, r.Body) Expect(err).NotTo(HaveOccurred()) }) + + http.HandleFunc("/uploadform", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + _, err := io.WriteString(w, `
+ + `) + Expect(err).NotTo(HaveOccurred()) + }) + + http.HandleFunc("/uploadhandler", func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + + err = r.ParseMultipartForm(100 * (1 << 20)) // max. 100 MB + Expect(err).ToNot(HaveOccurred()) + file, handler, err := r.FormFile("uploadfile") + Expect(err).ToNot(HaveOccurred()) + defer file.Close() + err = os.MkdirAll(uploadDir, os.ModeDir|0777) + Expect(err).ToNot(HaveOccurred()) + f, err := os.OpenFile(path.Join(uploadDir, handler.Filename), os.O_WRONLY|os.O_CREATE, 0666) + Expect(err).ToNot(HaveOccurred()) + defer f.Close() + io.Copy(f, file) + + _, err = io.WriteString(w, "") + Expect(err).NotTo(HaveOccurred()) + }) } func setupQuicServer() { @@ -175,6 +213,7 @@ var _ = AfterEach(func() { removeDownload("data") }) +// getDownloadSize gets the file size of a file in the /home/seluser/Downloads folder in the docker container func getDownloadSize(filename string) int { var out bytes.Buffer cmd := exec.Command("docker", "exec", "-i", "quic-test-selenium", "stat", "--printf=%s", "/home/seluser/Downloads/"+filename) @@ -190,6 +229,16 @@ func getDownloadSize(filename string) int { return size } +// getFileSize gets the file size of a file on the local file system +func getFileSize(filename string) int { + file, err := os.Open(filename) + Expect(err).ToNot(HaveOccurred()) + fi, err := file.Stat() + Expect(err).ToNot(HaveOccurred()) + return int(fi.Size()) +} + +// getDownloadMD5 gets the md5 sum file of a file in the /home/seluser/Downloads folder in the docker container func getDownloadMD5(filename string) []byte { var out bytes.Buffer cmd := exec.Command("docker", "exec", "-i", "quic-test-selenium", "md5sum", "/home/seluser/Downloads/"+filename) @@ -204,3 +253,24 @@ func getDownloadMD5(filename string) []byte { Expect(err).NotTo(HaveOccurred()) return res } + +// getFileMD5 gets the md5 sum of a file on the local file system +func getFileMD5(filepath string) []byte { + var result []byte + file, err := os.Open(filepath) + Expect(err).ToNot(HaveOccurred()) + defer file.Close() + + hash := md5.New() + _, err = io.Copy(hash, file) + Expect(err).ToNot(HaveOccurred()) + return hash.Sum(result) +} + +// copyFileToDocker copies a file from the local file system into the /home/seluser/ directory in the docker container +func copyFileToDocker(filepath string) { + cmd := exec.Command("docker", "cp", filepath, "quic-test-selenium:/home/seluser/") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + Eventually(session).Should(gexec.Exit(0)) +}