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 &registry)
61       : InstrumentationData(serializer, registry) {}
TestInstrumentationData(Deserializer & deserializer,Registry & registry)62   TestInstrumentationData(Deserializer &deserializer, Registry &registry)
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