llvm/llvm/unittests/Support/ProgramTest.cpp

//===- unittest/Support/ProgramTest.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Program.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "gtest/gtest.h"
#include <stdlib.h>
#include <thread>
#if defined(__APPLE__)
# include <crt_externs.h>
#elif !defined(_MSC_VER)
// Forward declare environ in case it's not provided by stdlib.h.
extern char **environ;
#endif

#if defined(LLVM_ON_UNIX)
#include <unistd.h>
void sleep_for(unsigned int seconds) {}
#elif defined(_WIN32)
#include <windows.h>
void sleep_for(unsigned int seconds) {
  Sleep(seconds * 1000);
}
#else
#error sleep_for is not implemented on your platform.
#endif

#define ASSERT_NO_ERROR(x)
// From TestMain.cpp.
extern const char *TestMainArgv0;

namespace {

usingnamespacellvm;
usingnamespacesys;

static cl::opt<std::string>
ProgramTestStringArg1("program-test-string-arg1");
static cl::opt<std::string>
ProgramTestStringArg2("program-test-string-arg2");

class ProgramEnvTest : public testing::Test {};

#ifdef _WIN32
void checkSeparators(StringRef Path) {
  char UndesiredSeparator = sys::path::get_separator()[0] == '/' ? '\\' : '/';
  ASSERT_EQ(Path.find(UndesiredSeparator), StringRef::npos);
}

TEST_F(ProgramEnvTest, CreateProcessLongPath) {
  if (getenv("LLVM_PROGRAM_TEST_LONG_PATH"))
    exit(0);

  // getMainExecutable returns an absolute path; prepend the long-path prefix.
  SmallString<128> MyAbsExe(
      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1));
  checkSeparators(MyAbsExe);
  // Force a path with backslashes, when we are going to prepend the \\?\
  // prefix.
  sys::path::native(MyAbsExe, sys::path::Style::windows_backslash);
  std::string MyExe;
  if (!StringRef(MyAbsExe).starts_with("\\\\?\\"))
    MyExe.append("\\\\?\\");
  MyExe.append(std::string(MyAbsExe.begin(), MyAbsExe.end()));

  StringRef ArgV[] = {MyExe,
                      "--gtest_filter=ProgramEnvTest.CreateProcessLongPath"};

  // Add LLVM_PROGRAM_TEST_LONG_PATH to the environment of the child.
  addEnvVar("LLVM_PROGRAM_TEST_LONG_PATH=1");

  // Redirect stdout to a long path.
  SmallString<128> TestDirectory;
  ASSERT_NO_ERROR(
    fs::createUniqueDirectory("program-redirect-test", TestDirectory));
  SmallString<256> LongPath(TestDirectory);
  LongPath.push_back('\\');
  // MAX_PATH = 260
  LongPath.append(260 - TestDirectory.size(), 'a');

  std::string Error;
  bool ExecutionFailed;
  std::optional<StringRef> Redirects[] = {std::nullopt, LongPath.str(),
                                          std::nullopt};
  int RC = ExecuteAndWait(MyExe, ArgV, getEnviron(), Redirects,
    /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &Error,
    &ExecutionFailed);
  EXPECT_FALSE(ExecutionFailed) << Error;
  EXPECT_EQ(0, RC);

  // Remove the long stdout.
  ASSERT_NO_ERROR(fs::remove(Twine(LongPath)));
  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory)));
}
#endif

TEST_F(ProgramEnvTest, CreateProcessTrailingSlash) {}

TEST_F(ProgramEnvTest, TestExecuteNoWait) {}

TEST_F(ProgramEnvTest, TestExecuteNoWaitDetached) {}

TEST_F(ProgramEnvTest, TestExecuteAndWaitTimeout) {}

TEST_F(ProgramEnvTest, TestExecuteNoWaitTimeoutPolling) {}

TEST(ProgramTest, TestExecuteNegative) {}

#ifdef _WIN32
const char utf16le_text[] =
    "\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61\x00";
const char utf16be_text[] =
    "\x00\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61";
#endif
const char utf8_text[] =;

TEST(ProgramTest, TestWriteWithSystemEncoding) {}

TEST_F(ProgramEnvTest, TestExecuteAndWaitStatistics) {}

TEST_F(ProgramEnvTest, TestLockFile) {}

TEST_F(ProgramEnvTest, TestExecuteWithNoStacktraceHandler) {}

} // end anonymous namespace