/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

#include <thrift/thrift-config.h>

#include <stdlib.h>
#include <time.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <sstream>
#include <fstream>

#include <boost/mpl/list.hpp>
#include <boost/shared_array.hpp>
#include <boost/random.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/version.hpp>

#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TFDTransport.h>
#include <thrift/transport/TFileTransport.h>
#include <thrift/transport/TZlibTransport.h>
#include <thrift/transport/TSocket.h>

#include <thrift/concurrency/FunctionRunner.h>
#if _WIN32
#include <thrift/transport/TPipe.h>
#include <thrift/windows/TWinsockSingleton.h>
#endif

using namespace apache::thrift::transport;
using namespace apache::thrift;

static boost::mt19937 rng;

void initrand(unsigned int seed) {
  rng.seed(seed);
}

class SizeGenerator {
public:
  virtual ~SizeGenerator() = default;
  virtual uint32_t nextSize() = 0;
  virtual std::string describe() const = 0;
};

class ConstantSizeGenerator : public SizeGenerator {
public:
  ConstantSizeGenerator(uint32_t value) : value_(value) {}
  uint32_t nextSize() override { return value_; }
  std::string describe() const override {
    std::ostringstream desc;
    desc << value_;
    return desc.str();
  }

private:
  uint32_t value_;
};

class RandomSizeGenerator : public SizeGenerator {
public:
  RandomSizeGenerator(uint32_t min, uint32_t max)
    : generator_(rng, boost::uniform_int<int>(min, max)) {}

  uint32_t nextSize() override { return generator_(); }

  std::string describe() const override {
    std::ostringstream desc;
    desc << "rand(" << getMin() << ", " << getMax() << ")";
    return desc.str();
  }

  uint32_t getMin() const { return (generator_.distribution().min)(); }
  uint32_t getMax() const { return (generator_.distribution().max)(); }

private:
  boost::variate_generator<boost::mt19937&, boost::uniform_int<int> > generator_;
};

/**
 * This class exists solely to make the TEST_RW() macro easier to use.
 * - it can be constructed implicitly from an integer
 * - it can contain either a ConstantSizeGenerator or a RandomSizeGenerator
 *   (TEST_RW can't take a SizeGenerator pointer or reference, since it needs
 *   to make a copy of the generator to bind it to the test function.)
 */
class GenericSizeGenerator : public SizeGenerator {
public:
  GenericSizeGenerator(uint32_t value) : generator_(new ConstantSizeGenerator(value)) {}
  GenericSizeGenerator(uint32_t min, uint32_t max)
    : generator_(new RandomSizeGenerator(min, max)) {}

  uint32_t nextSize() override { return generator_->nextSize(); }
  std::string describe() const override { return generator_->describe(); }

private:
  std::shared_ptr<SizeGenerator> generator_;
};

/**************************************************************************
 * Classes to set up coupled transports
 **************************************************************************/

/**
 * Helper class to represent a coupled pair of transports.
 *
 * Data written to the out transport can be read from the in transport.
 *
 * This is used as the base class for the various coupled transport
 * implementations.  It shouldn't be instantiated directly.
 */
template <class Transport_>
class CoupledTransports {
public:
  virtual ~CoupledTransports() = default;
  typedef Transport_ TransportType;

  CoupledTransports() : in(), out() {}

  std::shared_ptr<Transport_> in;
  std::shared_ptr<Transport_> out;

private:
  CoupledTransports(const CoupledTransports&) = delete;
  CoupledTransports& operator=(const CoupledTransports&) = delete;
};

/**
 * Coupled TMemoryBuffers
 */
class CoupledMemoryBuffers : public CoupledTransports<TMemoryBuffer> {
public:
  CoupledMemoryBuffers() : buf(new TMemoryBuffer) {
    in = buf;
    out = buf;
  }

  std::shared_ptr<TMemoryBuffer> buf;
};

/**
 * Helper template class for creating coupled transports that wrap
 * another transport.
 */
template <class WrapperTransport_, class InnerCoupledTransports_>
class CoupledWrapperTransportsT : public CoupledTransports<WrapperTransport_> {
public:
  CoupledWrapperTransportsT() {
    if (inner_.in) {
      this->in.reset(new WrapperTransport_(inner_.in));
    }
    if (inner_.out) {
      this->out.reset(new WrapperTransport_(inner_.out));
    }
  }

  InnerCoupledTransports_ inner_;
};

/**
 * Coupled TBufferedTransports.
 */
template <class InnerTransport_>
class CoupledBufferedTransportsT
    : public CoupledWrapperTransportsT<TBufferedTransport, InnerTransport_> {};

typedef CoupledBufferedTransportsT<CoupledMemoryBuffers> CoupledBufferedTransports;

/**
 * Coupled TFramedTransports.
 */
template <class InnerTransport_>
class CoupledFramedTransportsT
    : public CoupledWrapperTransportsT<TFramedTransport, InnerTransport_> {};

