|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.IO; |
| 4 | +using System.Linq; |
| 5 | +using System.Text; |
| 6 | +using Amazon.Lambda.RuntimeSupport.Helpers; |
| 7 | +using Amazon.Lambda.RuntimeSupport.UnitTests.TestHelpers; |
| 8 | +using Xunit; |
| 9 | + |
| 10 | +namespace Amazon.Lambda.RuntimeSupport.UnitTests |
| 11 | +{ |
| 12 | + public class FileDescriptorLogStreamTests |
| 13 | + { |
| 14 | + private const int HeaderLength = FileDescriptorLogFactory.LambdaTelemetryLogHeaderLength; |
| 15 | + private const int LogEntryMaxLength = FileDescriptorLogFactory.MaxCloudWatchLogEventSize; |
| 16 | + |
| 17 | + private static readonly byte[] ExpectedMagicBytes = |
| 18 | + { |
| 19 | + 0xA5, 0x5A, 0x00, 0x01 |
| 20 | + }; |
| 21 | + |
| 22 | + [Fact] |
| 23 | + public void MultilineLoggingInSingleLogEntryWithTlvFormat() |
| 24 | + { |
| 25 | + var logs = new List<byte[]>(); |
| 26 | + var offsets = new List<int>(); |
| 27 | + var counts = new List<int>(); |
| 28 | + var stream = new TestFileStream((log, offset, count) => |
| 29 | + { |
| 30 | + logs.Add(log); |
| 31 | + offsets.Add(offset); |
| 32 | + counts.Add(count); |
| 33 | + }); |
| 34 | + TextWriter writer = FileDescriptorLogFactory.InitializeWriter(stream); |
| 35 | + // assert that initializing the stream does not result in UTF-8 preamble log entry |
| 36 | + Assert.Equal(0, counts.Count); |
| 37 | + Assert.Equal(0, offsets.Count); |
| 38 | + Assert.Equal(0, logs.Count); |
| 39 | + |
| 40 | + const string logMessage = "hello world\nsomething else on a new line."; |
| 41 | + int logMessageLength = logMessage.Length; |
| 42 | + writer.Write(logMessage); |
| 43 | + |
| 44 | + Assert.Equal(2, offsets.Count); |
| 45 | + int headerLogEntryOffset = offsets[0]; |
| 46 | + int consoleLogEntryOffset = offsets[1]; |
| 47 | + Assert.Equal(0, headerLogEntryOffset); |
| 48 | + Assert.Equal(0, consoleLogEntryOffset); |
| 49 | + |
| 50 | + Assert.Equal(2, counts.Count); |
| 51 | + int headerLogEntrySize = counts[0]; |
| 52 | + int consoleLogEntrySize = counts[1]; |
| 53 | + Assert.Equal(HeaderLength, headerLogEntrySize); |
| 54 | + Assert.Equal(logMessageLength, consoleLogEntrySize); |
| 55 | + |
| 56 | + Assert.Equal(2, logs.Count); |
| 57 | + byte[] headerLogEntry = logs[0]; |
| 58 | + byte[] consoleLogEntry = logs[1]; |
| 59 | + Assert.Equal(HeaderLength, headerLogEntry.Length); |
| 60 | + Assert.Equal(logMessageLength, consoleLogEntry.Length); |
| 61 | + |
| 62 | + byte[] expectedLengthBytes = |
| 63 | + { |
| 64 | + 0x00, 0x00, 0x00, 0x29 |
| 65 | + }; |
| 66 | + AssertHeaderBytes(headerLogEntry, expectedLengthBytes); |
| 67 | + Assert.Equal(logMessage, Encoding.UTF8.GetString(consoleLogEntry)); |
| 68 | + } |
| 69 | + |
| 70 | + [Fact] |
| 71 | + public void MaxSizeProducesOneLogFrame() |
| 72 | + { |
| 73 | + var logs = new List<byte[]>(); |
| 74 | + var offsets = new List<int>(); |
| 75 | + var counts = new List<int>(); |
| 76 | + var stream = new TestFileStream((log, offset, count) => |
| 77 | + { |
| 78 | + logs.Add(log); |
| 79 | + offsets.Add(offset); |
| 80 | + counts.Add(count); |
| 81 | + }); |
| 82 | + TextWriter writer = FileDescriptorLogFactory.InitializeWriter(stream); |
| 83 | + // assert that initializing the stream does not result in UTF-8 preamble log entry |
| 84 | + Assert.Equal(0, counts.Count); |
| 85 | + Assert.Equal(0, offsets.Count); |
| 86 | + Assert.Equal(0, logs.Count); |
| 87 | + |
| 88 | + string logMessage = new string('a', LogEntryMaxLength - 1) + "b"; |
| 89 | + writer.Write(logMessage); |
| 90 | + |
| 91 | + Assert.Equal(2, offsets.Count); |
| 92 | + int headerLogEntryOffset = offsets[0]; |
| 93 | + int consoleLogEntryOffset = offsets[1]; |
| 94 | + Assert.Equal(0, headerLogEntryOffset); |
| 95 | + Assert.Equal(0, consoleLogEntryOffset); |
| 96 | + |
| 97 | + Assert.Equal(2, counts.Count); |
| 98 | + int headerLogEntrySize = counts[0]; |
| 99 | + int consoleLogEntrySize = counts[1]; |
| 100 | + Assert.Equal(HeaderLength, headerLogEntrySize); |
| 101 | + Assert.Equal(LogEntryMaxLength, consoleLogEntrySize); |
| 102 | + |
| 103 | + Assert.Equal(2, logs.Count); |
| 104 | + byte[] headerLogEntry = logs[0]; |
| 105 | + byte[] consoleLogEntry = logs[1]; |
| 106 | + Assert.Equal(HeaderLength, headerLogEntry.Length); |
| 107 | + Assert.Equal(LogEntryMaxLength, consoleLogEntry.Length); |
| 108 | + |
| 109 | + byte[] expectedLengthBytes = |
| 110 | + { |
| 111 | + 0x00, 0x03, 0xFF, 0xE6 |
| 112 | + }; |
| 113 | + AssertHeaderBytes(headerLogEntry, expectedLengthBytes); |
| 114 | + Assert.Equal(logMessage, Encoding.UTF8.GetString(consoleLogEntry)); |
| 115 | + } |
| 116 | + |
| 117 | + [Fact] |
| 118 | + public void LogEntryAboveMaxSizeProducesMultipleLogFrames() |
| 119 | + { |
| 120 | + var logs = new List<byte[]>(); |
| 121 | + var offsets = new List<int>(); |
| 122 | + var counts = new List<int>(); |
| 123 | + var stream = new TestFileStream((log, offset, count) => |
| 124 | + { |
| 125 | + logs.Add(log); |
| 126 | + offsets.Add(offset); |
| 127 | + counts.Add(count); |
| 128 | + }); |
| 129 | + TextWriter writer = FileDescriptorLogFactory.InitializeWriter(stream); |
| 130 | + // assert that initializing the stream does not result in UTF-8 preamble log entry |
| 131 | + Assert.Equal(0, counts.Count); |
| 132 | + Assert.Equal(0, offsets.Count); |
| 133 | + Assert.Equal(0, logs.Count); |
| 134 | + |
| 135 | + string logMessage = new string('a', LogEntryMaxLength) + "b"; |
| 136 | + writer.Write(logMessage); |
| 137 | + |
| 138 | + Assert.Equal(4, offsets.Count); |
| 139 | + int headerLogEntryOffset = offsets[0]; |
| 140 | + int consoleLogEntryOffset = offsets[1]; |
| 141 | + int headerLogSecondEntryOffset = offsets[2]; |
| 142 | + int consoleLogSecondEntryOffset = offsets[3]; |
| 143 | + Assert.Equal(0, headerLogEntryOffset); |
| 144 | + Assert.Equal(0, consoleLogEntryOffset); |
| 145 | + Assert.Equal(0, headerLogSecondEntryOffset); |
| 146 | + Assert.Equal(0, consoleLogSecondEntryOffset); |
| 147 | + |
| 148 | + Assert.Equal(4, counts.Count); |
| 149 | + int headerLogEntrySize = counts[0]; |
| 150 | + int consoleLogEntrySize = counts[1]; |
| 151 | + int headerLogSecondEntrySize = counts[2]; |
| 152 | + int consoleLogSecondEntrySize = counts[3]; |
| 153 | + Assert.Equal(HeaderLength, headerLogEntrySize); |
| 154 | + Assert.Equal(LogEntryMaxLength, consoleLogEntrySize); |
| 155 | + Assert.Equal(HeaderLength, headerLogSecondEntrySize); |
| 156 | + Assert.Equal(1, consoleLogSecondEntrySize); |
| 157 | + |
| 158 | + Assert.Equal(4, logs.Count); |
| 159 | + byte[] headerLogEntry = logs[0]; |
| 160 | + byte[] consoleLogEntry = logs[1]; |
| 161 | + byte[] headerLogSecondEntry = logs[2]; |
| 162 | + byte[] consoleLogSecondEntry = logs[3]; |
| 163 | + Assert.Equal(HeaderLength, headerLogEntry.Length); |
| 164 | + Assert.Equal(LogEntryMaxLength, consoleLogEntry.Length); |
| 165 | + Assert.Equal(HeaderLength, headerLogSecondEntry.Length); |
| 166 | + Assert.Equal(1, consoleLogSecondEntry.Length); |
| 167 | + |
| 168 | + byte[] expectedLengthBytes = |
| 169 | + { |
| 170 | + 0x00, 0x03, 0xFF, 0xE6 |
| 171 | + }; |
| 172 | + AssertHeaderBytes(headerLogEntry, expectedLengthBytes); |
| 173 | + |
| 174 | + byte[] expectedLengthBytesSecondEntry = |
| 175 | + { |
| 176 | + 0x00, 0x00, 0x00, 0x01 |
| 177 | + }; |
| 178 | + AssertHeaderBytes(headerLogSecondEntry, expectedLengthBytesSecondEntry); |
| 179 | + string expectedLogEntry = logMessage.Substring(0, LogEntryMaxLength); |
| 180 | + string expectedSecondLogEntry = logMessage.Substring(LogEntryMaxLength); |
| 181 | + Assert.Equal(expectedLogEntry, Encoding.UTF8.GetString(consoleLogEntry)); |
| 182 | + Assert.Equal(expectedSecondLogEntry, Encoding.UTF8.GetString(consoleLogSecondEntry)); |
| 183 | + } |
| 184 | + |
| 185 | + private static void AssertHeaderBytes(byte[] buf, byte[] expectedLengthBytes) |
| 186 | + { |
| 187 | + byte[] actualHeaderMagicBytes = buf.Take(4).ToArray(); |
| 188 | + byte[] actualHeaderLengthBytes = buf.TakeLast(4).ToArray(); |
| 189 | + Assert.Equal(ExpectedMagicBytes, actualHeaderMagicBytes); |
| 190 | + Assert.Equal(expectedLengthBytes, actualHeaderLengthBytes); |
| 191 | + } |
| 192 | + } |
| 193 | +} |
0 commit comments