관리-도구
편집 파일: MessageIOTest.cpp
#include <TestSupport.h> #include <IOTools/IOUtils.h> #include <IOTools/MessageIO.h> #include <SystemTools/SystemTime.h> using namespace Passenger; using namespace std; using namespace boost; namespace tut { struct IOTools_MessageIOTest: public TestBase { Pipe pipes; IOTools_MessageIOTest() { pipes = createPipe(__FILE__, __LINE__); } }; DEFINE_TEST_GROUP(IOTools_MessageIOTest); /***** Test readUint16() and writeUint16() *****/ TEST_METHOD(1) { // They work. writeUint16(pipes[1], 0x3F56); writeUint16(pipes[1], 0x3F57); writeUint16(pipes[1], 0x3F58); unsigned char buf[2]; ensure_equals(readExact(pipes[0], buf, 2), 2u); ensure_equals(buf[0], 0x3F); ensure_equals(buf[1], 0x56); ensure_equals(readUint16(pipes[0]), 0x3F57u); uint16_t out; ensure(readUint16(pipes[0], out)); ensure_equals(out, 0x3F58); } TEST_METHOD(2) { // readUint16() throws EOFException on premature EOF. writeExact(pipes[1], "x", 1); pipes[1].close(); try { readUint16(pipes[0]); fail("EOFException expected"); } catch (const EOFException &) { } } TEST_METHOD(3) { // readUint16(uint32_t &) returns false EOFException on premature EOF. writeExact(pipes[1], "x", 1); pipes[1].close(); uint16_t out; ensure(!readUint16(pipes[0], out)); } TEST_METHOD(4) { // Test timeout. unsigned long long timeout = 30000; unsigned long long startTime = SystemTime::getUsec(); try { readUint16(pipes[0], &timeout); fail("TimeoutException expected"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure("About 30 ms elapsed (1)", elapsed >= 29000 && elapsed <= 95000); ensure("Time is correctly deducted from 'timeout' (1)", timeout <= 2000); } writeUntilFull(pipes[1]); timeout = 30000; startTime = SystemTime::getUsec(); try { writeUint16(pipes[1], 0x12, &timeout); fail("TimeoutException expected"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure("About 30 ms elapsed (3)", elapsed >= 29000 && elapsed <= 95000); ensure("Time is correctly deducted from 'timeout' (4)", timeout <= 2000); } } /***** Test readUint32() and writeUint32() *****/ TEST_METHOD(10) { // They work. writeUint32(pipes[1], 0x12343F56); writeUint32(pipes[1], 0x12343F57); writeUint32(pipes[1], 0x12343F58); unsigned char buf[4]; ensure_equals(readExact(pipes[0], buf, 4), 4u); ensure_equals(buf[0], 0x12); ensure_equals(buf[1], 0x34); ensure_equals(buf[2], 0x3F); ensure_equals(buf[3], 0x56); ensure_equals(readUint32(pipes[0]), 0x12343F57u); uint32_t out; ensure(readUint32(pipes[0], out)); ensure_equals(out, 0x12343F58u); } TEST_METHOD(11) { // readUint32() throws EOFException on premature EOF. writeExact(pipes[1], "xyz", 3); pipes[1].close(); try { readUint32(pipes[0]); fail("EOFException expected"); } catch (const EOFException &) { } } TEST_METHOD(12) { // readUint16(uint32_t &) returns false EOFException on premature EOF. writeExact(pipes[1], "xyz", 3); pipes[1].close(); uint32_t out; ensure(!readUint32(pipes[0], out)); } TEST_METHOD(13) { // Test timeout. unsigned long long timeout = 30000; unsigned long long startTime = SystemTime::getUsec(); try { readUint32(pipes[0], &timeout); fail("TimeoutException expected"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure(elapsed >= 29000 && elapsed <= 90000); ensure(timeout <= 2000); } writeUntilFull(pipes[1]); timeout = 30000; startTime = SystemTime::getUsec(); try { writeUint32(pipes[1], 0x1234, &timeout); fail("TimeoutException expected"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure(elapsed >= 29000 && elapsed <= 90000); ensure(timeout <= 2000); } } /***** Test readArrayMessage() and writeArrayMessage() *****/ TEST_METHOD(20) { // Test <= 10 arguments. writeArrayMessage(pipes[1], "ab", "cd", "efg", NULL); writeArrayMessage(pipes[1], "ab", "cd", "efh", NULL); unsigned char buf[12]; readExact(pipes[0], buf, 12); ensure_equals(buf[0], 0u); ensure_equals(buf[1], 10u); ensure_equals(buf[2], 'a'); ensure_equals(buf[3], 'b'); ensure_equals(buf[4], '\0'); ensure_equals(buf[5], 'c'); ensure_equals(buf[6], 'd'); ensure_equals(buf[7], '\0'); ensure_equals(buf[8], 'e'); ensure_equals(buf[9], 'f'); ensure_equals(buf[10], 'g'); ensure_equals(buf[11], '\0'); vector<string> args = readArrayMessage(pipes[0]); ensure_equals(args.size(), 3u); ensure_equals(args[0], "ab"); ensure_equals(args[1], "cd"); ensure_equals(args[2], "efh"); } TEST_METHOD(21) { // Test > 10 arguments. writeArrayMessage(pipes[1], "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", NULL); writeArrayMessage(pipes[1], "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", NULL); unsigned char buf[26]; readExact(pipes[0], buf, 26); ensure_equals(buf[0], 0u); ensure_equals(buf[1], 24u); ensure_equals(buf[2], '1'); ensure_equals(buf[3], '\0'); ensure_equals(buf[4], '2'); ensure_equals(buf[5], '\0'); ensure_equals(buf[6], '3'); ensure_equals(buf[7], '\0'); ensure_equals(buf[8], '4'); ensure_equals(buf[9], '\0'); ensure_equals(buf[10], '5'); ensure_equals(buf[11], '\0'); ensure_equals(buf[12], '6'); ensure_equals(buf[13], '\0'); ensure_equals(buf[14], '7'); ensure_equals(buf[15], '\0'); ensure_equals(buf[16], '8'); ensure_equals(buf[17], '\0'); ensure_equals(buf[18], '9'); ensure_equals(buf[19], '\0'); ensure_equals(buf[20], '0'); ensure_equals(buf[21], '\0'); ensure_equals(buf[22], 'a'); ensure_equals(buf[23], '\0'); ensure_equals(buf[24], 'b'); ensure_equals(buf[25], '\0'); vector<string> args = readArrayMessage(pipes[0]); ensure_equals(args.size(), 12u); ensure_equals(args[0], "c"); ensure_equals(args[1], "d"); ensure_equals(args[2], "e"); ensure_equals(args[3], "f"); ensure_equals(args[4], "g"); ensure_equals(args[5], "h"); ensure_equals(args[6], "i"); ensure_equals(args[7], "j"); ensure_equals(args[8], "k"); ensure_equals(args[9], "l"); ensure_equals(args[10], "m"); ensure_equals(args[11], "n"); } TEST_METHOD(22) { // readArrayMessage() throws EOFException on premature EOF. writeExact(pipes[1], "\x00"); pipes[1].close(); try { readArrayMessage(pipes[0]); fail("EOFException expected (1)"); } catch (const EOFException &) { } pipes = createPipe(__FILE__, __LINE__); writeExact(pipes[1], "\x00\x04a\x00b"); pipes[1].close(); try { readArrayMessage(pipes[0]); fail("EOFException expected (2)"); } catch (const EOFException &) { } } TEST_METHOD(23) { // Test timeout. unsigned long long timeout = 30000; unsigned long long startTime = SystemTime::getUsec(); try { readArrayMessage(pipes[0], &timeout); fail("TimeoutException expected (1)"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure(elapsed >= 29000 && elapsed <= 90000); ensure(timeout <= 2000); } writeUntilFull(pipes[1]); timeout = 30000; startTime = SystemTime::getUsec(); try { writeArrayMessage(pipes[1], &timeout, "hi", "ho", NULL); fail("TimeoutException expected (2)"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure(elapsed >= 29000 && elapsed <= 90000); ensure(timeout <= 2000); } } /***** Test readScalarMessage() and writeScalarMessage() *****/ TEST_METHOD(30) { // They work. writeScalarMessage(pipes[1], "hello"); writeScalarMessage(pipes[1], "world"); unsigned char buf[4 + 5]; readExact(pipes[0], buf, 4 + 5); ensure_equals(buf[0], 0u); ensure_equals(buf[1], 0u); ensure_equals(buf[2], 0u); ensure_equals(buf[3], 5u); ensure_equals(buf[4], 'h'); ensure_equals(buf[5], 'e'); ensure_equals(buf[6], 'l'); ensure_equals(buf[7], 'l'); ensure_equals(buf[8], 'o'); ensure_equals(readScalarMessage(pipes[0]), "world"); } TEST_METHOD(31) { // readScalarMessage() throws EOFException on premature EOF. writeExact(pipes[1], StaticString("\x00", 1)); pipes[1].close(); try { readScalarMessage(pipes[0]); fail("EOFException expected (1)"); } catch (const EOFException &) { } pipes = createPipe(__FILE__, __LINE__); writeExact(pipes[1], StaticString("\x00\x00\x00\x04" "abc", 4 + 3)); pipes[1].close(); try { readScalarMessage(pipes[0]); fail("EOFException expected (2)"); } catch (const EOFException &) { } } TEST_METHOD(32) { // readScalarMessage() throws SecurityException if the // body larger than the limit writeExact(pipes[1], StaticString("\x00\x00\x00\x05", 4)); try { readScalarMessage(pipes[0], 4); fail("SecurityException expected (1)"); } catch (const SecurityException &) { } } TEST_METHOD(33) { // Test timeout. unsigned long long timeout = 30000; unsigned long long startTime = SystemTime::getUsec(); try { readScalarMessage(pipes[0], 0, &timeout); fail("TimeoutException expected (1)"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure(elapsed >= 29000 && elapsed <= 90000); ensure(timeout <= 2000); } writeUntilFull(pipes[1]); timeout = 30000; startTime = SystemTime::getUsec(); try { writeScalarMessage(pipes[1], "hello", &timeout); fail("TimeoutException expected (2)"); } catch (const TimeoutException &) { unsigned long long elapsed = SystemTime::getUsec() - startTime; ensure(elapsed >= 29000 && elapsed <= 90000); ensure(timeout <= 2000); } } }