|
@@ -8,10 +8,12 @@ import (
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
|
|
|
|
|
|
+ "fmt"
|
|
"github.com/flashmob/go-guerrilla/backends"
|
|
"github.com/flashmob/go-guerrilla/backends"
|
|
"github.com/flashmob/go-guerrilla/log"
|
|
"github.com/flashmob/go-guerrilla/log"
|
|
"github.com/flashmob/go-guerrilla/mail"
|
|
"github.com/flashmob/go-guerrilla/mail"
|
|
"github.com/flashmob/go-guerrilla/mocks"
|
|
"github.com/flashmob/go-guerrilla/mocks"
|
|
|
|
+ "net"
|
|
)
|
|
)
|
|
|
|
|
|
// getMockServerConfig gets a mock ServerConfig struct used for creating a new server
|
|
// getMockServerConfig gets a mock ServerConfig struct used for creating a new server
|
|
@@ -144,5 +146,128 @@ func TestXClient(t *testing.T) {
|
|
wg.Wait() // wait for handleClient to exit
|
|
wg.Wait() // wait for handleClient to exit
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// The backend gateway should time out after 1 second because it sleeps for 2 sec.
|
|
|
|
+// The transaction should wait until finished, and then test to see if we can do
|
|
|
|
+// a second transaction
|
|
|
|
+func TestGatewayTimeout(t *testing.T) {
|
|
|
|
+
|
|
|
|
+ bcfg := backends.BackendConfig{
|
|
|
|
+ "save_workers_size": 1,
|
|
|
|
+ "save_process": "HeadersParser|Debugger",
|
|
|
|
+ "log_received_mails": true,
|
|
|
|
+ "primary_mail_host": "example.com",
|
|
|
|
+ "gw_save_timeout": "1s",
|
|
|
|
+ "gw_val_rcpt_timeout": "1s",
|
|
|
|
+ "sleep_seconds": 2,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cfg := &AppConfig{
|
|
|
|
+ LogFile: log.OutputOff.String(),
|
|
|
|
+ AllowedHosts: []string{"grr.la"},
|
|
|
|
+ }
|
|
|
|
+ cfg.BackendConfig = bcfg
|
|
|
|
+
|
|
|
|
+ d := Daemon{Config: cfg}
|
|
|
|
+ err := d.Start()
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Error("server didn't start")
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ conn, err := net.Dial("tcp", "127.0.0.1:2525")
|
|
|
|
+ if err != nil {
|
|
|
|
+
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ in := bufio.NewReader(conn)
|
|
|
|
+ str, err := in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "HELO host\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ // perform 2 transactions
|
|
|
|
+ // both should panic.
|
|
|
|
+ for i := 0; i < 2; i++ {
|
|
|
|
+ fmt.Fprint(conn, "MAIL FROM:<[email protected]>r\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "RCPT TO:[email protected]\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "DATA\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "Subject: Test subject\r\n")
|
|
|
|
+ fmt.Fprint(conn, "\r\n")
|
|
|
|
+ fmt.Fprint(conn, "A an email body\r\n")
|
|
|
|
+ fmt.Fprint(conn, ".\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ expect := "transaction timeout"
|
|
|
|
+ if strings.Index(str, expect) == -1 {
|
|
|
|
+ t.Error("Expected the reply to have'", expect, "'but got", str)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ _ = str
|
|
|
|
+
|
|
|
|
+ d.Shutdown()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// The processor will panic and gateway should recover from it
|
|
|
|
+func TestGatewayPanic(t *testing.T) {
|
|
|
|
+ bcfg := backends.BackendConfig{
|
|
|
|
+ "save_workers_size": 1,
|
|
|
|
+ "save_process": "HeadersParser|Debugger",
|
|
|
|
+ "log_received_mails": true,
|
|
|
|
+ "primary_mail_host": "example.com",
|
|
|
|
+ "gw_save_timeout": "2s",
|
|
|
|
+ "gw_val_rcpt_timeout": "2s",
|
|
|
|
+ "sleep_seconds": 1,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cfg := &AppConfig{
|
|
|
|
+ LogFile: log.OutputOff.String(),
|
|
|
|
+ AllowedHosts: []string{"grr.la"},
|
|
|
|
+ }
|
|
|
|
+ cfg.BackendConfig = bcfg
|
|
|
|
+
|
|
|
|
+ d := Daemon{Config: cfg}
|
|
|
|
+ err := d.Start()
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Error("server didn't start")
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ conn, err := net.Dial("tcp", "127.0.0.1:2525")
|
|
|
|
+ if err != nil {
|
|
|
|
+
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ in := bufio.NewReader(conn)
|
|
|
|
+ str, err := in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "HELO host\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ // perform 2 transactions
|
|
|
|
+ // both should timeout. The reason why 2 is because we want to make
|
|
|
|
+ // sure that the client waits until processing finishes, and the
|
|
|
|
+ // timeout event is captured.
|
|
|
|
+ for i := 0; i < 2; i++ {
|
|
|
|
+ fmt.Fprint(conn, "MAIL FROM:<[email protected]>r\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "RCPT TO:[email protected]\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "DATA\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ fmt.Fprint(conn, "Subject: Test subject\r\n")
|
|
|
|
+ fmt.Fprint(conn, "\r\n")
|
|
|
|
+ fmt.Fprint(conn, "A an email body\r\n")
|
|
|
|
+ fmt.Fprint(conn, ".\r\n")
|
|
|
|
+ str, err = in.ReadString('\n')
|
|
|
|
+ expect := "storage failed"
|
|
|
|
+ if strings.Index(str, expect) == -1 {
|
|
|
|
+ t.Error("Expected the reply to have'", expect, "'but got", str)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ _ = str
|
|
|
|
+ d.Shutdown()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
// TODO
|
|
// TODO
|
|
// - test github issue #44 and #42
|
|
// - test github issue #44 and #42
|