typedef CoupledFramedTransportsT<CoupledMemoryBuffers> CoupledFramedTransports;

/**
 * Coupled TZlibTransports.
 */
template <class InnerTransport_>
class CoupledZlibTransportsT : public CoupledWrapperTransportsT<TZlibTransport, InnerTransport_> {};

typedef CoupledZlibTransportsT<CoupledMemoryBuffers> CoupledZlibTransports;

#ifndef _WIN32
// FD transport doesn't make much sense on Windows.
/**
 * Coupled TFDTransports.
 */
class CoupledFDTransports : public CoupledTransports<TFDTransport> {
public:
  CoupledFDTransports() {
    int pipes[2];

    if (pipe(pipes) != 0) {
      return;
    }

    in.reset(new TFDTransport(pipes[0], TFDTransport::CLOSE_ON_DESTROY));
    out.reset(new TFDTransport(pipes[1], TFDTransport::CLOSE_ON_DESTROY));
  }
};
#else
/**
 * Coupled pipe transports
 */
class CoupledPipeTransports : public CoupledTransports<TPipe> {
public:
  HANDLE hRead;
  HANDLE hWrite;

  CoupledPipeTransports() {
    BOOST_REQUIRE(CreatePipe(&hRead, &hWrite, nullptr, 1048576 * 2));
    in.reset(new TPipe(hRead, hWrite));
    in->open();
    out = in;
  }
};
#endif

/**
 * Coupled TSockets
 */
class CoupledSocketTransports : public CoupledTransports<TSocket> {
public:
  CoupledSocketTransports() {
    THRIFT_SOCKET sockets[2] = {0};
    if (THRIFT_SOCKETPAIR(PF_UNIX, SOCK_STREAM, 0, sockets) != 0) {
      return;
    }

    in.reset(new TSocket(sockets[0]));
    out.reset(new TSocket(sockets[1]));
    out->setSendTimeout(100);
  }
};

// These could be made to work on Windows, but I don't care enough to make it happen
#ifndef _WIN32
/**
 * Coupled TFileTransports
 */
class CoupledFileTransports : public CoupledTransports<TFileTransport> {
public:
  CoupledFileTransports() {
#ifndef _WIN32
    const char* tmp_dir = "/tmp";
#define FILENAME_SUFFIX "/thrift.transport_test"
#else
    const char* tmp_dir = getenv("TMP");
#define FILENAME_SUFFIX "\\thrift.transport_test"
#endif

    // Create a temporary file to use
    filename.resize(strlen(tmp_dir) + strlen(FILENAME_SUFFIX));
    THRIFT_SNPRINTF(&filename[0], filename.size(), "%s" FILENAME_SUFFIX, tmp_dir);
#undef FILENAME_SUFFIX

    { std::ofstream dummy_creation(filename.c_str(), std::ofstream::trunc); }

    in.reset(new TFileTransport(filename, true));
    out.reset(new TFileTransport(filename));
  }

  ~CoupledFileTransports() override { remove(filename.c_str()); }

  std::string filename;
};
#endif

/**
 * Wrapper around another CoupledTransports implementation that exposes the
 * transports as TTransport pointers.
 *
 * This is used since accessing a transport via a "TTransport*" exercises a
 * different code path than using the base pointer class.  As part of the
 * template code changes, most transport methods are no longer virtual.
 */
template <class CoupledTransports_>
class CoupledTTransports : public CoupledTransports<TTransport> {
public:
  CoupledTTransports() : transports() {
    in = transports.in;
    out = transports.out;
  }

  CoupledTransports_ transports;
};

/**
 * Wrapper around another CoupledTransports implementation that exposes the
 * transports as TBufferBase pointers.
 *
 * This can only be instantiated with a transport type that is a subclass of
 * TBufferBase.
 */
template <class CoupledTransports_>
class CoupledBufferBases : public CoupledTransports<TBufferBase> {
public:
  CoupledBufferBases() : transports() {
    in = transports.in;
    out = transports.out;
  }

  CoupledTransports_ transports;
};

/**************************************************************************
 * Alarm handling code for use in tests that check the transport blocking
 * semantics.
 *
 * If the transport ends up blocking, we don't want to hang forever.  We use
 * SIGALRM to fire schedule signal to wake up and try to write data so the
 * transport will unblock.
 *
 * It isn't really the safest thing in the world to be mucking around with
 * complicated global data structures in a signal handler.  It should probably
 * be okay though, since we know the main thread should always be blocked in a
 * read() request when the signal handler is running.
 **************************************************************************/

struct TriggerInfo {
  TriggerInfo(int seconds, const std::shared_ptr<TTransport>& transport, uint32_t writeLength)
    : timeoutSeconds(seconds), transport(transport), writeLength(writeLength), next(nullptr) {}

