1 //===-- ReproducerInstrumentationTest.cpp ---------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11
12 #include <cmath>
13 #include <limits>
14
15 #include "lldb/Utility/ReproducerInstrumentation.h"
16
17 using namespace lldb_private;
18 using namespace lldb_private::repro;
19
20 struct Foo {
21 int m = 1;
22 };
23 struct Bar {
24 double m = 2;
25 };
26
operator ==(const Foo & LHS,const Foo & RHS)27 bool operator==(const Foo &LHS, const Foo &RHS) { return LHS.m == RHS.m; }
operator ==(const Bar & LHS,const Bar & RHS)28 bool operator==(const Bar &LHS, const Bar &RHS) { return LHS.m == RHS.m; }
29
30 struct Pod {
31 bool a = true;
32 bool b = false;
33 char c = 'a';
34 float d = 1.1f;
35 int e = 2;
36 long long f = 3;
37 long g = 4;
38 short h = 5;
39 unsigned char i = 'b';
40 unsigned int j = 6;
41 unsigned long long k = 7;
42 unsigned long l = 8;
43 unsigned short m = 9;
44
PodPod45 Pod() {}
46 };
47
48 class TestingRegistry : public Registry {
49 public:
50 TestingRegistry();
51 };
52
53 static llvm::Optional<TestingRegistry> g_registry;
54 static llvm::Optional<Serializer> g_serializer;
55 static llvm::Optional<Deserializer> g_deserializer;
56
57 class TestInstrumentationData : public InstrumentationData {
58 public:
TestInstrumentationData()59 TestInstrumentationData() : InstrumentationData() {}
TestInstrumentationData(Serializer & serializer,Registry & registry)60 TestInstrumentationData(Serializer &serializer, Registry ®istry)
61 : InstrumentationData(serializer, registry) {}
TestInstrumentationData(Deserializer & deserializer,Registry & registry)62 TestInstrumentationData(Deserializer &deserializer, Registry ®istry)
63 : InstrumentationData(deserializer, registry) {}
64 };
65
GetTestInstrumentationData()66 inline TestInstrumentationData GetTestInstrumentationData() {
67 assert(!(g_serializer && g_deserializer));
68 if (g_serializer)
69 return TestInstrumentationData(*g_serializer, *g_registry);
70 if (g_deserializer)
71 return TestInstrumentationData(*g_deserializer, *g_registry);
72 return TestInstrumentationData();
73 }
74
75 class TestInstrumentationDataRAII {
76 public:
TestInstrumentationDataRAII(llvm::raw_string_ostream & os)77 TestInstrumentationDataRAII(llvm::raw_string_ostream &os) {
78 g_registry.emplace();
79 g_serializer.emplace(os);
80 g_deserializer.reset();
81 }
82
TestInstrumentationDataRAII(llvm::StringRef buffer)83 TestInstrumentationDataRAII(llvm::StringRef buffer) {
84 g_registry.emplace();
85 g_serializer.reset();
86 g_deserializer.emplace(buffer);
87 }
88
~TestInstrumentationDataRAII()89 ~TestInstrumentationDataRAII() { Reset(); }
90
Reset()91 void Reset() {
92 g_registry.reset();
93 g_serializer.reset();
94 g_deserializer.reset();
95 }
96
97 static std::unique_ptr<TestInstrumentationDataRAII>
GetRecordingData(llvm::raw_string_ostream & os)98 GetRecordingData(llvm::raw_string_ostream &os) {
99 return std::make_unique<TestInstrumentationDataRAII>(os);
100 }
101
102 static std::unique_ptr<TestInstrumentationDataRAII>
GetReplayData(llvm::StringRef buffer)103 GetReplayData(llvm::StringRef buffer) {
104 return std::make_unique<TestInstrumentationDataRAII>(buffer);
105 }
106 };
107
108 #define LLDB_GET_INSTRUMENTATION_DATA() GetTestInstrumentationData()
109
110 enum class Class {
111 Foo,
112 Bar,
113 };
114
115 class Instrumented {
116 public:
117 virtual ~Instrumented() = default;
118 virtual void Validate() = 0;
119 virtual bool IsA(Class c) = 0;
120 };
121
122 class InstrumentedFoo : public Instrumented {
123 public:
124 InstrumentedFoo() = default;
125 /// Instrumented methods.
126 /// {
127 InstrumentedFoo(int i);
128 InstrumentedFoo(const InstrumentedFoo &foo);
129 InstrumentedFoo &operator=(const InstrumentedFoo &foo);
130 void A(int a);
131 int GetA();
132 void B(int &b) const;
133 int &GetB();
134 int C(float *c);
135 float GetC();
136 int D(const char *d) const;
137 size_t GetD(char *buffer, size_t length);
138 static void E(double e);
139 double GetE();
140 static int F();
141 bool GetF();
142 void Validate() override;
143 //// }
IsA(Class c)144 virtual bool IsA(Class c) override { return c == Class::Foo; }
145
146 private:
147 int m_a = 0;
148 mutable int m_b = 0;
149 float m_c = 0;
150 mutable std::string m_d = {};
151 static double g_e;
152 static bool g_f;
153 mutable int m_called = 0;
154 };
155
156 class InstrumentedBar : public Instrumented {
157 public:
158 /// Instrumented methods.
159 /// {
160 InstrumentedBar();
161 InstrumentedFoo GetInstrumentedFoo();
162 InstrumentedFoo &GetInstrumentedFooRef();
163 InstrumentedFoo *GetInstrumentedFooPtr();
164 void SetInstrumentedFoo(InstrumentedFoo *foo);
165 void SetInstrumentedFoo(InstrumentedFoo &foo);
166 void Validate() override;
167 /// }
IsA(Class c)168 virtual bool IsA(Class c) override { return c == Class::Bar; }
169
170 private:
171 bool m_get_instrumend_foo_called = false;
172 InstrumentedFoo *m_foo_set_by_ptr = nullptr;
173 InstrumentedFoo *m_foo_set_by_ref = nullptr;
174 };
175
176 double InstrumentedFoo::g_e = 0;
177 bool InstrumentedFoo::g_f = false;
178
179 struct Validator {
180 enum Validation { valid, invalid };
ValidatorValidator181 Validator(Class clazz, Validation validation)
182 : clazz(clazz), validation(validation) {}
183 Class clazz;
184 Validation validation;
185 };
186
ValidateObjects(std::vector<void * > objects,std::vector<Validator> validators)187 void ValidateObjects(std::vector<void *> objects,
188 std::vector<Validator> validators) {
189 ASSERT_EQ(validators.size(), objects.size());
190 for (size_t i = 0; i < validators.size(); ++i) {
191 Validator &validator = validators[i];
192 Instrumented *instrumented = static_cast<Instrumented *>(objects[i]);
193 EXPECT_TRUE(instrumented->IsA(validator.clazz));
194 switch (validator.validation) {
195 case Validator::valid:
196 instrumented->Validate();
197 break;
198 case Validator::invalid:
199 break;
200 }
201 }
202 }
203
InstrumentedFoo(int i)204 InstrumentedFoo::InstrumentedFoo(int i) {
205 LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (int), i);
206 }
207
InstrumentedFoo(const InstrumentedFoo & foo)208 InstrumentedFoo::InstrumentedFoo(const InstrumentedFoo &foo) {
209 LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &), foo);
210 }
211
operator =(const InstrumentedFoo & foo)212 InstrumentedFoo &InstrumentedFoo::operator=(const InstrumentedFoo &foo) {
213 LLDB_RECORD_METHOD(InstrumentedFoo &,
214 InstrumentedFoo, operator=,(const InstrumentedFoo &), foo);
215 return *this;
216 }
217
A(int a)218 void InstrumentedFoo::A(int a) {
219 LLDB_RECORD_METHOD(void, InstrumentedFoo, A, (int), a);
220 B(a);
221 m_a = a;
222 }
223
GetA()224 int InstrumentedFoo::GetA() {
225 LLDB_RECORD_METHOD_NO_ARGS(int, InstrumentedFoo, GetA);
226
227 return m_a;
228 }
229
B(int & b) const230 void InstrumentedFoo::B(int &b) const {
231 LLDB_RECORD_METHOD_CONST(void, InstrumentedFoo, B, (int &), b);
232 m_called++;
233 m_b = b;
234 }
235
GetB()236 int &InstrumentedFoo::GetB() {
237 LLDB_RECORD_METHOD_NO_ARGS(int &, InstrumentedFoo, GetB);
238
239 return m_b;
240 }
241
C(float * c)242 int InstrumentedFoo::C(float *c) {
243 LLDB_RECORD_METHOD(int, InstrumentedFoo, C, (float *), c);
244 m_c = *c;
245 return 1;
246 }
247
GetC()248 float InstrumentedFoo::GetC() {
249 LLDB_RECORD_METHOD_NO_ARGS(float, InstrumentedFoo, GetC);
250
251 return m_c;
252 }
253
D(const char * d) const254 int InstrumentedFoo::D(const char *d) const {
255 LLDB_RECORD_METHOD_CONST(int, InstrumentedFoo, D, (const char *), d);
256 m_d = std::string(d);
257 return 2;
258 }
259
GetD(char * buffer,size_t length)260 size_t InstrumentedFoo::GetD(char *buffer, size_t length) {
261 LLDB_RECORD_CHAR_PTR_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t),
262 buffer, "", length);
263 ::snprintf(buffer, length, "%s", m_d.c_str());
264 return m_d.size();
265 }
266
E(double e)267 void InstrumentedFoo::E(double e) {
268 LLDB_RECORD_STATIC_METHOD(void, InstrumentedFoo, E, (double), e);
269 g_e = e;
270 }
271
GetE()272 double InstrumentedFoo::GetE() {
273 LLDB_RECORD_METHOD_NO_ARGS(double, InstrumentedFoo, GetE);
274
275 return g_e;
276 }
277
F()278 int InstrumentedFoo::F() {
279 LLDB_RECORD_STATIC_METHOD_NO_ARGS(int, InstrumentedFoo, F);
280 g_f = true;
281 return 3;
282 }
283
GetF()284 bool InstrumentedFoo::GetF() {
285 LLDB_RECORD_METHOD_NO_ARGS(bool, InstrumentedFoo, GetF);
286
287 return g_f;
288 }
289
Validate()290 void InstrumentedFoo::Validate() {
291 LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedFoo, Validate);
292 EXPECT_EQ(m_a, 100);
293 EXPECT_EQ(m_b, 200);
294 EXPECT_NEAR(m_c, 300.3, 0.01);
295 EXPECT_EQ(m_d, "bar");
296 EXPECT_NEAR(g_e, 400.4, 0.01);
297 EXPECT_EQ(g_f, true);
298 EXPECT_EQ(2, m_called);
299 }
300
InstrumentedBar()301 InstrumentedBar::InstrumentedBar() {
302 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(InstrumentedBar);
303 }
304
GetInstrumentedFoo()305 InstrumentedFoo InstrumentedBar::GetInstrumentedFoo() {
306 LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo, InstrumentedBar,
307 GetInstrumentedFoo);
308 m_get_instrumend_foo_called = true;
309 return LLDB_RECORD_RESULT(InstrumentedFoo(0));
310 }
311
GetInstrumentedFooRef()312 InstrumentedFoo &InstrumentedBar::GetInstrumentedFooRef() {
313 LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo &, InstrumentedBar,
314 GetInstrumentedFooRef);
315 InstrumentedFoo *foo = new InstrumentedFoo(0);
316 m_get_instrumend_foo_called = true;
317 return LLDB_RECORD_RESULT(*foo);
318 }
319
GetInstrumentedFooPtr()320 InstrumentedFoo *InstrumentedBar::GetInstrumentedFooPtr() {
321 LLDB_RECORD_METHOD_NO_ARGS(InstrumentedFoo *, InstrumentedBar,
322 GetInstrumentedFooPtr);
323 InstrumentedFoo *foo = new InstrumentedFoo(0);
324 m_get_instrumend_foo_called = true;
325 return LLDB_RECORD_RESULT(foo);
326 }
327
SetInstrumentedFoo(InstrumentedFoo * foo)328 void InstrumentedBar::SetInstrumentedFoo(InstrumentedFoo *foo) {
329 LLDB_RECORD_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
330 (InstrumentedFoo *), foo);
331 m_foo_set_by_ptr = foo;
332 }
333
SetInstrumentedFoo(InstrumentedFoo & foo)334 void InstrumentedBar::SetInstrumentedFoo(InstrumentedFoo &foo) {
335 LLDB_RECORD_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
336 (InstrumentedFoo &), foo);
337 m_foo_set_by_ref = &foo;
338 }
339
Validate()340 void InstrumentedBar::Validate() {
341 LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedBar, Validate);
342
343 EXPECT_TRUE(m_get_instrumend_foo_called);
344 EXPECT_NE(m_foo_set_by_ptr, nullptr);
345 EXPECT_EQ(m_foo_set_by_ptr, m_foo_set_by_ref);
346 }
347
TestingRegistry()348 TestingRegistry::TestingRegistry() {
349 Registry &R = *this;
350
351 LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (int i));
352 LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &));
353 LLDB_REGISTER_METHOD(InstrumentedFoo &,
354 InstrumentedFoo, operator=,(const InstrumentedFoo &));
355 LLDB_REGISTER_METHOD(void, InstrumentedFoo, A, (int));
356 LLDB_REGISTER_METHOD_CONST(void, InstrumentedFoo, B, (int &));
357 LLDB_REGISTER_METHOD(int, InstrumentedFoo, C, (float *));
358 LLDB_REGISTER_METHOD_CONST(int, InstrumentedFoo, D, (const char *));
359 LLDB_REGISTER_STATIC_METHOD(void, InstrumentedFoo, E, (double));
360 LLDB_REGISTER_STATIC_METHOD(int, InstrumentedFoo, F, ());
361 LLDB_REGISTER_METHOD(void, InstrumentedFoo, Validate, ());
362
363 LLDB_REGISTER_CONSTRUCTOR(InstrumentedBar, ());
364 LLDB_REGISTER_METHOD(InstrumentedFoo, InstrumentedBar, GetInstrumentedFoo,
365 ());
366 LLDB_REGISTER_METHOD(InstrumentedFoo &, InstrumentedBar,
367 GetInstrumentedFooRef, ());
368 LLDB_REGISTER_METHOD(InstrumentedFoo *, InstrumentedBar,
369 GetInstrumentedFooPtr, ());
370 LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
371 (InstrumentedFoo *));
372 LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo,
373 (InstrumentedFoo &));
374 LLDB_REGISTER_METHOD(void, InstrumentedBar, Validate, ());
375 LLDB_REGISTER_METHOD(int, InstrumentedFoo, GetA, ());
376 LLDB_REGISTER_METHOD(int &, InstrumentedFoo, GetB, ());
377 LLDB_REGISTER_METHOD(float, InstrumentedFoo, GetC, ());
378 LLDB_REGISTER_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t));
379 LLDB_REGISTER_METHOD(double, InstrumentedFoo, GetE, ());
380 LLDB_REGISTER_METHOD(bool, InstrumentedFoo, GetF, ());
381 }
382
383 static const Pod p;
384
TEST(IndexToObjectTest,ObjectForIndex)385 TEST(IndexToObjectTest, ObjectForIndex) {
386 IndexToObject index_to_object;
387 Foo foo;
388 Bar bar;
389
390 EXPECT_EQ(nullptr, index_to_object.GetObjectForIndex<Foo>(1));
391 EXPECT_EQ(nullptr, index_to_object.GetObjectForIndex<Bar>(2));
392
393 index_to_object.AddObjectForIndex<Foo>(1, foo);
394 index_to_object.AddObjectForIndex<Bar>(2, &bar);
395
396 EXPECT_EQ(&foo, index_to_object.GetObjectForIndex<Foo>(1));
397 EXPECT_EQ(&bar, index_to_object.GetObjectForIndex<Bar>(2));
398 }
399
TEST(DeserializerTest,HasData)400 TEST(DeserializerTest, HasData) {
401 {
402 Deserializer deserializer("");
403 EXPECT_FALSE(deserializer.HasData(1));
404 }
405
406 {
407 Deserializer deserializer("a");
408 EXPECT_TRUE(deserializer.HasData(1));
409 EXPECT_FALSE(deserializer.HasData(2));
410 }
411 }
412
TEST(SerializationRountripTest,SerializeDeserializePod)413 TEST(SerializationRountripTest, SerializeDeserializePod) {
414 std::string str;
415 llvm::raw_string_ostream os(str);
416
417 Serializer serializer(os);
418 serializer.SerializeAll(p.a, p.b, p.c, p.d, p.e, p.f, p.g, p.h, p.i, p.j, p.k,
419 p.l, p.m);
420
421 llvm::StringRef buffer(os.str());
422 Deserializer deserializer(buffer);
423
424 EXPECT_EQ(p.a, deserializer.Deserialize<bool>());
425 EXPECT_EQ(p.b, deserializer.Deserialize<bool>());
426 EXPECT_EQ(p.c, deserializer.Deserialize<char>());
427 EXPECT_EQ(p.d, deserializer.Deserialize<float>());
428 EXPECT_EQ(p.e, deserializer.Deserialize<int>());
429 EXPECT_EQ(p.f, deserializer.Deserialize<long long>());
430 EXPECT_EQ(p.g, deserializer.Deserialize<long>());
431 EXPECT_EQ(p.h, deserializer.Deserialize<short>());
432 EXPECT_EQ(p.i, deserializer.Deserialize<unsigned char>());
433 EXPECT_EQ(p.j, deserializer.Deserialize<unsigned int>());
434 EXPECT_EQ(p.k, deserializer.Deserialize<unsigned long long>());
435 EXPECT_EQ(p.l, deserializer.Deserialize<unsigned long>());
436 EXPECT_EQ(p.m, deserializer.Deserialize<unsigned short>());
437 }
438
TEST(SerializationRountripTest,SerializeDeserializePodPointers)439 TEST(SerializationRountripTest, SerializeDeserializePodPointers) {
440 std::string str;
441 llvm::raw_string_ostream os(str);
442
443 Serializer serializer(os);
444 serializer.SerializeAll(&p.a, &p.b, &p.c, &p.d, &p.e, &p.f, &p.g, &p.h, &p.i,
445 &p.j, &p.k, &p.l, &p.m);
446
447 llvm::StringRef buffer(os.str());
448 Deserializer deserializer(buffer);
449
450 EXPECT_EQ(p.a, *deserializer.Deserialize<bool *>());
451 EXPECT_EQ(p.b, *deserializer.Deserialize<bool *>());
452 EXPECT_EQ(p.c, *deserializer.Deserialize<char *>());
453 EXPECT_EQ(p.d, *deserializer.Deserialize<float *>());
454 EXPECT_EQ(p.e, *deserializer.Deserialize<int *>());
455 EXPECT_EQ(p.f, *deserializer.Deserialize<long long *>());
456 EXPECT_EQ(p.g, *deserializer.Deserialize<long *>());
457 EXPECT_EQ(p.h, *deserializer.Deserialize<short *>());
458 EXPECT_EQ(p.i, *deserializer.Deserialize<unsigned char *>());
459 EXPECT_EQ(p.j, *deserializer.Deserialize<unsigned int *>());
460 EXPECT_EQ(p.k, *deserializer.Deserialize<unsigned long long *>());
461 EXPECT_EQ(p.l, *deserializer.Deserialize<unsigned long *>());
462 EXPECT_EQ(p.m, *deserializer.Deserialize<unsigned short *>());
463 }
464
TEST(SerializationRountripTest,SerializeDeserializePodReferences)465 TEST(SerializationRountripTest, SerializeDeserializePodReferences) {
466 std::string str;
467 llvm::raw_string_ostream os(str);
468
469 Serializer serializer(os);
470 serializer.SerializeAll(p.a, p.b, p.c, p.d, p.e, p.f, p.g, p.h, p.i, p.j, p.k,
471 p.l, p.m);
472
473 llvm::StringRef buffer(os.str());
474 Deserializer deserializer(buffer);
475
476 EXPECT_EQ(p.a, deserializer.Deserialize<bool &>());
477 EXPECT_EQ(p.b, deserializer.Deserialize<bool &>());
478 EXPECT_EQ(p.c, deserializer.Deserialize<char &>());
479 EXPECT_EQ(p.d, deserializer.Deserialize<float &>());
480 EXPECT_EQ(p.e, deserializer.Deserialize<int &>());
481 EXPECT_EQ(p.f, deserializer.Deserialize<long long &>());
482 EXPECT_EQ(p.g, deserializer.Deserialize<long &>());
483 EXPECT_EQ(p.h, deserializer.Deserialize<short &>());
484 EXPECT_EQ(p.i, deserializer.Deserialize<unsigned char &>());
485 EXPECT_EQ(p.j, deserializer.Deserialize<unsigned int &>());
486 EXPECT_EQ(p.k, deserializer.Deserialize<unsigned long long &>());
487 EXPECT_EQ(p.l, deserializer.Deserialize<unsigned long &>());
488 EXPECT_EQ(p.m, deserializer.Deserialize<unsigned short &>());
489 }
490
TEST(SerializationRountripTest,SerializeDeserializeCString)491 TEST(SerializationRountripTest, SerializeDeserializeCString) {
492 const char *cstr = "string";
493
494 std::string str;
495 llvm::raw_string_ostream os(str);
496
497 Serializer serializer(os);
498 serializer.SerializeAll(cstr);
499
500 llvm::StringRef buffer(os.str());
501 Deserializer deserializer(buffer);
502
503 EXPECT_STREQ(cstr, deserializer.Deserialize<const char *>());
504 }
505
TEST(SerializationRountripTest,SerializeDeserializeCStringNull)506 TEST(SerializationRountripTest, SerializeDeserializeCStringNull) {
507 const char *cstr = nullptr;
508
509 std::string str;
510 llvm::raw_string_ostream os(str);
511
512 Serializer serializer(os);
513 serializer.SerializeAll(cstr);
514
515 llvm::StringRef buffer(os.str());
516 Deserializer deserializer(buffer);
517
518 EXPECT_EQ(nullptr, deserializer.Deserialize<const char *>());
519 }
520
TEST(SerializationRountripTest,SerializeDeserializeCStringArray)521 TEST(SerializationRountripTest, SerializeDeserializeCStringArray) {
522 const char *foo = "foo";
523 const char *bar = "bar";
524 const char *baz = "baz";
525 const char *arr[4] = {foo, bar, baz, nullptr};
526
527 std::string str;
528 llvm::raw_string_ostream os(str);
529
530 Serializer serializer(os);
531 serializer.SerializeAll(static_cast<const char **>(arr));
532
533 llvm::StringRef buffer(os.str());
534 Deserializer deserializer(buffer);
535
536 const char **deserialized = deserializer.Deserialize<const char **>();
537 EXPECT_STREQ("foo", deserialized[0]);
538 EXPECT_STREQ("bar", deserialized[1]);
539 EXPECT_STREQ("baz", deserialized[2]);
540 }
541
TEST(SerializationRountripTest,SerializeDeserializeCStringArrayNullptrElem)542 TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptrElem) {
543 const char *arr[1] = {nullptr};
544
545 std::string str;
546 llvm::raw_string_ostream os(str);
547
548 Serializer serializer(os);
549 serializer.SerializeAll(static_cast<const char **>(arr));
550
551 llvm::StringRef buffer(os.str());
552 Deserializer deserializer(buffer);
553
554 const char **deserialized = deserializer.Deserialize<const char **>();
555 EXPECT_EQ(nullptr, deserialized);
556 }
557
TEST(SerializationRountripTest,SerializeDeserializeCStringArrayNullptr)558 TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptr) {
559 std::string str;
560 llvm::raw_string_ostream os(str);
561
562 Serializer serializer(os);
563 serializer.SerializeAll(static_cast<const char **>(nullptr));
564
565 llvm::StringRef buffer(os.str());
566 Deserializer deserializer(buffer);
567
568 const char **deserialized = deserializer.Deserialize<const char **>();
569 EXPECT_EQ(nullptr, deserialized);
570 }
571
TEST(SerializationRountripTest,SerializeDeserializeObjectPointer)572 TEST(SerializationRountripTest, SerializeDeserializeObjectPointer) {
573 Foo foo;
574 Bar bar;
575
576 std::string str;
577 llvm::raw_string_ostream os(str);
578
579 Serializer serializer(os);
580 serializer.SerializeAll(static_cast<unsigned>(1), static_cast<unsigned>(2));
581 serializer.SerializeAll(&foo, &bar);
582
583 llvm::StringRef buffer(os.str());
584 Deserializer deserializer(buffer);
585
586 deserializer.HandleReplayResult(&foo);
587 deserializer.HandleReplayResult(&bar);
588
589 EXPECT_EQ(foo, *deserializer.Deserialize<Foo *>());
590 EXPECT_EQ(bar, *deserializer.Deserialize<Bar *>());
591 }
592
TEST(SerializationRountripTest,SerializeDeserializeObjectReference)593 TEST(SerializationRountripTest, SerializeDeserializeObjectReference) {
594 Foo foo;
595 Bar bar;
596
597 std::string str;
598 llvm::raw_string_ostream os(str);
599
600 Serializer serializer(os);
601 serializer.SerializeAll(static_cast<unsigned>(1), static_cast<unsigned>(2));
602 serializer.SerializeAll(foo, bar);
603
604 llvm::StringRef buffer(os.str());
605 Deserializer deserializer(buffer);
606
607 deserializer.HandleReplayResult(&foo);
608 deserializer.HandleReplayResult(&bar);
609
610 EXPECT_EQ(foo, deserializer.Deserialize<Foo &>());
611 EXPECT_EQ(bar, deserializer.Deserialize<Bar &>());
612 }
613
TEST(RecordReplayTest,InstrumentedFoo)614 TEST(RecordReplayTest, InstrumentedFoo) {
615 std::string str;
616 llvm::raw_string_ostream os(str);
617
618 {
619 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
620
621 int b = 200;
622 float c = 300.3f;
623 double e = 400.4;
624
625 InstrumentedFoo foo(0);
626 foo.A(100);
627 foo.B(b);
628 foo.C(&c);
629 foo.D("bar");
630 InstrumentedFoo::E(e);
631 InstrumentedFoo::F();
632 foo.Validate();
633 }
634
635 TestingRegistry registry;
636 Deserializer deserializer(os.str());
637 registry.Replay(deserializer);
638
639 ValidateObjects(deserializer.GetAllObjects(),
640 {{Class::Foo, Validator::valid}});
641 }
642
TEST(RecordReplayTest,InstrumentedFooSameThis)643 TEST(RecordReplayTest, InstrumentedFooSameThis) {
644 std::string str;
645 llvm::raw_string_ostream os(str);
646
647 {
648 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
649
650 int b = 200;
651 float c = 300.3f;
652 double e = 400.4;
653
654 InstrumentedFoo *foo = new InstrumentedFoo(0);
655 foo->A(100);
656 foo->B(b);
657 foo->C(&c);
658 foo->D("bar");
659 InstrumentedFoo::E(e);
660 InstrumentedFoo::F();
661 foo->Validate();
662 foo->~InstrumentedFoo();
663
664 InstrumentedFoo *foo2 = new (foo) InstrumentedFoo(0);
665 foo2->A(100);
666 foo2->B(b);
667 foo2->C(&c);
668 foo2->D("bar");
669 InstrumentedFoo::E(e);
670 InstrumentedFoo::F();
671 foo2->Validate();
672 delete foo2;
673 }
674
675 TestingRegistry registry;
676 Deserializer deserializer(os.str());
677 registry.Replay(deserializer);
678
679 ValidateObjects(deserializer.GetAllObjects(),
680 {{Class::Foo, Validator::valid}});
681 }
682
TEST(RecordReplayTest,InstrumentedBar)683 TEST(RecordReplayTest, InstrumentedBar) {
684 std::string str;
685 llvm::raw_string_ostream os(str);
686
687 {
688 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
689
690 InstrumentedBar bar;
691 InstrumentedFoo foo = bar.GetInstrumentedFoo();
692
693 int b = 200;
694 float c = 300.3f;
695 double e = 400.4;
696
697 foo.A(100);
698 foo.B(b);
699 foo.C(&c);
700 foo.D("bar");
701 InstrumentedFoo::E(e);
702 InstrumentedFoo::F();
703 foo.Validate();
704
705 bar.SetInstrumentedFoo(foo);
706 bar.SetInstrumentedFoo(&foo);
707 bar.Validate();
708 }
709
710 TestingRegistry registry;
711 Deserializer deserializer(os.str());
712 registry.Replay(deserializer);
713
714 ValidateObjects(
715 deserializer.GetAllObjects(),
716 {
717 {Class::Bar, Validator::valid}, // bar
718 {Class::Foo, Validator::invalid}, // bar.GetInstrumentedFoo()
719 {Class::Foo, Validator::valid}, // foo
720 });
721 }
722
TEST(RecordReplayTest,InstrumentedBarRef)723 TEST(RecordReplayTest, InstrumentedBarRef) {
724 std::string str;
725 llvm::raw_string_ostream os(str);
726
727 {
728 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
729
730 InstrumentedBar bar;
731 InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
732
733 int b = 200;
734 float c = 300.3f;
735 double e = 400.4;
736
737 foo.A(100);
738 foo.B(b);
739 foo.C(&c);
740 foo.D("bar");
741 InstrumentedFoo::E(e);
742 InstrumentedFoo::F();
743 foo.Validate();
744
745 bar.SetInstrumentedFoo(foo);
746 bar.SetInstrumentedFoo(&foo);
747 bar.Validate();
748 }
749
750 TestingRegistry registry;
751 Deserializer deserializer(os.str());
752 registry.Replay(deserializer);
753
754 ValidateObjects(
755 deserializer.GetAllObjects(),
756 {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}});
757 }
758
TEST(RecordReplayTest,InstrumentedBarPtr)759 TEST(RecordReplayTest, InstrumentedBarPtr) {
760 std::string str;
761 llvm::raw_string_ostream os(str);
762
763 {
764 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
765
766 InstrumentedBar bar;
767 InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
768
769 int b = 200;
770 float c = 300.3f;
771 double e = 400.4;
772
773 foo.A(100);
774 foo.B(b);
775 foo.C(&c);
776 foo.D("bar");
777 InstrumentedFoo::E(e);
778 InstrumentedFoo::F();
779 foo.Validate();
780
781 bar.SetInstrumentedFoo(foo);
782 bar.SetInstrumentedFoo(&foo);
783 bar.Validate();
784 }
785
786 TestingRegistry registry;
787 Deserializer deserializer(os.str());
788 registry.Replay(deserializer);
789
790 ValidateObjects(
791 deserializer.GetAllObjects(),
792 {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}});
793 }
794
TEST(PassiveReplayTest,InstrumentedFoo)795 TEST(PassiveReplayTest, InstrumentedFoo) {
796 std::string str;
797 llvm::raw_string_ostream os(str);
798
799 {
800 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
801
802 int b = 200;
803 float c = 300.3f;
804 double e = 400.4;
805
806 InstrumentedFoo foo(0);
807 foo.A(100);
808 foo.B(b);
809 foo.C(&c);
810 foo.D("bar");
811 InstrumentedFoo::E(e);
812 InstrumentedFoo::F();
813 foo.Validate();
814
815 EXPECT_EQ(foo.GetA(), 100);
816 EXPECT_EQ(foo.GetB(), 200);
817 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
818 char buffer[100];
819 foo.GetD(buffer, 100);
820 EXPECT_STREQ(buffer, "bar");
821 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
822 EXPECT_EQ(foo.GetF(), true);
823 }
824
825 std::string buffer = os.str();
826
827 {
828 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
829
830 int b = 999;
831 float c = 999.9f;
832 double e = 999.9;
833
834 InstrumentedFoo foo(9);
835 foo.A(999);
836 foo.B(b);
837 foo.C(&c);
838 foo.D("999");
839 InstrumentedFoo::E(e);
840 InstrumentedFoo::F();
841 foo.Validate();
842
843 EXPECT_EQ(foo.GetA(), 100);
844 EXPECT_EQ(foo.GetB(), 200);
845 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
846 char buffer[100];
847 foo.GetD(buffer, 100);
848 EXPECT_STREQ(buffer, "bar");
849 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
850 EXPECT_EQ(foo.GetF(), true);
851 }
852 }
853
TEST(PassiveReplayTest,InstrumentedFooInvalid)854 TEST(PassiveReplayTest, InstrumentedFooInvalid) {
855 std::string str;
856 llvm::raw_string_ostream os(str);
857
858 {
859 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
860
861 int b = 200;
862 float c = 300.3f;
863 double e = 400.4;
864
865 InstrumentedFoo foo(0);
866 foo.A(100);
867 foo.B(b);
868 foo.C(&c);
869 foo.D("bar");
870 InstrumentedFoo::E(e);
871 InstrumentedFoo::F();
872 foo.Validate();
873
874 EXPECT_EQ(foo.GetA(), 100);
875 EXPECT_EQ(foo.GetB(), 200);
876 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
877 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
878 EXPECT_EQ(foo.GetF(), true);
879 }
880
881 std::string buffer = os.str();
882
883 {
884 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
885
886 int b = 999;
887 float c = 999.9f;
888 double e = 999.9;
889
890 InstrumentedFoo foo(9);
891 foo.A(999);
892 foo.B(b);
893 foo.C(&c);
894 foo.D("999");
895 InstrumentedFoo::E(e);
896 InstrumentedFoo::F();
897 foo.Validate();
898
899 EXPECT_EQ(foo.GetA(), 100);
900 // Detect divergence.
901 EXPECT_DEATH(foo.GetA(), "");
902 }
903 }
904
TEST(PassiveReplayTest,InstrumentedBar)905 TEST(PassiveReplayTest, InstrumentedBar) {
906 std::string str;
907 llvm::raw_string_ostream os(str);
908
909 {
910 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
911
912 InstrumentedBar bar;
913 InstrumentedFoo foo = bar.GetInstrumentedFoo();
914
915 int b = 200;
916 float c = 300.3f;
917 double e = 400.4;
918
919 foo.A(100);
920 foo.B(b);
921 foo.C(&c);
922 foo.D("bar");
923 InstrumentedFoo::E(e);
924 InstrumentedFoo::F();
925 foo.Validate();
926
927 EXPECT_EQ(foo.GetA(), 100);
928 EXPECT_EQ(foo.GetB(), 200);
929 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
930 char buffer[100];
931 foo.GetD(buffer, 100);
932 EXPECT_STREQ(buffer, "bar");
933 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
934 EXPECT_EQ(foo.GetF(), true);
935
936 bar.SetInstrumentedFoo(foo);
937 bar.SetInstrumentedFoo(&foo);
938 bar.Validate();
939 }
940
941 std::string buffer = os.str();
942
943 {
944 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
945
946 InstrumentedBar bar;
947 InstrumentedFoo foo = bar.GetInstrumentedFoo();
948
949 int b = 99;
950 float c = 999.9f;
951 double e = 999.9;
952
953 foo.A(999);
954 foo.B(b);
955 foo.C(&c);
956 foo.D("999");
957 InstrumentedFoo::E(e);
958 InstrumentedFoo::F();
959 foo.Validate();
960
961 EXPECT_EQ(foo.GetA(), 100);
962 EXPECT_EQ(foo.GetB(), 200);
963 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
964 char buffer[100];
965 foo.GetD(buffer, 100);
966 EXPECT_STREQ(buffer, "bar");
967 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
968 EXPECT_EQ(foo.GetF(), true);
969
970 bar.SetInstrumentedFoo(foo);
971 bar.SetInstrumentedFoo(&foo);
972 bar.Validate();
973 }
974 }
975
TEST(PassiveReplayTest,InstrumentedBarRef)976 TEST(PassiveReplayTest, InstrumentedBarRef) {
977 std::string str;
978 llvm::raw_string_ostream os(str);
979
980 {
981 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
982
983 InstrumentedBar bar;
984 InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
985
986 int b = 200;
987 float c = 300.3f;
988 double e = 400.4;
989
990 foo.A(100);
991 foo.B(b);
992 foo.C(&c);
993 foo.D("bar");
994 InstrumentedFoo::E(e);
995 InstrumentedFoo::F();
996 foo.Validate();
997
998 EXPECT_EQ(foo.GetA(), 100);
999 EXPECT_EQ(foo.GetB(), 200);
1000 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1001 char buffer[100];
1002 foo.GetD(buffer, 100);
1003 EXPECT_STREQ(buffer, "bar");
1004 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1005 EXPECT_EQ(foo.GetF(), true);
1006
1007 bar.SetInstrumentedFoo(foo);
1008 bar.SetInstrumentedFoo(&foo);
1009 bar.Validate();
1010 }
1011
1012 std::string buffer = os.str();
1013
1014 {
1015 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
1016
1017 InstrumentedBar bar;
1018 InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
1019
1020 int b = 99;
1021 float c = 999.9f;
1022 double e = 999.9;
1023
1024 foo.A(999);
1025 foo.B(b);
1026 foo.C(&c);
1027 foo.D("999");
1028 InstrumentedFoo::E(e);
1029 InstrumentedFoo::F();
1030 foo.Validate();
1031
1032 EXPECT_EQ(foo.GetA(), 100);
1033 EXPECT_EQ(foo.GetB(), 200);
1034 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1035 char buffer[100];
1036 foo.GetD(buffer, 100);
1037 EXPECT_STREQ(buffer, "bar");
1038 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1039 EXPECT_EQ(foo.GetF(), true);
1040
1041 bar.SetInstrumentedFoo(foo);
1042 bar.SetInstrumentedFoo(&foo);
1043 bar.Validate();
1044 }
1045 }
1046
TEST(PassiveReplayTest,InstrumentedBarPtr)1047 TEST(PassiveReplayTest, InstrumentedBarPtr) {
1048 std::string str;
1049 llvm::raw_string_ostream os(str);
1050
1051 {
1052 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1053
1054 InstrumentedBar bar;
1055 InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
1056
1057 int b = 200;
1058 float c = 300.3f;
1059 double e = 400.4;
1060
1061 foo.A(100);
1062 foo.B(b);
1063 foo.C(&c);
1064 foo.D("bar");
1065 InstrumentedFoo::E(e);
1066 InstrumentedFoo::F();
1067 foo.Validate();
1068
1069 EXPECT_EQ(foo.GetA(), 100);
1070 EXPECT_EQ(foo.GetB(), 200);
1071 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1072 char buffer[100];
1073 foo.GetD(buffer, 100);
1074 EXPECT_STREQ(buffer, "bar");
1075 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1076 EXPECT_EQ(foo.GetF(), true);
1077
1078 bar.SetInstrumentedFoo(foo);
1079 bar.SetInstrumentedFoo(&foo);
1080 bar.Validate();
1081 }
1082
1083 std::string buffer = os.str();
1084
1085 {
1086 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
1087
1088 InstrumentedBar bar;
1089 InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
1090
1091 int b = 99;
1092 float c = 999.9f;
1093 double e = 999.9;
1094
1095 foo.A(999);
1096 foo.B(b);
1097 foo.C(&c);
1098 foo.D("999");
1099 InstrumentedFoo::E(e);
1100 InstrumentedFoo::F();
1101 foo.Validate();
1102
1103 EXPECT_EQ(foo.GetA(), 100);
1104 EXPECT_EQ(foo.GetB(), 200);
1105 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1106 char buffer[100];
1107 foo.GetD(buffer, 100);
1108 EXPECT_STREQ(buffer, "bar");
1109 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1110 EXPECT_EQ(foo.GetF(), true);
1111
1112 bar.SetInstrumentedFoo(foo);
1113 bar.SetInstrumentedFoo(&foo);
1114 bar.Validate();
1115 }
1116 }
1117