Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
1ac3accc
Commit
1ac3accc
authored
Jun 12, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make tests pass with -fno-rtti and -fno-exceptions.
parent
77abb6e6
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
230 additions
and
71 deletions
+230
-71
dynamic-test.c++
c++/src/capnp/dynamic-test.c++
+6
-0
dynamic.c++
c++/src/capnp/dynamic.c++
+6
-2
encoding-test.c++
c++/src/capnp/encoding-test.c++
+48
-40
schema-loader-test.c++
c++/src/capnp/schema-loader-test.c++
+9
-1
schema-test.c++
c++/src/capnp/schema-test.c++
+5
-0
array-test.c++
c++/src/kj/array-test.c++
+4
-0
common-test.c++
c++/src/kj/common-test.c++
+6
-0
debug-test.c++
c++/src/kj/debug-test.c++
+141
-27
exception-test.c++
c++/src/kj/exception-test.c++
+4
-0
exception.c++
c++/src/kj/exception.c++
+1
-1
No files found.
c++/src/capnp/dynamic-test.c++
View file @
1ac3accc
...
...
@@ -316,6 +316,12 @@ TEST(DynamicApi, UnionsWrite) {
EXPECT_EQ
(
1234567890123456789ll
,
reader
.
getUnion3
().
getU3f0s64
());
}
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
// All exceptions should be non-fatal, so when exceptions are disabled the code should return.
#define EXPECT_ANY_THROW(code) code
#endif
TEST
(
DynamicApi
,
ConversionFailures
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
DynamicStruct
>
(
Schema
::
from
<
TestAllTypes
>
());
...
...
c++/src/capnp/dynamic.c++
View file @
1ac3accc
...
...
@@ -1444,12 +1444,16 @@ HANDLE_NUMERIC_TYPE(double, kj::implicitCast, kj::implicitCast, kj::implicitCast
#define HANDLE_TYPE(name, discrim, typeName) \
ReaderFor<typeName> DynamicValue::Reader::AsImpl<typeName>::apply(const Reader& reader) { \
KJ_REQUIRE(reader.type == discrim, \
"Type mismatch when using DynamicValue::Reader::as()."); \
"Type mismatch when using DynamicValue::Reader::as().") { \
return ReaderFor<typeName>(); \
} \
return reader.name##Value; \
} \
BuilderFor<typeName> DynamicValue::Builder::AsImpl<typeName>::apply(Builder& builder) { \
KJ_REQUIRE(builder.type == discrim, \
"Type mismatch when using DynamicValue::Builder::as()."); \
"Type mismatch when using DynamicValue::Builder::as().") { \
return BuilderFor<typeName>(); \
} \
return builder.name##Value; \
}
...
...
c++/src/capnp/encoding-test.c++
View file @
1ac3accc
...
...
@@ -212,6 +212,14 @@ TEST(Encoding, GenericObjects) {
}
}
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
#define EXPECT_NONFATAL_FAILURE(code) code
#else
#define EXPECT_NONFATAL_FAILURE EXPECT_ANY_THROW
#endif
#ifdef NDEBUG
#define EXPECT_DEBUG_ANY_THROW(EXP)
#else
...
...
@@ -947,12 +955,12 @@ TEST(Encoding, UpgradeListInBuilder) {
root
.
setObjectField
<
List
<
Void
>>
({
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
checkList
(
root
.
getObjectField
<
List
<
Void
>>
(),
{
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
bool
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint8_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
bool
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint8_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
checkUpgradedList
(
root
,
{
0
,
0
,
0
,
0
},
{
""
,
""
,
""
,
""
});
// -----------------------------------------------------------------
...
...
@@ -962,11 +970,11 @@ TEST(Encoding, UpgradeListInBuilder) {
auto
orig
=
root
.
asReader
().
getObjectField
<
List
<
bool
>>
();
checkList
(
root
.
getObjectField
<
List
<
Void
>>
(),
{
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
checkList
(
root
.
getObjectField
<
List
<
bool
>>
(),
{
true
,
false
,
true
,
true
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint8_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint8_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
checkList
(
orig
,
{
true
,
false
,
true
,
true
});
checkUpgradedList
(
root
,
{
1
,
0
,
1
,
1
},
{
""
,
""
,
""
,
""
});
...
...
@@ -981,10 +989,10 @@ TEST(Encoding, UpgradeListInBuilder) {
checkList
(
root
.
getObjectField
<
List
<
Void
>>
(),
{
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
checkList
(
root
.
getObjectField
<
List
<
bool
>>
(),
{
false
,
true
,
true
,
false
});
checkList
(
root
.
getObjectField
<
List
<
uint8_t
>>
(),
{
0x12
,
0x23
,
0x33
,
0x44
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
checkList
(
orig
,
{
0x12
,
0x23
,
0x33
,
0x44
});
checkUpgradedList
(
root
,
{
0x12
,
0x23
,
0x33
,
0x44
},
{
""
,
""
,
""
,
""
});
...
...
@@ -1000,9 +1008,9 @@ TEST(Encoding, UpgradeListInBuilder) {
checkList
(
root
.
getObjectField
<
List
<
bool
>>
(),
{
false
,
true
,
true
,
false
});
checkList
(
root
.
getObjectField
<
List
<
uint8_t
>>
(),
{
0x12
,
0x23
,
0x33
,
0x44
});
checkList
(
root
.
getObjectField
<
List
<
uint16_t
>>
(),
{
0x5612
,
0x7823
,
0xab33
,
0xcd44
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
checkList
(
orig
,
{
0x5612
,
0x7823
,
0xab33
,
0xcd44
});
checkUpgradedList
(
root
,
{
0x5612
,
0x7823
,
0xab33
,
0xcd44
},
{
""
,
""
,
""
,
""
});
...
...
@@ -1019,8 +1027,8 @@ TEST(Encoding, UpgradeListInBuilder) {
checkList
(
root
.
getObjectField
<
List
<
uint8_t
>>
(),
{
0x12
,
0x23
,
0x32
,
0x45
});
checkList
(
root
.
getObjectField
<
List
<
uint16_t
>>
(),
{
0x5612
,
0x7823
,
0xab32
,
0xcd45
});
checkList
(
root
.
getObjectField
<
List
<
uint32_t
>>
(),
{
0x17595612u
,
0x29347823u
,
0x5923ab32u
,
0x1a39cd45u
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
checkList
(
orig
,
{
0x17595612u
,
0x29347823u
,
0x5923ab32u
,
0x1a39cd45u
});
checkUpgradedList
(
root
,
{
0x17595612
,
0x29347823
,
0x5923ab32
,
0x1a39cd45
},
{
""
,
""
,
""
,
""
});
...
...
@@ -1038,7 +1046,7 @@ TEST(Encoding, UpgradeListInBuilder) {
checkList
(
root
.
getObjectField
<
List
<
uint16_t
>>
(),
{
0xfe21
,
0xaf36
});
checkList
(
root
.
getObjectField
<
List
<
uint32_t
>>
(),
{
0x8735fe21u
,
0x1923af36u
});
checkList
(
root
.
getObjectField
<
List
<
uint64_t
>>
(),
{
0x1234abcd8735fe21ull
,
0x7173bc0e1923af36ull
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
checkList
(
orig
,
{
0x1234abcd8735fe21ull
,
0x7173bc0e1923af36ull
});
checkUpgradedList
(
root
,
{
0x1234abcd8735fe21ull
,
0x7173bc0e1923af36ull
},
{
""
,
""
});
...
...
@@ -1051,11 +1059,11 @@ TEST(Encoding, UpgradeListInBuilder) {
root
.
setObjectField
<
List
<
Text
>>
({
"foo"
,
"bar"
,
"baz"
});
auto
orig
=
root
.
asReader
().
getObjectField
<
List
<
Text
>>
();
checkList
(
root
.
getObjectField
<
List
<
Void
>>
(),
{
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
bool
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint8_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
bool
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint8_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
checkList
(
root
.
getObjectField
<
List
<
Text
>>
(),
{
"foo"
,
"bar"
,
"baz"
});
checkList
(
orig
,
{
"foo"
,
"bar"
,
"baz"
});
...
...
@@ -1117,9 +1125,9 @@ TEST(Encoding, UpgradeListInBuilder) {
}
checkList
(
root
.
getObjectField
<
List
<
bool
>>
(),
{
true
,
true
,
false
,
false
});
checkList
(
root
.
getObjectField
<
List
<
uint16_t
>>
(),
{
12573u
,
3251u
,
9238u
,
5832u
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
// Upgrade from multi-byte, sub-word data.
root
.
setObjectField
<
List
<
uint16_t
>>
({
12u
,
34u
,
56u
,
78u
});
...
...
@@ -1143,8 +1151,8 @@ TEST(Encoding, UpgradeListInBuilder) {
checkList
(
root
.
getObjectField
<
List
<
uint16_t
>>
(),
{
0x1235u
,
0x2879u
,
0x3082u
,
0x8948u
});
checkList
(
root
.
getObjectField
<
List
<
uint32_t
>>
(),
{
0x65ac1235u
,
0x13f12879u
,
0x33423082u
,
0x12988948u
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
// Upgrade from void -> data struct
root
.
setObjectField
<
List
<
Void
>>
({
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
...
...
@@ -1162,9 +1170,9 @@ TEST(Encoding, UpgradeListInBuilder) {
}
checkList
(
root
.
getObjectField
<
List
<
bool
>>
(),
{
true
,
true
,
false
,
false
});
checkList
(
root
.
getObjectField
<
List
<
uint16_t
>>
(),
{
12573u
,
3251u
,
9238u
,
5832u
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
// Upgrade from void -> pointer struct
root
.
setObjectField
<
List
<
Void
>>
({
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
,
Void
::
VOID
});
...
...
@@ -1180,18 +1188,18 @@ TEST(Encoding, UpgradeListInBuilder) {
l
[
2
].
setF
(
"baz"
);
l
[
3
].
setF
(
"qux"
);
}
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
bool
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
bool
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint16_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint32_t
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
uint64_t
>>
());
checkList
(
root
.
getObjectField
<
List
<
Text
>>
(),
{
"foo"
,
"bar"
,
"baz"
,
"qux"
});
// Verify that we cannot "side-grade" a pointer list to a data struct list, or a data list to
// a pointer struct list.
root
.
setObjectField
<
List
<
Text
>>
({
"foo"
,
"bar"
,
"baz"
,
"qux"
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
test
::
TestLists
::
Struct32
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
test
::
TestLists
::
Struct32
>>
());
root
.
setObjectField
<
List
<
uint32_t
>>
({
12
,
34
,
56
,
78
});
EXPECT_
ANY_THROW
(
root
.
getObjectField
<
List
<
Text
>>
());
EXPECT_
NONFATAL_FAILURE
(
root
.
getObjectField
<
List
<
Text
>>
());
}
// =======================================================================================
...
...
c++/src/capnp/schema-loader-test.c++
View file @
1ac3accc
...
...
@@ -56,6 +56,14 @@ TEST(SchemaLoader, Load) {
EXPECT_EQ
(
0u
,
struct16Schema
.
getProto
().
getBody
().
getStructNode
().
getMembers
().
size
());
}
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
#define EXPECT_NONFATAL_FAILURE(code) code
#else
#define EXPECT_NONFATAL_FAILURE EXPECT_ANY_THROW
#endif
TEST
(
SchemaLoader
,
Use
)
{
SchemaLoader
loader
;
...
...
@@ -196,7 +204,7 @@ TEST(SchemaLoader, Downgrade) {
TEST
(
SchemaLoader
,
Incompatible
)
{
SchemaLoader
loader
;
loader
.
loadCompiledTypeAndDependencies
<
test
::
TestListDefaults
>
();
EXPECT_
ANY_THROW
(
EXPECT_
NONFATAL_FAILURE
(
loadUnderAlternateTypeId
<
test
::
TestAllTypes
>
(
loader
,
typeId
<
test
::
TestListDefaults
>
()));
}
...
...
c++/src/capnp/schema-test.c++
View file @
1ac3accc
...
...
@@ -52,6 +52,11 @@ namespace capnp {
namespace
_
{
// private
namespace
{
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
#endif
TEST
(
Schema
,
Structs
)
{
StructSchema
schema
=
Schema
::
from
<
TestAllTypes
>
();
...
...
c++/src/kj/array-test.c++
View file @
1ac3accc
...
...
@@ -124,6 +124,7 @@ TEST(Array, ComplexConstructor) {
EXPECT_EQ
(
0
,
TestObject
::
count
);
}
#if !KJ_NO_EXCEPTIONS
TEST
(
Array
,
ThrowingConstructor
)
{
TestObject
::
count
=
0
;
TestObject
::
throwAt
=
16
;
...
...
@@ -145,6 +146,7 @@ TEST(Array, ThrowingDestructor) {
EXPECT_ANY_THROW
(
array
=
nullptr
);
EXPECT_EQ
(
0
,
TestObject
::
count
);
}
#endif // !KJ_NO_EXCEPTIONS
TEST
(
Array
,
AraryBuilder
)
{
TestObject
::
count
=
0
;
...
...
@@ -260,6 +262,7 @@ TEST(Array, AraryBuilderAddAll) {
EXPECT_EQ
(
0
,
TestObject
::
count
);
EXPECT_EQ
(
0
,
TestObject
::
copiedCount
);
#if !KJ_NO_EXCEPTIONS
{
// Complex case, exceptions occur.
TestObject
::
count
=
0
;
...
...
@@ -283,6 +286,7 @@ TEST(Array, AraryBuilderAddAll) {
}
EXPECT_EQ
(
0
,
TestObject
::
count
);
EXPECT_EQ
(
0
,
TestObject
::
copiedCount
);
#endif // !KJ_NO_EXCEPTIONS
}
TEST
(
Array
,
HeapCopy
)
{
...
...
c++/src/kj/common-test.c++
View file @
1ac3accc
...
...
@@ -204,8 +204,14 @@ TEST(Common, Downcast) {
EXPECT_EQ
(
&
bar
,
&
downcast
<
Bar
>
(
foo
));
#if !defined(NDEBUG) && !KJ_NO_RTTI
#if KJ_NO_EXCEPTIONS
#ifndef NDEBUG
EXPECT_DEATH_IF_SUPPORTED
(
downcast
<
Baz
>
(
foo
),
"Value cannot be downcast"
);
#endif
#else
EXPECT_ANY_THROW
(
downcast
<
Baz
>
(
foo
));
#endif
#endif
#if KJ_NO_RTTI
EXPECT_TRUE
(
dynamicDowncastIfAvailable
<
Bar
>
(
foo
)
==
nullptr
);
...
...
c++/src/kj/debug-test.c++
View file @
1ac3accc
...
...
@@ -27,6 +27,7 @@
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <exception>
...
...
@@ -43,6 +44,83 @@ public:
std
::
string
text
;
int
outputPipe
=
-
1
;
bool
forkForDeathTest
()
{
// This is called when exceptions are disabled. We fork the process instead and then expect
// the child to die.
int
pipeFds
[
2
];
pipe
(
pipeFds
);
pid_t
child
=
fork
();
if
(
child
==
0
)
{
// This is the child!
close
(
pipeFds
[
0
]);
outputPipe
=
pipeFds
[
1
];
return
true
;
}
else
{
close
(
pipeFds
[
1
]);
// Read child error messages into our local buffer.
char
buf
[
1024
];
for
(;;)
{
ssize_t
n
=
read
(
pipeFds
[
0
],
buf
,
sizeof
(
buf
));
if
(
n
<
0
)
{
if
(
errno
==
EINTR
)
{
continue
;
}
else
{
break
;
}
}
else
if
(
n
==
0
)
{
break
;
}
else
{
text
.
append
(
buf
,
n
);
}
}
close
(
pipeFds
[
0
]);
// Get exit status.
int
status
;
do
{
if
(
waitpid
(
child
,
&
status
,
0
)
<
0
)
{
if
(
errno
==
EINTR
)
{
continue
;
}
else
{
ADD_FAILURE
()
<<
"waidpid: "
<<
strerror
(
errno
);
return
false
;
}
}
}
while
(
false
);
EXPECT_TRUE
(
WIFEXITED
(
status
));
EXPECT_EQ
(
74
,
WEXITSTATUS
(
status
));
return
false
;
}
}
void
flush
()
{
if
(
outputPipe
!=
-
1
)
{
const
char
*
pos
=
&*
text
.
begin
();
const
char
*
end
=
pos
+
text
.
size
();
while
(
pos
<
end
)
{
ssize_t
n
=
write
(
outputPipe
,
pos
,
end
-
pos
);
if
(
n
<
0
)
{
if
(
errno
==
EINTR
)
{
continue
;
}
else
{
break
;
// Give up on error.
}
}
pos
+=
n
;
}
text
.
clear
();
}
}
void
onRecoverableException
(
Exception
&&
exception
)
override
{
text
+=
"recoverable exception: "
;
auto
what
=
str
(
exception
);
...
...
@@ -54,6 +132,7 @@ public:
text
.
append
(
what
.
cStr
(),
end
);
}
text
+=
'\n'
;
flush
();
}
void
onFatalException
(
Exception
&&
exception
)
override
{
...
...
@@ -67,7 +146,17 @@ public:
text
.
append
(
what
.
cStr
(),
end
);
}
text
+=
'\n'
;
flush
();
#if KJ_NO_EXCEPTIONS
if
(
outputPipe
>=
0
)
{
// This is a child process. We got what we want, now exit quickly without writing any
// additional messages, with a status code that the parent will interpret as "exited in the
// way we expected".
_exit
(
74
);
}
#else
throw
MockException
();
#endif
}
void
logMessage
(
const
char
*
file
,
int
line
,
int
contextDepth
,
String
&&
text
)
override
{
...
...
@@ -77,6 +166,12 @@ public:
}
};
#if KJ_NO_EXCEPTIONS
#define EXPECT_FATAL(code) if (mockCallback.forkForDeathTest()) { code; abort(); }
#else
#define EXPECT_FATAL(code) EXPECT_THROW(code, MockException);
#endif
std
::
string
fileLine
(
std
::
string
file
,
int
line
)
{
file
+=
':'
;
char
buffer
[
32
];
...
...
@@ -123,7 +218,7 @@ TEST(Debug, Log) {
Debug
::
setLogLevel
(
Debug
::
Severity
::
WARNING
);
KJ_ASSERT
(
1
==
1
);
EXPECT_
THROW
(
KJ_ASSERT
(
1
==
2
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_ASSERT
(
1
==
2
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": bug in code: expected "
"1 == 2
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
...
...
@@ -140,17 +235,17 @@ TEST(Debug, Log) {
EXPECT_TRUE
(
recovered
);
mockCallback
.
text
.
clear
();
EXPECT_
THROW
(
KJ_ASSERT
(
1
==
2
,
i
,
"hi"
,
str
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_ASSERT
(
1
==
2
,
i
,
"hi"
,
str
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": bug in code: expected "
"1 == 2; i = 123; hi; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_
THROW
(
KJ_REQUIRE
(
1
==
2
,
i
,
"hi"
,
str
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_REQUIRE
(
1
==
2
,
i
,
"hi"
,
str
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": requirement not met: expected "
"1 == 2; i = 123; hi; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_
THROW
(
KJ_FAIL_ASSERT
(
"foo"
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_FAIL_ASSERT
(
"foo"
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": bug in code: foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
...
...
@@ -159,28 +254,47 @@ TEST(Debug, Log) {
TEST
(
Debug
,
Catch
)
{
int
line
;
// Catch as kj::Exception.
Maybe
<
Exception
>
exception
=
kj
::
runCatchingExceptions
([
&
](){
line
=
__LINE__
;
KJ_FAIL_ASSERT
(
"foo"
);
});
KJ_IF_MAYBE
(
e
,
exception
)
{
String
what
=
str
(
*
e
);
std
::
string
text
(
what
.
cStr
(),
strchr
(
what
.
cStr
(),
'\n'
)
-
what
.
cStr
());
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
": bug in code: foo"
,
text
);
}
else
{
ADD_FAILURE
()
<<
"Expected exception."
;
{
// Catch recoverable as kj::Exception.
Maybe
<
Exception
>
exception
=
kj
::
runCatchingExceptions
([
&
](){
line
=
__LINE__
;
KJ_FAIL_ASSERT
(
"foo"
)
{
break
;
}
});
KJ_IF_MAYBE
(
e
,
exception
)
{
String
what
=
str
(
*
e
);
std
::
string
text
(
what
.
cStr
(),
strchr
(
what
.
cStr
(),
'\n'
)
-
what
.
cStr
());
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
": bug in code: foo"
,
text
);
}
else
{
ADD_FAILURE
()
<<
"Expected exception."
;
}
}
#if !KJ_NO_EXCEPTIONS
// Catch as std::exception.
try
{
line
=
__LINE__
;
KJ_FAIL_ASSERT
(
"foo"
);
ADD_FAILURE
()
<<
"Expected exception."
;
}
catch
(
const
std
::
exception
&
e
)
{
const
char
*
what
=
e
.
what
();
std
::
string
text
(
what
,
strchr
(
what
,
'\n'
)
-
what
);
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
": bug in code: foo"
,
text
);
{
// Catch fatal as kj::Exception.
Maybe
<
Exception
>
exception
=
kj
::
runCatchingExceptions
([
&
](){
line
=
__LINE__
;
KJ_FAIL_ASSERT
(
"foo"
);
});
KJ_IF_MAYBE
(
e
,
exception
)
{
String
what
=
str
(
*
e
);
std
::
string
text
(
what
.
cStr
(),
strchr
(
what
.
cStr
(),
'\n'
)
-
what
.
cStr
());
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
": bug in code: foo"
,
text
);
}
else
{
ADD_FAILURE
()
<<
"Expected exception."
;
}
}
{
// Catch as std::exception.
try
{
line
=
__LINE__
;
KJ_FAIL_ASSERT
(
"foo"
);
ADD_FAILURE
()
<<
"Expected exception."
;
}
catch
(
const
std
::
exception
&
e
)
{
const
char
*
what
=
e
.
what
();
std
::
string
text
(
what
,
strchr
(
what
,
'\n'
)
-
what
);
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
": bug in code: foo"
,
text
);
}
}
#endif
}
...
...
@@ -195,7 +309,7 @@ TEST(Debug, Syscall) {
int
fd
;
KJ_SYSCALL
(
fd
=
dup
(
STDIN_FILENO
));
KJ_SYSCALL
(
close
(
fd
));
EXPECT_
THROW
(
KJ_SYSCALL
(
close
(
fd
),
i
,
"bar"
,
str
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_SYSCALL
(
close
(
fd
),
i
,
"bar"
,
str
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": error from OS: close(fd): "
+
strerror
(
EBADF
)
+
"; i = 123; bar; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
...
...
@@ -221,7 +335,7 @@ TEST(Debug, Context) {
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_
THROW
(
KJ_FAIL_ASSERT
(
"bar"
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_FAIL_ASSERT
(
"bar"
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
cline
)
+
": context: foo
\n
"
+
fileLine
(
__FILE__
,
line
)
+
": bug in code: bar
\n
"
,
mockCallback
.
text
);
...
...
@@ -231,7 +345,7 @@ TEST(Debug, Context) {
int
i
=
123
;
const
char
*
str
=
"qux"
;
KJ_CONTEXT
(
"baz"
,
i
,
"corge"
,
str
);
int
cline2
=
__LINE__
;
EXPECT_
THROW
(
KJ_FAIL_ASSERT
(
"bar"
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_FAIL_ASSERT
(
"bar"
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
cline
)
+
": context: foo
\n
"
+
fileLine
(
__FILE__
,
cline2
)
+
": context: baz; i = 123; corge; str = qux
\n
"
...
...
@@ -242,7 +356,7 @@ TEST(Debug, Context) {
{
KJ_CONTEXT
(
"grault"
);
int
cline2
=
__LINE__
;
EXPECT_
THROW
(
KJ_FAIL_ASSERT
(
"bar"
),
MockException
);
line
=
__LINE__
;
EXPECT_
FATAL
(
KJ_FAIL_ASSERT
(
"bar"
)
);
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
cline
)
+
": context: foo
\n
"
+
fileLine
(
__FILE__
,
cline2
)
+
": context: grault
\n
"
...
...
c++/src/kj/exception-test.c++
View file @
1ac3accc
...
...
@@ -88,7 +88,11 @@ TEST(Exception, UnwindDetector) {
}
TEST
(
Exception
,
ExceptionCallbackMustBeOnStack
)
{
#if KJ_NO_EXCEPTIONS
EXPECT_DEATH_IF_SUPPORTED
(
new
ExceptionCallback
,
"must be allocated on the stack"
);
#else
EXPECT_ANY_THROW
(
new
ExceptionCallback
);
#endif
}
}
// namespace
...
...
c++/src/kj/exception.c++
View file @
1ac3accc
...
...
@@ -348,7 +348,7 @@ private:
getExceptionCallback
().
logMessage
(
e
.
getFile
(),
e
.
getLine
(),
0
,
str
(
e
.
getNature
(),
e
.
getDurability
()
==
Exception
::
Durability
::
TEMPORARY
?
" (temporary)"
:
""
,
e
.
getDescription
()
==
nullptr
?
""
:
": "
,
e
.
getDescription
(),
"
\n
stack: "
,
strArray
(
e
.
getStackTrace
(),
" "
)));
"
\n
stack: "
,
strArray
(
e
.
getStackTrace
(),
" "
)
,
"
\n
"
));
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment