LLVM  13.0.0git
SupportHelpers.h
Go to the documentation of this file.
1 //===- Testing/Support/SupportHelpers.h -----------------------------------===//
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 #ifndef LLVM_TESTING_SUPPORT_SUPPORTHELPERS_H
10 #define LLVM_TESTING_SUPPORT_SUPPORTHELPERS_H
11 
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/Support/Error.h"
16 #include "llvm/Support/Path.h"
18 #include "gmock/gmock-matchers.h"
19 #include "gtest/gtest-printers.h"
20 
21 #include <string>
22 
23 namespace llvm {
24 namespace detail {
25 struct ErrorHolder {
26  std::vector<std::shared_ptr<ErrorInfoBase>> Infos;
27 
28  bool Success() const { return Infos.empty(); }
29 };
30 
31 template <typename T> struct ExpectedHolder : public ErrorHolder {
33  : ErrorHolder(std::move(Err)), Exp(Exp) {}
34 
36 };
37 
38 inline void PrintTo(const ErrorHolder &Err, std::ostream *Out) {
39  raw_os_ostream OS(*Out);
40  OS << (Err.Success() ? "succeeded" : "failed");
41  if (!Err.Success()) {
42  const char *Delim = " (";
43  for (const auto &Info : Err.Infos) {
44  OS << Delim;
45  Delim = "; ";
46  Info->log(OS);
47  }
48  OS << ")";
49  }
50 }
51 
52 template <typename T>
53 void PrintTo(const ExpectedHolder<T> &Item, std::ostream *Out) {
54  if (Item.Success()) {
55  *Out << "succeeded with value " << ::testing::PrintToString(*Item.Exp);
56  } else {
57  PrintTo(static_cast<const ErrorHolder &>(Item), Out);
58  }
59 }
60 
61 template <class InnerMatcher> class ValueIsMatcher {
62 public:
63  explicit ValueIsMatcher(InnerMatcher ValueMatcher)
64  : ValueMatcher(ValueMatcher) {}
65 
66  template <class T>
67  operator ::testing::Matcher<const llvm::Optional<T> &>() const {
68  return ::testing::MakeMatcher(
69  new Impl<T>(::testing::SafeMatcherCast<T>(ValueMatcher)));
70  }
71 
72  template <class T>
73  class Impl : public ::testing::MatcherInterface<const llvm::Optional<T> &> {
74  public:
75  explicit Impl(const ::testing::Matcher<T> &ValueMatcher)
76  : ValueMatcher(ValueMatcher) {}
77 
79  testing::MatchResultListener *L) const override {
80  return Input && ValueMatcher.MatchAndExplain(Input.getValue(), L);
81  }
82 
83  void DescribeTo(std::ostream *OS) const override {
84  *OS << "has a value that ";
85  ValueMatcher.DescribeTo(OS);
86  }
87  void DescribeNegationTo(std::ostream *OS) const override {
88  *OS << "does not have a value that ";
89  ValueMatcher.DescribeTo(OS);
90  }
91 
92  private:
93  testing::Matcher<T> ValueMatcher;
94  };
95 
96 private:
97  InnerMatcher ValueMatcher;
98 };
99 } // namespace detail
100 
101 /// Matches an llvm::Optional<T> with a value that conforms to an inner matcher.
102 /// To match llvm::None you could use Eq(llvm::None).
103 template <class InnerMatcher>
104 detail::ValueIsMatcher<InnerMatcher> ValueIs(const InnerMatcher &ValueMatcher) {
105  return detail::ValueIsMatcher<InnerMatcher>(ValueMatcher);
106 }
107 namespace unittest {
108 
109 SmallString<128> getInputFileDirectory(const char *Argv0);
110 
111 /// A RAII object that creates a temporary directory upon initialization and
112 /// removes it upon destruction.
113 class TempDir {
114  SmallString<128> Path;
115 
116 public:
117  /// Creates a managed temporary directory.
118  ///
119  /// @param Name The name of the directory to create.
120  /// @param Unique If true, the directory will be created using
121  /// llvm::sys::fs::createUniqueDirectory.
122  explicit TempDir(StringRef Name, bool Unique = false) {
123  std::error_code EC;
124  if (Unique) {
126  if (!EC) {
127  // Resolve any symlinks in the new directory.
128  std::string UnresolvedPath(Path.str());
129  EC = llvm::sys::fs::real_path(UnresolvedPath, Path);
130  }
131  } else {
132  Path = Name;
134  }
135  if (EC)
136  Path.clear();
137  EXPECT_FALSE(EC) << EC.message();
138  }
139 
141  if (!Path.empty()) {
142  EXPECT_FALSE(llvm::sys::fs::remove_directories(Path.str()));
143  }
144  }
145 
146  TempDir(const TempDir &) = delete;
147  TempDir &operator=(const TempDir &) = delete;
148 
149  TempDir(TempDir &&) = default;
150  TempDir &operator=(TempDir &&) = default;
151 
152  /// The path to the temporary directory.
153  StringRef path() const { return Path; }
154 
155  /// The null-terminated C string pointing to the path.
156  const char *c_str() { return Path.c_str(); }
157 
158  /// Creates a new path by appending the argument to the path of the managed
159  /// directory using the native path separator.
160  SmallString<128> path(StringRef component) const {
161  SmallString<128> Result(Path);
162  SmallString<128> ComponentToAppend(component);
163  llvm::sys::path::native(ComponentToAppend);
164  llvm::sys::path::append(Result, Twine(ComponentToAppend));
165  return Result;
166  }
167 };
168 
169 /// A RAII object that creates a link upon initialization and
170 /// removes it upon destruction.
171 ///
172 /// The link may be a soft or a hard link, depending on the platform.
173 class TempLink {
174  SmallString<128> Path;
175 
176 public:
177  /// Creates a managed link at path Link pointing to Target.
179  Path = Link;
180  std::error_code EC = sys::fs::create_link(Target, Link);
181  if (EC)
182  Path.clear();
183  EXPECT_FALSE(EC);
184  }
186  if (!Path.empty()) {
187  EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
188  }
189  }
190 
191  TempLink(const TempLink &) = delete;
192  TempLink &operator=(const TempLink &) = delete;
193 
194  TempLink(TempLink &&) = default;
195  TempLink &operator=(TempLink &&) = default;
196 
197  /// The path to the link.
198  StringRef path() const { return Path; }
199 };
200 
201 /// A RAII object that creates a file upon initialization and
202 /// removes it upon destruction.
203 class TempFile {
204  SmallString<128> Path;
205 
206 public:
207  /// Creates a managed file.
208  ///
209  /// @param Name The name of the file to create.
210  /// @param Contents The string to write to the file.
211  /// @param Unique If true, the file will be created using
212  /// llvm::sys::fs::createTemporaryFile.
213  TempFile(StringRef Name, StringRef Suffix = "", StringRef Contents = "",
214  bool Unique = false) {
215  std::error_code EC;
216  int fd;
217  if (Unique) {
218  EC = llvm::sys::fs::createTemporaryFile(Name, Suffix, fd, Path);
219  } else {
220  Path = Name;
221  if (!Suffix.empty()) {
222  Path.append(".");
223  Path.append(Suffix);
224  }
225  EC = llvm::sys::fs::openFileForWrite(Path, fd);
226  }
227  EXPECT_FALSE(EC);
228  raw_fd_ostream OS(fd, /*shouldClose*/ true);
229  OS << Contents;
230  OS.flush();
231  EXPECT_FALSE(OS.error());
232  if (EC || OS.error())
233  Path.clear();
234  }
236  if (!Path.empty()) {
237  EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
238  }
239  }
240 
241  /// The path to the file.
242  StringRef path() const { return Path; }
243 };
244 
245 } // namespace unittest
246 } // namespace llvm
247 
248 #endif
llvm::sys::fs::openFileForWrite
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
Definition: FileSystem.h:1012
llvm::unittest::TempFile
A RAII object that creates a file upon initialization and removes it upon destruction.
Definition: SupportHelpers.h:203
llvm::unittest::TempDir::path
StringRef path() const
The path to the temporary directory.
Definition: SupportHelpers.h:153
llvm
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Optional.h
FileSystem.h
llvm::ValueIs
detail::ValueIsMatcher< InnerMatcher > ValueIs(const InnerMatcher &ValueMatcher)
Matches an llvm::Optional<T> with a value that conforms to an inner matcher.
Definition: SupportHelpers.h:104
llvm::unittest::TempFile::path
StringRef path() const
The path to the file.
Definition: SupportHelpers.h:242
llvm::raw_os_ostream
raw_os_ostream - A raw_ostream that writes to an std::ostream.
Definition: raw_os_ostream.h:24
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:124
Path.h
Error.h
llvm::sys::path::native
void native(const Twine &path, SmallVectorImpl< char > &result, Style style=Style::native)
Convert path to the native form.
Definition: Path.cpp:538
llvm::Optional
Definition: APInt.h:33
llvm::detail::ErrorHolder
Definition: SupportHelpers.h:25
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::codeview::Link
@ Link
Definition: CodeView.h:151
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:454
llvm::detail::ValueIsMatcher::Impl
Definition: SupportHelpers.h:73
llvm::unittest::TempDir::path
SmallString< 128 > path(StringRef component) const
Creates a new path by appending the argument to the path of the managed directory using the native pa...
Definition: SupportHelpers.h:160
llvm::sys::fs::create_link
std::error_code create_link(const Twine &to, const Twine &from)
Create a link from from to to.
llvm::unittest::TempDir::~TempDir
~TempDir()
Definition: SupportHelpers.h:140
SmallString.h
llvm::sys::fs::createUniqueDirectory
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition: Path.cpp:882
llvm::sys::fs::real_path
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
llvm::detail::ValueIsMatcher
Definition: SupportHelpers.h:61
llvm::unittest::TempFile::~TempFile
~TempFile()
Definition: SupportHelpers.h:235
llvm::raw_ostream::flush
void flush()
Definition: raw_ostream.h:183
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:26
llvm::SmallString< 128 >
llvm::SmallString::append
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:67
llvm::detail::ValueIsMatcher::ValueIsMatcher
ValueIsMatcher(InnerMatcher ValueMatcher)
Definition: SupportHelpers.h:63
llvm::SmallString::c_str
const char * c_str()
Definition: SmallString.h:262
llvm::detail::ExpectedHolder::ExpectedHolder
ExpectedHolder(ErrorHolder Err, Expected< T > &Exp)
Definition: SupportHelpers.h:32
llvm::sys::fs::remove_directories
std::error_code remove_directories(const Twine &path, bool IgnoreErrors=true)
Recursively delete a directory.
llvm::unittest::TempDir::operator=
TempDir & operator=(const TempDir &)=delete
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1556
llvm::unittest::TempDir
A RAII object that creates a temporary directory upon initialization and removes it upon destruction.
Definition: SupportHelpers.h:113
llvm::unittest::getInputFileDirectory
SmallString< 128 > getInputFileDirectory(const char *Argv0)
Definition: SupportHelpers.cpp:36
llvm::sys::fs::create_directory
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
llvm::detail::ExpectedHolder
Definition: SupportHelpers.h:31
llvm::sys::fs::remove
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
llvm::raw_fd_ostream::error
std::error_code error() const
Definition: raw_ostream.h:514
llvm::detail::ErrorHolder::Success
bool Success() const
Definition: SupportHelpers.h:28
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:432
llvm::sys::fs::createTemporaryFile
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath)
Create a file in the system temporary directory.
Definition: Path.cpp:862
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:941
llvm::detail::ValueIsMatcher::Impl::DescribeTo
void DescribeTo(std::ostream *OS) const override
Definition: SupportHelpers.h:83
llvm::unittest::TempDir::c_str
const char * c_str()
The null-terminated C string pointing to the path.
Definition: SupportHelpers.h:156
llvm::detail::ValueIsMatcher::Impl::DescribeNegationTo
void DescribeNegationTo(std::ostream *OS) const override
Definition: SupportHelpers.h:87
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::detail::ExpectedHolder::Exp
Expected< T > & Exp
Definition: SupportHelpers.h:35
llvm::SmallString::str
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:259
llvm::detail::ErrorHolder::Infos
std::vector< std::shared_ptr< ErrorInfoBase > > Infos
Definition: SupportHelpers.h:26
llvm::unittest::TempDir::TempDir
TempDir(StringRef Name, bool Unique=false)
Creates a managed temporary directory.
Definition: SupportHelpers.h:122
raw_os_ostream.h
llvm::detail::PrintTo
void PrintTo(const ErrorHolder &Err, std::ostream *Out)
Definition: SupportHelpers.h:38
llvm::detail::ValueIsMatcher::Impl::MatchAndExplain
bool MatchAndExplain(const llvm::Optional< T > &Input, testing::MatchResultListener *L) const override
Definition: SupportHelpers.h:78
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:280
llvm::detail::ValueIsMatcher::Impl::Impl
Impl(const ::testing::Matcher< T > &ValueMatcher)
Definition: SupportHelpers.h:75
llvm::unittest::TempFile::TempFile
TempFile(StringRef Name, StringRef Suffix="", StringRef Contents="", bool Unique=false)
Creates a managed file.
Definition: SupportHelpers.h:213