  int timeoutSeconds;
  std::shared_ptr<TTransport> transport;
  uint32_t writeLength;
  TriggerInfo* next;
};

apache::thrift::concurrency::Monitor g_alarm_monitor;
TriggerInfo* g_triggerInfo;
unsigned int g_numTriggersFired;
bool g_teardown = false;

void alarm_handler() {
  TriggerInfo* info = nullptr;
  {
    apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
    // The alarm timed out, which almost certainly means we're stuck
    // on a transport that is incorrectly blocked.
    ++g_numTriggersFired;

    // Note: we print messages to stdout instead of stderr, since
    // tools/test/runner only records stdout messages in the failure messages for
    // boost tests.  (boost prints its test info to stdout.)
    printf("Timeout alarm expired; attempting to unblock transport\n");
    if (g_triggerInfo == nullptr) {
      printf("  trigger stack is empty!\n");
    }

    // Pop off the first TriggerInfo.
    // If there is another one, schedule an alarm for it.
    info = g_triggerInfo;
    g_triggerInfo = info->next;
  }

  // Write some data to the transport to hopefully unblock it.
  auto* buf = new uint8_t[info->writeLength];
  memset(buf, 'b', info->writeLength);
  std::unique_ptr<uint8_t[]> array(buf);
  info->transport->write(buf, info->writeLength);
  info->transport->flush();

  delete info;
}

void alarm_handler_wrapper() {
  int64_t timeout = 0; // timeout of 0 means wait forever
  while (true) {
    bool fireHandler = false;
    {
      apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
      if (g_teardown)
        return;
      // calculate timeout
      if (g_triggerInfo == nullptr) {
        timeout = 0;
      } else {
        timeout = g_triggerInfo->timeoutSeconds * 1000;
      }

      int waitResult = g_alarm_monitor.waitForTimeRelative(timeout);
      if (waitResult == THRIFT_ETIMEDOUT)
        fireHandler = true;
    }
    if (fireHandler)
      alarm_handler(); // calling outside the lock
  }
}

/**
 * Add a trigger to be scheduled "seconds" seconds after the
 * last currently scheduled trigger.
 *
 * (Note that this is not "seconds" from now.  That might be more logical, but
 * would require slightly more complicated sorting, rather than just appending
 * to the end.)
 */
void add_trigger(unsigned int seconds,
                 const std::shared_ptr<TTransport>& transport,
                 uint32_t write_len) {
  auto* info = new TriggerInfo(seconds, transport, write_len);
  {
    apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
    if (g_triggerInfo == nullptr) {
      // This is the first trigger.
      // Set g_triggerInfo, and schedule the alarm
      g_triggerInfo = info;
      g_alarm_monitor.notify();
    } else {
      // Add this trigger to the end of the list
      TriggerInfo* prev = g_triggerInfo;
      while (prev->next) {
        prev = prev->next;
      }
      prev->next = info;
    }
  }
}

void clear_triggers() {
  TriggerInfo* info = nullptr;

  {
    apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
    info = g_triggerInfo;
    g_triggerInfo = nullptr;
    g_numTriggersFired = 0;
    g_alarm_monitor.notify();
  }

  while (info != nullptr) {
    TriggerInfo* next = info->next;
    delete info;
    info = next;
  }
}

void set_trigger(unsigned int seconds,
                 const std::shared_ptr<TTransport>& transport,
                 uint32_t write_len) {
  clear_triggers();
  add_trigger(seconds, transport, write_len);
}

/**************************************************************************
 * Test functions
 **************************************************************************/

/**
 * Test interleaved write and read calls.
 *
 * Generates a buffer totalSize bytes long, then writes it to the transport,
 * and verifies the written data can be read back correctly.
 *
 * Mode of operation:
 * - call wChunkGenerator to figure out how large of a chunk to write
 *   - call wSizeGenerator to get the size for individual write() calls,
 *     and do this repeatedly until the entire chunk is written.
 * - call rChunkGenerator to figure out how large of a chunk to read
 *   - call rSizeGenerator to get the size for individual read() calls,
 *     and do this repeatedly until the entire chunk is read.
 * - repeat until the full buffer is written and read back,
 *   then compare the data read back against the original buffer
 *
 *
 * - If any of the size generators return 0, this means to use the maximum
 *   possible size.
 *
 * - If maxOutstanding is non-zero, write chunk sizes will be chosen such that
 *   there are never more than maxOutstanding bytes waiting to be read back.
 */
