1 //===-- ReproducerTest.cpp --------------------------------------*- C++ -*-===//
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 "llvm/Support/Error.h"
13 #include "llvm/Testing/Support/Error.h"
14 
15 #include "lldb/Utility/FileSpec.h"
16 #include "lldb/Utility/Reproducer.h"
17 
18 using namespace llvm;
19 using namespace lldb_private;
20 using namespace lldb_private::repro;
21 
22 struct DummyInfo {
23   static const char *name;
24   static const char *file;
25 };
26 
27 const char *DummyInfo::name = "dummy";
28 const char *DummyInfo::file = "dummy.yaml";
29 
30 class DummyProvider : public repro::Provider<DummyProvider> {
31 public:
32   typedef DummyInfo info;
33 
34   DummyProvider(const FileSpec &directory) : Provider(directory) {}
35 
36   static char ID;
37 };
38 
39 class DummyReproducer : public Reproducer {
40 public:
41   DummyReproducer() : Reproducer(){};
42 
43   using Reproducer::SetCapture;
44   using Reproducer::SetReplay;
45 };
46 
47 char DummyProvider::ID = 0;
48 
49 TEST(ReproducerTest, SetCapture) {
50   DummyReproducer reproducer;
51 
52   // Initially both generator and loader are unset.
53   EXPECT_EQ(nullptr, reproducer.GetGenerator());
54   EXPECT_EQ(nullptr, reproducer.GetLoader());
55 
56   // Enable capture and check that means we have a generator.
57   EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
58                     Succeeded());
59   EXPECT_NE(nullptr, reproducer.GetGenerator());
60   EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
61   EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
62 
63   // Ensure that we cannot enable replay.
64   EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), Failed());
65   EXPECT_EQ(nullptr, reproducer.GetLoader());
66 
67   // Ensure we can disable the generator again.
68   EXPECT_THAT_ERROR(reproducer.SetCapture(llvm::None), Succeeded());
69   EXPECT_EQ(nullptr, reproducer.GetGenerator());
70   EXPECT_EQ(nullptr, reproducer.GetLoader());
71 }
72 
73 TEST(ReproducerTest, SetReplay) {
74   DummyReproducer reproducer;
75 
76   // Initially both generator and loader are unset.
77   EXPECT_EQ(nullptr, reproducer.GetGenerator());
78   EXPECT_EQ(nullptr, reproducer.GetLoader());
79 
80   // Expected to fail because we can't load the index.
81   EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), Failed());
82   // However the loader should still be set, which we check here.
83   EXPECT_NE(nullptr, reproducer.GetLoader());
84 
85   // Make sure the bogus path is correctly set.
86   EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetLoader()->GetRoot());
87   EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
88 
89   // Ensure that we cannot enable replay.
90   EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")), Failed());
91   EXPECT_EQ(nullptr, reproducer.GetGenerator());
92 }
93 
94 TEST(GeneratorTest, Create) {
95   DummyReproducer reproducer;
96 
97   EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
98                     Succeeded());
99   auto &generator = *reproducer.GetGenerator();
100 
101   auto *provider = generator.Create<DummyProvider>();
102   EXPECT_NE(nullptr, provider);
103   EXPECT_EQ(FileSpec("/bogus/path"), provider->GetRoot());
104 }
105 
106 TEST(GeneratorTest, Get) {
107   DummyReproducer reproducer;
108 
109   EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
110                     Succeeded());
111   auto &generator = *reproducer.GetGenerator();
112 
113   auto *provider = generator.Create<DummyProvider>();
114   EXPECT_NE(nullptr, provider);
115 
116   auto *provider_alt = generator.Get<DummyProvider>();
117   EXPECT_EQ(provider, provider_alt);
118 }
119 
120 TEST(GeneratorTest, GetOrCreate) {
121   DummyReproducer reproducer;
122 
123   EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
124                     Succeeded());
125   auto &generator = *reproducer.GetGenerator();
126 
127   auto &provider = generator.GetOrCreate<DummyProvider>();
128   EXPECT_EQ(FileSpec("/bogus/path"), provider.GetRoot());
129 
130   auto &provider_alt = generator.GetOrCreate<DummyProvider>();
131   EXPECT_EQ(&provider, &provider_alt);
132 }
133