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