template <class CoupledTransports>
void test_rw(uint32_t totalSize,
             SizeGenerator& wSizeGenerator,
             SizeGenerator& rSizeGenerator,
             SizeGenerator& wChunkGenerator,
             SizeGenerator& rChunkGenerator,
             uint32_t maxOutstanding) {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  boost::shared_array<uint8_t> wbuf = boost::shared_array<uint8_t>(new uint8_t[totalSize]);
  boost::shared_array<uint8_t> rbuf = boost::shared_array<uint8_t>(new uint8_t[totalSize]);

  // store some data in wbuf
  for (uint32_t n = 0; n < totalSize; ++n) {
    wbuf[n] = (n & 0xff);
  }
  // clear rbuf
  memset(rbuf.get(), 0, totalSize);

  uint32_t total_written = 0;
  uint32_t total_read = 0;
  while (total_read < totalSize) {
    // Determine how large a chunk of data to write
    uint32_t wchunk_size = wChunkGenerator.nextSize();
    if (wchunk_size == 0 || wchunk_size > totalSize - total_written) {
      wchunk_size = totalSize - total_written;
    }

    // Make sure (total_written - total_read) + wchunk_size
    // is less than maxOutstanding
    if (maxOutstanding > 0 && wchunk_size > maxOutstanding - (total_written - total_read)) {
      wchunk_size = maxOutstanding - (total_written - total_read);
    }

    // Write the chunk
    uint32_t chunk_written = 0;
    while (chunk_written < wchunk_size) {
      uint32_t write_size = wSizeGenerator.nextSize();
      if (write_size == 0 || write_size > wchunk_size - chunk_written) {
        write_size = wchunk_size - chunk_written;
      }

      try {
        transports.out->write(wbuf.get() + total_written, write_size);
      } catch (TTransportException& te) {
        if (te.getType() == TTransportException::TIMED_OUT)
          break;
        throw te;
      }
      chunk_written += write_size;
      total_written += write_size;
    }

    // Flush the data, so it will be available in the read transport
    // Don't flush if wchunk_size is 0.  (This should only happen if
    // total_written == totalSize already, and we're only reading now.)
    if (wchunk_size > 0) {
      transports.out->flush();
    }

    // Determine how large a chunk of data to read back
    uint32_t rchunk_size = rChunkGenerator.nextSize();
    if (rchunk_size == 0 || rchunk_size > total_written - total_read) {
      rchunk_size = total_written - total_read;
    }

    // Read the chunk
    uint32_t chunk_read = 0;
    while (chunk_read < rchunk_size) {
      uint32_t read_size = rSizeGenerator.nextSize();
      if (read_size == 0 || read_size > rchunk_size - chunk_read) {
        read_size = rchunk_size - chunk_read;
      }

      int bytes_read = -1;
      try {
        bytes_read = transports.in->read(rbuf.get() + total_read, read_size);
      } catch (TTransportException& e) {
        BOOST_FAIL("read(pos=" << total_read << ", size=" << read_size << ") threw exception \""
                               << e.what() << "\"; written so far: " << total_written << " / "
                               << totalSize << " bytes");
      }

      BOOST_REQUIRE_MESSAGE(bytes_read > 0,
                            "read(pos=" << total_read << ", size=" << read_size << ") returned "
                                        << bytes_read << "; written so far: " << total_written
                                        << " / " << totalSize << " bytes");
      chunk_read += bytes_read;
      total_read += bytes_read;
    }
  }

  // make sure the data read back is identical to the data written
  BOOST_CHECK_EQUAL(memcmp(rbuf.get(), wbuf.get(), totalSize), 0);
}

template <class CoupledTransports>
void test_read_part_available() {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  uint8_t write_buf[16];
  uint8_t read_buf[16];
  memset(write_buf, 'a', sizeof(write_buf));

  // Attemping to read 10 bytes when only 9 are available should return 9
  // immediately.
  transports.out->write(write_buf, 9);
  transports.out->flush();
  set_trigger(3, transports.out, 1);
  uint32_t bytes_read = transports.in->read(read_buf, 10);
  BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0);
  BOOST_CHECK_EQUAL(bytes_read, (uint32_t)9);

  clear_triggers();
}

template <class CoupledTransports>
void test_read_part_available_in_chunks() {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  uint8_t write_buf[16];
  uint8_t read_buf[16];
  memset(write_buf, 'a', sizeof(write_buf));

  // Write 10 bytes (in a single frame, for transports that use framing)
  transports.out->write(write_buf, 10);
  transports.out->flush();

  // Read 1 byte, to force the transport to read the frame
  uint32_t bytes_read = transports.in->read(read_buf, 1);
  BOOST_CHECK_EQUAL(bytes_read, 1u);

  // Read more than what is remaining and verify the transport does not block
  set_trigger(3, transports.out, 1);
  bytes_read = transports.in->read(read_buf, 10);
  BOOST_CHECK_EQUAL(g_numTriggersFired, 0u);
  BOOST_CHECK_EQUAL(bytes_read, 9u);

  clear_triggers();
}

