passenger 3.0.8 → 3.0.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data/NEWS +9 -0
- data/bin/passenger-install-nginx-module +1 -1
- data/build/basics.rb +0 -1
- data/build/cxx_tests.rb +5 -0
- data/build/rpm.rb +1 -1
- data/doc/Users guide Apache.html +1 -1
- data/doc/Users guide Nginx.html +1 -1
- data/ext/apache2/Configuration.cpp +12 -0
- data/ext/apache2/Configuration.hpp +12 -1
- data/ext/apache2/Hooks.cpp +2 -0
- data/ext/common/AgentsStarter.cpp +4 -0
- data/ext/common/AgentsStarter.h +2 -0
- data/ext/common/AgentsStarter.hpp +4 -0
- data/ext/common/Constants.h +1 -1
- data/ext/common/Logging.h +481 -261
- data/ext/common/LoggingAgent/LoggingServer.h +10 -4
- data/ext/common/LoggingAgent/Main.cpp +7 -2
- data/ext/common/LoggingAgent/RemoteSender.h +25 -3
- data/ext/common/MessageChannel.h +18 -227
- data/ext/common/MessageClient.h +95 -92
- data/ext/common/Utils/IOUtils.cpp +114 -1
- data/ext/common/Utils/IOUtils.h +57 -1
- data/ext/common/Utils/MessageIO.h +576 -0
- data/ext/nginx/Configuration.c +35 -0
- data/ext/nginx/Configuration.h +2 -0
- data/ext/nginx/ContentHandler.c +17 -6
- data/ext/nginx/ngx_http_passenger_module.c +8 -0
- data/lib/phusion_passenger.rb +2 -2
- data/lib/phusion_passenger/analytics_logger.rb +174 -117
- data/lib/phusion_passenger/app_process.rb +14 -2
- data/test/cxx/CxxTestMain.cpp +14 -19
- data/test/cxx/IOUtilsTest.cpp +68 -18
- data/test/cxx/LoggingTest.cpp +20 -24
- data/test/cxx/MessageChannelTest.cpp +1 -1
- data/test/cxx/MessageIOTest.cpp +310 -0
- data/test/cxx/TestSupport.cpp +47 -0
- data/test/cxx/TestSupport.h +8 -0
- data/test/ruby/analytics_logger_spec.rb +20 -28
- data/test/tut/tut.h +2 -0
- metadata +11 -11
- data/build/rdoctask.rb +0 -209
- data/test/cxx/HttpStatusExtractorTest.cpp +0 -198
@@ -70,7 +70,7 @@ class AppProcess
|
|
70
70
|
return nil
|
71
71
|
end
|
72
72
|
|
73
|
-
search_results =
|
73
|
+
search_results = search_gem('rails', gem_version_spec)
|
74
74
|
found_version = search_results.map do |x|
|
75
75
|
x.version.version
|
76
76
|
end.sort.last
|
@@ -79,7 +79,7 @@ class AppProcess
|
|
79
79
|
# date because the Rails version may have been installed now.
|
80
80
|
# So we reload the RubyGems cache and try again.
|
81
81
|
Gem.clear_paths
|
82
|
-
search_results =
|
82
|
+
search_results = search_gem('rails', gem_version_spec)
|
83
83
|
found_version = search_results.map do |x|
|
84
84
|
x.version.version
|
85
85
|
end.sort.last
|
@@ -94,6 +94,18 @@ class AppProcess
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
+
def self.search_gem(gem_name, gem_version_spec)
|
98
|
+
if defined?(Gem::Specification) && Gem::Specification.respond_to?(:find_all_by_name)
|
99
|
+
return Gem::Specification.find_all_by_name(gem_name, gem_version_spec)
|
100
|
+
elsif Gem.respond_to?(:source_index)
|
101
|
+
dep = Gem::Dependency.new(gem_name, gem_version_spec)
|
102
|
+
return Gem.source_index.search(dep, true)
|
103
|
+
else
|
104
|
+
dep = Gem::Dependency.new(gem_name, gem_version_spec)
|
105
|
+
return Gem.cache.search(dep, true)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
97
109
|
# Construct an AppProcess by reading information from the given MessageChannel.
|
98
110
|
# The other side of the channel must be writing AppProcess information using
|
99
111
|
# AppProcess#write_to_channel.
|
data/test/cxx/CxxTestMain.cpp
CHANGED
@@ -98,25 +98,20 @@ main(int argc, char *argv[]) {
|
|
98
98
|
allGroups = tut::runner.get().list_groups();
|
99
99
|
parseOptions(argc, argv);
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
all_ok = all_ok && reporter.all_ok();
|
111
|
-
}
|
101
|
+
bool all_ok = true;
|
102
|
+
if (runMode == RUN_ALL_GROUPS) {
|
103
|
+
tut::runner.get().run_tests();
|
104
|
+
all_ok = reporter.all_ok();
|
105
|
+
} else {
|
106
|
+
all_ok = true;
|
107
|
+
for (groupnames_iterator it = groupsToRun.begin(); it != groupsToRun.end(); it++) {
|
108
|
+
tut::runner.get().run_tests(*it);
|
109
|
+
all_ok = all_ok && reporter.all_ok();
|
112
110
|
}
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
} catch (const std::exception &ex) {
|
119
|
-
cerr << "*** Exception raised: " << ex.what() << endl;
|
120
|
-
return 2;
|
111
|
+
}
|
112
|
+
if (all_ok) {
|
113
|
+
return 0;
|
114
|
+
} else {
|
115
|
+
return 1;
|
121
116
|
}
|
122
117
|
}
|
data/test/cxx/IOUtilsTest.cpp
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#include "TestSupport.h"
|
2
|
-
#include
|
2
|
+
#include <Utils/IOUtils.h>
|
3
|
+
#include <Utils/SystemTime.h>
|
3
4
|
#include <oxt/system_calls.hpp>
|
4
5
|
#include <boost/bind.hpp>
|
5
6
|
#include <sys/types.h>
|
@@ -54,23 +55,6 @@ namespace tut {
|
|
54
55
|
return p;
|
55
56
|
}
|
56
57
|
|
57
|
-
void writeUntilFull(int fd) {
|
58
|
-
char buf[1024 * 4];
|
59
|
-
memset(buf, 0, sizeof(buf));
|
60
|
-
bool done = false;
|
61
|
-
while (!done) {
|
62
|
-
ssize_t ret = write(fd, buf, sizeof(buf));
|
63
|
-
if (ret == -1) {
|
64
|
-
if (errno == EAGAIN) {
|
65
|
-
done = true;
|
66
|
-
} else {
|
67
|
-
int e = errno;
|
68
|
-
throw SystemException("Cannot write to pipe", e);
|
69
|
-
}
|
70
|
-
}
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
58
|
static void writeDataAfterSomeTime(int fd, unsigned int sleepTimeInUsec) {
|
75
59
|
try {
|
76
60
|
syscalls::usleep(sleepTimeInUsec);
|
@@ -485,6 +469,25 @@ namespace tut {
|
|
485
469
|
ensure_equals(writevData, "hellomyworld!!");
|
486
470
|
}
|
487
471
|
|
472
|
+
TEST_METHOD(45) {
|
473
|
+
// Test writev() timeout support.
|
474
|
+
setWritevFunction(NULL);
|
475
|
+
Pipe p = createPipe();
|
476
|
+
unsigned long long startTime = SystemTime::getUsec();
|
477
|
+
unsigned long long timeout = 30000;
|
478
|
+
try {
|
479
|
+
StaticString data[] = { "hello", "world" };
|
480
|
+
for (int i = 0; i < 1024 * 1024; i++) {
|
481
|
+
gatheredWrite(p[1], data, 2, &timeout);
|
482
|
+
}
|
483
|
+
fail("TimeoutException expected");
|
484
|
+
} catch (const TimeoutException &) {
|
485
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
486
|
+
ensure("30 msec have passed", elapsed >= 29000 && elapsed <= 45000);
|
487
|
+
ensure(timeout <= 2000);
|
488
|
+
}
|
489
|
+
}
|
490
|
+
|
488
491
|
/***** Test waitUntilReadable() *****/
|
489
492
|
|
490
493
|
TEST_METHOD(50) {
|
@@ -793,4 +796,51 @@ namespace tut {
|
|
793
796
|
// Pass.
|
794
797
|
}
|
795
798
|
}
|
799
|
+
|
800
|
+
/***** Test readFileDescriptor() and writeFileDescriptor() *****/
|
801
|
+
|
802
|
+
TEST_METHOD(80) {
|
803
|
+
// Test whether it works.
|
804
|
+
SocketPair sockets = createUnixSocketPair();
|
805
|
+
Pipe pipes = createPipe();
|
806
|
+
writeFileDescriptor(sockets[0], pipes[1]);
|
807
|
+
FileDescriptor fd = readFileDescriptor(sockets[1]);
|
808
|
+
writeExact(fd, "hello");
|
809
|
+
char buf[6];
|
810
|
+
ensure_equals(readExact(pipes[0], buf, 5), 5u);
|
811
|
+
buf[5] = '\0';
|
812
|
+
ensure_equals(StaticString(buf), "hello");
|
813
|
+
}
|
814
|
+
|
815
|
+
TEST_METHOD(81) {
|
816
|
+
// Test whether timeout works.
|
817
|
+
SocketPair sockets = createUnixSocketPair();
|
818
|
+
Pipe pipes = createPipe();
|
819
|
+
|
820
|
+
unsigned long long timeout = 30000;
|
821
|
+
unsigned long long startTime = SystemTime::getUsec();
|
822
|
+
try {
|
823
|
+
FileDescriptor fd = readFileDescriptor(sockets[0], &timeout);
|
824
|
+
fail("TimeoutException expected");
|
825
|
+
} catch (const TimeoutException &) {
|
826
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
827
|
+
ensure("readFileDescriptor() timed out after 30 msec",
|
828
|
+
elapsed >= 29000 && elapsed <= 45000);
|
829
|
+
ensure(timeout <= 2000);
|
830
|
+
}
|
831
|
+
|
832
|
+
writeUntilFull(sockets[0]);
|
833
|
+
|
834
|
+
startTime = SystemTime::getUsec();
|
835
|
+
timeout = 30000;
|
836
|
+
try {
|
837
|
+
writeFileDescriptor(sockets[0], pipes[0], &timeout);
|
838
|
+
fail("TimeoutException expected");
|
839
|
+
} catch (const TimeoutException &) {
|
840
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
841
|
+
ensure("writeFileDescriptor() timed out after 30 msec",
|
842
|
+
elapsed >= 29000 && elapsed <= 45000);
|
843
|
+
ensure(timeout <= 2000);
|
844
|
+
}
|
845
|
+
}
|
796
846
|
}
|
data/test/cxx/LoggingTest.cpp
CHANGED
@@ -152,7 +152,7 @@ namespace tut {
|
|
152
152
|
log->getGroupName(), log->getCategory());
|
153
153
|
log2->message("message 2");
|
154
154
|
log2->flushToDiskAfterClose(true);
|
155
|
-
|
155
|
+
|
156
156
|
log.reset();
|
157
157
|
log2.reset();
|
158
158
|
|
@@ -268,24 +268,6 @@ namespace tut {
|
|
268
268
|
ensure_equals(data, "localhost");
|
269
269
|
}
|
270
270
|
|
271
|
-
TEST_METHOD(10) {
|
272
|
-
// newTransaction() reestablishes the connection to the logging
|
273
|
-
// server if the logging server crashed and was restarted
|
274
|
-
SystemTime::forceAll(TODAY);
|
275
|
-
|
276
|
-
logger->newTransaction("foobar");
|
277
|
-
stopLoggingServer();
|
278
|
-
startLoggingServer();
|
279
|
-
|
280
|
-
AnalyticsLogPtr log = logger->newTransaction("foobar");
|
281
|
-
log->message("hello");
|
282
|
-
log->flushToDiskAfterClose(true);
|
283
|
-
log.reset();
|
284
|
-
|
285
|
-
string data = readAll(loggingDir + "/1/" FOOBAR_LOCALHOST_PREFIX "/requests/2010/01/13/12/log.txt");
|
286
|
-
ensure("(1)", data.find("hello\n") != string::npos);
|
287
|
-
}
|
288
|
-
|
289
271
|
TEST_METHOD(11) {
|
290
272
|
// newTransaction() does not reconnect to the server for a short
|
291
273
|
// period of time if connecting failed
|
@@ -305,22 +287,36 @@ namespace tut {
|
|
305
287
|
}
|
306
288
|
|
307
289
|
TEST_METHOD(12) {
|
308
|
-
//
|
309
|
-
//
|
290
|
+
// If the logging server crashed and was restarted then
|
291
|
+
// newTransaction() and continueTransaction() print a warning and return
|
292
|
+
// a null log object. One of the next newTransaction()/continueTransaction()
|
293
|
+
// calls will reestablish the connection when the connection timeout
|
294
|
+
// has passed.
|
310
295
|
SystemTime::forceAll(TODAY);
|
296
|
+
AnalyticsLogPtr log, log2;
|
311
297
|
|
312
|
-
|
298
|
+
log = logger->newTransaction("foobar");
|
313
299
|
logger2->continueTransaction(log->getTxnId(), "foobar");
|
314
300
|
stopLoggingServer();
|
315
301
|
startLoggingServer();
|
316
302
|
|
317
|
-
|
303
|
+
log = logger->newTransaction("foobar");
|
304
|
+
ensure("(1)", log->isNull());
|
305
|
+
log2 = logger2->continueTransaction("some-id", "foobar");
|
306
|
+
ensure("(2)", log2->isNull());
|
307
|
+
|
308
|
+
SystemTime::forceAll(TODAY + 60000000);
|
309
|
+
log = logger->newTransaction("foobar");
|
310
|
+
ensure("(3)", !log->isNull());
|
311
|
+
log2 = logger2->continueTransaction(log->getTxnId(), "foobar");
|
312
|
+
ensure("(4)", !log2->isNull());
|
318
313
|
log2->message("hello");
|
319
314
|
log2->flushToDiskAfterClose(true);
|
315
|
+
log.reset();
|
320
316
|
log2.reset();
|
321
317
|
|
322
318
|
string data = readAll(loggingDir + "/1/" FOOBAR_LOCALHOST_PREFIX "/requests/2010/01/13/12/log.txt");
|
323
|
-
ensure("(
|
319
|
+
ensure("(5)", data.find("hello\n") != string::npos);
|
324
320
|
}
|
325
321
|
|
326
322
|
TEST_METHOD(13) {
|
@@ -458,7 +458,7 @@ namespace tut {
|
|
458
458
|
fail("TimeoutException expected");
|
459
459
|
} catch (const TimeoutException &) {
|
460
460
|
unsigned long long elapsed = timer.elapsed();
|
461
|
-
ensure("Spent at least 35 msec waiting", elapsed >=
|
461
|
+
ensure("Spent at least 35 msec waiting", elapsed >= 34);
|
462
462
|
ensure("Spent at most 60 msec waiting", elapsed <= 60);
|
463
463
|
ensure("The passed time is deducted from timeout", timeout < 5);
|
464
464
|
}
|
@@ -0,0 +1,310 @@
|
|
1
|
+
#include "TestSupport.h"
|
2
|
+
#include <Utils/IOUtils.h>
|
3
|
+
#include <Utils/MessageIO.h>
|
4
|
+
#include <Utils/SystemTime.h>
|
5
|
+
|
6
|
+
using namespace Passenger;
|
7
|
+
using namespace std;
|
8
|
+
using namespace boost;
|
9
|
+
|
10
|
+
namespace tut {
|
11
|
+
struct MessageIOTest {
|
12
|
+
Pipe pipes;
|
13
|
+
|
14
|
+
MessageIOTest() {
|
15
|
+
pipes = createPipe();
|
16
|
+
}
|
17
|
+
};
|
18
|
+
|
19
|
+
DEFINE_TEST_GROUP(MessageIOTest);
|
20
|
+
|
21
|
+
/***** Test readUint16() and writeUint16() *****/
|
22
|
+
|
23
|
+
TEST_METHOD(1) {
|
24
|
+
// They work.
|
25
|
+
writeUint16(pipes[1], 0x3F56);
|
26
|
+
writeUint16(pipes[1], 0x3F57);
|
27
|
+
writeUint16(pipes[1], 0x3F58);
|
28
|
+
|
29
|
+
unsigned char buf[2];
|
30
|
+
ensure_equals(readExact(pipes[0], buf, 2), 2u);
|
31
|
+
ensure_equals(buf[0], 0x3F);
|
32
|
+
ensure_equals(buf[1], 0x56);
|
33
|
+
|
34
|
+
ensure_equals(readUint16(pipes[0]), 0x3F57u);
|
35
|
+
|
36
|
+
uint16_t out;
|
37
|
+
ensure(readUint16(pipes[0], out));
|
38
|
+
ensure_equals(out, 0x3F58);
|
39
|
+
}
|
40
|
+
|
41
|
+
TEST_METHOD(2) {
|
42
|
+
// readUint16() throws EOFException on premature EOF.
|
43
|
+
writeExact(pipes[1], "x", 1);
|
44
|
+
pipes[1].close();
|
45
|
+
try {
|
46
|
+
readUint16(pipes[0]);
|
47
|
+
fail("EOFException expected");
|
48
|
+
} catch (const EOFException &) {
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
TEST_METHOD(3) {
|
53
|
+
// readUint16(uint32_t &) returns false EOFException on premature EOF.
|
54
|
+
writeExact(pipes[1], "x", 1);
|
55
|
+
pipes[1].close();
|
56
|
+
uint16_t out;
|
57
|
+
ensure(!readUint16(pipes[0], out));
|
58
|
+
}
|
59
|
+
|
60
|
+
TEST_METHOD(4) {
|
61
|
+
// Test timeout.
|
62
|
+
unsigned long long timeout = 30000;
|
63
|
+
unsigned long long startTime = SystemTime::getUsec();
|
64
|
+
try {
|
65
|
+
readUint16(pipes[0], &timeout);
|
66
|
+
fail("TimeoutException expected");
|
67
|
+
} catch (const TimeoutException &) {
|
68
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
69
|
+
ensure("About 30 ms elapsed (1)", elapsed >= 29000 && elapsed <= 50000);
|
70
|
+
ensure("Time is correctly deducted from 'timeout' (1)", timeout <= 2000);
|
71
|
+
}
|
72
|
+
|
73
|
+
writeUntilFull(pipes[1]);
|
74
|
+
|
75
|
+
timeout = 30000;
|
76
|
+
startTime = SystemTime::getUsec();
|
77
|
+
try {
|
78
|
+
writeUint16(pipes[1], 0x12, &timeout);
|
79
|
+
fail("TimeoutException expected");
|
80
|
+
} catch (const TimeoutException &) {
|
81
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
82
|
+
ensure("About 30 ms elapsed (3)", elapsed >= 29000 && elapsed <= 50000);
|
83
|
+
ensure("Time is correctly deducted from 'timeout' (4)", timeout <= 2000);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
/***** Test readUint32() and writeUint32() *****/
|
88
|
+
|
89
|
+
TEST_METHOD(10) {
|
90
|
+
// They work.
|
91
|
+
writeUint32(pipes[1], 0x12343F56);
|
92
|
+
writeUint32(pipes[1], 0x12343F57);
|
93
|
+
writeUint32(pipes[1], 0x12343F58);
|
94
|
+
|
95
|
+
unsigned char buf[4];
|
96
|
+
ensure_equals(readExact(pipes[0], buf, 4), 4u);
|
97
|
+
ensure_equals(buf[0], 0x12);
|
98
|
+
ensure_equals(buf[1], 0x34);
|
99
|
+
ensure_equals(buf[2], 0x3F);
|
100
|
+
ensure_equals(buf[3], 0x56);
|
101
|
+
|
102
|
+
ensure_equals(readUint32(pipes[0]), 0x12343F57u);
|
103
|
+
|
104
|
+
uint32_t out;
|
105
|
+
ensure(readUint32(pipes[0], out));
|
106
|
+
ensure_equals(out, 0x12343F58u);
|
107
|
+
}
|
108
|
+
|
109
|
+
TEST_METHOD(11) {
|
110
|
+
// readUint32() throws EOFException on premature EOF.
|
111
|
+
writeExact(pipes[1], "xyz", 3);
|
112
|
+
pipes[1].close();
|
113
|
+
try {
|
114
|
+
readUint32(pipes[0]);
|
115
|
+
fail("EOFException expected");
|
116
|
+
} catch (const EOFException &) {
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
TEST_METHOD(12) {
|
121
|
+
// readUint16(uint32_t &) returns false EOFException on premature EOF.
|
122
|
+
writeExact(pipes[1], "xyz", 3);
|
123
|
+
pipes[1].close();
|
124
|
+
uint32_t out;
|
125
|
+
ensure(!readUint32(pipes[0], out));
|
126
|
+
}
|
127
|
+
|
128
|
+
TEST_METHOD(13) {
|
129
|
+
// Test timeout.
|
130
|
+
unsigned long long timeout = 30000;
|
131
|
+
unsigned long long startTime = SystemTime::getUsec();
|
132
|
+
try {
|
133
|
+
readUint32(pipes[0], &timeout);
|
134
|
+
fail("TimeoutException expected");
|
135
|
+
} catch (const TimeoutException &) {
|
136
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
137
|
+
ensure(elapsed >= 29000 && elapsed <= 50000);
|
138
|
+
ensure(timeout <= 2000);
|
139
|
+
}
|
140
|
+
|
141
|
+
writeUntilFull(pipes[1]);
|
142
|
+
|
143
|
+
timeout = 30000;
|
144
|
+
startTime = SystemTime::getUsec();
|
145
|
+
try {
|
146
|
+
writeUint32(pipes[1], 0x1234, &timeout);
|
147
|
+
fail("TimeoutException expected");
|
148
|
+
} catch (const TimeoutException &) {
|
149
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
150
|
+
ensure(elapsed >= 29000 && elapsed <= 50000);
|
151
|
+
ensure(timeout <= 2000);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
/***** Test readArrayMessage() and writeArrayMessage() *****/
|
156
|
+
|
157
|
+
TEST_METHOD(20) {
|
158
|
+
// They work.
|
159
|
+
writeArrayMessage(pipes[1], "ab", "cd", "efg", NULL);
|
160
|
+
writeArrayMessage(pipes[1], "ab", "cd", "efh", NULL);
|
161
|
+
|
162
|
+
unsigned char buf[12];
|
163
|
+
readExact(pipes[0], buf, 12);
|
164
|
+
ensure_equals(buf[0], 0u);
|
165
|
+
ensure_equals(buf[1], 10u);
|
166
|
+
ensure_equals(buf[2], 'a');
|
167
|
+
ensure_equals(buf[3], 'b');
|
168
|
+
ensure_equals(buf[4], '\0');
|
169
|
+
ensure_equals(buf[5], 'c');
|
170
|
+
ensure_equals(buf[6], 'd');
|
171
|
+
ensure_equals(buf[7], '\0');
|
172
|
+
ensure_equals(buf[8], 'e');
|
173
|
+
ensure_equals(buf[9], 'f');
|
174
|
+
ensure_equals(buf[10], 'g');
|
175
|
+
ensure_equals(buf[11], '\0');
|
176
|
+
|
177
|
+
vector<string> args = readArrayMessage(pipes[0]);
|
178
|
+
ensure_equals(args.size(), 3u);
|
179
|
+
ensure_equals(args[0], "ab");
|
180
|
+
ensure_equals(args[1], "cd");
|
181
|
+
ensure_equals(args[2], "efh");
|
182
|
+
}
|
183
|
+
|
184
|
+
TEST_METHOD(21) {
|
185
|
+
// readArrayMessage() throws EOFException on premature EOF.
|
186
|
+
writeExact(pipes[1], "\x00");
|
187
|
+
pipes[1].close();
|
188
|
+
try {
|
189
|
+
readArrayMessage(pipes[0]);
|
190
|
+
fail("EOFException expected (1)");
|
191
|
+
} catch (const EOFException &) {
|
192
|
+
}
|
193
|
+
|
194
|
+
pipes = createPipe();
|
195
|
+
writeExact(pipes[1], "\x00\x04a\x00b");
|
196
|
+
pipes[1].close();
|
197
|
+
try {
|
198
|
+
readArrayMessage(pipes[0]);
|
199
|
+
fail("EOFException expected (2)");
|
200
|
+
} catch (const EOFException &) {
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
TEST_METHOD(22) {
|
205
|
+
// Test timeout.
|
206
|
+
unsigned long long timeout = 30000;
|
207
|
+
unsigned long long startTime = SystemTime::getUsec();
|
208
|
+
try {
|
209
|
+
readArrayMessage(pipes[0], &timeout);
|
210
|
+
fail("TimeoutException expected (1)");
|
211
|
+
} catch (const TimeoutException &) {
|
212
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
213
|
+
ensure(elapsed >= 29000 && elapsed <= 50000);
|
214
|
+
ensure(timeout <= 2000);
|
215
|
+
}
|
216
|
+
|
217
|
+
writeUntilFull(pipes[1]);
|
218
|
+
|
219
|
+
timeout = 30000;
|
220
|
+
startTime = SystemTime::getUsec();
|
221
|
+
try {
|
222
|
+
writeArrayMessage(pipes[1], &timeout, "hi", "ho", NULL);
|
223
|
+
fail("TimeoutException expected (2)");
|
224
|
+
} catch (const TimeoutException &) {
|
225
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
226
|
+
ensure(elapsed >= 29000 && elapsed <= 50000);
|
227
|
+
ensure(timeout <= 2000);
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
/***** Test readArrayMessage() and writeArrayMessage() *****/
|
232
|
+
|
233
|
+
TEST_METHOD(30) {
|
234
|
+
// They work.
|
235
|
+
writeScalarMessage(pipes[1], "hello");
|
236
|
+
writeScalarMessage(pipes[1], "world");
|
237
|
+
|
238
|
+
unsigned char buf[4 + 5];
|
239
|
+
readExact(pipes[0], buf, 4 + 5);
|
240
|
+
ensure_equals(buf[0], 0u);
|
241
|
+
ensure_equals(buf[1], 0u);
|
242
|
+
ensure_equals(buf[2], 0u);
|
243
|
+
ensure_equals(buf[3], 5u);
|
244
|
+
ensure_equals(buf[4], 'h');
|
245
|
+
ensure_equals(buf[5], 'e');
|
246
|
+
ensure_equals(buf[6], 'l');
|
247
|
+
ensure_equals(buf[7], 'l');
|
248
|
+
ensure_equals(buf[8], 'o');
|
249
|
+
|
250
|
+
ensure_equals(readScalarMessage(pipes[0]), "world");
|
251
|
+
}
|
252
|
+
|
253
|
+
TEST_METHOD(31) {
|
254
|
+
// readScalarMessage() throws EOFException on premature EOF.
|
255
|
+
writeExact(pipes[1], StaticString("\x00", 1));
|
256
|
+
pipes[1].close();
|
257
|
+
try {
|
258
|
+
readScalarMessage(pipes[0]);
|
259
|
+
fail("EOFException expected (1)");
|
260
|
+
} catch (const EOFException &) {
|
261
|
+
}
|
262
|
+
|
263
|
+
pipes = createPipe();
|
264
|
+
writeExact(pipes[1], StaticString("\x00\x00\x00\x04" "abc", 4 + 3));
|
265
|
+
pipes[1].close();
|
266
|
+
try {
|
267
|
+
readScalarMessage(pipes[0]);
|
268
|
+
fail("EOFException expected (2)");
|
269
|
+
} catch (const EOFException &) {
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
TEST_METHOD(32) {
|
274
|
+
// readScalarMessage() throws SecurityException if the
|
275
|
+
// body larger than the limit
|
276
|
+
writeExact(pipes[1], StaticString("\x00\x00\x00\x05", 4));
|
277
|
+
try {
|
278
|
+
readScalarMessage(pipes[0], 4);
|
279
|
+
fail("SecurityException expected (1)");
|
280
|
+
} catch (const SecurityException &) {
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
TEST_METHOD(33) {
|
285
|
+
// Test timeout.
|
286
|
+
unsigned long long timeout = 30000;
|
287
|
+
unsigned long long startTime = SystemTime::getUsec();
|
288
|
+
try {
|
289
|
+
readScalarMessage(pipes[0], 0, &timeout);
|
290
|
+
fail("TimeoutException expected (1)");
|
291
|
+
} catch (const TimeoutException &) {
|
292
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
293
|
+
ensure(elapsed >= 29000 && elapsed <= 50000);
|
294
|
+
ensure(timeout <= 2000);
|
295
|
+
}
|
296
|
+
|
297
|
+
writeUntilFull(pipes[1]);
|
298
|
+
|
299
|
+
timeout = 30000;
|
300
|
+
startTime = SystemTime::getUsec();
|
301
|
+
try {
|
302
|
+
writeScalarMessage(pipes[1], "hello", &timeout);
|
303
|
+
fail("TimeoutException expected (2)");
|
304
|
+
} catch (const TimeoutException &) {
|
305
|
+
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
306
|
+
ensure(elapsed >= 29000 && elapsed <= 50000);
|
307
|
+
ensure(timeout <= 2000);
|
308
|
+
}
|
309
|
+
}
|
310
|
+
}
|