Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 10, 22:30 UTC
| 1 | // Copyright 2015 Matthew Holt and The Caddy Authors |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package caddy |
| 16 | |
| 17 | import ( |
| 18 | "bytes" |
| 19 | "strings" |
| 20 | "testing" |
| 21 | |
| 22 | "go.uber.org/zap" |
| 23 | "go.uber.org/zap/zapcore" |
| 24 | |
| 25 | "github.com/caddyserver/caddy/v2/internal" |
| 26 | ) |
| 27 | |
| 28 | func TestCustomLog_loggerAllowed(t *testing.T) { |
| 29 | type fields struct { |
| 30 | BaseLog BaseLog |
| 31 | Include []string |
| 32 | Exclude []string |
| 33 | } |
| 34 | type args struct { |
| 35 | name string |
| 36 | isModule bool |
| 37 | } |
| 38 | tests := []struct { |
| 39 | name string |
| 40 | fields fields |
| 41 | args args |
| 42 | want bool |
| 43 | }{ |
| 44 | { |
| 45 | name: "include", |
| 46 | fields: fields{ |
| 47 | Include: []string{"foo"}, |
| 48 | }, |
| 49 | args: args{ |
| 50 | name: "foo", |
| 51 | isModule: true, |
| 52 | }, |
| 53 | want: true, |
| 54 | }, |
| 55 | { |
| 56 | name: "exclude", |
| 57 | fields: fields{ |
| 58 | Exclude: []string{"foo"}, |
| 59 | }, |
| 60 | args: args{ |
| 61 | name: "foo", |
| 62 | isModule: true, |
| 63 | }, |
| 64 | want: false, |
| 65 | }, |
| 66 | { |
| 67 | name: "include and exclude", |
| 68 | fields: fields{ |
| 69 | Include: []string{"foo"}, |
| 70 | Exclude: []string{"foo"}, |
| 71 | }, |
| 72 | args: args{ |
| 73 | name: "foo", |
| 74 | isModule: true, |
| 75 | }, |
| 76 | want: false, |
| 77 | }, |
| 78 | { |
| 79 | name: "include and exclude (longer namespace)", |
| 80 | fields: fields{ |
| 81 | Include: []string{"foo.bar"}, |
| 82 | Exclude: []string{"foo"}, |
| 83 | }, |
| 84 | args: args{ |
| 85 | name: "foo.bar", |
| 86 | isModule: true, |
| 87 | }, |
| 88 | want: true, |
| 89 | }, |
| 90 | { |
| 91 | name: "include module from parent", |
| 92 | fields: fields{ |
| 93 | Include: []string{"foo"}, |
| 94 | Exclude: []string{}, |
| 95 | }, |
| 96 | args: args{ |
| 97 | name: "foo.bar", |
| 98 | isModule: true, |
| 99 | }, |
| 100 | want: true, |
| 101 | }, |
| 102 | { |
| 103 | name: "excluded module is not printed", |
| 104 | fields: fields{ |
| 105 | Include: []string{"admin.api.load"}, |
| 106 | Exclude: []string{"admin.api"}, |
| 107 | }, |
| 108 | args: args{ |
| 109 | name: "admin.api", |
| 110 | isModule: false, |
| 111 | }, |
| 112 | want: false, |
| 113 | }, |
| 114 | } |
| 115 | for _, tt := range tests { |
| 116 | t.Run(tt.name, func(t *testing.T) { |
| 117 | cl := &CustomLog{ |
| 118 | BaseLog: tt.fields.BaseLog, |
| 119 | Include: tt.fields.Include, |
| 120 | Exclude: tt.fields.Exclude, |
| 121 | } |
| 122 | if got := cl.loggerAllowed(tt.args.name, tt.args.isModule); got != tt.want { |
| 123 | t.Errorf("CustomLog.loggerAllowed() = %v, want %v", got, tt.want) |
| 124 | } |
| 125 | }) |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | func TestUnbufferDefaultLogger(t *testing.T) { |
| 130 | defaultLoggerMu.RLock() |
| 131 | origDefault := defaultLogger |
| 132 | defaultLoggerMu.RUnlock() |
| 133 | t.Cleanup(func() { |
| 134 | defaultLoggerMu.Lock() |
| 135 | defaultLogger = origDefault |
| 136 | defaultLoggerMu.Unlock() |
| 137 | }) |
| 138 | |
| 139 | // Set up an observing logger to verify buffer flushing and post-unbuffer logging |
| 140 | buf := new(bytes.Buffer) |
| 141 | destCore := zapcore.NewCore( |
| 142 | zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()), |
| 143 | zapcore.AddSync(buf), |
| 144 | zapcore.InfoLevel, |
| 145 | ) |
| 146 | destLogger := zap.New(destCore) |
| 147 | |
| 148 | defaultLoggerMu.Lock() |
| 149 | defaultLogger = &defaultCustomLog{ |
| 150 | CustomLog: &CustomLog{}, |
| 151 | logger: destLogger, |
| 152 | } |
| 153 | defaultLoggerMu.Unlock() |
| 154 | |
| 155 | // 1. Engage buffered logging |
| 156 | bufferedLogger, origLogger, _ := BufferedLog() |
| 157 | |
| 158 | // Verify default logger is now using the buffer core |
| 159 | if _, ok := Log().Core().(*internal.LogBufferCore); !ok { |
| 160 | t.Fatal("expected default logger core to be *internal.LogBufferCore") |
| 161 | } |
| 162 | |
| 163 | // 2. Log while buffered |
| 164 | bufferedLogger.Info("early startup log message") |
| 165 | |
| 166 | // Messages should not be written to destination yet while buffered |
| 167 | if buf.Len() > 0 { |
| 168 | t.Fatalf("expected destination buffer to be empty while buffered, got: %s", buf.String()) |
| 169 | } |
| 170 | |
| 171 | // 3. Unbuffer the default logger |
| 172 | UnbufferDefaultLogger(origLogger) |
| 173 | |
| 174 | // Verify default logger core is no longer LogBufferCore |
| 175 | if _, ok := Log().Core().(*internal.LogBufferCore); ok { |
| 176 | t.Fatal("expected default logger core to no longer be *internal.LogBufferCore after UnbufferDefaultLogger") |
| 177 | } |
| 178 | |
| 179 | // Verify early buffered logs were flushed to destination logger |
| 180 | if !strings.Contains(buf.String(), "early startup log message") { |
| 181 | t.Fatalf("expected destination buffer to contain early startup log message, got: %s", buf.String()) |
| 182 | } |
| 183 | |
| 184 | // 4. Log after unbuffering: should go directly to destination logger, not swallowed |
| 185 | Log().Error("startup failed error") |
| 186 | if !strings.Contains(buf.String(), "startup failed error") { |
| 187 | t.Fatalf("expected destination buffer to contain error message, got: %s", buf.String()) |
| 188 | } |
| 189 | |
| 190 | // 5. Calling UnbufferDefaultLogger again when not buffered should be a safe no-op |
| 191 | UnbufferDefaultLogger(origLogger) |
| 192 | if _, ok := Log().Core().(*internal.LogBufferCore); ok { |
| 193 | t.Fatal("unexpected buffer core after second unbuffer call") |
| 194 | } |
| 195 | } |