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"
TEST(RegularExpression,Valid)16
17 using namespace lldb_private;
18 using namespace lldb_private::repro;
19
20 struct Foo {
21 int m = 1;
22 };
23 struct Bar {
TEST(RegularExpression,CopyAssignment)24 double m = 2;
25 };
26
27 bool operator==(const Foo &LHS, const Foo &RHS) { return LHS.m == RHS.m; }
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;
TEST(RegularExpression,Empty)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;
TEST(RegularExpression,Invalid)43 unsigned short m = 9;
44
45 Pod() {}
46 };
47
48 class TestingRegistry : public Registry {
49 public:
50 TestingRegistry();
51 };
52
TEST(RegularExpression,Match)53 static std::unique_ptr<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:
59 TestInstrumentationData() : InstrumentationData() {}
60 TestInstrumentationData(Serializer &serializer, Registry ®istry)
61 : InstrumentationData(serializer, registry) {}
62 TestInstrumentationData(Deserializer &deserializer, Registry ®istry)
63 : InstrumentationData(deserializer, registry) {}
64 };
65
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:
77 TestInstrumentationDataRAII(llvm::raw_string_ostream &os) {
78 g_registry = std::make_unique<TestingRegistry>();
79 g_serializer.emplace(os);
80 g_deserializer.reset();
81 }
82
83 TestInstrumentationDataRAII(llvm::StringRef buffer) {
84 g_registry = std::make_unique<TestingRegistry>();
85 g_serializer.reset();
86 g_deserializer.emplace(buffer);
87 }
88
89 ~TestInstrumentationDataRAII() { Reset(); }
90
91 void Reset() {
92 g_registry.reset();
93 g_serializer.reset();
94 g_deserializer.reset();
95 }
96
97 static std::unique_ptr<TestInstrumentationDataRAII>
98 GetRecordingData(llvm::raw_string_ostream &os) {
99 return std::make_unique<TestInstrumentationDataRAII>(os);
100 }
101
102 static std::unique_ptr<TestInstrumentationDataRAII>
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 //// }
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 /// }
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 };
181 Validator(Class clazz, Validation validation)
182 : clazz(clazz), validation(validation) {}
183 Class clazz;
184 Validation validation;
185 };
186
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
204 InstrumentedFoo::InstrumentedFoo(int i) {
205 LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (int), i);
206 }
207
208 InstrumentedFoo::InstrumentedFoo(const InstrumentedFoo &foo) {
209 LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &), foo);
210 }
211
212 InstrumentedFoo &InstrumentedFoo::operator=(const InstrumentedFoo &foo) {
213 LLDB_RECORD_METHOD(InstrumentedFoo &,
214 InstrumentedFoo, operator=,(const InstrumentedFoo &), foo);
215 return *this;
216 }
217
218 void InstrumentedFoo::A(int a) {
219 LLDB_RECORD_METHOD(void, InstrumentedFoo, A, (int), a);
220 B(a);
221 m_a = a;
222 }
223
224 int InstrumentedFoo::GetA() {
225 LLDB_RECORD_METHOD_NO_ARGS(int, InstrumentedFoo, GetA);
226
227 return m_a;
228 }
229
230 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
236 int &InstrumentedFoo::GetB() {
237 LLDB_RECORD_METHOD_NO_ARGS(int &, InstrumentedFoo, GetB);
238
239 return m_b;
240 }
241
242 int InstrumentedFoo::C(float *c) {
243 LLDB_RECORD_METHOD(int, InstrumentedFoo, C, (float *), c);
244 m_c = *c;
245 return 1;
246 }
247
248 float InstrumentedFoo::GetC() {
249 LLDB_RECORD_METHOD_NO_ARGS(float, InstrumentedFoo, GetC);
250
251 return m_c;
252 }
253
254 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
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
267 void InstrumentedFoo::E(double e) {
268 LLDB_RECORD_STATIC_METHOD(void, InstrumentedFoo, E, (double), e);
269 g_e = e;
270 }
271
272 double InstrumentedFoo::GetE() {
273 LLDB_RECORD_METHOD_NO_ARGS(double, InstrumentedFoo, GetE);
274
275 return g_e;
276 }
277
278 int InstrumentedFoo::F() {
279 LLDB_RECORD_STATIC_METHOD_NO_ARGS(int, InstrumentedFoo, F);
280 g_f = true;
281 return 3;
282 }
283
284 bool InstrumentedFoo::GetF() {
285 LLDB_RECORD_METHOD_NO_ARGS(bool, InstrumentedFoo, GetF);
286
287 return g_f;
288 }
289
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
301 InstrumentedBar::InstrumentedBar() {
302 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(InstrumentedBar);
303 }
304
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
572 TEST(SerializationRountripTest, SerializeDeserializeObjectPointer) {
573 Foo foo;
574 Bar bar;
575
576 std::string str;
577 llvm::raw_string_ostream os(str);
578
579 unsigned sequence = 123;
580
581 Serializer serializer(os);
582 serializer.SerializeAll(sequence, static_cast<unsigned>(1));
583 serializer.SerializeAll(sequence, static_cast<unsigned>(2));
584 serializer.SerializeAll(&foo, &bar);
585
586 llvm::StringRef buffer(os.str());
587 Deserializer deserializer(buffer);
588
589 deserializer.HandleReplayResult(&foo);
590 deserializer.HandleReplayResult(&bar);
591
592 EXPECT_EQ(foo, *deserializer.Deserialize<Foo *>());
593 EXPECT_EQ(bar, *deserializer.Deserialize<Bar *>());
594 }
595
596 TEST(SerializationRountripTest, SerializeDeserializeObjectReference) {
597 Foo foo;
598 Bar bar;
599
600 std::string str;
601 llvm::raw_string_ostream os(str);
602
603 unsigned sequence = 123;
604
605 Serializer serializer(os);
606 serializer.SerializeAll(sequence, static_cast<unsigned>(1));
607 serializer.SerializeAll(sequence, static_cast<unsigned>(2));
608 serializer.SerializeAll(foo, bar);
609
610 llvm::StringRef buffer(os.str());
611 Deserializer deserializer(buffer);
612
613 deserializer.HandleReplayResult(&foo);
614 deserializer.HandleReplayResult(&bar);
615
616 EXPECT_EQ(foo, deserializer.Deserialize<Foo &>());
617 EXPECT_EQ(bar, deserializer.Deserialize<Bar &>());
618 }
619
620 TEST(RecordReplayTest, InstrumentedFoo) {
621 std::string str;
622 llvm::raw_string_ostream os(str);
623
624 {
625 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
626
627 int b = 200;
628 float c = 300.3f;
629 double e = 400.4;
630
631 InstrumentedFoo foo(0);
632 foo.A(100);
633 foo.B(b);
634 foo.C(&c);
635 foo.D("bar");
636 InstrumentedFoo::E(e);
637 InstrumentedFoo::F();
638 foo.Validate();
639 }
640
641 TestingRegistry registry;
642 Deserializer deserializer(os.str());
643 registry.Replay(deserializer);
644
645 ValidateObjects(deserializer.GetAllObjects(),
646 {{Class::Foo, Validator::valid}});
647 }
648
649 TEST(RecordReplayTest, InstrumentedFooSameThis) {
650 std::string str;
651 llvm::raw_string_ostream os(str);
652
653 {
654 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
655
656 int b = 200;
657 float c = 300.3f;
658 double e = 400.4;
659
660 InstrumentedFoo *foo = new InstrumentedFoo(0);
661 foo->A(100);
662 foo->B(b);
663 foo->C(&c);
664 foo->D("bar");
665 InstrumentedFoo::E(e);
666 InstrumentedFoo::F();
667 foo->Validate();
668 foo->~InstrumentedFoo();
669
670 InstrumentedFoo *foo2 = new (foo) InstrumentedFoo(0);
671 foo2->A(100);
672 foo2->B(b);
673 foo2->C(&c);
674 foo2->D("bar");
675 InstrumentedFoo::E(e);
676 InstrumentedFoo::F();
677 foo2->Validate();
678 delete foo2;
679 }
680
681 TestingRegistry registry;
682 Deserializer deserializer(os.str());
683 registry.Replay(deserializer);
684
685 ValidateObjects(deserializer.GetAllObjects(),
686 {{Class::Foo, Validator::valid}});
687 }
688
689 TEST(RecordReplayTest, InstrumentedBar) {
690 std::string str;
691 llvm::raw_string_ostream os(str);
692
693 {
694 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
695
696 InstrumentedBar bar;
697 InstrumentedFoo foo = bar.GetInstrumentedFoo();
698
699 int b = 200;
700 float c = 300.3f;
701 double e = 400.4;
702
703 foo.A(100);
704 foo.B(b);
705 foo.C(&c);
706 foo.D("bar");
707 InstrumentedFoo::E(e);
708 InstrumentedFoo::F();
709 foo.Validate();
710
711 bar.SetInstrumentedFoo(foo);
712 bar.SetInstrumentedFoo(&foo);
713 bar.Validate();
714 }
715
716 TestingRegistry registry;
717 Deserializer deserializer(os.str());
718 registry.Replay(deserializer);
719
720 ValidateObjects(
721 deserializer.GetAllObjects(),
722 {
723 {Class::Bar, Validator::valid}, // bar
724 {Class::Foo, Validator::invalid}, // bar.GetInstrumentedFoo()
725 {Class::Foo, Validator::valid}, // foo
726 });
727 }
728
729 TEST(RecordReplayTest, InstrumentedBarRef) {
730 std::string str;
731 llvm::raw_string_ostream os(str);
732
733 {
734 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
735
736 InstrumentedBar bar;
737 InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
738
739 int b = 200;
740 float c = 300.3f;
741 double e = 400.4;
742
743 foo.A(100);
744 foo.B(b);
745 foo.C(&c);
746 foo.D("bar");
747 InstrumentedFoo::E(e);
748 InstrumentedFoo::F();
749 foo.Validate();
750
751 bar.SetInstrumentedFoo(foo);
752 bar.SetInstrumentedFoo(&foo);
753 bar.Validate();
754 }
755
756 TestingRegistry registry;
757 Deserializer deserializer(os.str());
758 registry.Replay(deserializer);
759
760 ValidateObjects(
761 deserializer.GetAllObjects(),
762 {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}});
763 }
764
765 TEST(RecordReplayTest, InstrumentedBarPtr) {
766 std::string str;
767 llvm::raw_string_ostream os(str);
768
769 {
770 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
771
772 InstrumentedBar bar;
773 InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
774
775 int b = 200;
776 float c = 300.3f;
777 double e = 400.4;
778
779 foo.A(100);
780 foo.B(b);
781 foo.C(&c);
782 foo.D("bar");
783 InstrumentedFoo::E(e);
784 InstrumentedFoo::F();
785 foo.Validate();
786
787 bar.SetInstrumentedFoo(foo);
788 bar.SetInstrumentedFoo(&foo);
789 bar.Validate();
790 }
791
792 TestingRegistry registry;
793 Deserializer deserializer(os.str());
794 registry.Replay(deserializer);
795
796 ValidateObjects(
797 deserializer.GetAllObjects(),
798 {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}});
799 }
800
801 TEST(PassiveReplayTest, InstrumentedFoo) {
802 std::string str;
803 llvm::raw_string_ostream os(str);
804
805 {
806 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
807
808 int b = 200;
809 float c = 300.3f;
810 double e = 400.4;
811
812 InstrumentedFoo foo(0);
813 foo.A(100);
814 foo.B(b);
815 foo.C(&c);
816 foo.D("bar");
817 InstrumentedFoo::E(e);
818 InstrumentedFoo::F();
819 foo.Validate();
820
821 EXPECT_EQ(foo.GetA(), 100);
822 EXPECT_EQ(foo.GetB(), 200);
823 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
824 char buffer[100];
825 foo.GetD(buffer, 100);
826 EXPECT_STREQ(buffer, "bar");
827 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
828 EXPECT_EQ(foo.GetF(), true);
829 }
830
831 std::string buffer = os.str();
832
833 {
834 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
835
836 int b = 999;
837 float c = 999.9f;
838 double e = 999.9;
839
840 InstrumentedFoo foo(9);
841 foo.A(999);
842 foo.B(b);
843 foo.C(&c);
844 foo.D("999");
845 InstrumentedFoo::E(e);
846 InstrumentedFoo::F();
847 foo.Validate();
848
849 EXPECT_EQ(foo.GetA(), 100);
850 EXPECT_EQ(foo.GetB(), 200);
851 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
852 char buffer[100];
853 foo.GetD(buffer, 100);
854 EXPECT_STREQ(buffer, "bar");
855 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
856 EXPECT_EQ(foo.GetF(), true);
857 }
858 }
859
860 TEST(PassiveReplayTest, InstrumentedFooInvalid) {
861 std::string str;
862 llvm::raw_string_ostream os(str);
863
864 {
865 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
866
867 int b = 200;
868 float c = 300.3f;
869 double e = 400.4;
870
871 InstrumentedFoo foo(0);
872 foo.A(100);
873 foo.B(b);
874 foo.C(&c);
875 foo.D("bar");
876 InstrumentedFoo::E(e);
877 InstrumentedFoo::F();
878 foo.Validate();
879
880 EXPECT_EQ(foo.GetA(), 100);
881 EXPECT_EQ(foo.GetB(), 200);
882 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
883 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
884 EXPECT_EQ(foo.GetF(), true);
885 }
886
887 std::string buffer = os.str();
888
889 {
890 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
891
892 int b = 999;
893 float c = 999.9f;
894 double e = 999.9;
895
896 InstrumentedFoo foo(9);
897 foo.A(999);
898 foo.B(b);
899 foo.C(&c);
900 foo.D("999");
901 InstrumentedFoo::E(e);
902 InstrumentedFoo::F();
903 foo.Validate();
904
905 EXPECT_EQ(foo.GetA(), 100);
906 // Detect divergence.
907 EXPECT_DEATH(foo.GetA(), "");
908 }
909 }
910
911 TEST(PassiveReplayTest, InstrumentedBar) {
912 std::string str;
913 llvm::raw_string_ostream os(str);
914
915 {
916 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
917
918 InstrumentedBar bar;
919 InstrumentedFoo foo = bar.GetInstrumentedFoo();
920
921 int b = 200;
922 float c = 300.3f;
923 double e = 400.4;
924
925 foo.A(100);
926 foo.B(b);
927 foo.C(&c);
928 foo.D("bar");
929 InstrumentedFoo::E(e);
930 InstrumentedFoo::F();
931 foo.Validate();
932
933 EXPECT_EQ(foo.GetA(), 100);
934 EXPECT_EQ(foo.GetB(), 200);
935 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
936 char buffer[100];
937 foo.GetD(buffer, 100);
938 EXPECT_STREQ(buffer, "bar");
939 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
940 EXPECT_EQ(foo.GetF(), true);
941
942 bar.SetInstrumentedFoo(foo);
943 bar.SetInstrumentedFoo(&foo);
944 bar.Validate();
945 }
946
947 std::string buffer = os.str();
948
949 {
950 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
951
952 InstrumentedBar bar;
953 InstrumentedFoo foo = bar.GetInstrumentedFoo();
954
955 int b = 99;
956 float c = 999.9f;
957 double e = 999.9;
958
959 foo.A(999);
960 foo.B(b);
961 foo.C(&c);
962 foo.D("999");
963 InstrumentedFoo::E(e);
964 InstrumentedFoo::F();
965 foo.Validate();
966
967 EXPECT_EQ(foo.GetA(), 100);
968 EXPECT_EQ(foo.GetB(), 200);
969 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
970 char buffer[100];
971 foo.GetD(buffer, 100);
972 EXPECT_STREQ(buffer, "bar");
973 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
974 EXPECT_EQ(foo.GetF(), true);
975
976 bar.SetInstrumentedFoo(foo);
977 bar.SetInstrumentedFoo(&foo);
978 bar.Validate();
979 }
980 }
981
982 TEST(PassiveReplayTest, InstrumentedBarRef) {
983 std::string str;
984 llvm::raw_string_ostream os(str);
985
986 {
987 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
988
989 InstrumentedBar bar;
990 InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
991
992 int b = 200;
993 float c = 300.3f;
994 double e = 400.4;
995
996 foo.A(100);
997 foo.B(b);
998 foo.C(&c);
999 foo.D("bar");
1000 InstrumentedFoo::E(e);
1001 InstrumentedFoo::F();
1002 foo.Validate();
1003
1004 EXPECT_EQ(foo.GetA(), 100);
1005 EXPECT_EQ(foo.GetB(), 200);
1006 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1007 char buffer[100];
1008 foo.GetD(buffer, 100);
1009 EXPECT_STREQ(buffer, "bar");
1010 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1011 EXPECT_EQ(foo.GetF(), true);
1012
1013 bar.SetInstrumentedFoo(foo);
1014 bar.SetInstrumentedFoo(&foo);
1015 bar.Validate();
1016 }
1017
1018 std::string buffer = os.str();
1019
1020 {
1021 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
1022
1023 InstrumentedBar bar;
1024 InstrumentedFoo &foo = bar.GetInstrumentedFooRef();
1025
1026 int b = 99;
1027 float c = 999.9f;
1028 double e = 999.9;
1029
1030 foo.A(999);
1031 foo.B(b);
1032 foo.C(&c);
1033 foo.D("999");
1034 InstrumentedFoo::E(e);
1035 InstrumentedFoo::F();
1036 foo.Validate();
1037
1038 EXPECT_EQ(foo.GetA(), 100);
1039 EXPECT_EQ(foo.GetB(), 200);
1040 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1041 char buffer[100];
1042 foo.GetD(buffer, 100);
1043 EXPECT_STREQ(buffer, "bar");
1044 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1045 EXPECT_EQ(foo.GetF(), true);
1046
1047 bar.SetInstrumentedFoo(foo);
1048 bar.SetInstrumentedFoo(&foo);
1049 bar.Validate();
1050 }
1051 }
1052
1053 TEST(PassiveReplayTest, InstrumentedBarPtr) {
1054 std::string str;
1055 llvm::raw_string_ostream os(str);
1056
1057 {
1058 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1059
1060 InstrumentedBar bar;
1061 InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
1062
1063 int b = 200;
1064 float c = 300.3f;
1065 double e = 400.4;
1066
1067 foo.A(100);
1068 foo.B(b);
1069 foo.C(&c);
1070 foo.D("bar");
1071 InstrumentedFoo::E(e);
1072 InstrumentedFoo::F();
1073 foo.Validate();
1074
1075 EXPECT_EQ(foo.GetA(), 100);
1076 EXPECT_EQ(foo.GetB(), 200);
1077 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1078 char buffer[100];
1079 foo.GetD(buffer, 100);
1080 EXPECT_STREQ(buffer, "bar");
1081 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1082 EXPECT_EQ(foo.GetF(), true);
1083
1084 bar.SetInstrumentedFoo(foo);
1085 bar.SetInstrumentedFoo(&foo);
1086 bar.Validate();
1087 }
1088
1089 std::string buffer = os.str();
1090
1091 {
1092 auto data = TestInstrumentationDataRAII::GetReplayData(buffer);
1093
1094 InstrumentedBar bar;
1095 InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr());
1096
1097 int b = 99;
1098 float c = 999.9f;
1099 double e = 999.9;
1100
1101 foo.A(999);
1102 foo.B(b);
1103 foo.C(&c);
1104 foo.D("999");
1105 InstrumentedFoo::E(e);
1106 InstrumentedFoo::F();
1107 foo.Validate();
1108
1109 EXPECT_EQ(foo.GetA(), 100);
1110 EXPECT_EQ(foo.GetB(), 200);
1111 EXPECT_NEAR(foo.GetC(), 300.3, 0.01);
1112 char buffer[100];
1113 foo.GetD(buffer, 100);
1114 EXPECT_STREQ(buffer, "bar");
1115 EXPECT_NEAR(foo.GetE(), 400.4, 0.01);
1116 EXPECT_EQ(foo.GetF(), true);
1117
1118 bar.SetInstrumentedFoo(foo);
1119 bar.SetInstrumentedFoo(&foo);
1120 bar.Validate();
1121 }
1122 }
1123
1124 TEST(RecordReplayTest, ValidSequence) {
1125 std::string str;
1126 llvm::raw_string_ostream os(str);
1127
1128 {
1129 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1130
1131 unsigned sequence = 1;
1132 int (*f)() = &lldb_private::repro::invoke<int (*)()>::method<
1133 InstrumentedFoo::F>::record;
1134 unsigned id = g_registry->GetID(uintptr_t(f));
1135 g_serializer->SerializeAll(sequence, id);
1136
1137 unsigned result = 0;
1138 g_serializer->SerializeAll(sequence, result);
1139 }
1140
1141 TestingRegistry registry;
1142 Deserializer deserializer(os.str());
1143 registry.Replay(deserializer);
1144 }
1145
1146 TEST(RecordReplayTest, InvalidSequence) {
1147 std::string str;
1148 llvm::raw_string_ostream os(str);
1149
1150 {
1151 auto data = TestInstrumentationDataRAII::GetRecordingData(os);
1152
1153 unsigned sequence = 1;
1154 int (*f)() = &lldb_private::repro::invoke<int (*)()>::method<
1155 InstrumentedFoo::F>::record;
1156 unsigned id = g_registry->GetID(uintptr_t(f));
1157 g_serializer->SerializeAll(sequence, id);
1158
1159 unsigned result = 0;
1160 unsigned invalid_sequence = 2;
1161 g_serializer->SerializeAll(invalid_sequence, result);
1162 }
1163
1164 TestingRegistry registry;
1165 Deserializer deserializer(os.str());
1166 EXPECT_DEATH(registry.Replay(deserializer), "");
1167 }
1168