Alien-cares

 view release on metacpan or  search on metacpan

libcares/test/ares-test.cc  view on Meta::CPAN

namespace ares {
namespace test {

bool verbose = false;
int mock_port = 5300;

const std::vector<int> both_families = {AF_INET, AF_INET6};
const std::vector<int> ipv4_family = {AF_INET};
const std::vector<int> ipv6_family = {AF_INET6};

const std::vector<std::pair<int, bool>> both_families_both_modes = {
  std::make_pair<int, bool>(AF_INET, false),
  std::make_pair<int, bool>(AF_INET, true),
  std::make_pair<int, bool>(AF_INET6, false),
  std::make_pair<int, bool>(AF_INET6, true)
};
const std::vector<std::pair<int, bool>> ipv4_family_both_modes = {
  std::make_pair<int, bool>(AF_INET, false),
  std::make_pair<int, bool>(AF_INET, true)
};
const std::vector<std::pair<int, bool>> ipv6_family_both_modes = {
  std::make_pair<int, bool>(AF_INET6, false),
  std::make_pair<int, bool>(AF_INET6, true)
};

// Which parameters to use in tests
std::vector<int> families = both_families;
std::vector<std::pair<int, bool>> families_modes = both_families_both_modes;

unsigned long long LibraryTest::fails_ = 0;
std::map<size_t, int> LibraryTest::size_fails_;

void ProcessWork(ares_channel channel,
                 std::function<std::set<int>()> get_extrafds,
                 std::function<void(int)> process_extra) {
  int nfds, count;
  fd_set readers, writers;
  struct timeval tv;
  while (true) {
    // Retrieve the set of file descriptors that the library wants us to monitor.
    FD_ZERO(&readers);
    FD_ZERO(&writers);
    nfds = ares_fds(channel, &readers, &writers);
    if (nfds == 0)  // no work left to do in the library
      return;

    // Add in the extra FDs if present.
    std::set<int> extrafds = get_extrafds();
    for (int extrafd : extrafds) {
      FD_SET(extrafd, &readers);
      if (extrafd >= nfds) {
        nfds = extrafd + 1;
      }
    }

    // Wait for activity or timeout.
    tv.tv_sec = 0;
    tv.tv_usec = 100000;  // 100ms
    count = select(nfds, &readers, &writers, nullptr, &tv);
    if (count < 0) {
      fprintf(stderr, "select() failed, errno %d\n", errno);
      return;
    }

    // Let the library process any activity.
    ares_process(channel, &readers, &writers);

    // Let the provided callback process any activity on the extra FD.
    for (int extrafd : extrafds) {
      if (FD_ISSET(extrafd, &readers)) {
        process_extra(extrafd);
      }
    }
  }
}

// static
void LibraryTest::SetAllocFail(int nth) {
  assert(nth > 0);
  assert(nth <= (int)(8 * sizeof(fails_)));
  fails_ |= (1LL << (nth - 1));
}

// static
void LibraryTest::SetAllocSizeFail(size_t size) {
  size_fails_[size]++;
}

// static
void LibraryTest::ClearFails() {
  fails_ = 0;
  size_fails_.clear();
}


// static
bool LibraryTest::ShouldAllocFail(size_t size) {
  bool fail = (fails_ & 0x01);
  fails_ >>= 1;
  if (size_fails_[size] > 0) {
    size_fails_[size]--;
    fail = true;
  }
  return fail;
}

// static
void* LibraryTest::amalloc(size_t size) {
  if (ShouldAllocFail(size)) {
    if (verbose) std::cerr << "Failing malloc(" << size << ") request" << std::endl;
    return nullptr;
  } else {
    return malloc(size);
  }
}

// static
void* LibraryTest::arealloc(void *ptr, size_t size) {
  if (ShouldAllocFail(size)) {
    if (verbose) std::cerr << "Failing realloc(" << ptr << ", " << size << ") request" << std::endl;
    return nullptr;



( run in 0.554 second using v1.01-cache-2.11-cpan-2398b32b56e )