template <class CoupledTransports>
void test_read_partial_midframe() {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  uint8_t write_buf[16];
  uint8_t read_buf[16];
  memset(write_buf, 'a', sizeof(write_buf));

  // Attempt to read 10 bytes, when only 9 are available, but after we have
  // already read part of the data that is available.  This exercises a
  // different code path for several of the transports.
  //
  // For transports that add their own framing (e.g., TFramedTransport and
  // TFileTransport), the two flush calls break up the data in to a 10 byte
  // frame and a 3 byte frame.  The first read then puts us partway through the
  // first frame, and then we attempt to read past the end of that frame, and
  // through the next frame, too.
  //
  // For buffered transports that perform read-ahead (e.g.,
  // TBufferedTransport), the read-ahead will most likely see all 13 bytes
  // written on the first read.  The next read will then attempt to read past
  // the end of the read-ahead buffer.
  //
  // Flush 10 bytes, then 3 bytes.  This creates 2 separate frames for
  // transports that track framing internally.
  transports.out->write(write_buf, 10);
  transports.out->flush();
  transports.out->write(write_buf, 3);
  transports.out->flush();

  // Now read 4 bytes, so that we are partway through the written data.
  uint32_t bytes_read = transports.in->read(read_buf, 4);
  BOOST_CHECK_EQUAL(bytes_read, (uint32_t)4);

  // Now attempt to read 10 bytes.  Only 9 more are available.
  //
  // We should be able to get all 9 bytes, but it might take multiple read
  // calls, since it is valid for read() to return fewer bytes than requested.
  // (Most transports do immediately return 9 bytes, but the framing transports
  // tend to only return to the end of the current frame, which is 6 bytes in
  // this case.)
  uint32_t total_read = 0;
  while (total_read < 9) {
    set_trigger(3, transports.out, 1);
    bytes_read = transports.in->read(read_buf, 10);
    BOOST_REQUIRE_EQUAL(g_numTriggersFired, (unsigned int)0);
    BOOST_REQUIRE_GT(bytes_read, (uint32_t)0);
    total_read += bytes_read;
    BOOST_REQUIRE_LE(total_read, (uint32_t)9);
  }

  BOOST_CHECK_EQUAL(total_read, (uint32_t)9);

  clear_triggers();
}

template <class CoupledTransports>
void test_borrow_part_available() {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  uint8_t write_buf[16];
  uint8_t read_buf[16];
  memset(write_buf, 'a', sizeof(write_buf));

  // Attemping to borrow 10 bytes when only 9 are available should return nullptr
  // immediately.
  transports.out->write(write_buf, 9);
  transports.out->flush();
  set_trigger(3, transports.out, 1);
  uint32_t borrow_len = 10;
  const uint8_t* borrowed_buf = transports.in->borrow(read_buf, &borrow_len);
  BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0);
  BOOST_CHECK(borrowed_buf == nullptr);

  clear_triggers();
}

template <class CoupledTransports>
void test_read_none_available() {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  uint8_t read_buf[16];

  // Attempting to read when no data is available should either block until
  // some data is available, or fail immediately.  (e.g., TSocket blocks,
  // TMemoryBuffer just fails.)
  //
  // If the transport blocks, it should succeed once some data is available,
  // even if less than the amount requested becomes available.
  set_trigger(1, transports.out, 2);
  add_trigger(1, transports.out, 8);
  uint32_t bytes_read = transports.in->read(read_buf, 10);
  if (bytes_read == 0) {
    BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0);
    clear_triggers();
  } else {
    BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)1);
    BOOST_CHECK_EQUAL(bytes_read, (uint32_t)2);
  }

  clear_triggers();
}

template <class CoupledTransports>
void test_borrow_none_available() {
  CoupledTransports transports;
  BOOST_REQUIRE(transports.in != nullptr);
  BOOST_REQUIRE(transports.out != nullptr);

  uint8_t write_buf[16];
  memset(write_buf, 'a', sizeof(write_buf));

  // Attempting to borrow when no data is available should fail immediately
  set_trigger(1, transports.out, 10);
  uint32_t borrow_len = 10;
  const uint8_t* borrowed_buf = transports.in->borrow(nullptr, &borrow_len);
  BOOST_CHECK(borrowed_buf == nullptr);
  BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0);

  clear_triggers();
}

/**************************************************************************
 * Test case generation
 *
 * Pretty ugly and annoying.  This would be much easier if we the unit test
 * framework didn't force each test to be a separate function.
 * - Writing a completely separate function definition for each of these would
 *   result in a lot of repetitive boilerplate code.
 * - Combining many tests into a single function makes it more difficult to
 *   tell precisely which tests failed.  It also means you can't get a progress
 *   update after each test, and the tests are already fairly slow.
 * - Similar registration could be achieved with BOOST_TEST_CASE_TEMPLATE,
 *   but it requires a lot of awkward MPL code, and results in useless test
 *   case names.  (The names are generated from std::type_info::name(), which
 *   is compiler-dependent.  gcc returns mangled names.)
 **************************************************************************/

#define ADD_TEST_RW(CoupledTransports, totalSize, ...)                                             \
  addTestRW<CoupledTransports>(BOOST_STRINGIZE(CoupledTransports), totalSize, __VA_ARGS__);

