proxygen
AsyncIOTest.cpp File Reference
#include <folly/experimental/io/AsyncIO.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <random>
#include <thread>
#include <vector>
#include <glog/logging.h>
#include <folly/ScopeGuard.h>
#include <folly/String.h>
#include <folly/experimental/io/FsUtil.h>
#include <folly/portability/GTest.h>
#include <folly/portability/Sockets.h>

Go to the source code of this file.

Functions

 TEST (AsyncIO, ZeroAsyncDataNotPollable)
 
 TEST (AsyncIO, ZeroAsyncDataPollable)
 
 TEST (AsyncIO, SingleAsyncDataNotPollable)
 
 TEST (AsyncIO, SingleAsyncDataPollable)
 
 TEST (AsyncIO, MultipleAsyncDataNotPollable)
 
 TEST (AsyncIO, MultipleAsyncDataPollable)
 
 TEST (AsyncIO, ManyAsyncDataNotPollable)
 
 TEST (AsyncIO, ManyAsyncDataPollable)
 
 TEST (AsyncIO, NonBlockingWait)
 
 TEST (AsyncIO, Cancel)
 

Function Documentation

TEST ( AsyncIO  ,
ZeroAsyncDataNotPollable   
)

Definition at line 290 of file AsyncIOTest.cpp.

290  {
291  testReads({{0, 0}}, AsyncIO::NOT_POLLABLE);
292 }
TEST ( AsyncIO  ,
ZeroAsyncDataPollable   
)

Definition at line 294 of file AsyncIOTest.cpp.

294  {
295  testReads({{0, 0}}, AsyncIO::POLLABLE);
296 }
TEST ( AsyncIO  ,
SingleAsyncDataNotPollable   
)

Definition at line 298 of file AsyncIOTest.cpp.

298  {
299  testReads({{0, kAlign}}, AsyncIO::NOT_POLLABLE);
300  testReads({{0, kAlign}}, AsyncIO::NOT_POLLABLE);
301 }
TEST ( AsyncIO  ,
SingleAsyncDataPollable   
)

Definition at line 303 of file AsyncIOTest.cpp.

303  {
304  testReads({{0, kAlign}}, AsyncIO::POLLABLE);
305  testReads({{0, kAlign}}, AsyncIO::POLLABLE);
306 }
TEST ( AsyncIO  ,
MultipleAsyncDataNotPollable   
)

Definition at line 308 of file AsyncIOTest.cpp.

308  {
309  testReads(
310  {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
311  AsyncIO::NOT_POLLABLE);
312  testReads(
313  {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
314  AsyncIO::NOT_POLLABLE);
315 
316  testReads(
317  {{0, 5 * 1024 * 1024}, {kAlign, 5 * 1024 * 1024}}, AsyncIO::NOT_POLLABLE);
318 
319  testReads(
320  {
321  {kAlign, 0},
322  {kAlign, kAlign},
323  {kAlign, 2 * kAlign},
324  {kAlign, 20 * kAlign},
325  {kAlign, 1024 * 1024},
326  },
327  AsyncIO::NOT_POLLABLE);
328 }
TEST ( AsyncIO  ,
MultipleAsyncDataPollable   
)

Definition at line 330 of file AsyncIOTest.cpp.

330  {
331  testReads(
332  {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
333  AsyncIO::POLLABLE);
334  testReads(
335  {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
336  AsyncIO::POLLABLE);
337 
338  testReads(
339  {{0, 5 * 1024 * 1024}, {kAlign, 5 * 1024 * 1024}}, AsyncIO::NOT_POLLABLE);
340 
341  testReads(
342  {
343  {kAlign, 0},
344  {kAlign, kAlign},
345  {kAlign, 2 * kAlign},
346  {kAlign, 20 * kAlign},
347  {kAlign, 1024 * 1024},
348  },
349  AsyncIO::NOT_POLLABLE);
350 }
TEST ( AsyncIO  ,
ManyAsyncDataNotPollable   
)

Definition at line 352 of file AsyncIOTest.cpp.

References i, and v.

352  {
353  {
354  std::vector<TestSpec> v;
355  for (int i = 0; i < 1000; i++) {
356  v.push_back({off_t(kAlign * i), kAlign});
357  }
358  testReads(v, AsyncIO::NOT_POLLABLE);
359  }
360 }
auto v
TEST ( AsyncIO  ,
ManyAsyncDataPollable   
)

Definition at line 362 of file AsyncIOTest.cpp.

References i, and v.

362  {
363  {
364  std::vector<TestSpec> v;
365  for (int i = 0; i < 1000; i++) {
366  v.push_back({off_t(kAlign * i), kAlign});
367  }
368  testReads(v, AsyncIO::POLLABLE);
369  }
370 }
auto v
TEST ( AsyncIO  ,
NonBlockingWait   
)

Definition at line 372 of file AsyncIOTest.cpp.

References folly::netops::close(), folly::errnoStr(), EXPECT_EQ, EXPECT_LE, EXPECT_TRUE, folly::AsyncIO::pending(), SCOPE_EXIT, folly::size(), folly::AsyncIO::submit(), and folly::AsyncIO::wait().

372  {
373  AsyncIO aioReader(1, AsyncIO::NOT_POLLABLE);
374  AsyncIO::Op op;
375  int fd = ::open(tempFile.path().c_str(), O_DIRECT | O_RDONLY);
376  PCHECK(fd != -1);
377  SCOPE_EXIT {
378  ::close(fd);
379  };
380  size_t size = 2 * kAlign;
381  auto buf = allocateAligned(size);
382  op.pread(fd, buf.get(), size, 0);
383  aioReader.submit(&op);
384  EXPECT_EQ(aioReader.pending(), 1);
385 
386  folly::Range<AsyncIO::Op**> completed;
387  while (completed.empty()) {
388  // poll without blocking until the read request completes.
389  completed = aioReader.wait(0);
390  }
391  EXPECT_EQ(completed.size(), 1);
392 
393  EXPECT_TRUE(completed[0] == &op);
394  ssize_t res = op.result();
395  EXPECT_LE(0, res) << folly::errnoStr(-res);
396  EXPECT_EQ(size, res);
397  EXPECT_EQ(aioReader.pending(), 0);
398 }
#define EXPECT_LE(val1, val2)
Definition: gtest.h:1928
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
fbstring errnoStr(int err)
Definition: String.cpp:463
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
int close(NetworkSocket s)
Definition: NetOps.cpp:90
TEST ( AsyncIO  ,
Cancel   
)

Definition at line 400 of file AsyncIOTest.cpp.

References folly::AsyncIO::cancel(), folly::netops::close(), EXPECT_EQ, EXPECT_GE, EXPECT_TRUE, i, ops, folly::AsyncIO::pending(), SCOPE_EXIT, folly::size(), folly::AsyncIO::submit(), and folly::AsyncIO::wait().

400  {
401  constexpr size_t kNumOpsBatch1 = 10;
402  constexpr size_t kNumOpsBatch2 = 10;
403 
404  AsyncIO aioReader(kNumOpsBatch1 + kNumOpsBatch2, AsyncIO::NOT_POLLABLE);
405  int fd = ::open(tempFile.path().c_str(), O_DIRECT | O_RDONLY);
406  PCHECK(fd != -1);
407  SCOPE_EXIT {
408  ::close(fd);
409  };
410 
411  size_t completed = 0;
412 
413  std::vector<std::unique_ptr<AsyncIO::Op>> ops;
414  std::vector<ManagedBuffer> bufs;
415  const auto schedule = [&](size_t n) {
416  for (size_t i = 0; i < n; ++i) {
417  const size_t size = 2 * kAlign;
418  bufs.push_back(allocateAligned(size));
419 
420  ops.push_back(std::make_unique<AsyncIO::Op>());
421  auto& op = *ops.back();
422 
423  op.setNotificationCallback([&](AsyncIOOp*) { ++completed; });
424  op.pread(fd, bufs.back().get(), size, 0);
425  aioReader.submit(&op);
426  }
427  };
428 
429  // Mix completed and canceled operations for this test.
430  // In order to achieve that, schedule in two batches and do partial
431  // wait() after the first one.
432 
433  schedule(kNumOpsBatch1);
434  EXPECT_EQ(aioReader.pending(), kNumOpsBatch1);
435  EXPECT_EQ(completed, 0);
436 
437  auto result = aioReader.wait(1);
438  EXPECT_GE(result.size(), 1);
439  EXPECT_EQ(completed, result.size());
440  EXPECT_EQ(aioReader.pending(), kNumOpsBatch1 - result.size());
441 
442  schedule(kNumOpsBatch2);
443  EXPECT_EQ(aioReader.pending(), ops.size() - result.size());
444  EXPECT_EQ(completed, result.size());
445 
446  auto canceled = aioReader.cancel();
447  EXPECT_EQ(canceled.size(), ops.size() - result.size());
448  EXPECT_EQ(aioReader.pending(), 0);
449  EXPECT_EQ(completed, result.size());
450 
451  size_t foundCompleted = 0;
452  for (auto& op : ops) {
453  if (op->state() == AsyncIOOp::State::COMPLETED) {
454  ++foundCompleted;
455  } else {
456  EXPECT_TRUE(op->state() == AsyncIOOp::State::CANCELED) << *op;
457  }
458  }
459  EXPECT_EQ(foundCompleted, completed);
460 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
const int ops
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
int close(NetworkSocket s)
Definition: NetOps.cpp:90