Skip to content
Snippets Groups Projects
Select Git revision
  • 0f5f7351f908eebf2a645630cd48e2fda66e2d57
  • master default protected
  • 1.31
  • 4.30.1
  • 4.30.0
  • 4.29.1
  • 4.29.0
  • 4.28.0
  • 4.27.0
  • 4.26.0
  • 4.25.5
  • 4.25.4
  • 4.25.3
  • 4.25.2
  • 4.25.1
  • 4.25.0
  • 4.24.3
  • 4.24.2
  • 4.24.1
  • 4.24.0
  • 4.23.6
  • 4.23.5
  • 4.23.4
23 results

Makefile

Blame
  • runnable-mail_test.go 4.26 KiB
    // Copyright 2023 schukai GmbH
    // SPDX-License-Identifier: AGPL-3.0
    
    //go:build !bench && !race
    
    package jobqueue
    
    import (
    	"context"
    	"fmt"
    	"github.com/docker/docker/api/types"
    	"github.com/docker/docker/api/types/container"
    	"github.com/docker/docker/client"
    	"github.com/docker/go-connections/nat"
    	"github.com/stretchr/testify/assert"
    	"net"
    	"os"
    	"testing"
    	"time"
    )
    
    const DOCKER_TEST_HOST_IP = "127.0.0.1"
    
    func startTestSMTPDockerImageAndContainer(t *testing.T, port string, ctx context.Context) error {
    	t.Helper()
    
    	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
    	if err != nil {
    		return err
    	}
    
    	imageName := "axllent/mailpit"
    
    	reader, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
    	if err != nil {
    		return err
    	}
    
    	// if debug image pull, comment out the following lines
    	//_, _ = io.Copy(os.Stdout, reader)
    	_ = reader
    
    	hostConfig := &container.HostConfig{
    		PortBindings: nat.PortMap{
    			"1025/tcp": []nat.PortBinding{
    				{
    					HostIP:   DOCKER_TEST_HOST_IP,
    					HostPort: port,
    				},
    			},
    			// if you want to test the web interface, uncomment the following lines
    			//"8025/tcp": []nat.PortBinding{
    			//	{
    			//		HostIP:   DOCKER_TEST_HOST_IP,
    			//		HostPort: "8025",
    			//	},
    			//},
    		},
    	}
    
    	resp, err := cli.ContainerCreate(ctx, &container.Config{
    		Image: imageName,
    	}, hostConfig, nil, nil, "")
    
    	if err != nil {
    		return err
    	}
    
    	if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
    		return err
    	}
    
    	go func() {
    		<-ctx.Done()
    
    		timeout := 0
    		stopOptions := container.StopOptions{
    			Timeout: &timeout,
    			Signal:  "SIGKILL",
    		}
    		newCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    		defer cancel()
    		if err := cli.ContainerStop(newCtx, resp.ID, stopOptions); err != nil {
    			t.Errorf("ContainerStop returned error: %v", err)
    		}
    		if err := cli.ContainerRemove(newCtx, resp.ID, types.ContainerRemoveOptions{
    			Force: true,
    		}); err != nil {
    			t.Errorf("ContainerRemove returned error: %v", err)
    		}
    
    	}()
    
    	statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
    	select {
    	case err := <-errCh:
    		if err != nil {
    			// empty error means container exited normally (see container_wait.go)
    			if err.Error() == "" {
    				return nil
    			}
    
    			return err
    		}
    	case <-statusCh:
    
    	}
    
    	return nil
    }
    
    func TestMailRunner(t *testing.T) {
    	if os.Getenv("CI_SERVER") != "" {
    		t.Skip("Skipping test because CI_SERVER is set")
    		// TODO: run this test in CI
    	}
    
    	ctb := context.Background()
    	ctx, cancel := context.WithCancel(ctb)
    	t.Cleanup(func() {
    		cancel()
    		time.Sleep(1 * time.Second)
    	})
    
    	listener, err := net.Listen("tcp", DOCKER_TEST_HOST_IP+":0")
    	if err != nil {
    		t.Errorf("Unexpected error: %v", err)
    		return
    	}
    	portAsInt := listener.Addr().(*net.TCPAddr).Port
    	portAsString := fmt.Sprintf("%d", portAsInt)
    	_ = listener.Close()
    
    	done := make(chan bool)
    	go func() {
    		err = startTestSMTPDockerImageAndContainer(t, portAsString, ctx)
    		if err != nil {
    			t.Errorf("Unexpected error: %v", err)
    			cancel()
    		}
    		done <- true
    	}()
    
    	waitCtx, waitCancel := context.WithTimeout(ctx, 60*time.Second)
    	defer waitCancel()
    	for {
    		conn, err := net.DialTimeout("tcp", net.JoinHostPort(DOCKER_TEST_HOST_IP, portAsString), 1*time.Second)
    		if err == nil {
    			err = conn.Close()
    			assert.Nil(t, err)
    			break
    		}
    		select {
    		case <-waitCtx.Done():
    			t.Error("Timeout waiting for container service")
    			cancel()
    			return
    		default:
    			time.Sleep(1 * time.Second)
    		}
    	}
    
    	time.Sleep(1 * time.Second)
    
    	mailRunnable := &MailRunnable{
    		To:       "to@example.com",
    		From:     "from@example.com",
    		Subject:  "this is a test",
    		Body:     "this is the body",
    		Server:   DOCKER_TEST_HOST_IP,
    		Port:     portAsString,
    		Username: "",
    		Password: "",
    		Headers: map[string]string{
    			"X-Test": "test",
    		},
    	}
    
    	xtx := context.Background()
    	result, err := mailRunnable.Run(xtx)
    
    	// Assertions
    	assert.NoError(t, err)
    	assert.Equal(t, ResultStatusSuccess, result.Status)
    	assert.IsType(t, MailResult{}, result.Data)
    
    	// check result.Data contains 4 files
    	mailResult := result.Data.Sent
    	assert.Equal(t, true, mailResult)
    
    	cancel()
    
    	select {
    	case <-done:
    		time.Sleep(1 * time.Second)
    	case <-time.After(1 * time.Minute):
    		t.Error("test hangs, timeout reached")
    	}
    
    }