daemon_ut.cpp 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "daemon.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/network/pair.h>
  4. #include <util/network/socket.h>
  5. #include <util/system/pipe.h>
  6. Y_UNIT_TEST_SUITE(TDaemonTest) {
  7. #ifdef _unix_
  8. template <typename Func>
  9. static bool ProcessBuffer(Func&& func, void* bufin, size_t size) {
  10. char* buf = (char*)bufin;
  11. do {
  12. const ssize_t bytesDone = func(buf, size);
  13. if (bytesDone == 0) {
  14. return false;
  15. }
  16. if (bytesDone < 0) {
  17. if (errno == EAGAIN || errno == EINTR) {
  18. continue;
  19. } else {
  20. return false;
  21. }
  22. }
  23. buf += bytesDone;
  24. size -= bytesDone;
  25. } while (size != 0);
  26. return true;
  27. }
  28. const int size = 1024 * 4;
  29. const int pagesSize = sizeof(int) * size;
  30. Y_UNIT_TEST(WaitForMessageSocket) {
  31. using namespace NDaemonMaker;
  32. SOCKET sockets[2];
  33. SocketPair(sockets, false, true);
  34. TSocket sender(sockets[0]);
  35. TSocket receiver(sockets[1]);
  36. int status = -1;
  37. int* pages = new int[size];
  38. memset(pages, 0, pagesSize);
  39. if (MakeMeDaemon(closeStdIoOnly, openDevNull, chdirNone, returnFromParent)) {
  40. sender.Close();
  41. UNIT_ASSERT(ProcessBuffer([&receiver](char* ptr, size_t sz) -> size_t { return receiver.Recv(ptr, sz); }, &status, sizeof(status)));
  42. UNIT_ASSERT(ProcessBuffer([&receiver](char* ptr, size_t sz) -> size_t { return receiver.Recv(ptr, sz); }, pages, pagesSize));
  43. UNIT_ASSERT(memchr(pages, 0, pagesSize) == nullptr);
  44. } else {
  45. receiver.Close();
  46. status = 0;
  47. UNIT_ASSERT(ProcessBuffer([&sender](char* ptr, size_t sz) -> size_t { return sender.Send(ptr, sz); }, &status, sizeof(status)));
  48. memset(pages, 1, pagesSize);
  49. UNIT_ASSERT(ProcessBuffer([&sender](char* ptr, size_t sz) -> size_t { return sender.Send(ptr, sz); }, pages, pagesSize));
  50. exit(0);
  51. }
  52. UNIT_ASSERT(status == 0);
  53. delete[] pages;
  54. }
  55. Y_UNIT_TEST(WaitForMessagePipe) {
  56. using namespace NDaemonMaker;
  57. TPipeHandle sender;
  58. TPipeHandle receiver;
  59. TPipeHandle::Pipe(receiver, sender);
  60. int status = -1;
  61. int* pages = new int[size];
  62. memset(pages, 0, pagesSize);
  63. if (MakeMeDaemon(closeStdIoOnly, openDevNull, chdirNone, returnFromParent)) {
  64. sender.Close();
  65. UNIT_ASSERT(ProcessBuffer([&receiver](char* ptr, size_t sz) -> size_t { return receiver.Read(ptr, sz); }, &status, sizeof(status)));
  66. UNIT_ASSERT(ProcessBuffer([&receiver](char* ptr, size_t sz) -> size_t { return receiver.Read(ptr, sz); }, pages, pagesSize));
  67. UNIT_ASSERT(memchr(pages, 0, pagesSize) == nullptr);
  68. } else {
  69. receiver.Close();
  70. status = 0;
  71. UNIT_ASSERT(ProcessBuffer([&sender](char* ptr, size_t sz) -> size_t { return sender.Write(ptr, sz); }, &status, sizeof(status)));
  72. memset(pages, 1, pagesSize);
  73. UNIT_ASSERT(ProcessBuffer([&sender](char* ptr, size_t sz) -> size_t { return sender.Write(ptr, sz); }, pages, pagesSize));
  74. exit(0);
  75. }
  76. UNIT_ASSERT(status == 0);
  77. delete[] pages;
  78. }
  79. #endif
  80. } // Y_UNIT_TEST_SUITE(TDaemonTest)