#define TEST_RW(CoupledTransports, totalSize, ...)                                                 \
  do {                                                                                             \
    /* Add the test as specified, to test the non-virtual function calls */                        \
    ADD_TEST_RW(CoupledTransports, totalSize, __VA_ARGS__);                                        \
    /*                                                                                             \
     * Also test using the transport as a TTransport*, to test                                     \
     * the read_virt()/write_virt() calls                                                          \
     */                                                                                            \
    ADD_TEST_RW(CoupledTTransports<CoupledTransports>, totalSize, __VA_ARGS__);                    \
    /* Test wrapping the transport with TBufferedTransport */                                      \
    ADD_TEST_RW(CoupledBufferedTransportsT<CoupledTransports>, totalSize, __VA_ARGS__);            \
    /* Test wrapping the transport with TFramedTransports */                                       \
    ADD_TEST_RW(CoupledFramedTransportsT<CoupledTransports>, totalSize, __VA_ARGS__);              \
    /* Test wrapping the transport with TZlibTransport */                                          \
    ADD_TEST_RW(CoupledZlibTransportsT<CoupledTransports>, totalSize, __VA_ARGS__);                \
  } while (0)

#define ADD_TEST_BLOCKING(CoupledTransports)                                                       \
  addTestBlocking<CoupledTransports>(BOOST_STRINGIZE(CoupledTransports));

#define TEST_BLOCKING_BEHAVIOR(CoupledTransports)                                                  \
  ADD_TEST_BLOCKING(CoupledTransports);                                                            \
  ADD_TEST_BLOCKING(CoupledTTransports<CoupledTransports>);                                        \
  ADD_TEST_BLOCKING(CoupledBufferedTransportsT<CoupledTransports>);                                \
  ADD_TEST_BLOCKING(CoupledFramedTransportsT<CoupledTransports>);                                  \
  ADD_TEST_BLOCKING(CoupledZlibTransportsT<CoupledTransports>);

class TransportTestGen {
public:
  TransportTestGen(boost::unit_test::test_suite* suite, float sizeMultiplier)
    : suite_(suite), sizeMultiplier_(sizeMultiplier) {}

