summaryrefslogtreecommitdiffhomepage
path: root/test/util/temp_path.h
blob: 33eb6a72c01a9b49300df6e20dbe190ae6582fca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright 2018 Google LLC
//
// 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.

#ifndef GVISOR_TEST_UTIL_TEMP_PATH_H_
#define GVISOR_TEST_UTIL_TEMP_PATH_H_

#include <sys/stat.h>
#include <string>
#include <utility>

#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "test/util/posix_error.h"

namespace gvisor {
namespace testing {

// Returns an absolute path for a file in `dir` that does not yet exist.
// Distinct calls to NewTempAbsPathInDir from the same process, even from
// multiple threads, are guaranteed to return different paths. Distinct calls to
// NewTempAbsPathInDir from different processes are not synchronized.
std::string NewTempAbsPathInDir(absl::string_view base);

// Like NewTempAbsPathInDir, but the returned path is in the test's temporary
// directory, as provided by the testing framework.
std::string NewTempAbsPath();

// Like NewTempAbsPathInDir, but the returned path is relative (to the current
// working directory).
std::string NewTempRelPath();

// Returns the absolute path for the test temp dir.
std::string GetAbsoluteTestTmpdir();

// Represents a temporary file or directory.
class TempPath {
 public:
  // Default creation mode for files.
  static constexpr mode_t kDefaultFileMode = 0644;

  // Default creation mode for directories.
  static constexpr mode_t kDefaultDirMode = 0755;

  // Creates a temporary file in directory `parent` with mode `mode` and
  // contents `content`.
  static PosixErrorOr<TempPath> CreateFileWith(absl::string_view parent,
                                               absl::string_view content,
                                               mode_t mode);

  // Creates an empty temporary subdirectory in directory `parent` with mode
  // `mode`.
  static PosixErrorOr<TempPath> CreateDirWith(absl::string_view parent,
                                              mode_t mode);

  // Creates a temporary symlink in directory `parent` to destination `dest`.
  static PosixErrorOr<TempPath> CreateSymlinkTo(absl::string_view parent,
                                                std::string const& dest);

  // Creates an empty temporary file in directory `parent` with mode
  // kDefaultFileMode.
  static PosixErrorOr<TempPath> CreateFileIn(absl::string_view parent);

  // Creates an empty temporary subdirectory in directory `parent` with mode
  // kDefaultDirMode.
  static PosixErrorOr<TempPath> CreateDirIn(absl::string_view parent);

  // Creates an empty temporary file in the test's temporary directory with mode
  // `mode`.
  static PosixErrorOr<TempPath> CreateFileMode(mode_t mode);

  // Creates an empty temporary file in the test's temporary directory with
  // mode kDefaultFileMode.
  static PosixErrorOr<TempPath> CreateFile();

  // Creates an empty temporary subdirectory in the test's temporary directory
  // with mode kDefaultDirMode.
  static PosixErrorOr<TempPath> CreateDir();

  // Constructs a TempPath that represents nothing.
  TempPath() = default;

  // Constructs a TempPath that represents the given path, which will be deleted
  // when the TempPath is destroyed.
  explicit TempPath(std::string path) : path_(std::move(path)) {}

  // Attempts to delete the represented temporary file or directory (in the
  // latter case, also attempts to delete its contents).
  ~TempPath();

  // Attempts to delete the represented temporary file or directory, then
  // transfers ownership of the path represented by orig to this TempPath.
  TempPath(TempPath&& orig);
  TempPath& operator=(TempPath&& orig);

  // Changes the path this TempPath represents. If the TempPath already
  // represented a path, deletes and returns that path. Otherwise returns the
  // empty std::string.
  std::string reset(std::string newpath);
  std::string reset() { return reset(""); }

  // Forgets and returns the path this TempPath represents. The path is not
  // deleted.
  std::string release();

  // Returns the path this TempPath represents.
  std::string path() const { return path_; }

 private:
  template <typename F>
  static PosixErrorOr<TempPath> CreateIn(absl::string_view const parent,
                                         F const& f) {
    std::string path = NewTempAbsPathInDir(parent);
    RETURN_IF_ERRNO(f(path));
    return TempPath(std::move(path));
  }

  std::string path_;
};

}  // namespace testing
}  // namespace gvisor

#endif  // GVISOR_TEST_UTIL_TEMP_PATH_H_