github.com/tommi2day/gomodules@v1.13.2-0.20240423190010-b7d55d252a27/maillib/mail_docker_test.go (about) 1 package maillib 2 3 import ( 4 "fmt" 5 "net" 6 "os" 7 "time" 8 9 "github.com/tommi2day/gomodules/common" 10 "github.com/tommi2day/gomodules/test" 11 12 "github.com/ory/dockertest/v3" 13 "github.com/ory/dockertest/v3/docker" 14 ) 15 16 const mailRepo = "docker.io/mailserver/docker-mailserver" 17 const mailRepoTag = "13.2.0" 18 const smtpPort = 31025 19 const imapPort = 31143 20 const sslPort = 31465 21 const tlsPort = 31587 22 const imapsPort = 31993 23 const containerTimeout = 120 24 25 var mailContainerName string 26 var mailContainer *dockertest.Resource 27 var mailServer = "127.0.0.1" 28 29 // prepareContainer create an Oracle Docker Container 30 func prepareMailContainer() (container *dockertest.Resource, err error) { 31 if os.Getenv("SKIP_MAIL") != "" { 32 err = fmt.Errorf("skipping Mail Container in CI environment") 33 return 34 } 35 // align hostname in CI 36 host := os.Getenv("MAIL_HOST") 37 if host != "" { 38 mailServer = host 39 } 40 mailContainerName = os.Getenv("MAIL_CONTAINER_NAME") 41 if mailContainerName == "" { 42 mailContainerName = "mailserver" 43 } 44 pool, err := common.GetDockerPool() 45 if err != nil { 46 err = fmt.Errorf("cannot attach to docker: %v", err) 47 return 48 } 49 50 vendorImagePrefix := os.Getenv("VENDOR_IMAGE_PREFIX") 51 repoString := vendorImagePrefix + mailRepo 52 fmt.Printf("Try to start docker container for %s:%s\n", repoString, mailRepoTag) 53 container, err = pool.RunWithOptions(&dockertest.RunOptions{ 54 Repository: repoString, 55 Tag: mailRepoTag, 56 57 Env: []string{ 58 "LOG_LEVEL=debug", 59 "ONE_DIR=1", 60 "POSTFIX_INET_PROTOCOLS=ipv4", 61 "PERMIT_DOCKER=connected-networks", 62 "ENABLE_OPENDKIM=0", 63 "ENABLE_OPENDMARC=0", 64 "ENABLE_AMAVIS=0", 65 "SSL_TYPE=manual", 66 "SSL_CERT_PATH=/tmp/custom-certs/" + mailHostname + "-full.crt", 67 "SSL_KEY_PATH=/tmp/custom-certs/" + mailHostname + ".key", 68 }, 69 Hostname: mailHostname, 70 Name: mailContainerName, 71 Mounts: []string{ 72 test.TestDir + "/docker/mail/config:/tmp/docker-mailserver/", 73 test.TestDir + "/docker/mail/ssl:/tmp/custom-certs/:ro", 74 }, 75 /* 76 CapAdd: []string{ 77 "NET_ADMIN", 78 }, 79 */ 80 ExposedPorts: []string{"25", "143", "465", "587", "993"}, 81 PortBindings: map[docker.Port][]docker.PortBinding{ 82 "25": { 83 {HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", smtpPort)}, 84 }, 85 "143": { 86 {HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", imapPort)}, 87 }, 88 "465": { 89 {HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", sslPort)}, 90 }, 91 "587": { 92 {HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", tlsPort)}, 93 }, 94 "993": { 95 {HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", imapsPort)}, 96 }, 97 }, 98 }, func(config *docker.HostConfig) { 99 // set AutoRemove to true so that stopped container goes away by itself 100 config.AutoRemove = true 101 config.RestartPolicy = docker.RestartPolicy{Name: "no"} 102 }) 103 104 if err != nil { 105 err = fmt.Errorf("error starting mailserver docker container: %v", err) 106 return 107 } 108 109 pool.MaxWait = containerTimeout * time.Second 110 fmt.Printf("Wait to successfully connect to Mailserver with %s:%d (max %ds)...\n", mailServer, tlsPort, containerTimeout) 111 start := time.Now() 112 var c net.Conn 113 if err = pool.Retry(func() error { 114 c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", mailServer, tlsPort)) 115 if err != nil { 116 fmt.Printf("Err:%s\n", err) 117 } 118 return err 119 }); err != nil { 120 fmt.Printf("Could not connect to Mail Container: %s", err) 121 return 122 } 123 _ = c.Close() 124 125 // show env 126 // cmdout, _, err=execCmd(container, []string{"bash", "-c", "env|sort"}) 127 128 // wait 20s to init container 129 time.Sleep(20 * time.Second) 130 elapsed := time.Since(start) 131 fmt.Printf("Mail Container is available after %s\n", elapsed.Round(time.Millisecond)) 132 133 // test main.cf 134 cmdout := "" 135 cmd := []string{"/bin/ls", "-l", "/etc/postfix/*"} 136 cmdout, _, err = common.ExecDockerCmd(container, cmd) 137 if err != nil { 138 fmt.Printf("Exec Error %s", err) 139 } else { 140 fmt.Printf("Cmd:%v\n %s", cmd, cmdout) 141 } 142 err = nil 143 return 144 }