  void generate() {
    GenericSizeGenerator rand4k(1, 4096);

    /*
     * We do the basically the same set of tests for each transport type,
     * although we tweak the parameters in some places.
     */

    // TMemoryBuffer tests
    TEST_RW(CoupledMemoryBuffers, 1024 * 1024, 0, 0);
    TEST_RW(CoupledMemoryBuffers, 1024 * 256, rand4k, rand4k);
    TEST_RW(CoupledMemoryBuffers, 1024 * 256, 167, 163);
    TEST_RW(CoupledMemoryBuffers, 1024 * 16, 1, 1);

    TEST_RW(CoupledMemoryBuffers, 1024 * 256, 0, 0, rand4k, rand4k);
    TEST_RW(CoupledMemoryBuffers, 1024 * 256, rand4k, rand4k, rand4k, rand4k);
    TEST_RW(CoupledMemoryBuffers, 1024 * 256, 167, 163, rand4k, rand4k);
    TEST_RW(CoupledMemoryBuffers, 1024 * 16, 1, 1, rand4k, rand4k);

    TEST_BLOCKING_BEHAVIOR(CoupledMemoryBuffers);

#ifndef _WIN32
    // TFDTransport tests
    // Since CoupledFDTransports tests with a pipe, writes will block
    // if there is too much outstanding unread data in the pipe.
    uint32_t fd_max_outstanding = 4096;
    TEST_RW(CoupledFDTransports, 1024 * 1024, 0, 0, 0, 0, fd_max_outstanding);
    TEST_RW(CoupledFDTransports, 1024 * 256, rand4k, rand4k, 0, 0, fd_max_outstanding);
    TEST_RW(CoupledFDTransports, 1024 * 256, 167, 163, 0, 0, fd_max_outstanding);
    TEST_RW(CoupledFDTransports, 1024 * 16, 1, 1, 0, 0, fd_max_outstanding);

    TEST_RW(CoupledFDTransports, 1024 * 256, 0, 0, rand4k, rand4k, fd_max_outstanding);
    TEST_RW(CoupledFDTransports, 1024 * 256, rand4k, rand4k, rand4k, rand4k, fd_max_outstanding);
    TEST_RW(CoupledFDTransports, 1024 * 256, 167, 163, rand4k, rand4k, fd_max_outstanding);
    TEST_RW(CoupledFDTransports, 1024 * 16, 1, 1, rand4k, rand4k, fd_max_outstanding);

    TEST_BLOCKING_BEHAVIOR(CoupledFDTransports);
#else
    // TPipe tests (WIN32 only)
    TEST_RW(CoupledPipeTransports, 1024 * 1024, 0, 0);
    TEST_RW(CoupledPipeTransports, 1024 * 256, rand4k, rand4k);
    TEST_RW(CoupledPipeTransports, 1024 * 256, 167, 163);
    TEST_RW(CoupledPipeTransports, 1024 * 16, 1, 1);

    TEST_RW(CoupledPipeTransports, 1024 * 256, 0, 0, rand4k, rand4k);
    TEST_RW(CoupledPipeTransports, 1024 * 256, rand4k, rand4k, rand4k, rand4k);
    TEST_RW(CoupledPipeTransports, 1024 * 256, 167, 163, rand4k, rand4k);
    TEST_RW(CoupledPipeTransports, 1024 * 16, 1, 1, rand4k, rand4k);

    TEST_BLOCKING_BEHAVIOR(CoupledPipeTransports);
#endif //_WIN32

    // TSocket tests
    uint32_t socket_max_outstanding = 4096;
    TEST_RW(CoupledSocketTransports, 1024 * 1024, 0, 0, 0, 0, socket_max_outstanding);
    TEST_RW(CoupledSocketTransports, 1024 * 256, rand4k, rand4k, 0, 0, socket_max_outstanding);
    TEST_RW(CoupledSocketTransports, 1024 * 256, 167, 163, 0, 0, socket_max_outstanding);
    // Doh.  Apparently writing to a socket has some additional overhead for
    // each send() call.  If we have more than ~400 outstanding 1-byte write
    // requests, additional send() calls start blocking.
    TEST_RW(CoupledSocketTransports, 1024 * 16, 1, 1, 0, 0, socket_max_outstanding);
    TEST_RW(CoupledSocketTransports, 1024 * 256, 0, 0, rand4k, rand4k, socket_max_outstanding);
    TEST_RW(CoupledSocketTransports,
            1024 * 256,
            rand4k,
            rand4k,
            rand4k,
            rand4k,
            socket_max_outstanding);
    TEST_RW(CoupledSocketTransports, 1024 * 256, 167, 163, rand4k, rand4k, socket_max_outstanding);
    TEST_RW(CoupledSocketTransports, 1024 * 16, 1, 1, rand4k, rand4k, socket_max_outstanding);

    TEST_BLOCKING_BEHAVIOR(CoupledSocketTransports);

// These could be made to work on Windows, but I don't care enough to make it happen
#ifndef _WIN32
    // TFileTransport tests
    // We use smaller buffer sizes here, since TFileTransport is fairly slow.
    //
    // TFileTransport can't write more than 16MB at once
    uint32_t max_write_at_once = 1024 * 1024 * 16 - 4;
    TEST_RW(CoupledFileTransports, 1024 * 1024, max_write_at_once, 0);
    TEST_RW(CoupledFileTransports, 1024 * 128, rand4k, rand4k);
    TEST_RW(CoupledFileTransports, 1024 * 128, 167, 163);
    TEST_RW(CoupledFileTransports, 1024 * 2, 1, 1);

    TEST_RW(CoupledFileTransports, 1024 * 64, 0, 0, rand4k, rand4k);
    TEST_RW(CoupledFileTransports, 1024 * 64, rand4k, rand4k, rand4k, rand4k);
    TEST_RW(CoupledFileTransports, 1024 * 64, 167, 163, rand4k, rand4k);
    TEST_RW(CoupledFileTransports, 1024 * 2, 1, 1, rand4k, rand4k);

    TEST_BLOCKING_BEHAVIOR(CoupledFileTransports);
#endif

    // Add some tests that access TBufferedTransport and TFramedTransport
    // via TTransport pointers and TBufferBase pointers.
    ADD_TEST_RW(CoupledTTransports<CoupledBufferedTransports>,
                1024 * 1024,
                rand4k,
                rand4k,
                rand4k,
                rand4k);
    ADD_TEST_RW(CoupledBufferBases<CoupledBufferedTransports>,
                1024 * 1024,
                rand4k,
                rand4k,
                rand4k,
                rand4k);
    ADD_TEST_RW(CoupledTTransports<CoupledFramedTransports>,
                1024 * 1024,
                rand4k,
                rand4k,
                rand4k,
                rand4k);
    ADD_TEST_RW(CoupledBufferBases<CoupledFramedTransports>,
                1024 * 1024,
                rand4k,
                rand4k,
                rand4k,
                rand4k);

    // Test using TZlibTransport via a TTransport pointer
    ADD_TEST_RW(CoupledTTransports<CoupledZlibTransports>,
                1024 * 1024,
                rand4k,
                rand4k,
                rand4k,
                rand4k);
  }

#if (BOOST_VERSION >= 105900)
#define MAKE_TEST_CASE(_FUNC, _NAME) boost::unit_test::make_test_case(_FUNC, _NAME, __FILE__, __LINE__)
#else
#define MAKE_TEST_CASE(_FUNC, _NAME) boost::unit_test::make_test_case(_FUNC, _NAME)
#endif

private:
  template <class CoupledTransports>
  void addTestRW(const char* transport_name,
                 uint32_t totalSize,
                 GenericSizeGenerator wSizeGen,
                 GenericSizeGenerator rSizeGen,
                 GenericSizeGenerator wChunkSizeGen = 0,
                 GenericSizeGenerator rChunkSizeGen = 0,
                 uint32_t maxOutstanding = 0,
                 uint32_t expectedFailures = 0) {
    // adjust totalSize by the specified sizeMultiplier_ first
    totalSize = static_cast<uint32_t>(totalSize * sizeMultiplier_);

    std::ostringstream name;
    name << transport_name << "::test_rw(" << totalSize << ", " << wSizeGen.describe() << ", "
         << rSizeGen.describe() << ", " << wChunkSizeGen.describe() << ", "
         << rChunkSizeGen.describe() << ", " << maxOutstanding << ")";

#if (BOOST_VERSION >= 105900)
    std::function<void ()> test_func
#else
    boost::unit_test::callback0<> test_func
#endif
        = std::bind(test_rw<CoupledTransports>,
                                       totalSize,
                                       wSizeGen,
                                       rSizeGen,
                                       wChunkSizeGen,
                                       rChunkSizeGen,
                                       maxOutstanding);
    suite_->add(MAKE_TEST_CASE(test_func, name.str()), expectedFailures);
  }

