[Lldb-commits] [PATCH] D83441: [ldb/Reproducers] Add YamlRecorder and MultiProvider

2020-07-10 Thread Jonas Devlieghere via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
JDevlieghere marked 5 inline comments as done.
Closed by commit rG169c83208f37: [ldb/Reproducers] Add YamlRecorder and 
MultiProvider (authored by JDevlieghere).
Herald added a project: LLDB.

Changed prior to commit:
  https://reviews.llvm.org/D83441?vs=276597=277133#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83441/new/

https://reviews.llvm.org/D83441

Files:
  lldb/include/lldb/Utility/Reproducer.h
  lldb/source/API/SBDebugger.cpp
  lldb/source/Utility/Reproducer.cpp
  lldb/unittests/Utility/ReproducerTest.cpp

Index: lldb/unittests/Utility/ReproducerTest.cpp
===
--- lldb/unittests/Utility/ReproducerTest.cpp
+++ lldb/unittests/Utility/ReproducerTest.cpp
@@ -9,6 +9,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Testing/Support/Error.h"
 
@@ -31,8 +32,25 @@
   static char ID;
 };
 
+class YamlMultiProvider
+: public MultiProvider {
+public:
+  struct Info {
+static const char *name;
+static const char *file;
+  };
+
+  YamlMultiProvider(const FileSpec ) : MultiProvider(directory) {}
+
+  static char ID;
+};
+
 const char *DummyProvider::Info::name = "dummy";
 const char *DummyProvider::Info::file = "dummy.yaml";
+const char *YamlMultiProvider::Info::name = "mutli";
+const char *YamlMultiProvider::Info::file = "mutli.yaml";
+char DummyProvider::ID = 0;
+char YamlMultiProvider::ID = 0;
 
 class DummyReproducer : public Reproducer {
 public:
@@ -42,7 +60,25 @@
   using Reproducer::SetReplay;
 };
 
-char DummyProvider::ID = 0;
+struct YamlData {
+  YamlData() : i(-1) {}
+  YamlData(int i) : i(i) {}
+  int i;
+};
+
+inline bool operator==(const YamlData , const YamlData ) {
+  return LHS.i == RHS.i;
+}
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData)
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits {
+  static void mapping(IO , YamlData ) { io.mapRequired("i", Y.i); };
+};
+} // namespace yaml
+} // namespace llvm
 
 TEST(ReproducerTest, SetCapture) {
   DummyReproducer reproducer;
@@ -144,3 +180,83 @@
   auto _alt = generator.GetOrCreate();
   EXPECT_EQ(, _alt);
 }
+
+TEST(GeneratorTest, YamlMultiProvider) {
+  SmallString<128> root;
+  std::error_code ec = llvm::sys::fs::createUniqueDirectory("reproducer", root);
+  ASSERT_FALSE(static_cast(ec));
+
+  auto cleanup = llvm::make_scope_exit(
+  [&] { EXPECT_FALSE(llvm::sys::fs::remove_directories(root.str())); });
+
+  YamlData data0(0);
+  YamlData data1(1);
+  YamlData data2(2);
+  YamlData data3(3);
+
+  {
+DummyReproducer reproducer;
+EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec(root.str())), Succeeded());
+
+auto  = *reproducer.GetGenerator();
+auto *provider = generator.Create();
+ASSERT_NE(nullptr, provider);
+
+auto *recorder = provider->GetNewRecorder();
+ASSERT_NE(nullptr, recorder);
+recorder->Record(data0);
+recorder->Record(data1);
+
+recorder = provider->GetNewRecorder();
+ASSERT_NE(nullptr, recorder);
+recorder->Record(data2);
+recorder->Record(data3);
+
+generator.Keep();
+  }
+
+  {
+DummyReproducer reproducer;
+EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec(root.str())), Succeeded());
+
+auto  = *reproducer.GetLoader();
+std::unique_ptr> multi_loader =
+repro::MultiLoader::Create();
+
+// Read the first file.
+{
+  llvm::Optional file = multi_loader->GetNextFile();
+  EXPECT_TRUE(static_cast(file));
+
+  auto buffer = llvm::MemoryBuffer::getFile(*file);
+  EXPECT_TRUE(static_cast(buffer));
+
+  yaml::Input yin((*buffer)->getBuffer());
+  std::vector data;
+  yin >> data;
+
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_THAT(data, testing::ElementsAre(data0, data1));
+}
+
+// Read the second file.
+{
+  llvm::Optional file = multi_loader->GetNextFile();
+  EXPECT_TRUE(static_cast(file));
+
+  auto buffer = llvm::MemoryBuffer::getFile(*file);
+  EXPECT_TRUE(static_cast(buffer));
+
+  yaml::Input yin((*buffer)->getBuffer());
+  std::vector data;
+  yin >> data;
+
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_THAT(data, testing::ElementsAre(data2, data3));
+}
+
+// There is no third file.
+llvm::Optional file = multi_loader->GetNextFile();
+EXPECT_FALSE(static_cast(file));
+  }
+}
Index: lldb/source/Utility/Reproducer.cpp
===
--- lldb/source/Utility/Reproducer.cpp
+++ lldb/source/Utility/Reproducer.cpp
@@ -272,40 +272,15 @@
   return std::move(recorder);
 }
 
