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