github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/daemon/logger/syslog/syslog_test.go (about) 1 package syslog // import "github.com/docker/docker/daemon/logger/syslog" 2 3 import ( 4 "log" 5 "net" 6 "os" 7 "path/filepath" 8 "reflect" 9 "runtime" 10 "strings" 11 "testing" 12 13 syslog "github.com/RackSec/srslog" 14 ) 15 16 func functionMatches(expectedFun interface{}, actualFun interface{}) bool { 17 return reflect.ValueOf(expectedFun).Pointer() == reflect.ValueOf(actualFun).Pointer() 18 } 19 20 func TestParseLogFormat(t *testing.T) { 21 formatter, framer, err := parseLogFormat("rfc5424", "udp") 22 if err != nil || !functionMatches(rfc5424formatterWithAppNameAsTag, formatter) || 23 !functionMatches(syslog.DefaultFramer, framer) { 24 t.Fatal("Failed to parse rfc5424 format", err, formatter, framer) 25 } 26 27 formatter, framer, err = parseLogFormat("rfc5424", "tcp+tls") 28 if err != nil || !functionMatches(rfc5424formatterWithAppNameAsTag, formatter) || 29 !functionMatches(syslog.RFC5425MessageLengthFramer, framer) { 30 t.Fatal("Failed to parse rfc5424 format", err, formatter, framer) 31 } 32 33 formatter, framer, err = parseLogFormat("rfc5424micro", "udp") 34 if err != nil || !functionMatches(rfc5424microformatterWithAppNameAsTag, formatter) || 35 !functionMatches(syslog.DefaultFramer, framer) { 36 t.Fatal("Failed to parse rfc5424 (microsecond) format", err, formatter, framer) 37 } 38 39 formatter, framer, err = parseLogFormat("rfc5424micro", "tcp+tls") 40 if err != nil || !functionMatches(rfc5424microformatterWithAppNameAsTag, formatter) || 41 !functionMatches(syslog.RFC5425MessageLengthFramer, framer) { 42 t.Fatal("Failed to parse rfc5424 (microsecond) format", err, formatter, framer) 43 } 44 45 formatter, framer, err = parseLogFormat("rfc3164", "") 46 if err != nil || !functionMatches(syslog.RFC3164Formatter, formatter) || 47 !functionMatches(syslog.DefaultFramer, framer) { 48 t.Fatal("Failed to parse rfc3164 format", err, formatter, framer) 49 } 50 51 formatter, framer, err = parseLogFormat("", "") 52 if err != nil || !functionMatches(syslog.UnixFormatter, formatter) || 53 !functionMatches(syslog.DefaultFramer, framer) { 54 t.Fatal("Failed to parse empty format", err, formatter, framer) 55 } 56 57 formatter, framer, err = parseLogFormat("invalid", "") 58 if err == nil { 59 t.Fatal("Failed to parse invalid format", err, formatter, framer) 60 } 61 } 62 63 func TestValidateLogOptEmpty(t *testing.T) { 64 emptyConfig := make(map[string]string) 65 if err := ValidateLogOpt(emptyConfig); err != nil { 66 t.Fatal("Failed to parse empty config", err) 67 } 68 } 69 70 func TestValidateSyslogAddress(t *testing.T) { 71 const sockPlaceholder = "/TEMPDIR/socket.sock" 72 s, err := os.Create(filepath.Join(t.TempDir(), "socket.sock")) 73 if err != nil { 74 log.Fatal(err) 75 } 76 socketPath := s.Name() 77 _ = s.Close() 78 79 tests := []struct { 80 address string 81 expectedErr string 82 skipOn string 83 }{ 84 { 85 address: "this is not an uri", 86 expectedErr: "unsupported scheme: ''", 87 }, 88 { 89 address: "corrupted:42", 90 expectedErr: "unsupported scheme: 'corrupted'", 91 }, 92 { 93 address: "unix://" + sockPlaceholder, 94 skipOn: "windows", // doesn't work with unix:// sockets 95 }, 96 { 97 address: "unix:///does_not_exist", 98 expectedErr: "no such file or directory", 99 skipOn: "windows", // error message differs 100 }, 101 { 102 address: "tcp://1.2.3.4", 103 }, 104 { 105 address: "udp://1.2.3.4", 106 }, 107 { 108 address: "http://1.2.3.4", 109 expectedErr: "unsupported scheme: 'http'", 110 }, 111 } 112 for _, tc := range tests { 113 tc := tc 114 if tc.skipOn == runtime.GOOS { 115 continue 116 } 117 t.Run(tc.address, func(t *testing.T) { 118 address := strings.Replace(tc.address, sockPlaceholder, socketPath, 1) 119 err := ValidateLogOpt(map[string]string{"syslog-address": address}) 120 if tc.expectedErr != "" { 121 if err == nil { 122 t.Fatal("expected an error, got nil") 123 } 124 if !strings.Contains(err.Error(), tc.expectedErr) { 125 t.Fatalf("expected error to contain '%s', got: '%s'", tc.expectedErr, err) 126 } 127 } else if err != nil { 128 t.Fatalf("unexpected error: '%s'", err) 129 } 130 }) 131 } 132 } 133 134 func TestParseAddressDefaultPort(t *testing.T) { 135 _, address, err := parseAddress("tcp://1.2.3.4") 136 if err != nil { 137 t.Fatal(err) 138 } 139 140 _, port, _ := net.SplitHostPort(address) 141 if port != defaultPort { 142 t.Fatalf("Expected to default to port %s. It used port %s", defaultPort, port) 143 } 144 } 145 146 func TestValidateSyslogFacility(t *testing.T) { 147 err := ValidateLogOpt(map[string]string{ 148 "syslog-facility": "Invalid facility", 149 }) 150 if err == nil { 151 t.Fatal("Expected error if facility level is invalid") 152 } 153 } 154 155 func TestValidateLogOptSyslogFormat(t *testing.T) { 156 err := ValidateLogOpt(map[string]string{ 157 "syslog-format": "Invalid format", 158 }) 159 if err == nil { 160 t.Fatal("Expected error if format is invalid") 161 } 162 } 163 164 func TestValidateLogOpt(t *testing.T) { 165 err := ValidateLogOpt(map[string]string{ 166 "env": "http://127.0.0.1", 167 "env-regex": "abc", 168 "labels": "labelA", 169 "labels-regex": "def", 170 "syslog-address": "udp://1.2.3.4:1111", 171 "syslog-facility": "daemon", 172 "syslog-tls-ca-cert": "/etc/ca-certificates/custom/ca.pem", 173 "syslog-tls-cert": "/etc/ca-certificates/custom/cert.pem", 174 "syslog-tls-key": "/etc/ca-certificates/custom/key.pem", 175 "syslog-tls-skip-verify": "true", 176 "tag": "true", 177 "syslog-format": "rfc3164", 178 }) 179 if err != nil { 180 t.Fatal(err) 181 } 182 183 err = ValidateLogOpt(map[string]string{ 184 "not-supported-option": "a", 185 }) 186 if err == nil { 187 t.Fatal("Expecting error on unsupported options") 188 } 189 }