Commit 90cda34c authored by Kenton Varda's avatar Kenton Varda

MinGW: All tests pass in lite mode.

parent df7d814a
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h>
#include "test-util.h" #include "test-util.h"
namespace capnp { namespace capnp {
...@@ -288,13 +289,39 @@ TEST(Serialize, WriteMessageEvenSegmentCount) { ...@@ -288,13 +289,39 @@ TEST(Serialize, WriteMessageEvenSegmentCount) {
EXPECT_TRUE(output.dataEquals(serialized.asPtr())); EXPECT_TRUE(output.dataEquals(serialized.asPtr()));
} }
#if _WIN32
int mkstemp(char *tpl) {
char* end = tpl + strlen(tpl);
while (end > tpl && *(end-1) == 'X') --end;
for (;;) {
KJ_ASSERT(_mktemp(tpl) == tpl);
int fd = open(tpl, O_RDWR | O_CREAT | O_EXCL | O_TEMPORARY | O_BINARY, 0700);
if (fd >= 0) {
return fd;
}
int error = errno;
if (error != EEXIST && error != EINTR) {
KJ_FAIL_SYSCALL("open(mktemp())", error);
}
memset(end, 'X', strlen(end));
}
}
#endif
TEST(Serialize, FileDescriptors) { TEST(Serialize, FileDescriptors) {
char filename[] = "/tmp/capnproto-serialize-test-XXXXXX"; char filename[] = "/tmp/capnproto-serialize-test-XXXXXX";
kj::AutoCloseFd tmpfile(mkstemp(filename)); kj::AutoCloseFd tmpfile(mkstemp(filename));
ASSERT_GE(tmpfile.get(), 0); ASSERT_GE(tmpfile.get(), 0);
#if !_WIN32
// Unlink the file so that it will be deleted on close. // Unlink the file so that it will be deleted on close.
// (For win32, we already handled this is mkstemp().)
EXPECT_EQ(0, unlink(filename)); EXPECT_EQ(0, unlink(filename));
#endif
{ {
TestMessageBuilder builder(7); TestMessageBuilder builder(7);
...@@ -340,6 +367,7 @@ TEST(Serialize, RejectTooManySegments) { ...@@ -340,6 +367,7 @@ TEST(Serialize, RejectTooManySegments) {
EXPECT_TRUE(e != nullptr) << "Should have thrown an exception."; EXPECT_TRUE(e != nullptr) << "Should have thrown an exception.";
} }
#if !__MINGW32__ // Inexplicably crashes when exception is thrown from constructor.
TEST(Serialize, RejectHugeMessage) { TEST(Serialize, RejectHugeMessage) {
// A message whose root struct contains two words of data! // A message whose root struct contains two words of data!
AlignedData<4> data = {{0,0,0,0,3,0,0,0, 0,0,0,0,2,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}}; AlignedData<4> data = {{0,0,0,0,3,0,0,0, 0,0,0,0,2,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}};
...@@ -359,6 +387,7 @@ TEST(Serialize, RejectHugeMessage) { ...@@ -359,6 +387,7 @@ TEST(Serialize, RejectHugeMessage) {
EXPECT_TRUE(e != nullptr) << "Should have thrown an exception."; EXPECT_TRUE(e != nullptr) << "Should have thrown an exception.";
} }
#endif // !__MINGW32__
// TODO(test): Test error cases. // TODO(test): Test error cases.
......
...@@ -29,8 +29,11 @@ ...@@ -29,8 +29,11 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <exception> #include <exception>
#if !_WIN32
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif
namespace kj { namespace kj {
namespace _ { // private namespace _ { // private
...@@ -50,6 +53,11 @@ public: ...@@ -50,6 +53,11 @@ public:
// This is called when exceptions are disabled. We fork the process instead and then expect // This is called when exceptions are disabled. We fork the process instead and then expect
// the child to die. // the child to die.
#if _WIN32
// Windows doesn't support fork() or anything like it. Just skip the test.
return false;
#else
int pipeFds[2]; int pipeFds[2];
KJ_SYSCALL(pipe(pipeFds)); KJ_SYSCALL(pipe(pipeFds));
pid_t child = fork(); pid_t child = fork();
...@@ -98,6 +106,7 @@ public: ...@@ -98,6 +106,7 @@ public:
return false; return false;
} }
#endif // _WIN32, else
} }
void flush() { void flush() {
......
...@@ -85,6 +85,7 @@ TEST(Exception, UnwindDetector) { ...@@ -85,6 +85,7 @@ TEST(Exception, UnwindDetector) {
} }
} }
#if !__MINGW32__ // Inexplicably crashes when exception is thrown from constructor.
TEST(Exception, ExceptionCallbackMustBeOnStack) { TEST(Exception, ExceptionCallbackMustBeOnStack) {
#if KJ_NO_EXCEPTIONS #if KJ_NO_EXCEPTIONS
EXPECT_DEATH_IF_SUPPORTED(new ExceptionCallback, "must be allocated on the stack"); EXPECT_DEATH_IF_SUPPORTED(new ExceptionCallback, "must be allocated on the stack");
...@@ -92,6 +93,7 @@ TEST(Exception, ExceptionCallbackMustBeOnStack) { ...@@ -92,6 +93,7 @@ TEST(Exception, ExceptionCallbackMustBeOnStack) {
EXPECT_ANY_THROW(new ExceptionCallback); EXPECT_ANY_THROW(new ExceptionCallback);
#endif #endif
} }
#endif // !__MINGW32__
#if !KJ_NO_EXCEPTIONS #if !KJ_NO_EXCEPTIONS
TEST(Exception, ScopeSuccessFail) { TEST(Exception, ScopeSuccessFail) {
......
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <unistd.h> #include <unistd.h>
#if _WIN32
#include <io.h>
#include <fcntl.h>
#define pipe(fds) _pipe(fds, 8192, _O_BINARY)
#endif
namespace kj { namespace kj {
namespace { namespace {
......
...@@ -22,11 +22,14 @@ ...@@ -22,11 +22,14 @@
#include "io.h" #include "io.h"
#include "debug.h" #include "debug.h"
#include <unistd.h> #include <unistd.h>
#include <sys/uio.h>
#include <algorithm> #include <algorithm>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#if !_WIN32
#include <sys/uio.h>
#endif
namespace kj { namespace kj {
InputStream::~InputStream() noexcept(false) {} InputStream::~InputStream() noexcept(false) {}
...@@ -278,6 +281,15 @@ void FdOutputStream::write(const void* buffer, size_t size) { ...@@ -278,6 +281,15 @@ void FdOutputStream::write(const void* buffer, size_t size) {
} }
void FdOutputStream::write(ArrayPtr<const ArrayPtr<const byte>> pieces) { void FdOutputStream::write(ArrayPtr<const ArrayPtr<const byte>> pieces) {
#if _WIN32
// Windows has no reasonable writev(). It has WriteFileGather, but this call has the unreasonable
// restriction that each segment must be page-aligned. So, fall back to write().
for (auto piece: pieces) {
write(piece.begin(), piece.size());
}
#else
// Apparently, there is a maximum number of iovecs allowed per call. I don't understand why. // Apparently, there is a maximum number of iovecs allowed per call. I don't understand why.
// Also, most platforms define IOV_MAX but Linux defines only UIO_MAXIOV. Unfortunately, Solaris // Also, most platforms define IOV_MAX but Linux defines only UIO_MAXIOV. Unfortunately, Solaris
// defines a constant UIO_MAXIOV with a different meaning, so we check for IOV_MAX first. // defines a constant UIO_MAXIOV with a different meaning, so we check for IOV_MAX first.
...@@ -324,6 +336,7 @@ void FdOutputStream::write(ArrayPtr<const ArrayPtr<const byte>> pieces) { ...@@ -324,6 +336,7 @@ void FdOutputStream::write(ArrayPtr<const ArrayPtr<const byte>> pieces) {
current->iov_len -= n; current->iov_len -= n;
} }
} }
#endif
} }
} // namespace kj } // namespace kj
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include <string> #include <string>
namespace kj { namespace kj {
std::ostream& operator<<(std::ostream& os, const kj::String& s) { return os << s.cStr(); }
namespace _ { // private namespace _ { // private
namespace { namespace {
......
...@@ -210,6 +210,19 @@ void RemovePlus(char* buffer) { ...@@ -210,6 +210,19 @@ void RemovePlus(char* buffer) {
} }
} }
void RemoveE0(char* buffer) {
// Remove redundant leading 0's after an e, e.g. 1e012. Seems to appear on
// Windows.
for (;;) {
buffer = strstr(buffer, "e0");
if (buffer == NULL || buffer[2] < '0' || buffer[2] > '9') {
return;
}
memmove(buffer + 1, buffer + 2, strlen(buffer + 2) + 1);
}
}
char* DoubleToBuffer(double value, char* buffer) { char* DoubleToBuffer(double value, char* buffer) {
// DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
// platforms these days. Just in case some system exists where DBL_DIG // platforms these days. Just in case some system exists where DBL_DIG
...@@ -252,6 +265,9 @@ char* DoubleToBuffer(double value, char* buffer) { ...@@ -252,6 +265,9 @@ char* DoubleToBuffer(double value, char* buffer) {
DelocalizeRadix(buffer); DelocalizeRadix(buffer);
RemovePlus(buffer); RemovePlus(buffer);
#if _WIN32
RemoveE0(buffer);
#endif // _WIN32
return buffer; return buffer;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment