summaryrefslogtreecommitdiffstats
path: root/store/storetest/docker.go
diff options
context:
space:
mode:
Diffstat (limited to 'store/storetest/docker.go')
-rw-r--r--store/storetest/docker.go141
1 files changed, 141 insertions, 0 deletions
diff --git a/store/storetest/docker.go b/store/storetest/docker.go
new file mode 100644
index 000000000..ef34541e4
--- /dev/null
+++ b/store/storetest/docker.go
@@ -0,0 +1,141 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package storetest
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "os/exec"
+ "strings"
+ "time"
+
+ l4g "github.com/alecthomas/log4go"
+
+ "github.com/mattermost/mattermost-server/model"
+)
+
+type Container struct {
+ Id string
+ NetworkSettings struct {
+ Ports map[string][]struct {
+ HostPort string
+ }
+ }
+}
+
+type RunningContainer struct {
+ Container
+}
+
+func (c *RunningContainer) Stop() error {
+ l4g.Info("removing container: %v", c.Id)
+ return exec.Command("docker", "rm", "-f", c.Id).Run()
+}
+
+func NewMySQLContainer() (*RunningContainer, *model.SqlSettings, error) {
+ container, err := runContainer([]string{
+ "-e", "MYSQL_ROOT_PASSWORD=mostest",
+ "-e", "MYSQL_USER=mmuser",
+ "-e", "MYSQL_PASSWORD=mostest",
+ "-e", "MYSQL_DATABASE=mattermost_test",
+ "--tmpfs", "/var/lib/mysql",
+ "mysql:5.7",
+ })
+ if err != nil {
+ return nil, nil, err
+ }
+ l4g.Info("Waiting for mysql connectivity")
+ port := container.NetworkSettings.Ports["3306/tcp"][0].HostPort
+ if err := waitForPort(port); err != nil {
+ container.Stop()
+ return nil, nil, err
+ }
+ return container, databaseSettings("mysql", "mmuser:mostest@tcp(127.0.0.1:"+port+")/mattermost_test?charset=utf8mb4,utf8"), nil
+}
+
+func NewPostgreSQLContainer() (*RunningContainer, *model.SqlSettings, error) {
+ container, err := runContainer([]string{
+ "-e", "POSTGRES_USER=mmuser",
+ "-e", "POSTGRES_PASSWORD=mostest",
+ "--tmpfs", "/var/lib/postgresql/data",
+ "postgres:9.4",
+ })
+ if err != nil {
+ return nil, nil, err
+ }
+ l4g.Info("Waiting for postgres connectivity")
+ port := container.NetworkSettings.Ports["5432/tcp"][0].HostPort
+ if err := waitForPort(port); err != nil {
+ container.Stop()
+ return nil, nil, err
+ }
+ return container, databaseSettings("postgres", "postgres://mmuser:mostest@127.0.0.1:"+port+"?sslmode=disable"), nil
+}
+
+func databaseSettings(driver, dataSource string) *model.SqlSettings {
+ settings := &model.SqlSettings{
+ DriverName: &driver,
+ DataSource: &dataSource,
+ DataSourceReplicas: []string{},
+ DataSourceSearchReplicas: []string{},
+ MaxIdleConns: new(int),
+ MaxOpenConns: new(int),
+ Trace: false,
+ AtRestEncryptKey: model.NewRandomString(32),
+ QueryTimeout: new(int),
+ }
+ *settings.MaxIdleConns = 10
+ *settings.MaxOpenConns = 100
+ *settings.QueryTimeout = 10
+ return settings
+}
+
+func runContainer(args []string) (*RunningContainer, error) {
+ name := "mattermost-storetest-" + model.NewId()
+ dockerArgs := append([]string{"run", "-d", "-P", "--name", name}, args...)
+ out, err := exec.Command("docker", dockerArgs...).Output()
+ if err != nil {
+ return nil, err
+ }
+ id := strings.TrimSpace(string(out))
+ out, err = exec.Command("docker", "inspect", id).Output()
+ if err != nil {
+ exec.Command("docker", "rm", "-f", id).Run()
+ return nil, err
+ }
+ var containers []Container
+ if err := json.Unmarshal(out, &containers); err != nil {
+ exec.Command("docker", "rm", "-f", id).Run()
+ return nil, err
+ }
+ l4g.Info("running container: %v", id)
+ return &RunningContainer{containers[0]}, nil
+}
+
+func waitForPort(port string) error {
+ for i := 0; i < 120; i++ {
+ conn, err := net.DialTimeout("tcp", "127.0.0.1:"+port, time.Minute)
+ if err != nil {
+ return err
+ }
+ if err = conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500)); err != nil {
+ return err
+ }
+ _, err = conn.Read(make([]byte, 1))
+ conn.Close()
+ if err == nil {
+ return nil
+ }
+ if e, ok := err.(net.Error); ok && e.Timeout() {
+ return nil
+ }
+ if err != io.EOF {
+ return err
+ }
+ time.Sleep(time.Millisecond * 200)
+ }
+ return fmt.Errorf("timeout waiting for port %v", port)
+}