folly/folly/testing/TestUtil.h

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <map>
#include <string>

#include <folly/Range.h>
#include <folly/ScopeGuard.h>
#include <folly/experimental/io/FsUtil.h>

namespace folly {
namespace test {

/**
 * Temporary file.
 *
 * By default, the file is created in a system-specific location (the value
 * of the TMPDIR environment variable, or /tmp), but you can override that
 * with a different (non-empty) directory passed to the constructor.
 *
 * By default, the file is closed and deleted when the TemporaryFile object
 * is destroyed, but both these behaviors can be overridden with arguments
 * to the constructor.
 */
class TemporaryFile {};

/**
 * Temporary directory.
 *
 * By default, the temporary directory is created in a system-specific
 * location (the value of the TMPDIR environment variable, or /tmp), but you
 * can override that with a non-empty directory passed to the constructor.
 *
 * By default, the directory is recursively deleted when the TemporaryDirectory
 * object is destroyed, but that can be overridden with an argument
 * to the constructor.
 */

class TemporaryDirectory {};

/**
 * Changes into a temporary directory, and deletes it with all its contents
 * upon destruction, also changing back to the original working directory.
 */
class ChangeToTempDir {};

namespace detail {
struct SavedState {};
SavedState disableInvalidParameters();
void enableInvalidParameters(SavedState state);
} // namespace detail

// Ok, so fun fact: The CRT on windows will actually abort
// on certain failed parameter validation checks in debug
// mode rather than simply returning -1 as it does in release
// mode. We can however, ensure consistent behavior by
// registering our own thread-local invalid parameter handler
// for the duration of the call, and just have that handler
// immediately return. We also have to disable CRT asertion
// alerts for the duration of the call, otherwise we get
// the abort-retry-ignore window.
template <typename Func>
auto msvcSuppressAbortOnInvalidParams(Func func) -> decltype(func()) {}

/**
 * Easy PCRE regex matching. Note that pattern must match the ENTIRE target,
 * so use .* at the start and end of the pattern, as appropriate.  See
 * http://regex101.com/ for a PCRE simulator.
 */
#define EXPECT_PCRE_MATCH(pattern_stringpiece, target_stringpiece)
#define EXPECT_NO_PCRE_MATCH(pattern_stringpiece, target_stringpiece)

namespace detail {
bool hasPCREPatternMatch(StringPiece pattern, StringPiece target);
bool hasNoPCREPatternMatch(StringPiece pattern, StringPiece target);
} // namespace detail

/**
 * Use these patterns together with CaptureFD and EXPECT_PCRE_MATCH() to
 * test for the presence (or absence) of log lines at a particular level:
 *
 *   CaptureFD stderr(2);
 *   LOG(INFO) << "All is well";
 *   EXPECT_NO_PCRE_MATCH(glogErrOrWarnPattern(), stderr.readIncremental());
 *   LOG(ERROR) << "Uh-oh";
 *   EXPECT_PCRE_MATCH(glogErrorPattern(), stderr.readIncremental());
 */
inline std::string glogErrorPattern() {}
inline std::string glogWarningPattern() {}
// Error OR warning
inline std::string glogErrOrWarnPattern() {}

/**
 * Temporarily capture a file descriptor by redirecting it into a file.
 * You can consume its entire output thus far via read(), incrementally
 * via readIncremental(), or via callback using chunk_cob.
 * Great for testing logging (see also glog*Pattern()).
 */
class CaptureFD {};

//  find_resource
//
//  Finds the file path of a resource which was built alongside a test binary.
//
//  Care must be taken to set up the test and resource build rules in accordance
//  with this function.
fs::path find_resource(const std::string& resource);

} // namespace test
} // namespace folly