mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			213 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//+build linux darwin
 | 
						|
 | 
						|
package httpserver
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"io/ioutil"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"strings"
 | 
						|
	"sync"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"gopkg.in/mcuadros/go-syslog.v2"
 | 
						|
	"gopkg.in/mcuadros/go-syslog.v2/format"
 | 
						|
)
 | 
						|
 | 
						|
func TestLoggingToStdout(t *testing.T) {
 | 
						|
	testCases := []struct {
 | 
						|
		Output         string
 | 
						|
		ExpectedOutput string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			Output:         "stdout",
 | 
						|
			ExpectedOutput: "Hello world logged to stdout",
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, testCase := range testCases {
 | 
						|
		output := captureStdout(func() {
 | 
						|
			logger := Logger{Output: testCase.Output, fileMu: new(sync.RWMutex)}
 | 
						|
 | 
						|
			if err := logger.Start(); err != nil {
 | 
						|
				t.Fatalf("Got unexpected error: %v", err)
 | 
						|
			}
 | 
						|
 | 
						|
			logger.Println(testCase.ExpectedOutput)
 | 
						|
		})
 | 
						|
 | 
						|
		if !strings.Contains(output, testCase.ExpectedOutput) {
 | 
						|
			t.Fatalf("Test #%d: Expected output to contain: %s, got: %s", i, testCase.ExpectedOutput, output)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestLoggingToStderr(t *testing.T) {
 | 
						|
 | 
						|
	testCases := []struct {
 | 
						|
		Output         string
 | 
						|
		ExpectedOutput string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			Output:         "stderr",
 | 
						|
			ExpectedOutput: "Hello world logged to stderr",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			Output:         "",
 | 
						|
			ExpectedOutput: "Hello world logged to stderr #2",
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, testCase := range testCases {
 | 
						|
		output := captureStderr(func() {
 | 
						|
			logger := Logger{Output: testCase.Output, fileMu: new(sync.RWMutex)}
 | 
						|
 | 
						|
			if err := logger.Start(); err != nil {
 | 
						|
				t.Fatalf("Got unexpected error: %v", err)
 | 
						|
			}
 | 
						|
 | 
						|
			logger.Println(testCase.ExpectedOutput)
 | 
						|
		})
 | 
						|
 | 
						|
		if !strings.Contains(output, testCase.ExpectedOutput) {
 | 
						|
			t.Fatalf("Test #%d: Expected output to contain: %s, got: %s", i, testCase.ExpectedOutput, output)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestLoggingToFile(t *testing.T) {
 | 
						|
	file := filepath.Join(os.TempDir(), "access.log")
 | 
						|
	expectedOutput := "Hello world written to file"
 | 
						|
 | 
						|
	logger := Logger{Output: file}
 | 
						|
 | 
						|
	if err := logger.Start(); err != nil {
 | 
						|
		t.Fatalf("Got unexpected error during logger start: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	logger.Print(expectedOutput)
 | 
						|
 | 
						|
	content, err := ioutil.ReadFile(file)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Could not read log file content: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	if !bytes.Contains(content, []byte(expectedOutput)) {
 | 
						|
		t.Fatalf("Expected log file to contain: %s, got: %s", expectedOutput, string(content))
 | 
						|
	}
 | 
						|
 | 
						|
	os.Remove(file)
 | 
						|
}
 | 
						|
 | 
						|
func TestLoggingToSyslog(t *testing.T) {
 | 
						|
 | 
						|
	testCases := []struct {
 | 
						|
		Output         string
 | 
						|
		ExpectedOutput string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			Output:         "syslog://127.0.0.1:5660",
 | 
						|
			ExpectedOutput: "Hello world! Test #1 over tcp",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			Output:         "syslog+tcp://127.0.0.1:5661",
 | 
						|
			ExpectedOutput: "Hello world! Test #2 over tcp",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			Output:         "syslog+udp://127.0.0.1:5662",
 | 
						|
			ExpectedOutput: "Hello world! Test #3 over udp",
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, testCase := range testCases {
 | 
						|
 | 
						|
		ch := make(chan format.LogParts, 256)
 | 
						|
		server, err := bootServer(testCase.Output, ch)
 | 
						|
		defer server.Kill()
 | 
						|
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("Test #%d: expected no error during syslog server boot, got: %v", i, err)
 | 
						|
		}
 | 
						|
 | 
						|
		logger := Logger{Output: testCase.Output, fileMu: new(sync.RWMutex)}
 | 
						|
 | 
						|
		if err := logger.Start(); err != nil {
 | 
						|
			t.Errorf("Test #%d: expected no error during logger start, got: %v", i, err)
 | 
						|
		}
 | 
						|
 | 
						|
		defer logger.Close()
 | 
						|
 | 
						|
		logger.Print(testCase.ExpectedOutput)
 | 
						|
 | 
						|
		actual := <-ch
 | 
						|
 | 
						|
		if content, ok := actual["content"].(string); ok {
 | 
						|
			if !strings.Contains(content, testCase.ExpectedOutput) {
 | 
						|
				t.Errorf("Test #%d: expected server to capture content: %s, but got: %s", i, testCase.ExpectedOutput, content)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			t.Errorf("Test #%d: expected server to capture content but got: %v", i, actual)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func bootServer(location string, ch chan format.LogParts) (*syslog.Server, error) {
 | 
						|
	address := parseSyslogAddress(location)
 | 
						|
 | 
						|
	if address == nil {
 | 
						|
		return nil, fmt.Errorf("Could not parse syslog address: %s", location)
 | 
						|
	}
 | 
						|
 | 
						|
	server := syslog.NewServer()
 | 
						|
	server.SetFormat(syslog.Automatic)
 | 
						|
 | 
						|
	switch address.network {
 | 
						|
	case "tcp":
 | 
						|
		server.ListenTCP(address.address)
 | 
						|
	case "udp":
 | 
						|
		server.ListenUDP(address.address)
 | 
						|
	}
 | 
						|
 | 
						|
	server.SetHandler(syslog.NewChannelHandler(ch))
 | 
						|
 | 
						|
	if err := server.Boot(); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	return server, nil
 | 
						|
}
 | 
						|
 | 
						|
func captureStdout(f func()) string {
 | 
						|
	original := os.Stdout
 | 
						|
	r, w, _ := os.Pipe()
 | 
						|
 | 
						|
	os.Stdout = w
 | 
						|
 | 
						|
	f()
 | 
						|
 | 
						|
	w.Close()
 | 
						|
 | 
						|
	written, _ := ioutil.ReadAll(r)
 | 
						|
	os.Stdout = original
 | 
						|
 | 
						|
	return string(written)
 | 
						|
}
 | 
						|
 | 
						|
func captureStderr(f func()) string {
 | 
						|
	original := os.Stderr
 | 
						|
	r, w, _ := os.Pipe()
 | 
						|
 | 
						|
	os.Stderr = w
 | 
						|
 | 
						|
	f()
 | 
						|
 | 
						|
	w.Close()
 | 
						|
 | 
						|
	written, _ := ioutil.ReadAll(r)
 | 
						|
	os.Stderr = original
 | 
						|
 | 
						|
	return string(written)
 | 
						|
}
 |