YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/fs/fs_manager-test.cc
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
33
#include <glog/logging.h>
34
#include <glog/stl_logging.h>
35
#include <gtest/gtest.h>
36
37
#include "yb/fs/fs_manager.h"
38
39
#include "yb/gutil/strings/util.h"
40
41
#include "yb/util/status.h"
42
#include "yb/util/test_macros.h"
43
#include "yb/util/test_util.h"
44
45
using std::shared_ptr;
46
47
DECLARE_string(fs_data_dirs);
48
DECLARE_string(fs_wal_dirs);
49
50
namespace yb {
51
52
class FsManagerTestBase : public YBTest {
53
 public:
54
11
  void SetUp() override {
55
11
    YBTest::SetUp();
56
57
    // Initialize File-System Layout
58
11
    ReinitFsManager();
59
11
    ASSERT_OK(fs_manager_->CreateInitialFileSystemLayout());
60
11
    ASSERT_OK(fs_manager_->Open());
61
11
  }
62
63
11
  void ReinitFsManager() {
64
11
    ReinitFsManager({ GetTestPath("fs_root") }, { GetTestPath("fs_root")} );
65
11
  }
66
67
22
  void ReinitFsManager(const vector<string>& wal_paths, const vector<string>& data_paths) {
68
    // Blow away the old memtrackers first.
69
22
    fs_manager_.reset();
70
71
22
    FsManagerOpts opts;
72
22
    opts.wal_paths = wal_paths;
73
22
    opts.data_paths = data_paths;
74
22
    opts.server_type = kServerType;
75
22
    fs_manager_.reset(new FsManager(env_.get(), opts));
76
22
  }
77
78
3
  void ReinitFsManager(const FsManagerOpts& opts) {
79
3
    fs_manager_.reset(new FsManager(env_.get(), opts));
80
3
  }
81
82
5
  void ValidateRootDataPaths(const string& data_path, const string& wal_path) {
83
5
    ASSERT_TRUE(HasPrefixString(fs_manager()->GetConsensusMetadataDir(), data_path));
84
5
    ASSERT_TRUE(HasPrefixString(fs_manager()->GetRaftGroupMetadataDir(), data_path));
85
5
    vector<string> data_dirs = fs_manager()->GetDataRootDirs();
86
5
    ASSERT_EQ(1, data_dirs.size());
87
5
    ASSERT_TRUE(HasPrefixString(data_dirs[0], data_path));
88
5
    if (!wal_path.empty()) {
89
2
      vector<string> wal_dirs = fs_manager()->GetWalRootDirs();
90
2
      ASSERT_EQ(1, wal_dirs.size());
91
2
      ASSERT_TRUE(HasPrefixString(wal_dirs[0], wal_path));
92
2
    }
93
5
  }
94
95
  void SetupFlagsAndBaseDirs(
96
3
      const string& data_path, const string& wal_path, FsManagerOpts* out_opts) {
97
    // Setup data in case empty.
98
3
    FLAGS_fs_data_dirs = data_path;
99
3
    if (!data_path.empty()) {
100
2
      string path = GetTestPath(data_path);
101
2
      ASSERT_OK(env_->CreateDir(path));
102
2
      FLAGS_fs_data_dirs = path;
103
2
    }
104
    // Setup wal in case empty.
105
3
    FLAGS_fs_wal_dirs = wal_path;
106
3
    if (!wal_path.empty()) {
107
2
      string path = GetTestPath(wal_path);
108
2
      ASSERT_OK(env_->CreateDir(path));
109
2
      FLAGS_fs_wal_dirs = path;
110
2
    }
111
    // Setup opts from flags and add server type.
112
3
    FsManagerOpts opts;
113
3
    opts.server_type = kServerType;
114
3
    *out_opts = opts;
115
3
  }
116
117
2
  void SetupForDelete(ShouldDeleteLogs delete_logs_dir = ShouldDeleteLogs::kFalse) {
118
2
    string path = GetTestPath("new_fs_root");
119
2
    ASSERT_OK(env_->CreateDir(path));
120
121
2
    ReinitFsManager(vector <string> (), {path});
122
2
    ASSERT_OK(fs_manager()->CreateInitialFileSystemLayout());
123
2
    ValidateRootDataPaths(path, "");
124
125
2
    log_dir_ = path + "/yb-data/logs";
126
2
    ASSERT_OK(env_->CreateDir(log_dir_));
127
2
    ASSERT_OK(fs_manager()->DeleteFileSystemLayout(delete_logs_dir));
128
2
  }
129
130
2
  void EnsureDataDirNotPresent() {
131
2
    std::vector <std::string> data_dirs = fs_manager()->GetDataRootDirs();
132
2
    for (auto data_dir : data_dirs) {
133
2
      bool is_dir = false;
134
2
      ASSERT_NOK(env_->IsDirectory(data_dir, &is_dir));
135
2
      ASSERT_FALSE(is_dir);
136
2
    }
137
2
  }
138
139
44
  FsManager *fs_manager() const { return fs_manager_.get(); }
140
141
2
  string log_dir() const { return log_dir_; }
142
143
  const char* kServerType = "tserver_test";
144
145
 private:
146
  std::unique_ptr<FsManager> fs_manager_;
147
  string log_dir_ = "";
148
};
149
150
1
TEST_F(FsManagerTestBase, TestIllegalPaths) {
151
1
  vector<string> illegal = { "", "asdf", "/foo\n\t" };
152
3
  for (const string& path : illegal) {
153
3
    ReinitFsManager({ path }, { path });
154
3
    ASSERT_TRUE(fs_manager()->CreateInitialFileSystemLayout().IsIOError());
155
3
  }
156
1
}
157
158
1
TEST_F(FsManagerTestBase, TestMultiplePaths) {
159
1
  vector<string> wal_paths = { GetTestPath("a"), GetTestPath("b"), GetTestPath("c") };
160
1
  vector<string> data_paths = { GetTestPath("a"), GetTestPath("b"), GetTestPath("c") };
161
1
  ReinitFsManager(wal_paths, data_paths);
162
1
  ASSERT_OK(fs_manager()->CreateInitialFileSystemLayout());
163
1
  ASSERT_OK(fs_manager()->Open());
164
1
}
165
166
1
TEST_F(FsManagerTestBase, TestMatchingPathsWithMismatchedSlashes) {
167
1
  vector<string> wal_paths = { GetTestPath("foo") };
168
1
  vector<string> data_paths = { wal_paths[0] + "/" };
169
1
  ReinitFsManager(wal_paths, data_paths);
170
1
  ASSERT_OK(fs_manager()->CreateInitialFileSystemLayout());
171
1
}
172
173
1
TEST_F(FsManagerTestBase, TestDuplicatePaths) {
174
1
  const string wal_path = GetTestPath("foo");
175
1
  const string data_path = GetTestPath("bar");
176
1
  ReinitFsManager({ wal_path, wal_path, wal_path }, { data_path, data_path, data_path });
177
1
  ASSERT_OK(fs_manager()->CreateInitialFileSystemLayout());
178
1
  ASSERT_EQ(
179
1
      vector<string>({ JoinPathSegments(
180
1
          GetServerTypeDataPath(wal_path, kServerType),
181
1
          fs_manager()->kWalDirName) }),
182
1
      fs_manager()->GetWalRootDirs());
183
1
  ASSERT_EQ(
184
1
      vector<string>({ JoinPathSegments(
185
1
          GetServerTypeDataPath(data_path, kServerType),
186
1
          fs_manager()->kDataDirName) }),
187
1
      fs_manager()->GetDataRootDirs());
188
1
}
189
190
1
TEST_F(FsManagerTestBase, TestListTablets) {
191
1
  vector<string> tablet_ids;
192
1
  ASSERT_OK(fs_manager()->ListTabletIds(&tablet_ids));
193
1
  ASSERT_EQ(0, tablet_ids.size());
194
195
1
  string path = fs_manager()->GetRaftGroupMetadataDir();
196
1
  std::unique_ptr<WritableFile> writer;
197
1
  ASSERT_OK(env_->NewWritableFile(
198
1
      JoinPathSegments(path, "foo.tmp"), &writer));
199
1
  ASSERT_OK(env_->NewWritableFile(
200
1
      JoinPathSegments(path, "foo.tmp.abc123"), &writer));
201
1
  ASSERT_OK(env_->NewWritableFile(
202
1
      JoinPathSegments(path, ".hidden"), &writer));
203
1
  ASSERT_OK(env_->NewWritableFile(
204
1
      JoinPathSegments(path, "a_tablet_sort_of"), &writer));
205
206
1
  ASSERT_OK(fs_manager()->ListTabletIds(&tablet_ids));
207
2
  ASSERT_EQ(1, tablet_ids.size()) << tablet_ids;
208
1
}
209
210
1
TEST_F(FsManagerTestBase, TestCannotUseNonEmptyFsRoot) {
211
1
  string path = GetTestPath("new_fs_root");
212
1
  ReinitFsManager({ path }, { path });
213
1
  ASSERT_OK(fs_manager()->CreateInitialFileSystemLayout());
214
1
  {
215
1
    std::unique_ptr<WritableFile> writer;
216
1
    ASSERT_OK(env_->NewWritableFile(
217
1
        JoinPathSegments(GetServerTypeDataPath(path, kServerType), "some_file"), &writer));
218
1
  }
219
220
  // Try to create the FS layout. It should fail.
221
1
  ASSERT_TRUE(fs_manager()->CreateInitialFileSystemLayout().IsAlreadyPresent());
222
1
}
223
224
1
TEST_F(FsManagerTestBase, TestEmptyDataPath) {
225
1
  ReinitFsManager(vector<string>(), vector<string>());
226
1
  Status s = fs_manager()->CreateInitialFileSystemLayout();
227
1
  ASSERT_TRUE(s.IsIOError());
228
1
  ASSERT_STR_CONTAINS(s.ToString(),
229
1
                      "List of data directories (fs_data_dirs) not provided");
230
1
}
231
232
1
TEST_F(FsManagerTestBase, TestOnlyDataPath) {
233
1
  string path = GetTestPath("new_fs_root");
234
1
  ASSERT_OK(env_->CreateDir(path));
235
236
1
  ReinitFsManager(vector<string>(), { path });
237
1
  ASSERT_OK(fs_manager()->CreateInitialFileSystemLayout());
238
1
  ValidateRootDataPaths(path, "");
239
1
}
240
241
1
TEST_F(FsManagerTestBase, TestPathsFromFlags) {
242
1
  FsManagerOpts opts;
243
  // If no wal specified, we inherit from fs_data_dirs
244
1
  {
245
1
    SetupFlagsAndBaseDirs("new_data_root_1", "", &opts);
246
1
    ReinitFsManager(opts);
247
1
    Status s = fs_manager()->CreateInitialFileSystemLayout();
248
1
    ASSERT_OK(s);
249
1
    ValidateRootDataPaths(FLAGS_fs_data_dirs, FLAGS_fs_data_dirs);
250
1
  }
251
  // If they are both set, we expect them to be whatever they are set to.
252
1
  {
253
1
    SetupFlagsAndBaseDirs("new_data_root_2", "new_wal_root_2", &opts);
254
1
    ReinitFsManager(opts);
255
1
    Status s = fs_manager()->CreateInitialFileSystemLayout();
256
1
    ASSERT_OK(s);
257
1
    ValidateRootDataPaths(FLAGS_fs_data_dirs, FLAGS_fs_wal_dirs);
258
1
  }
259
260
  // If no data_dirs is set, we expect a failure!
261
1
  {
262
1
    SetupFlagsAndBaseDirs("", "new_wal_root_3", &opts);
263
1
    ReinitFsManager(opts);
264
1
    Status s = fs_manager()->CreateInitialFileSystemLayout();
265
1
    ASSERT_TRUE(s.IsIOError());
266
1
    ASSERT_STR_CONTAINS(s.ToString(),
267
1
                        "List of data directories (fs_data_dirs) not provided");
268
1
  }
269
1
}
270
271
1
TEST_F(FsManagerTestBase, TestDataDirDeletedAndNotLogDir) {
272
1
  SetupForDelete();
273
274
1
  EnsureDataDirNotPresent();
275
276
1
  bool is_dir = false;
277
1
  ASSERT_OK(env_->IsDirectory(log_dir(), &is_dir));
278
1
  ASSERT_TRUE(is_dir);
279
1
}
280
281
1
TEST_F(FsManagerTestBase, TestLogDirAlsoDeleted) {
282
1
  SetupForDelete(ShouldDeleteLogs::kTrue);
283
284
1
  EnsureDataDirNotPresent();
285
286
1
  bool is_dir = false;
287
1
  ASSERT_NOK(env_->IsDirectory(log_dir(), &is_dir));
288
1
  ASSERT_FALSE(is_dir);
289
1
}
290
291
} // namespace yb