[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-27 Thread Jonas Devlieghere via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL347716: [Reproducers] Improve reproducer API and add unit 
tests. (authored by JDevlieghere, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D54616?vs=175293=175578#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D54616

Files:
  lldb/trunk/include/lldb/API/SBDebugger.h
  lldb/trunk/include/lldb/Core/Debugger.h
  lldb/trunk/include/lldb/Utility/Reproducer.h
  lldb/trunk/scripts/interface/SBDebugger.i
  lldb/trunk/source/API/SBDebugger.cpp
  lldb/trunk/source/Commands/CommandObjectReproducer.cpp
  lldb/trunk/source/Core/Debugger.cpp
  lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  lldb/trunk/source/Utility/Reproducer.cpp
  lldb/trunk/tools/driver/Driver.cpp
  lldb/trunk/unittests/Utility/CMakeLists.txt
  lldb/trunk/unittests/Utility/ReproducerTest.cpp

Index: lldb/trunk/unittests/Utility/ReproducerTest.cpp
===
--- lldb/trunk/unittests/Utility/ReproducerTest.cpp
+++ lldb/trunk/unittests/Utility/ReproducerTest.cpp
@@ -0,0 +1,126 @@
+//===-- ReproducerTest.cpp --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Reproducer.h"
+
+using namespace llvm;
+using namespace lldb_private;
+using namespace lldb_private::repro;
+
+class DummyProvider : public repro::Provider {
+public:
+  static constexpr const char *NAME = "dummy";
+
+  DummyProvider(const FileSpec ) : Provider(directory) {
+m_info.name = "dummy";
+m_info.files.push_back("dummy.yaml");
+  }
+
+  static char ID;
+};
+
+char DummyProvider::ID = 0;
+
+TEST(ReproducerTest, SetCapture) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Enable capture and check that means we have a generator.
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  EXPECT_NE(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+
+  // Ensure that we cannot enable replay.
+  EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), Failed());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Ensure we can disable the generator again.
+  EXPECT_THAT_ERROR(reproducer.SetCapture(llvm::None), Succeeded());
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+}
+
+TEST(ReproducerTest, SetReplay) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Expected to fail because we can't load the index.
+  EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), Failed());
+  // However the loader should still be set, which we check here.
+  EXPECT_NE(nullptr, reproducer.GetLoader());
+
+  // Make sure the bogus path is correctly set.
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetLoader()->GetRoot());
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+
+  // Ensure that we cannot enable replay.
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")), Failed());
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+}
+
+TEST(GeneratorTest, Create) {
+  Reproducer reproducer;
+
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+  EXPECT_EQ(FileSpec("/bogus/path"), provider->GetRoot());
+  EXPECT_EQ(std::string("dummy"), provider->GetInfo().name);
+  EXPECT_EQ((size_t)1, provider->GetInfo().files.size());
+  EXPECT_EQ(std::string("dummy.yaml"), provider->GetInfo().files.front());
+}
+
+TEST(GeneratorTest, Get) {
+  Reproducer reproducer;
+
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+
+  auto *provider_alt = generator.Get();
+  EXPECT_EQ(provider, provider_alt);
+}
+
+TEST(GeneratorTest, GetOrCreate) {
+  Reproducer reproducer;
+
+  

[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-27 Thread Davide Italiano via Phabricator via lldb-commits
davide accepted this revision.
davide added a comment.
This revision is now accepted and ready to land.

LGTM


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

https://reviews.llvm.org/D54616



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


[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-27 Thread Pavel Labath via Phabricator via lldb-commits
labath added a comment.

I haven't been following the reproducer work in detail, but this seems 
reasonable to me. Thanks for incorporating my drive-by suggestions.




Comment at: include/lldb/Utility/Reproducer.h:104
+  template  T *Create() {
+std::unique_ptr provider(new T(m_root));
+return static_cast(Register(std::move(provider)));

You should still be able to use make_unique here.



Comment at: include/lldb/Utility/Reproducer.h:134
 
-  std::vector> m_providers;
+  /// List of providers indexed by their name for easy access.
+  llvm::DenseMap> m_providers;

Out of date comment.


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

https://reviews.llvm.org/D54616



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


[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-27 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere added a comment.

Does anybody want to have another look or can I land this?


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

https://reviews.llvm.org/D54616



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


[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-26 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere updated this revision to Diff 175293.
JDevlieghere marked 6 inline comments as done.
JDevlieghere added a comment.

Thanks Pavel, really useful feedback, I learned a few new things :-)


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

https://reviews.llvm.org/D54616

Files:
  include/lldb/API/SBDebugger.h
  include/lldb/Core/Debugger.h
  include/lldb/Utility/Reproducer.h
  scripts/interface/SBDebugger.i
  source/API/SBDebugger.cpp
  source/Commands/CommandObjectReproducer.cpp
  source/Core/Debugger.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/Reproducer.cpp
  tools/driver/Driver.cpp
  unittests/Utility/CMakeLists.txt
  unittests/Utility/ReproducerTest.cpp

Index: unittests/Utility/ReproducerTest.cpp
===
--- /dev/null
+++ unittests/Utility/ReproducerTest.cpp
@@ -0,0 +1,126 @@
+//===-- ReproducerTest.cpp --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Reproducer.h"
+
+using namespace llvm;
+using namespace lldb_private;
+using namespace lldb_private::repro;
+
+class DummyProvider : public repro::Provider {
+public:
+  static constexpr const char *NAME = "dummy";
+
+  DummyProvider(const FileSpec ) : Provider(directory) {
+m_info.name = "dummy";
+m_info.files.push_back("dummy.yaml");
+  }
+
+  static char ID;
+};
+
+char DummyProvider::ID = 0;
+
+TEST(ReproducerTest, SetCapture) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Enable capture and check that means we have a generator.
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  EXPECT_NE(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+
+  // Ensure that we cannot enable replay.
+  EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), Failed());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Ensure we can disable the generator again.
+  EXPECT_THAT_ERROR(reproducer.SetCapture(llvm::None), Succeeded());
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+}
+
+TEST(ReproducerTest, SetReplay) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Expected to fail because we can't load the index.
+  EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), Failed());
+  // However the loader should still be set, which we check here.
+  EXPECT_NE(nullptr, reproducer.GetLoader());
+
+  // Make sure the bogus path is correctly set.
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetLoader()->GetRoot());
+  EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+
+  // Ensure that we cannot enable replay.
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")), Failed());
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+}
+
+TEST(GeneratorTest, Create) {
+  Reproducer reproducer;
+
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+  EXPECT_EQ(FileSpec("/bogus/path"), provider->GetRoot());
+  EXPECT_EQ(std::string("dummy"), provider->GetInfo().name);
+  EXPECT_EQ((size_t)1, provider->GetInfo().files.size());
+  EXPECT_EQ(std::string("dummy.yaml"), provider->GetInfo().files.front());
+}
+
+TEST(GeneratorTest, Get) {
+  Reproducer reproducer;
+
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+
+  auto *provider_alt = generator.Get();
+  EXPECT_EQ(provider, provider_alt);
+}
+
+TEST(GeneratorTest, GetOrCreate) {
+  Reproducer reproducer;
+
+  EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")),
+Succeeded());
+  auto  = *reproducer.GetGenerator();
+
+  auto  = generator.GetOrCreate();
+  EXPECT_EQ(FileSpec("/bogus/path"), provider.GetRoot());
+  EXPECT_EQ(std::string("dummy"), provider.GetInfo().name);
+  EXPECT_EQ((size_t)1, 

[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-19 Thread Pavel Labath via Phabricator via lldb-commits
labath added inline comments.



Comment at: include/lldb/Utility/Reproducer.h:59-64
+  void InitializeFileInfo(llvm::StringRef name,
+  llvm::ArrayRef files) {
+m_info.name = name;
+for (auto file : files)
+  m_info.files.push_back(file);
+  }

Could this be replaced by additional arguments to the constructor (avoiding 
two-stage initialization)?



Comment at: include/lldb/Utility/Reproducer.h:99
+  template  T *Get() {
+auto it = m_providers.find(T::NAME);
+if (it == m_providers.end())

Is the value of the `NAME` used anywhere? If not, you could just have each 
class define a `char` variable (like `llvm::ErrorInfo` subclasses do) and then 
use its address as a key, making everything faster.

(Even if name is useful (for printing to the user or whatever), it might be 
worth to switch to using the char-address for lookup and then just have 
`getName` method for other things.)



Comment at: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp:304
+ProcessGDBRemoteProvider *provider =
+g->GetOrCreate();
 // Set the history stream to the stream owned by the provider.

could `GetOrCreate` keep returning a reference (to avoid spurious `guaranteed 
to be not null` comments)?



Comment at: source/Utility/Reproducer.cpp:131-133
+  assert(m_providers.empty() &&
+ "Changing the root directory after providers have "
+ "been registered would invalidate the index.");

Given these limitations, would it be possible to set the root once in the 
constructor and keep it immutable since then?



Comment at: unittests/Utility/ReproducerTest.cpp:44-46
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));

Shorter and with better error messages:
`EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec("/bogus/path")), 
llvm::Succeeded());`



Comment at: unittests/Utility/ReproducerTest.cpp:79-81
+auto error = reproducer.SetCapture(FileSpec("/bogus/path"));
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));

