blob: a08a0a1101c111fc2c677cb1878d8b484be8cad4 [file] [log] [blame]
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +00001// Copyright 2006-2009 the V8 project authors. All rights reserved.
2//
3// Tests of logging utilities from log-utils.h
4
5#ifdef ENABLE_LOGGING_AND_PROFILING
6
7#include "v8.h"
8
9#include "log-utils.h"
10#include "cctest.h"
11
ager@chromium.orgeadaf222009-06-16 09:43:10 +000012using v8::internal::CStrVector;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000013using v8::internal::EmbeddedVector;
14using v8::internal::LogDynamicBuffer;
ager@chromium.orgeadaf222009-06-16 09:43:10 +000015using v8::internal::LogRecordCompressor;
16using v8::internal::MutableCStrVector;
17using v8::internal::ScopedVector;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000018using v8::internal::Vector;
19
20// Fills 'ref_buffer' with test data: a sequence of two-digit
21// hex numbers: '0001020304...'. Then writes 'ref_buffer' contents to 'dynabuf'.
22static void WriteData(LogDynamicBuffer* dynabuf, Vector<char>* ref_buffer) {
23 static const char kHex[] = "0123456789ABCDEF";
24 CHECK_GT(ref_buffer->length(), 0);
25 CHECK_GT(513, ref_buffer->length());
26 for (int i = 0, half_len = ref_buffer->length() >> 1; i < half_len; ++i) {
27 (*ref_buffer)[i << 1] = kHex[i >> 4];
28 (*ref_buffer)[(i << 1) + 1] = kHex[i & 15];
29 }
30 if (ref_buffer->length() & 1) {
31 ref_buffer->last() = kHex[ref_buffer->length() >> 5];
32 }
33 CHECK_EQ(ref_buffer->length(),
34 dynabuf->Write(ref_buffer->start(), ref_buffer->length()));
35}
36
37
38static int ReadData(
39 LogDynamicBuffer* dynabuf, int start_pos, i::Vector<char>* buffer) {
40 return dynabuf->Read(start_pos, buffer->start(), buffer->length());
41}
42
43
44// Helper function used by CHECK_EQ to compare Vectors. Templatized to
45// accept both "char" and "const char" vector contents.
46template <typename E, typename V>
47static inline void CheckEqualsHelper(const char* file, int line,
48 const char* expected_source,
49 const Vector<E>& expected,
50 const char* value_source,
51 const Vector<V>& value) {
52 if (expected.length() != value.length()) {
53 V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
ager@chromium.orgeadaf222009-06-16 09:43:10 +000054 "# Vectors lengths differ: %d expected, %d found\n"
55 "# Expected: %.*s\n"
56 "# Found: %.*s",
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000057 expected_source, value_source,
ager@chromium.orgeadaf222009-06-16 09:43:10 +000058 expected.length(), value.length(),
59 expected.length(), expected.start(),
60 value.length(), value.start());
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000061 }
62 if (strncmp(expected.start(), value.start(), expected.length()) != 0) {
63 V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
64 "# Vectors contents differ:\n"
65 "# Expected: %.*s\n"
66 "# Found: %.*s",
67 expected_source, value_source,
68 expected.length(), expected.start(),
69 value.length(), value.start());
70 }
71}
72
73
74TEST(DynaBufSingleBlock) {
75 LogDynamicBuffer dynabuf(32, 32, "", 0);
76 EmbeddedVector<char, 32> ref_buf;
77 WriteData(&dynabuf, &ref_buf);
78 EmbeddedVector<char, 32> buf;
79 CHECK_EQ(32, dynabuf.Read(0, buf.start(), buf.length()));
80 CHECK_EQ(32, ReadData(&dynabuf, 0, &buf));
81 CHECK_EQ(ref_buf, buf);
82
83 // Verify that we can't read and write past the end.
84 CHECK_EQ(0, dynabuf.Read(32, buf.start(), buf.length()));
85 CHECK_EQ(0, dynabuf.Write(buf.start(), buf.length()));
86}
87
88
89TEST(DynaBufCrossBlocks) {
90 LogDynamicBuffer dynabuf(32, 128, "", 0);
91 EmbeddedVector<char, 48> ref_buf;
92 WriteData(&dynabuf, &ref_buf);
93 CHECK_EQ(48, dynabuf.Write(ref_buf.start(), ref_buf.length()));
94 // Verify that we can't write data when remaining buffer space isn't enough.
95 CHECK_EQ(0, dynabuf.Write(ref_buf.start(), ref_buf.length()));
96 EmbeddedVector<char, 48> buf;
97 CHECK_EQ(48, ReadData(&dynabuf, 0, &buf));
98 CHECK_EQ(ref_buf, buf);
99 CHECK_EQ(48, ReadData(&dynabuf, 48, &buf));
100 CHECK_EQ(ref_buf, buf);
101 CHECK_EQ(0, ReadData(&dynabuf, 48 * 2, &buf));
102}
103
104
105TEST(DynaBufReadTruncation) {
106 LogDynamicBuffer dynabuf(32, 128, "", 0);
107 EmbeddedVector<char, 128> ref_buf;
108 WriteData(&dynabuf, &ref_buf);
109 EmbeddedVector<char, 128> buf;
110 CHECK_EQ(128, ReadData(&dynabuf, 0, &buf));
111 CHECK_EQ(ref_buf, buf);
112 // Try to read near the end with a buffer larger than remaining data size.
113 EmbeddedVector<char, 48> tail_buf;
114 CHECK_EQ(32, ReadData(&dynabuf, 128 - 32, &tail_buf));
115 CHECK_EQ(ref_buf.SubVector(128 - 32, 128), tail_buf.SubVector(0, 32));
116}
117
118
119TEST(DynaBufSealing) {
120 const char* seal = "Sealed";
121 const int seal_size = strlen(seal);
122 LogDynamicBuffer dynabuf(32, 128, seal, seal_size);
123 EmbeddedVector<char, 100> ref_buf;
124 WriteData(&dynabuf, &ref_buf);
125 // Try to write data that will not fit in the buffer.
126 CHECK_EQ(0, dynabuf.Write(ref_buf.start(), 128 - 100 - seal_size + 1));
127 // Now the buffer is sealed, writing of any amount of data is forbidden.
128 CHECK_EQ(0, dynabuf.Write(ref_buf.start(), 1));
129 EmbeddedVector<char, 100> buf;
130 CHECK_EQ(100, ReadData(&dynabuf, 0, &buf));
131 CHECK_EQ(ref_buf, buf);
132 // Check the seal.
133 EmbeddedVector<char, 50> seal_buf;
134 CHECK_EQ(seal_size, ReadData(&dynabuf, 100, &seal_buf));
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000135 CHECK_EQ(CStrVector(seal), seal_buf.SubVector(0, seal_size));
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000136 // Verify that there's no data beyond the seal.
137 CHECK_EQ(0, ReadData(&dynabuf, 100 + seal_size, &buf));
138}
139
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000140
141TEST(CompressorStore) {
142 LogRecordCompressor comp(2);
143 const Vector<const char> empty = CStrVector("");
144 CHECK(comp.Store(empty));
145 CHECK(!comp.Store(empty));
146 CHECK(!comp.Store(empty));
147 const Vector<const char> aaa = CStrVector("aaa");
148 CHECK(comp.Store(aaa));
149 CHECK(!comp.Store(aaa));
150 CHECK(!comp.Store(aaa));
151 CHECK(comp.Store(empty));
152 CHECK(!comp.Store(empty));
153 CHECK(!comp.Store(empty));
154}
155
156
157void CheckCompression(LogRecordCompressor* comp,
158 const Vector<const char>& after) {
159 EmbeddedVector<char, 100> result;
160 CHECK(comp->RetrievePreviousCompressed(&result));
161 CHECK_EQ(after, result);
162}
163
164
165void CheckCompression(LogRecordCompressor* comp,
166 const char* after) {
167 CheckCompression(comp, CStrVector(after));
168}
169
170
171TEST(CompressorNonCompressed) {
172 LogRecordCompressor comp(0);
173 CHECK(!comp.RetrievePreviousCompressed(NULL));
174 const Vector<const char> empty = CStrVector("");
175 CHECK(comp.Store(empty));
176 CHECK(!comp.RetrievePreviousCompressed(NULL));
177 const Vector<const char> a_x_20 = CStrVector("aaaaaaaaaaaaaaaaaaaa");
178 CHECK(comp.Store(a_x_20));
179 CheckCompression(&comp, empty);
180 CheckCompression(&comp, empty);
181 CHECK(comp.Store(empty));
182 CheckCompression(&comp, a_x_20);
183 CheckCompression(&comp, a_x_20);
184}
185
186
187TEST(CompressorSingleLine) {
188 LogRecordCompressor comp(1);
189 const Vector<const char> string_1 = CStrVector("eee,ddd,ccc,bbb,aaa");
190 CHECK(comp.Store(string_1));
191 const Vector<const char> string_2 = CStrVector("fff,ddd,ccc,bbb,aaa");
192 CHECK(comp.Store(string_2));
193 // string_1 hasn't been compressed.
194 CheckCompression(&comp, string_1);
195 CheckCompression(&comp, string_1);
196 const Vector<const char> string_3 = CStrVector("hhh,ggg,ccc,bbb,aaa");
197 CHECK(comp.Store(string_3));
198 // string_2 compressed using string_1.
199 CheckCompression(&comp, "fff#1:3");
200 CheckCompression(&comp, "fff#1:3");
201 CHECK(!comp.Store(string_3));
202 // Expecting no changes.
203 CheckCompression(&comp, "fff#1:3");
204 CHECK(!comp.Store(string_3));
205 // Expecting no changes.
206 CheckCompression(&comp, "fff#1:3");
207 const Vector<const char> string_4 = CStrVector("iii,hhh,ggg,ccc,bbb,aaa");
208 CHECK(comp.Store(string_4));
209 // string_3 compressed using string_2.
210 CheckCompression(&comp, "hhh,ggg#1:7");
211 const Vector<const char> string_5 = CStrVector("nnn,mmm,lll,kkk,jjj");
212 CHECK(comp.Store(string_5));
213 // string_4 compressed using string_3.
214 CheckCompression(&comp, "iii,#1");
215 const Vector<const char> string_6 = CStrVector("nnn,mmmmmm,lll,kkk,jjj");
216 CHECK(comp.Store(string_6));
217 // string_5 hasn't been compressed.
218 CheckCompression(&comp, string_5);
219 CHECK(comp.Store(string_5));
220 // string_6 compressed using string_5.
221 CheckCompression(&comp, "nnn,mmm#1:4");
222 const Vector<const char> string_7 = CStrVector("nnnnnn,mmm,lll,kkk,jjj");
223 CHECK(comp.Store(string_7));
224 // string_5 compressed using string_6.
225 CheckCompression(&comp, "nnn,#1:7");
226 const Vector<const char> string_8 = CStrVector("xxn,mmm,lll,kkk,jjj");
227 CHECK(comp.Store(string_8));
228 // string_7 compressed using string_5.
229 CheckCompression(&comp, "nnn#1");
230 const Vector<const char> string_9 =
231 CStrVector("aaaaaaaaaaaaa,bbbbbbbbbbbbbbbbb");
232 CHECK(comp.Store(string_9));
233 // string_8 compressed using string_7.
234 CheckCompression(&comp, "xx#1:5");
235 const Vector<const char> string_10 =
236 CStrVector("aaaaaaaaaaaaa,cccccccbbbbbbbbbb");
237 CHECK(comp.Store(string_10));
238 // string_9 hasn't been compressed.
239 CheckCompression(&comp, string_9);
240 CHECK(comp.Store(string_1));
241 // string_10 compressed using string_9.
242 CheckCompression(&comp, "aaaaaaaaaaaaa,ccccccc#1:21");
243}
244
245
246
247TEST(CompressorMultiLines) {
248 const int kWindowSize = 3;
249 LogRecordCompressor comp(kWindowSize);
250 const Vector<const char> string_1 = CStrVector("eee,ddd,ccc,bbb,aaa");
251 CHECK(comp.Store(string_1));
252 const Vector<const char> string_2 = CStrVector("iii,hhh,ggg,fff,aaa");
253 CHECK(comp.Store(string_2));
254 const Vector<const char> string_3 = CStrVector("mmm,lll,kkk,jjj,aaa");
255 CHECK(comp.Store(string_3));
256 const Vector<const char> string_4 = CStrVector("nnn,hhh,ggg,fff,aaa");
257 CHECK(comp.Store(string_4));
258 const Vector<const char> string_5 = CStrVector("ooo,lll,kkk,jjj,aaa");
259 CHECK(comp.Store(string_5));
260 // string_4 compressed using string_2.
261 CheckCompression(&comp, "nnn#2:3");
262 CHECK(comp.Store(string_1));
263 // string_5 compressed using string_3.
264 CheckCompression(&comp, "ooo#2:3");
265 CHECK(comp.Store(string_4));
266 // string_1 is out of buffer by now, so it shouldn't be compressed.
267 CHECK_GE(3, kWindowSize);
268 CheckCompression(&comp, string_1);
269 CHECK(comp.Store(string_2));
270 // string_4 compressed using itself.
271 CheckCompression(&comp, "#3");
272}
273
274
275TEST(CompressorBestSelection) {
276 LogRecordCompressor comp(3);
277 const Vector<const char> string_1 = CStrVector("eee,ddd,ccc,bbb,aaa");
278 CHECK(comp.Store(string_1));
279 const Vector<const char> string_2 = CStrVector("ddd,ccc,bbb,aaa");
280 CHECK(comp.Store(string_2));
281 const Vector<const char> string_3 = CStrVector("fff,eee,ddd,ccc,bbb,aaa");
282 CHECK(comp.Store(string_3));
283 // string_2 compressed using string_1.
284 CheckCompression(&comp, "#1:4");
285 const Vector<const char> string_4 = CStrVector("nnn,hhh,ggg,fff,aaa");
286 CHECK(comp.Store(string_4));
287 // Compressing string_3 using string_1 gives a better compression than
288 // using string_2.
289 CheckCompression(&comp, "fff,#2");
290}
291
292
293TEST(CompressorCompressibility) {
294 LogRecordCompressor comp(2);
295 const Vector<const char> string_1 = CStrVector("eee,ddd,ccc,bbb,aaa");
296 CHECK(comp.Store(string_1));
297 const Vector<const char> string_2 = CStrVector("ccc,bbb,aaa");
298 CHECK(comp.Store(string_2));
299 const Vector<const char> string_3 = CStrVector("aaa");
300 CHECK(comp.Store(string_3));
301 // string_2 compressed using string_1.
302 CheckCompression(&comp, "#1:8");
303 const Vector<const char> string_4 = CStrVector("xxx");
304 CHECK(comp.Store(string_4));
305 // string_3 can't be compressed using string_2 --- too short.
306 CheckCompression(&comp, string_3);
307}
308
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000309#endif // ENABLE_LOGGING_AND_PROFILING