-DataRecorder *CommandProvider::GetNewDataRecorder() {
-  std::size_t i = m_data_recorders.size() + 1;
-  std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
-  llvm::Twine(i) + 

[Lldb-commits] [PATCH] D83441: [ldb/Reproducers] Add YamlRecorder and MultiProvider

2020-07-10 Thread Pavel Labath via Phabricator via lldb-commits
labath accepted this revision.
labath added a comment.
This revision is now accepted and ready to land.

This seems fine. A bit more doxygen wouldn't hurt...




Comment at: lldb/source/Utility/Reproducer.cpp:10
 #include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/Event.h"
 #include "lldb/Utility/LLDBAssert.h"

It doesn't look like this is actually needed.



Comment at: lldb/unittests/Utility/ReproducerTest.cpp:65-66
+struct YamlData {
+  YamlData() : i(-1){};
+  YamlData(int i) : i(i){};
+  int i;

superfluous semicolons



Comment at: lldb/unittests/Utility/ReproducerTest.cpp:74-75
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector)
+

Are both of these needed? I would expect the first one to be enough...



Comment at: lldb/unittests/Utility/ReproducerTest.cpp:240-242
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_EQ(data[0], data0);
+  EXPECT_EQ(data[1], data1);

`EXPECT_THAT(data, testing::ElementsAre(data0, data1));`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83441/new/

https://reviews.llvm.org/D83441



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D83441: [ldb/Reproducers] Add YamlRecorder and MultiProvider

2020-07-08 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere updated this revision to Diff 276597.
JDevlieghere added a comment.

Use `ScopeExit` to cleanup reproducer after test completes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83441/new/

https://reviews.llvm.org/D83441

Files:
  lldb/include/lldb/Utility/Reproducer.h
  lldb/source/API/SBDebugger.cpp
  lldb/source/Utility/Reproducer.cpp
  lldb/unittests/Utility/ReproducerTest.cpp

Index: lldb/unittests/Utility/ReproducerTest.cpp
===
--- lldb/unittests/Utility/ReproducerTest.cpp
+++ lldb/unittests/Utility/ReproducerTest.cpp
@@ -9,6 +9,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Testing/Support/Error.h"
 
@@ -31,8 +32,26 @@
   static char ID;
 };
 
+class YamlMultiProvider
+: public MultiProvider {
+public:
+  struct Info {
+static const char *name;
+static const char *file;
+  };
+
+  YamlMultiProvider(const FileSpec )
+  : MultiProvider(directory) {}
+
+  static char ID;
+};
+
 const char *DummyProvider::Info::name = "dummy";
 const char *DummyProvider::Info::file = "dummy.yaml";
+const char *YamlMultiProvider::Info::name = "mutli";
+const char *YamlMultiProvider::Info::file = "mutli.yaml";
+char DummyProvider::ID = 0;
+char YamlMultiProvider::ID = 0;
 
 class DummyReproducer : public Reproducer {
 public:
@@ -42,7 +61,26 @@
   using Reproducer::SetReplay;
 };
 
-char DummyProvider::ID = 0;
+struct YamlData {
+  YamlData() : i(-1){};
+  YamlData(int i) : i(i){};
+  int i;
+};
+
+inline bool operator==(const YamlData , const YamlData ) {
+  return LHS.i == RHS.i;
+}
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector)
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits {
+  static void mapping(IO , YamlData ) { io.mapRequired("i", Y.i); };
+};
+} // namespace yaml
+} // namespace llvm
 
 TEST(ReproducerTest, SetCapture) {
   DummyReproducer reproducer;
@@ -144,3 +182,85 @@
   auto _alt = generator.GetOrCreate();
   EXPECT_EQ(, _alt);
 }
