Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/test/test_common/environment.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <cstdint>
4
#include <string>
5
#include <vector>
6
7
#include "envoy/network/address.h"
8
#include "envoy/server/options.h"
9
10
#include "source/common/json/json_loader.h"
11
12
#include "absl/container/node_hash_map.h"
13
#include "absl/strings/str_cat.h"
14
#include "absl/strings/string_view.h"
15
#include "absl/types/optional.h"
16
#include "tools/cpp/runfiles/runfiles.h"
17
18
namespace Envoy {
19
20
namespace Grpc {
21
22
// Support parameterizing over gRPC client type.
23
enum class ClientType { EnvoyGrpc, GoogleGrpc };
24
25
} // namespace Grpc
26
27
class TestEnvironment {
28
public:
29
  using PortMap = absl::node_hash_map<std::string, uint32_t>;
30
31
  using ParamMap = absl::node_hash_map<std::string, std::string>;
32
33
  /**
34
   * Perform common initialization steps needed to run a test binary. This
35
   * method should be called first in all test main functions.
36
   * @param program_name argv[0] test program is invoked with
37
   */
38
  static void initializeTestMain(char* program_name);
39
40
  /**
41
   * Initialize command-line options for later access by tests in getOptions().
42
   * @param argc number of command-line args.
43
   * @param argv array of command-line args.
44
   */
45
  static void initializeOptions(int argc, char** argv);
46
47
  /**
48
   * Check whether testing with IP version type {v4 or v6} is enabled via
49
   * setting the environment variable ENVOY_IP_TEST_VERSIONS.
50
   * @param Network::Address::IpVersion IP address version to check.
51
   * @return bool if testing only with IP type addresses only.
52
   */
53
  static bool shouldRunTestForIpVersion(Network::Address::IpVersion type);
54
55
  /**
56
   * Return a vector of IP address parameters to test. Tests can be run with
57
   * only IPv4 addressing or only IPv6 addressing by setting the environment
58
   * variable ENVOY_IP_TEST_VERSIONS to "v4only" or "v6only", respectively.
59
   * The default test setting runs all tests with both IPv4 and IPv6 addresses.
60
   * @return std::vector<Network::Address::IpVersion> vector of IP address
61
   * types to test.
62
   */
63
  static std::vector<Network::Address::IpVersion> getIpVersionsForTest();
64
65
  /**
66
   * Return a vector of spdlog loggers as parameters to test. Tests are mainly
67
   * for the behavior consistency between default loggers and fine-grained loggers.
68
   * @return std::vector<spdlog::logger*>
69
   */
70
  static std::vector<spdlog::logger*> getSpdLoggersForTest();
71
72
  /**
73
   * Tests can be run with Envoy Grpc and Google Grpc or Envoy Grpc alone by setting compiler option
74
   * `--define google_grpc=disabled`.
75
   * @return a vector of Grpc versions to test.
76
   */
77
  static std::vector<Grpc::ClientType> getsGrpcVersionsForTest();
78
79
  /**
80
   * Obtain command-line options reference.
81
   * @return Server::Options& with command-line options.
82
   */
83
  static Server::Options& getOptions();
84
85
  /**
86
   * Obtain the value of an environment variable, null if not available.
87
   * @return absl::optional<std::string> with the value of the environment variable.
88
   */
89
  static absl::optional<std::string> getOptionalEnvVar(const std::string& var);
90
91
  /**
92
   * Obtain the value of an environment variable, die if not available.
93
   * @return std::string with the value of the environment variable.
94
   */
95
  static std::string getCheckedEnvVar(const std::string& var);
96
97
  /**
98
   * Obtain a private writable temporary directory.
99
   * @return const std::string& with the path to the temporary directory.
100
   */
101
  static const std::string& temporaryDirectory();
102
103
  /**
104
   * Prefix a given path with the private writable test temporary directory.
105
   * @param path path suffix.
106
   * @return std::string path qualified with temporary directory.
107
   */
108
12.4k
  static std::string temporaryPath(absl::string_view path) {
109
12.4k
    return absl::StrCat(temporaryDirectory(), "/", path);
110
12.4k
  }
111
112
  /**
113
   * Obtain platform specific new line character(s)
114
   * @return absl::string_view platform specific new line character(s)
115
   */
116
  static constexpr absl::string_view newLine
117
#ifdef WIN32
118
      {"\r\n"};
119
#else
120
      {"\n"};
121
#endif
122
123
  /**
124
   * Obtain read-only test input data directory.
125
   * @param workspace the name of the Bazel workspace where the input data is.
126
   * @return const std::string& with the path to the read-only test input directory.
127
   */
128
  static std::string runfilesDirectory(const std::string& workspace = "envoy");
129
130
  /**
131
   * Prefix a given path with the read-only test input data directory.
132
   * @param path path suffix.
133
   * @return std::string path qualified with read-only test input data directory.
134
   */
135
  static std::string runfilesPath(const std::string& path, const std::string& workspace = "envoy");
136
137
  /**
138
   * Obtain Unix Domain Socket temporary directory.
139
   * @return std::string& with the path to the Unix Domain Socket temporary directory.
140
   */
141
  static const std::string unixDomainSocketDirectory();
142
143
  /**
144
   * Prefix a given path with the Unix Domain Socket temporary directory.
145
   * @param path path suffix.
146
   * @param abstract_namespace true if an abstract namespace should be returned.
147
   * @return std::string path qualified with the Unix Domain Socket temporary directory.
148
   */
149
  static std::string unixDomainSocketPath(const std::string& path,
150
0
                                          bool abstract_namespace = false) {
151
0
    return (abstract_namespace ? "@" : "") + unixDomainSocketDirectory() + "/" + path;
152
0
  }
153
154
  /**
155
   * String environment path, loopback, and DNS resolver type substitution.
156
   * @param str string with template patterns including {{ test_tmpdir }}.
157
   * @param version supplies the IP version to substitute for relevant templates.
158
   * @return std::string with patterns replaced with environment values.
159
   */
160
  static std::string
161
  substitute(const std::string& str,
162
             Network::Address::IpVersion version = Network::Address::IpVersion::v4);
163
164
  /**
165
   * Substitute ports, paths, and IP loopback addresses in a JSON file in the
166
   * private writable test temporary directory.
167
   * @param path path prefix for the input file with port and path templates.
168
   * @param port_map map from port name to port number.
169
   * @param version IP address version to substitute.
170
   * @return std::string path for the generated file.
171
   */
172
  static std::string temporaryFileSubstitute(const std::string& path, const PortMap& port_map,
173
                                             Network::Address::IpVersion version);
174
  /**
175
   * Substitute ports, paths, and IP loopback addresses in a JSON file in the
176
   * private writable test temporary directory.
177
   * @param path path prefix for the input file with port and path templates.
178
   * @param param_map map from parameter name to values.
179
   * @param port_map map from port name to port number.
180
   * @param version IP address version to substitute.
181
   * @return std::string path for the generated file.
182
   */
183
  static std::string temporaryFileSubstitute(const std::string& path, const ParamMap& param_map,
184
                                             const PortMap& port_map,
185
                                             Network::Address::IpVersion version);
186
187
  /**
188
   * Build JSON object from a string subject to environment path, loopback, and DNS resolver type
189
   * substitution.
190
   * @param json JSON with template patterns including {{ test_certs }}.
191
   * @param version supplies the IP version to substitute for relevant templates.
192
   * @return Json::ObjectSharedPtr with built JSON object.
193
   */
194
  static Json::ObjectSharedPtr
195
  jsonLoadFromString(const std::string& json,
196
                     Network::Address::IpVersion version = Network::Address::IpVersion::v4);
197
198
#ifndef TARGET_OS_IOS
199
  /**
200
   * Execute a program under ::system. Any failure is fatal.
201
   * @param args program path and arguments.
202
   */
203
204
  static void exec(const std::vector<std::string>& args);
205
#endif
206
207
  /**
208
   * Dumps the contents of the string into a temporary file from temporaryDirectory() + filename.
209
   *
210
   * @param filename: the name of the file to use
211
   * @param contents: the data to go in the file.
212
   * @param fully_qualified_path: if true, will write to filename without prepending the tempdir.
213
   * @param unlink: if true will delete any prior file before writing.
214
   * @return the fully qualified path of the output file.
215
   */
216
  static std::string writeStringToFileForTest(const std::string& filename,
217
                                              const std::string& contents,
218
                                              bool fully_qualified_path = false,
219
                                              bool unlink = true);
220
  /**
221
   * Dumps the contents of the file into the string.
222
   *
223
   * @param filename: the fully qualified name of the file to use
224
   */
225
  static std::string readFileToStringForTest(const std::string& filename);
226
227
  /**
228
   * Create a path on the filesystem (mkdir -p ... equivalent).
229
   * @param path.
230
   */
231
  static void createPath(const std::string& path);
232
233
  /**
234
   * Remove a path on the filesystem (rm -rf ... equivalent).
235
   * @param path.
236
   */
237
  static void removePath(const std::string& path);
238
239
  /**
240
   * Rename a file
241
   * @param old_name
242
   * @param new_name
243
   */
244
  static void renameFile(const std::string& old_name, const std::string& new_name);
245
246
  /**
247
   * Create a symlink
248
   * @param target
249
   * @param link
250
   */
251
  static void createSymlink(const std::string& target, const std::string& link);
252
253
  /**
254
   * Set environment variable. Same args as setenv(2).
255
   */
256
  static void setEnvVar(const std::string& name, const std::string& value, int overwrite);
257
258
  /**
259
   * Removes environment variable. Same args as unsetenv(3).
260
   */
261
  static void unsetEnvVar(const std::string& name);
262
263
  /**
264
   * Set runfiles with current test, this have to be called before calling path related functions.
265
   */
266
  static void setRunfiles(bazel::tools::cpp::runfiles::Runfiles* runfiles);
267
268
private:
269
  static bazel::tools::cpp::runfiles::Runfiles* runfiles_;
270
};
271
272
/**
273
 * A utility class for atomically updating a file using symbolic link swap.
274
 * Note the file lifetime is limited to the instance of the AtomicFileUpdater
275
 * which erases any existing files upon creation, used for specific test
276
 * scenarios. See discussion at https://github.com/envoyproxy/envoy/pull/4298
277
 */
278
class AtomicFileUpdater {
279
public:
280
  AtomicFileUpdater(const std::string& filename);
281
282
  void update(const std::string& contents);
283
284
private:
285
  const std::string link_;
286
  const std::string new_link_;
287
  const std::string target1_;
288
  const std::string target2_;
289
  bool use_target1_{true};
290
};
291
292
} // namespace Envoy