`EXPECT_THAT_ERROR(..., llvm::Failed());`


https://reviews.llvm.org/D54616



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


[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-16 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere updated this revision to Diff 174416.

https://reviews.llvm.org/D54616

Files:
  include/lldb/API/SBDebugger.h
  include/lldb/Core/Debugger.h
  include/lldb/Utility/Reproducer.h
  scripts/interface/SBDebugger.i
  source/API/SBDebugger.cpp
  source/Commands/CommandObjectReproducer.cpp
  source/Core/Debugger.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/Reproducer.cpp
  tools/driver/Driver.cpp
  unittests/Utility/CMakeLists.txt
  unittests/Utility/ReproducerTest.cpp

Index: unittests/Utility/ReproducerTest.cpp
===
--- /dev/null
+++ unittests/Utility/ReproducerTest.cpp
@@ -0,0 +1,142 @@
+//===-- ReproducerTest.cpp --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Reproducer.h"
+
+using namespace lldb_private;
+using namespace lldb_private::repro;
+
+class DummyProvider : public repro::Provider {
+public:
+  static constexpr const char *NAME = "dummy";
+
+  DummyProvider(const FileSpec ) : Provider(directory) {
+InitializeFileInfo(NAME, {"dummy.yaml"});
+  }
+};
+
+TEST(ReproducerTest, SetCapture) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Enable capture and check that means we have a generator.
+  {
+llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
+EXPECT_NE(nullptr, reproducer.GetGenerator());
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+  }
+
+  // Ensure that we cannot enable replay.
+  {
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));
+EXPECT_EQ(nullptr, reproducer.GetLoader());
+  }
+
+  // Ensure we can disable the generator again.
+  llvm::cantFail(reproducer.SetCapture(llvm::None));
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+}
+
+TEST(ReproducerTest, SetReplay) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Enable capture and check that means we have a generator.
+  {
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
+// Expected to fail because we can't load the index.
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));
+// However the loader should still be set, which we check here.
+EXPECT_NE(nullptr, reproducer.GetLoader());
+
+// Make sure the bogus path is correctly set.
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetLoader()->GetRoot());
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+  }
+
+  // Ensure that we cannot enable replay.
+  {
+auto error = reproducer.SetCapture(FileSpec("/bogus/path"));
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));
+EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  }
+}
+
+TEST(GeneratorTest, ChangeRoot) {
+  Reproducer reproducer;
+
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
+  auto  = *reproducer.GetGenerator();
+
+  // As long as we haven't registered any providers this should work.
+  generator.ChangeRoot(FileSpec("/other/bogus/path"));
+
+  EXPECT_EQ(FileSpec("/other/bogus/path"),
+reproducer.GetGenerator()->GetRoot());
+  EXPECT_EQ(FileSpec("/other/bogus/path"), reproducer.GetReproducerPath());
+}
+
+TEST(GeneratorTest, Create) {
+  Reproducer reproducer;
+
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+  EXPECT_EQ(FileSpec("/bogus/path"), provider->GetRoot());
+  EXPECT_EQ(std::string("dummy"), provider->GetInfo().name);
+  EXPECT_EQ((size_t)1, provider->GetInfo().files.size());
+  EXPECT_EQ(std::string("dummy.yaml"), provider->GetInfo().files.front());
+}
+
+TEST(GeneratorTest, Get) {
+  Reproducer reproducer;
+
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+
+  auto *provider_alt = generator.Get();
+  EXPECT_EQ(provider, provider_alt);
+}
+
+TEST(GeneratorTest, GetOrCreate) {
+  Reproducer reproducer;
+
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
+  auto  = 

[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-16 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere updated this revision to Diff 174407.
JDevlieghere added a comment.

Simplify code a little, as per Stefan's (offline) suggestion.


https://reviews.llvm.org/D54616

Files:
  include/lldb/API/SBDebugger.h
  include/lldb/Utility/Reproducer.h
  scripts/interface/SBDebugger.i
  source/API/SBDebugger.cpp
  source/Commands/CommandObjectReproducer.cpp
  source/Core/Debugger.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/Reproducer.cpp
  tools/driver/Driver.cpp
  unittests/Utility/ReproducerTest.cpp

Index: unittests/Utility/ReproducerTest.cpp
===
--- unittests/Utility/ReproducerTest.cpp
+++ unittests/Utility/ReproducerTest.cpp
@@ -33,22 +33,24 @@
 
   // Enable capture and check that means we have a generator.
   {
-auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-EXPECT_FALSE(static_cast(error));
+llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
 EXPECT_NE(nullptr, reproducer.GetGenerator());
-
-// Make sure the bogus path is correctly set.
 EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
 EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
   }
 
   // Ensure that we cannot enable replay.
   {
-auto error = reproducer.SetReplay(true);
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
 EXPECT_EQ(nullptr, reproducer.GetLoader());
   }
+
+  // Ensure we can disable the generator again.
+  llvm::cantFail(reproducer.SetCapture(llvm::None));
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
 }
 
 TEST(ReproducerTest, SetReplay) {
@@ -60,7 +62,7 @@
 
   // Enable capture and check that means we have a generator.
   {
-auto error = reproducer.SetReplay(true, FileSpec("/bogus/path"));
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
 // Expected to fail because we can't load the index.
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
@@ -74,7 +76,7 @@
 
   // Ensure that we cannot enable replay.
   {
-auto error = reproducer.SetCapture(true);
+auto error = reproducer.SetCapture(FileSpec("/bogus/path"));
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
 EXPECT_EQ(nullptr, reproducer.GetGenerator());
@@ -84,8 +86,7 @@
 TEST(GeneratorTest, ChangeRoot) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   // As long as we haven't registered any providers this should work.
@@ -99,8 +100,7 @@
 TEST(GeneratorTest, Create) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.Create();
@@ -114,8 +114,7 @@
 TEST(GeneratorTest, Get) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.Create();
@@ -128,8 +127,7 @@
 TEST(GeneratorTest, GetOrCreate) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.GetOrCreate();
Index: tools/driver/Driver.cpp
===
--- tools/driver/Driver.cpp
+++ tools/driver/Driver.cpp
@@ -734,7 +734,9 @@
 case 'z': {
   SBFileSpec file(optarg);
   if (file.Exists()) {
-m_debugger.SetReproducerPath(optarg);
+SBError repro_error = m_debugger.ReplayReproducer(optarg);
+if (repro_error.Fail())
+  error = repro_error;
   } else
 error.SetErrorStringWithFormat("file specified in --reproducer "
"(-z) option doesn't exist: '%s'",
Index: source/Utility/Reproducer.cpp
===
--- source/Utility/Reproducer.cpp
+++ source/Utility/Reproducer.cpp
@@ -51,34 +51,32 @@
   return nullptr;
 }
 
-llvm::Error Reproducer::SetCapture(bool value, FileSpec root) {
+llvm::Error Reproducer::SetCapture(llvm::Optional root) {
   std::lock_guard guard(m_mutex);
 
-  if (value && m_loader)
+  if (root && m_loader)
 return make_error(
 "cannot generate a reproducer when replay 

[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-16 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere updated this revision to Diff 174399.
JDevlieghere marked an inline comment as done.
JDevlieghere added a comment.

Missed a comment; fixed now.


https://reviews.llvm.org/D54616

Files:
  include/lldb/API/SBDebugger.h
  include/lldb/Utility/Reproducer.h
  scripts/interface/SBDebugger.i
  source/API/SBDebugger.cpp
  source/Commands/CommandObjectReproducer.cpp
  source/Core/Debugger.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/Reproducer.cpp
  tools/driver/Driver.cpp
  unittests/Utility/ReproducerTest.cpp

Index: unittests/Utility/ReproducerTest.cpp
===
--- unittests/Utility/ReproducerTest.cpp
+++ unittests/Utility/ReproducerTest.cpp
@@ -33,22 +33,24 @@
 
   // Enable capture and check that means we have a generator.
   {
-auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-EXPECT_FALSE(static_cast(error));
+llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
 EXPECT_NE(nullptr, reproducer.GetGenerator());
-
-// Make sure the bogus path is correctly set.
 EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
 EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
   }
 
   // Ensure that we cannot enable replay.
   {
-auto error = reproducer.SetReplay(true);
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
 EXPECT_EQ(nullptr, reproducer.GetLoader());
   }
+
+  // Ensure we can disable the generator again.
+  llvm::cantFail(reproducer.SetCapture(llvm::None));
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
 }
 
 TEST(ReproducerTest, SetReplay) {
@@ -60,7 +62,7 @@
 
   // Enable capture and check that means we have a generator.
   {
-auto error = reproducer.SetReplay(true, FileSpec("/bogus/path"));
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
 // Expected to fail because we can't load the index.
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
@@ -74,7 +76,7 @@
 
   // Ensure that we cannot enable replay.
   {
-auto error = reproducer.SetCapture(true);
+auto error = reproducer.SetCapture(FileSpec("/bogus/path"));
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
 EXPECT_EQ(nullptr, reproducer.GetGenerator());
@@ -84,8 +86,7 @@
 TEST(GeneratorTest, ChangeRoot) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   // As long as we haven't registered any providers this should work.
@@ -99,8 +100,7 @@
 TEST(GeneratorTest, Create) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.Create();
@@ -114,8 +114,7 @@
 TEST(GeneratorTest, Get) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.Create();
@@ -128,8 +127,7 @@
 TEST(GeneratorTest, GetOrCreate) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.GetOrCreate();
Index: tools/driver/Driver.cpp
===
--- tools/driver/Driver.cpp
+++ tools/driver/Driver.cpp
@@ -734,7 +734,9 @@
 case 'z': {
   SBFileSpec file(optarg);
   if (file.Exists()) {
-m_debugger.SetReproducerPath(optarg);
+SBError repro_error = m_debugger.ReplayReproducer(optarg);
+if (repro_error.Fail())
+  error = repro_error;
   } else
 error.SetErrorStringWithFormat("file specified in --reproducer "
"(-z) option doesn't exist: '%s'",
Index: source/Utility/Reproducer.cpp
===
--- source/Utility/Reproducer.cpp
+++ source/Utility/Reproducer.cpp
@@ -51,34 +51,32 @@
   return nullptr;
 }
 
-llvm::Error Reproducer::SetCapture(bool value, FileSpec root) {
+llvm::Error Reproducer::SetCapture(llvm::Optional root) {
   std::lock_guard guard(m_mutex);
 
-  if (value && m_loader)
+  if (root && m_loader)
 return make_error(
 "cannot generate a 

[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-16 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere updated this revision to Diff 174398.
JDevlieghere marked 4 inline comments as done.
JDevlieghere added a comment.

Address Stefan's review feedback.


https://reviews.llvm.org/D54616

Files:
  include/lldb/API/SBDebugger.h
  include/lldb/Utility/Reproducer.h
  scripts/interface/SBDebugger.i
  source/API/SBDebugger.cpp
  source/Commands/CommandObjectReproducer.cpp
  source/Core/Debugger.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/Reproducer.cpp
  tools/driver/Driver.cpp
  unittests/Utility/ReproducerTest.cpp

Index: unittests/Utility/ReproducerTest.cpp
===
--- unittests/Utility/ReproducerTest.cpp
+++ unittests/Utility/ReproducerTest.cpp
@@ -33,22 +33,24 @@
 
   // Enable capture and check that means we have a generator.
   {
-auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-EXPECT_FALSE(static_cast(error));
+llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
 EXPECT_NE(nullptr, reproducer.GetGenerator());
-
-// Make sure the bogus path is correctly set.
 EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
 EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
   }
 
   // Ensure that we cannot enable replay.
   {
-auto error = reproducer.SetReplay(true);
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
 EXPECT_EQ(nullptr, reproducer.GetLoader());
   }
+
+  // Ensure we can disable the generator again.
+  llvm::cantFail(reproducer.SetCapture(llvm::None));
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
 }
 
 TEST(ReproducerTest, SetReplay) {
@@ -60,7 +62,7 @@
 
   // Enable capture and check that means we have a generator.
   {
-auto error = reproducer.SetReplay(true, FileSpec("/bogus/path"));
+auto error = reproducer.SetReplay(FileSpec("/bogus/path"));
 // Expected to fail because we can't load the index.
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
@@ -74,7 +76,7 @@
 
   // Ensure that we cannot enable replay.
   {
-auto error = reproducer.SetCapture(true);
+auto error = reproducer.SetCapture(FileSpec("/bogus/path"));
 EXPECT_TRUE(static_cast(error));
 llvm::consumeError(std::move(error));
 EXPECT_EQ(nullptr, reproducer.GetGenerator());
@@ -84,8 +86,7 @@
 TEST(GeneratorTest, ChangeRoot) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   // As long as we haven't registered any providers this should work.
@@ -99,8 +100,7 @@
 TEST(GeneratorTest, Create) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.Create();
@@ -114,8 +114,7 @@
 TEST(GeneratorTest, Get) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.Create();
@@ -128,8 +127,7 @@
 TEST(GeneratorTest, GetOrCreate) {
   Reproducer reproducer;
 
-  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
-  EXPECT_FALSE(static_cast(error));
+  llvm::cantFail(reproducer.SetCapture(FileSpec("/bogus/path")));
   auto  = *reproducer.GetGenerator();
 
   auto *provider = generator.GetOrCreate();
Index: tools/driver/Driver.cpp
===
--- tools/driver/Driver.cpp
+++ tools/driver/Driver.cpp
@@ -734,7 +734,9 @@
 case 'z': {
   SBFileSpec file(optarg);
   if (file.Exists()) {
-m_debugger.SetReproducerPath(optarg);
+SBError repro_error = m_debugger.ReplayReproducer(optarg);
+if (repro_error.Fail())
+  error = repro_error;
   } else
 error.SetErrorStringWithFormat("file specified in --reproducer "
"(-z) option doesn't exist: '%s'",
Index: source/Utility/Reproducer.cpp
===
--- source/Utility/Reproducer.cpp
+++ source/Utility/Reproducer.cpp
@@ -51,34 +51,32 @@
   return nullptr;
 }
 
-llvm::Error Reproducer::SetCapture(bool value, FileSpec root) {
+llvm::Error Reproducer::SetCapture(llvm::Optional root) {
   std::lock_guard guard(m_mutex);
 
-  if (value && m_loader)
+  if (root && m_loader)
 return make_error(
 "cannot generate a 

[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-16 Thread Stefan Gränitz via Phabricator via lldb-commits
sgraenitz added a comment.

Looks pretty good to me, but added my 2¢ on minor things.




Comment at: include/lldb/Utility/Reproducer.h:169
+  llvm::Error SetCapture(bool value, FileSpec root = {});
+  llvm::Error SetReplay(bool value, FileSpec root = {});
 

Are the default-value-cases necessary?



Comment at: source/API/SBDebugger.cpp:1064
+m_opaque_sp->SetReproducerReplay(llvm::StringRef::withNullAsEmpty(p));
+llvm::consumeError(std::move(error));
+  }

Will the error be passed up the stack soon? Otherwise maybe add FIXME comment?



Comment at: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp:303
+if (ProcessGDBRemoteProvider *provider =
+g->GetOrCreate()) {
+  // Set the history stream to the stream owned by the provider.

In which case would `GetOrCreate()` fail?



Comment at: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp:3440
   // Construct replay history path.
-  FileSpec history_file(loader->GetDirectory());
+  FileSpec history_file = (loader->GetRoot());
   history_file.AppendPathComponent(provider_info->files.front());

Brackets



Comment at: unittests/Utility/ReproducerTest.cpp:37
+auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
+EXPECT_FALSE(static_cast(error));
+EXPECT_NE(nullptr, reproducer.GetGenerator());

It may be good to know what went wrong if this fails. And: are the other 
`EXPECT`s still relevant in the error-case?

If `SetCapture()` can fail in this particular situation, you may want to do 
something like:
```
if (error)
  FAIL() << llvm::toString(std::move(error));
```
Otherwise, if this was only to prepare the test and you wanted to indicate that 
it's not supposed to fail, then you could do:
```
llvm::cantFail(reproducer.SetCapture(true, FileSpec("/bogus/path"));
```


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D54616



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


[Lldb-commits] [PATCH] D54616: [Reproducers] Improve reproducer API and add unit tests.

2018-11-15 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere created this revision.
JDevlieghere added reviewers: davide, shafik, friss, jingham.
JDevlieghere added a project: LLDB.
Herald added subscribers: abidh, mgorny.

When I landed the initial reproducer framework I knew there were some things 
that needed improvement. Rather than bundling it with a patch that adds more 
functionality I split it off into this patch. I also think the API is stable 
enough to add unit testing, which is included in this patch as well.

Other improvements include:

- Refactor how we initialize the loader and generator.
- Improve naming consistency: capture and replay seems the least ambiguous.
- Index providers by name and make sure there's only one of each.
- Add convenience methods for creating and accessing providers.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D54616

Files:
  include/lldb/Core/Debugger.h
  include/lldb/Utility/Reproducer.h
  source/API/SBDebugger.cpp
  source/Commands/CommandObjectReproducer.cpp
  source/Core/Debugger.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Utility/Reproducer.cpp
  unittests/Utility/CMakeLists.txt
  unittests/Utility/ReproducerTest.cpp

Index: unittests/Utility/ReproducerTest.cpp
===
--- /dev/null
+++ unittests/Utility/ReproducerTest.cpp
@@ -0,0 +1,144 @@
+//===-- ReproducerTest.cpp --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Reproducer.h"
+
+using namespace lldb_private;
+using namespace lldb_private::repro;
+
+class DummyProvider : public repro::Provider {
+public:
+  static constexpr const char *NAME = "dummy";
+
+  DummyProvider(const FileSpec ) : Provider(directory) {
+InitializeFileInfo(NAME, {"dummy.yaml"});
+  }
+};
+
+TEST(ReproducerTest, SetCapture) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Enable capture and check that means we have a generator.
+  {
+auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
+EXPECT_FALSE(static_cast(error));
+EXPECT_NE(nullptr, reproducer.GetGenerator());
+
+// Make sure the bogus path is correctly set.
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetGenerator()->GetRoot());
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+  }
+
+  // Ensure that we cannot enable replay.
+  {
+auto error = reproducer.SetReplay(true);
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));
+EXPECT_EQ(nullptr, reproducer.GetLoader());
+  }
+}
+
+TEST(ReproducerTest, SetReplay) {
+  Reproducer reproducer;
+
+  // Initially both generator and loader are unset.
+  EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  EXPECT_EQ(nullptr, reproducer.GetLoader());
+
+  // Enable capture and check that means we have a generator.
+  {
+auto error = reproducer.SetReplay(true, FileSpec("/bogus/path"));
+// Expected to fail because we can't load the index.
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));
+// However the loader should still be set, which we check here.
+EXPECT_NE(nullptr, reproducer.GetLoader());
+
+// Make sure the bogus path is correctly set.
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetLoader()->GetRoot());
+EXPECT_EQ(FileSpec("/bogus/path"), reproducer.GetReproducerPath());
+  }
+
+  // Ensure that we cannot enable replay.
+  {
+auto error = reproducer.SetCapture(true);
+EXPECT_TRUE(static_cast(error));
+llvm::consumeError(std::move(error));
+EXPECT_EQ(nullptr, reproducer.GetGenerator());
+  }
+}
+
+TEST(GeneratorTest, ChangeRoot) {
+  Reproducer reproducer;
+
+  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
+  EXPECT_FALSE(static_cast(error));
+  auto  = *reproducer.GetGenerator();
+
+  // As long as we haven't registered any providers this should work.
+  generator.ChangeRoot(FileSpec("/other/bogus/path"));
+
+  EXPECT_EQ(FileSpec("/other/bogus/path"),
+reproducer.GetGenerator()->GetRoot());
+  EXPECT_EQ(FileSpec("/other/bogus/path"), reproducer.GetReproducerPath());
+}
+
+TEST(GeneratorTest, Create) {
+  Reproducer reproducer;
+
+  auto error = reproducer.SetCapture(true, FileSpec("/bogus/path"));
+  EXPECT_FALSE(static_cast(error));
+  auto  = *reproducer.GetGenerator();
+
+  auto *provider = generator.Create();
+  EXPECT_NE(nullptr, provider);
+  EXPECT_EQ(FileSpec("/bogus/path"), provider->GetRoot());
+  EXPECT_EQ(std::string("dummy"), provider->GetInfo().name);
+  EXPECT_EQ((size_t)1,