+
+TEST(GeneratorTest, YamlMultiProvider) {
+  SmallString<128> root;
+  std::error_code ec = llvm::sys::fs::createUniqueDirectory("reproducer", root);
+  ASSERT_FALSE(static_cast(ec));
+
+  auto cleanup = llvm::make_scope_exit(
+  [&] { EXPECT_FALSE(llvm::sys::fs::remove_directories(root.str())); });
+
+  YamlData data0(0);
+  YamlData data1(1);
+  YamlData data2(2);
+  YamlData data3(3);
+
+  {
+DummyReproducer reproducer;
+EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec(root.str())), Succeeded());
+
+auto  = *reproducer.GetGenerator();
+auto *provider = generator.Create();
+ASSERT_NE(nullptr, provider);
+
+auto *recorder = provider->GetNewRecorder();
+ASSERT_NE(nullptr, recorder);
+recorder->Record(data0);
+recorder->Record(data1);
+
+recorder = provider->GetNewRecorder();
+ASSERT_NE(nullptr, recorder);
+recorder->Record(data2);
+recorder->Record(data3);
+
+generator.Keep();
+  }
+
+  {
+DummyReproducer reproducer;
+EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec(root.str())), Succeeded());
+
+auto  = *reproducer.GetLoader();
+std::unique_ptr> multi_loader =
+repro::MultiLoader::Create();
+
+// Read the first file.
+{
+  llvm::Optional file = multi_loader->GetNextFile();
+  EXPECT_TRUE(static_cast(file));
+
+  auto buffer = llvm::MemoryBuffer::getFile(*file);
+  EXPECT_TRUE(static_cast(buffer));
+
+  yaml::Input yin((*buffer)->getBuffer());
+  std::vector data;
+  yin >> data;
+
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_EQ(data[0], data0);
+  EXPECT_EQ(data[1], data1);
+}
+
+// Read the second file.
+{
+  llvm::Optional file = multi_loader->GetNextFile();
+  EXPECT_TRUE(static_cast(file));
+
+  auto buffer = llvm::MemoryBuffer::getFile(*file);
+  EXPECT_TRUE(static_cast(buffer));
+
+  yaml::Input yin((*buffer)->getBuffer());
+  std::vector data;
+  yin >> data;
+
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_EQ(data[0], data2);
+  EXPECT_EQ(data[1], data3);
+}
+
+// There is no third file.
+llvm::Optional file = multi_loader->GetNextFile();
+EXPECT_FALSE(static_cast(file));
+  }
+}
Index: lldb/source/Utility/Reproducer.cpp
===
--- lldb/source/Utility/Reproducer.cpp
+++ lldb/source/Utility/Reproducer.cpp
@@ -7,6 +7,7 @@
 //===--===//
 
 #include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/Event.h"
 #include "lldb/Utility/LLDBAssert.h"
 
 #include "llvm/Support/FileSystem.h"
@@ -272,40 +273,15 @@
   return std::move(recorder);
 }
 
