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( 56 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), 57 Succeeded()); 58 EXPECT_NE(nullptr, reproducer.GetGenerator()); 59 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), 60 reproducer.GetGenerator()->GetRoot()); 61 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), 62 reproducer.GetReproducerPath()); 63 64 // Ensure that we cannot enable replay. 65 EXPECT_THAT_ERROR( 66 reproducer.SetReplay(FileSpec("//bogus/path", FileSpec::Style::posix)), 67 Failed()); 68 EXPECT_EQ(nullptr, reproducer.GetLoader()); 69 70 // Ensure we can disable the generator again. 71 EXPECT_THAT_ERROR(reproducer.SetCapture(llvm::None), Succeeded()); 72 EXPECT_EQ(nullptr, reproducer.GetGenerator()); 73 EXPECT_EQ(nullptr, reproducer.GetLoader()); 74 } 75 76 TEST(ReproducerTest, SetReplay) { 77 DummyReproducer reproducer; 78 79 // Initially both generator and loader are unset. 80 EXPECT_EQ(nullptr, reproducer.GetGenerator()); 81 EXPECT_EQ(nullptr, reproducer.GetLoader()); 82 83 // Expected to fail because we can't load the index. 84 EXPECT_THAT_ERROR( 85 reproducer.SetReplay(FileSpec("//bogus/path", FileSpec::Style::posix)), 86 Failed()); 87 // However the loader should still be set, which we check here. 88 EXPECT_NE(nullptr, reproducer.GetLoader()); 89 90 // Make sure the bogus path is correctly set. 91 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), 92 reproducer.GetLoader()->GetRoot()); 93 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), 94 reproducer.GetReproducerPath()); 95 96 // Ensure that we cannot enable replay. 97 EXPECT_THAT_ERROR( 98 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), 99 Failed()); 100 EXPECT_EQ(nullptr, reproducer.GetGenerator()); 101 } 102 103 TEST(GeneratorTest, Create) { 104 DummyReproducer reproducer; 105 106 EXPECT_THAT_ERROR( 107 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), 108 Succeeded()); 109 auto &generator = *reproducer.GetGenerator(); 110 111 auto *provider = generator.Create<DummyProvider>(); 112 EXPECT_NE(nullptr, provider); 113 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), 114 provider->GetRoot()); 115 } 116 117 TEST(GeneratorTest, Get) { 118 DummyReproducer reproducer; 119 120 EXPECT_THAT_ERROR( 121 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), 122 Succeeded()); 123 auto &generator = *reproducer.GetGenerator(); 124 125 auto *provider = generator.Create<DummyProvider>(); 126 EXPECT_NE(nullptr, provider); 127 128 auto *provider_alt = generator.Get<DummyProvider>(); 129 EXPECT_EQ(provider, provider_alt); 130 } 131 132 TEST(GeneratorTest, GetOrCreate) { 133 DummyReproducer reproducer; 134 135 EXPECT_THAT_ERROR( 136 reproducer.SetCapture(FileSpec("//bogus/path", FileSpec::Style::posix)), 137 Succeeded()); 138 auto &generator = *reproducer.GetGenerator(); 139 140 auto &provider = generator.GetOrCreate<DummyProvider>(); 141 EXPECT_EQ(FileSpec("//bogus/path", FileSpec::Style::posix), 142 provider.GetRoot()); 143 144 auto &provider_alt = generator.GetOrCreate<DummyProvider>(); 145 EXPECT_EQ(&provider, &provider_alt); 146 } 147