11//go:build integration && (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris)
2- // +build integration
3- // +build darwin dragonfly freebsd linux netbsd openbsd solaris
42
53/*
64Maddy Mail Server - Composable all-in-one email server.
7- Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
5+ Copyright © 2019-2026 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
86
97This program is free software: you can redistribute it and/or modify
108it under the terms of the GNU General Public License as published by
@@ -26,9 +24,9 @@ package tests_test
2624
2725import (
2826 "bufio"
27+ "bytes"
2928 "errors"
3029 "flag"
31- "io/ioutil"
3230 "os"
3331 "os/exec"
3432 "os/user"
@@ -47,7 +45,8 @@ func init() {
4745 flag .StringVar (& DovecotExecutable , "integration.dovecot" , "dovecot" , "path to dovecot executable for interop tests" )
4846}
4947
50- const dovecotConf = `base_dir = $ROOT/run/
48+ const dovecotConf = `
49+ base_dir = $ROOT/run/
5150state_dir = $ROOT/lib/
5251log_path = /dev/stderr
5352ssl = no
@@ -56,12 +55,14 @@ default_internal_user = $USER
5655default_internal_group = $GROUP
5756default_login_user = $USER
5857
58+ auth_failure_delay = 0
59+
5960passdb {
6061 driver = passwd-file
6162 args = $ROOT/passwd
6263}
6364
64- userdb {
65+ userdb file {
6566 driver = passwd-file
6667 args = $ROOT/passwd
6768}
@@ -78,7 +79,7 @@ protocols = imap
7879service imap-login {
7980 chroot =
8081 inet_listener imap {
81- address = 127.0.0.1
82+ listen = 127.0.0.1
8283 port = 0
8384 }
8485}
@@ -95,8 +96,64 @@ auth_verbose_passwords = yes
9596mail_debug = yes
9697`
9798
99+ const dovecotConf24 = `dovecot_config_version = 2.4.0
100+ dovecot_storage_version = 2.4.0
101+
102+ base_dir = $ROOT/run/
103+ state_dir = $ROOT/lib/
104+ mail_plugin_dir = $ROOT/lib/
105+ login_plugin_dir = $ROOT/lib/
106+ log_path = /dev/stderr
107+ ssl = no
108+
109+ default_internal_user = $USER
110+ default_internal_group = $GROUP
111+ default_login_user = $USER
112+
113+ auth_failure_delay = 0
114+
115+ passdb file {
116+ driver = passwd-file
117+ passwd_file_path = $ROOT/passwd
118+ }
119+
120+ userdb file {
121+ driver = passwd-file
122+ passwd_file_path = $ROOT/passwd
123+ }
124+
125+ service auth {
126+ unix_listener auth {
127+ mode = 0666
128+ }
129+ }
130+
131+ # Turn on debugging information, to help troubleshooting issues.
132+ auth_verbose = yes
133+ auth_debug = yes
134+ auth_debug_passwords = yes
135+ auth_verbose_passwords = yes
136+ mail_debug = yes
137+ `
138+
98139const dovecotPasswd = `tester:{plain}123456:1000:1000::/home/user`
99140
141+ func isDovecot24 (t * testing.T , dovecotExec string ) bool {
142+ cmd := exec .Command (dovecotExec , "--version" )
143+ var stdout bytes.Buffer
144+ cmd .Stdout = & stdout
145+ if err := cmd .Run (); err != nil {
146+ t .Fatal (err )
147+ }
148+
149+ version , _ , _ := strings .Cut (stdout .String (), "-" )
150+ t .Log ("Dovecot version:" , stdout .String ())
151+
152+ parts := strings .SplitN (version , "." , 3 )
153+
154+ return len (parts ) >= 2 && parts [0 ] == "2" && parts [1 ] >= "4"
155+ }
156+
100157func runDovecot (t * testing.T ) (string , * exec.Cmd ) {
101158 dovecotExec , err := exec .LookPath (DovecotExecutable )
102159 if err != nil {
@@ -117,15 +174,20 @@ func runDovecot(t *testing.T) (string, *exec.Cmd) {
117174 t .Fatal (err )
118175 }
119176
177+ dovecotConfTemplate := dovecotConf
178+ if isDovecot24 (t , dovecotExec ) {
179+ dovecotConfTemplate = dovecotConf24
180+ }
181+
120182 dovecotConf := strings .NewReplacer (
121183 "$ROOT" , tempDir ,
122184 "$USER" , curUser .Username ,
123- "$GROUP" , curGroup .Name ).Replace (dovecotConf )
124- err = ioutil .WriteFile (filepath .Join (tempDir , "dovecot.conf" ), []byte (dovecotConf ), os .ModePerm )
185+ "$GROUP" , curGroup .Name ).Replace (dovecotConfTemplate )
186+ err = os .WriteFile (filepath .Join (tempDir , "dovecot.conf" ), []byte (dovecotConf ), os .ModePerm )
125187 if err != nil {
126188 t .Fatal (err )
127189 }
128- err = ioutil .WriteFile (filepath .Join (tempDir , "passwd" ), []byte (dovecotPasswd ), os .ModePerm )
190+ err = os .WriteFile (filepath .Join (tempDir , "passwd" ), []byte (dovecotPasswd ), os .ModePerm )
129191 if err != nil {
130192 t .Fatal (err )
131193 }
@@ -147,9 +209,14 @@ func runDovecot(t *testing.T) (string, *exec.Cmd) {
147209 for scnr .Scan () {
148210 line := scnr .Text ()
149211
150- // One of messages printed near completing initialization.
212+ // One of messages printed near completing initialization (Dovecot 2.3 or older)
151213 if strings .Contains (line , "starting up for imap" ) {
152- time .Sleep (500 * time .Millisecond )
214+ time .Sleep (500 * time .Millisecond )
215+ ready <- struct {}{}
216+ }
217+ // Dovecot 2.4+
218+ if strings .Contains (line , "starting up without any protocols" ) {
219+ time .Sleep (500 * time .Millisecond )
153220 ready <- struct {}{}
154221 }
155222
0 commit comments