-DataRecorder *CommandProvider::GetNewDataRecorder() {
-  std::size_t i = m_data_recorders.size() + 1;
-  std::string filename = (llvm::Twine(Info::name) + 

[Lldb-commits] [PATCH] D83441: [ldb/Reproducers] Add YamlRecorder and MultiProvider

2020-07-08 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere created this revision.
JDevlieghere added reviewers: labath, teemperor.

This patch does several things that are all closely related:

- It introduces a new `YamlRecorder` as a counterpart to the existing 
`DataRecorder`. As the name suggests the former serializes data as yaml while 
the latter uses raw texts or bytes.
- It introduces a new `MultiProvider` base class which can be backed by either 
a `DataRecorder` or a `YamlRecorder`.
- It reimplements the `CommandProvider` in terms of the new `MultiProvider`.
- Finally, it adds unit testing coverage for the `MultiProvider`, a naive 
`YamlProvider` built on top of the new `YamlRecorder` and the existing 
`MutliLoader`.

This is the basis of a future patch that I'm working on which will implement a 
Provider through the `YamlRecorder`.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D83441

Files:
  lldb/include/lldb/Utility/Reproducer.h
  lldb/source/API/SBDebugger.cpp
  lldb/source/Utility/Reproducer.cpp
  lldb/unittests/Utility/ReproducerTest.cpp

Index: lldb/unittests/Utility/ReproducerTest.cpp
===
--- lldb/unittests/Utility/ReproducerTest.cpp
+++ lldb/unittests/Utility/ReproducerTest.cpp
@@ -31,8 +31,26 @@
   static char ID;
 };
 
+class YamlMultiProvider
+: public MultiProvider {
+public:
+  struct Info {
+static const char *name;
+static const char *file;
+  };
+
+  YamlMultiProvider(const FileSpec )
+  : MultiProvider(directory) {}
+
+  static char ID;
+};
+
 const char *DummyProvider::Info::name = "dummy";
 const char *DummyProvider::Info::file = "dummy.yaml";
+const char *YamlMultiProvider::Info::name = "mutli";
+const char *YamlMultiProvider::Info::file = "mutli.yaml";
+char DummyProvider::ID = 0;
+char YamlMultiProvider::ID = 0;
 
 class DummyReproducer : public Reproducer {
 public:
@@ -42,7 +60,26 @@
   using Reproducer::SetReplay;
 };
 
-char DummyProvider::ID = 0;
+struct YamlData {
+  YamlData() : i(-1){};
+  YamlData(int i) : i(i){};
+  int i;
+};
+
+inline bool operator==(const YamlData , const YamlData ) {
+  return LHS.i == RHS.i;
+}
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector)
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits {
+  static void mapping(IO , YamlData ) { io.mapRequired("i", Y.i); };
+};
+} // namespace yaml
+} // namespace llvm
 
 TEST(ReproducerTest, SetCapture) {
   DummyReproducer reproducer;
@@ -144,3 +181,82 @@
   auto _alt = generator.GetOrCreate();
   EXPECT_EQ(, _alt);
 }
+
+TEST(GeneratorTest, YamlMultiProvider) {
+  SmallString<128> root;
+  std::error_code ec = llvm::sys::fs::createUniqueDirectory("reproducer", root);
+  ASSERT_FALSE(static_cast(ec));
+
+  YamlData data0(0);
+  YamlData data1(1);
+  YamlData data2(2);
+  YamlData data3(3);
+
+  {
+DummyReproducer reproducer;
+EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec(root.str())), Succeeded());
+
+auto  = *reproducer.GetGenerator();
+auto *provider = generator.Create();
+ASSERT_NE(nullptr, provider);
+
+auto *recorder = provider->GetNewRecorder();
+ASSERT_NE(nullptr, recorder);
+recorder->Record(data0);
+recorder->Record(data1);
+
+recorder = provider->GetNewRecorder();
+ASSERT_NE(nullptr, recorder);
+recorder->Record(data2);
+recorder->Record(data3);
+
+generator.Keep();
+  }
+
+  {
+DummyReproducer reproducer;
+EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec(root.str())), Succeeded());
+
+auto  = *reproducer.GetLoader();
+std::unique_ptr> multi_loader =
+repro::MultiLoader::Create();
+
+// Read the first file.
+{
+  llvm::Optional file = multi_loader->GetNextFile();
+  EXPECT_TRUE(static_cast(file));
+
+  auto buffer = llvm::MemoryBuffer::getFile(*file);
+  EXPECT_TRUE(static_cast(buffer));
+
+  yaml::Input yin((*buffer)->getBuffer());
+  std::vector data;
+  yin >> data;
+
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_EQ(data[0], data0);
+  EXPECT_EQ(data[1], data1);
+}
+
+// Read the second file.
+{
+  llvm::Optional file = multi_loader->GetNextFile();
+  EXPECT_TRUE(static_cast(file));
+
+  auto buffer = llvm::MemoryBuffer::getFile(*file);
+  EXPECT_TRUE(static_cast(buffer));
+
+  yaml::Input yin((*buffer)->getBuffer());
+  std::vector data;
+  yin >> data;
+
+  ASSERT_EQ(data.size(), 2U);
+  EXPECT_EQ(data[0], data2);
+  EXPECT_EQ(data[1], data3);
+}
+
+// There is no third file.
+llvm::Optional file = multi_loader->GetNextFile();
+EXPECT_FALSE(static_cast(file));
+  }
+}
Index: lldb/source/Utility/Reproducer.cpp
===
--- lldb/source/Utility/Reproducer.cpp
+++ lldb/source/Utility/Reproducer.cpp
@@ -7,6 +7,7 @@
 //===--===//
 
 #include "lldb/Utility/Reproducer.h"