[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / lldb / unittests / Utility / ReproducerTest.cpp
blob71130bee736a2d6a99128de5cf5fef783903c131
1 //===-- ReproducerTest.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 //===----------------------------------------------------------------------===//
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
12 #include "lldb/Utility/FileSpec.h"
13 #include "lldb/Utility/Reproducer.h"
14 #include "lldb/Utility/ReproducerProvider.h"
15 #include "llvm/ADT/ScopeExit.h"
16 #include "llvm/Support/Error.h"
17 #include "llvm/Testing/Support/Error.h"
19 using namespace llvm;
20 using namespace lldb_private;
21 using namespace lldb_private::repro;
23 class DummyProvider : public repro::Provider<DummyProvider> {
24 public:
25 struct Info {
26 static const char *name;
27 static const char *file;
30 DummyProvider(const FileSpec &directory) : Provider(directory) {}
32 static char ID;
35 class YamlMultiProvider
36 : public MultiProvider<YamlRecorder, YamlMultiProvider> {
37 public:
38 struct Info {
39 static const char *name;
40 static const char *file;
43 YamlMultiProvider(const FileSpec &directory) : MultiProvider(directory) {}
45 static char ID;
48 const char *DummyProvider::Info::name = "dummy";
49 const char *DummyProvider::Info::file = "dummy.yaml";
50 const char *YamlMultiProvider::Info::name = "mutli";
51 const char *YamlMultiProvider::Info::file = "mutli.yaml";
52 char DummyProvider::ID = 0;
53 char YamlMultiProvider::ID = 0;
55 class DummyReproducer : public Reproducer {
56 public:
57 DummyReproducer() : Reproducer(){};
59 using Reproducer::SetCapture;
62 struct YamlData {
63 YamlData() : i(-1) {}
64 YamlData(int i) : i(i) {}
65 int i;
68 inline bool operator==(const YamlData &LHS, const YamlData &RHS) {
69 return LHS.i == RHS.i;
72 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData)
74 namespace llvm {
75 namespace yaml {
76 template <> struct MappingTraits<YamlData> {
77 static void mapping(IO &io, YamlData &Y) { io.mapRequired("i", Y.i); };
79 } // namespace yaml
80 } // namespace llvm
82 TEST(ReproducerTest, SetCapture) {
83 DummyReproducer reproducer;
85 // Initially both generator and loader are unset.
86 EXPECT_EQ(nullptr, reproducer.GetGenerator());
87 EXPECT_EQ(nullptr, reproducer.GetLoader());
89 // Enable capture and check that means we have a generator.
90 EXPECT_THAT_ERROR(
91 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)),
92 Succeeded());
93 EXPECT_NE(nullptr, reproducer.GetGenerator());
94 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix),
95 reproducer.GetGenerator()->GetRoot());
96 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix),
97 reproducer.GetReproducerPath());
99 // Ensure that we cannot enable replay.
100 EXPECT_EQ(nullptr, reproducer.GetLoader());
102 // Ensure we can disable the generator again.
103 EXPECT_THAT_ERROR(reproducer.SetCapture(llvm::None), Succeeded());
104 EXPECT_EQ(nullptr, reproducer.GetGenerator());
105 EXPECT_EQ(nullptr, reproducer.GetLoader());
108 TEST(GeneratorTest, Create) {
109 DummyReproducer reproducer;
111 EXPECT_THAT_ERROR(
112 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)),
113 Succeeded());
114 auto &generator = *reproducer.GetGenerator();
116 auto *provider = generator.Create<DummyProvider>();
117 EXPECT_NE(nullptr, provider);
118 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix),
119 provider->GetRoot());
122 TEST(GeneratorTest, Get) {
123 DummyReproducer reproducer;
125 EXPECT_THAT_ERROR(
126 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)),
127 Succeeded());
128 auto &generator = *reproducer.GetGenerator();
130 auto *provider = generator.Create<DummyProvider>();
131 EXPECT_NE(nullptr, provider);
133 auto *provider_alt = generator.Get<DummyProvider>();
134 EXPECT_EQ(provider, provider_alt);
137 TEST(GeneratorTest, GetOrCreate) {
138 DummyReproducer reproducer;
140 EXPECT_THAT_ERROR(
141 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)),
142 Succeeded());
143 auto &generator = *reproducer.GetGenerator();
145 auto &provider = generator.GetOrCreate<DummyProvider>();
146 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix),
147 provider.GetRoot());
149 auto &provider_alt = generator.GetOrCreate<DummyProvider>();
150 EXPECT_EQ(&provider, &provider_alt);
153 TEST(GeneratorTest, YamlMultiProvider) {
154 SmallString<128> root;
155 std::error_code ec = llvm::sys::fs::createUniqueDirectory("reproducer", root);
156 ASSERT_FALSE(static_cast<bool>(ec));
158 auto cleanup = llvm::make_scope_exit(
159 [&] { EXPECT_FALSE(llvm::sys::fs::remove_directories(root.str())); });
161 YamlData data0(0);
162 YamlData data1(1);
163 YamlData data2(2);
164 YamlData data3(3);
167 DummyReproducer reproducer;
168 EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec(root.str())), Succeeded());
170 auto &generator = *reproducer.GetGenerator();
171 auto *provider = generator.Create<YamlMultiProvider>();
172 ASSERT_NE(nullptr, provider);
174 auto *recorder = provider->GetNewRecorder();
175 ASSERT_NE(nullptr, recorder);
176 recorder->Record(data0);
177 recorder->Record(data1);
179 recorder = provider->GetNewRecorder();
180 ASSERT_NE(nullptr, recorder);
181 recorder->Record(data2);
182 recorder->Record(data3);
184 generator.Keep();