  template <class CoupledTransports>
  void addTestBlocking(const char* transportName, uint32_t expectedFailures = 0) {
    char name[1024];

    THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_part_available()", transportName);
    suite_->add(MAKE_TEST_CASE(test_read_part_available<CoupledTransports>, name), expectedFailures);

    THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_part_available_in_chunks()", transportName);
    suite_->add(MAKE_TEST_CASE(test_read_part_available_in_chunks<CoupledTransports>, name), expectedFailures);

    THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_partial_midframe()", transportName);
    suite_->add(MAKE_TEST_CASE(test_read_partial_midframe<CoupledTransports>, name), expectedFailures);

    THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_none_available()", transportName);
    suite_->add(MAKE_TEST_CASE(test_read_none_available<CoupledTransports>, name), expectedFailures);

    THRIFT_SNPRINTF(name, sizeof(name), "%s::test_borrow_part_available()", transportName);
    suite_->add(MAKE_TEST_CASE(test_borrow_part_available<CoupledTransports>, name), expectedFailures);

    THRIFT_SNPRINTF(name, sizeof(name), "%s::test_borrow_none_available()", transportName);
    suite_->add(MAKE_TEST_CASE(test_borrow_none_available<CoupledTransports>, name), expectedFailures);
  }

  boost::unit_test::test_suite* suite_;
  // sizeMultiplier_ is configurable via the command line, and allows the
  // user to adjust between smaller buffers that can be tested quickly,
  // or larger buffers that more thoroughly exercise the code, but take
  // longer.
  float sizeMultiplier_;
};

/**************************************************************************
 * General Initialization
 **************************************************************************/

struct global_fixture {
  std::shared_ptr<apache::thrift::concurrency::Thread> alarmThread_;
  global_fixture() {
#if _WIN32
    apache::thrift::transport::TWinsockSingleton::create();
#endif

    apache::thrift::concurrency::ThreadFactory factory;
    factory.setDetached(false);

    alarmThread_ = factory.newThread(
        apache::thrift::concurrency::FunctionRunner::create(alarm_handler_wrapper));
    alarmThread_->start();
  }
  ~global_fixture() {
    {
      apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
      g_teardown = true;
      g_alarm_monitor.notify();
    }
    alarmThread_->join();
  }
};

#if (BOOST_VERSION >= 105900)
BOOST_GLOBAL_FIXTURE(global_fixture);
#else
BOOST_GLOBAL_FIXTURE(global_fixture)
#endif

#ifdef BOOST_TEST_DYN_LINK
bool init_unit_test_suite() {
  struct timeval tv;
  THRIFT_GETTIMEOFDAY(&tv, nullptr);
  int seed = tv.tv_sec ^ tv.tv_usec;

  initrand(seed);

  boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
  suite->p_name.value = "TransportTest";
  TransportTestGen transport_test_generator(suite, 1);
  transport_test_generator.generate();
  return true;
}

int main( int argc, char* argv[] ) {
  return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
}
#else
boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
  THRIFT_UNUSED_VARIABLE(argc);
  THRIFT_UNUSED_VARIABLE(argv);
  struct timeval tv;
  THRIFT_GETTIMEOFDAY(&tv, nullptr);
  int seed = tv.tv_sec ^ tv.tv_usec;

  initrand(seed);

  boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
  suite->p_name.value = "TransportTest";
  TransportTestGen transport_test_generator(suite, 1);
  transport_test_generator.generate();
  return nullptr;
}
#endif
