OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 30 matching lines...) Expand all Loading... |
41 // The definition of the request structure from child_port.h isn’t available | 41 // The definition of the request structure from child_port.h isn’t available |
42 // here. It needs custom initialization code, so duplicate the expected | 42 // here. It needs custom initialization code, so duplicate the expected |
43 // definition of the structure from child_port.h here in this file, and provide | 43 // definition of the structure from child_port.h here in this file, and provide |
44 // the initialization code as a method in true object-oriented fashion. | 44 // the initialization code as a method in true object-oriented fashion. |
45 | 45 |
46 struct __attribute__((packed, aligned(4))) ChildPortCheckInRequest { | 46 struct __attribute__((packed, aligned(4))) ChildPortCheckInRequest { |
47 ChildPortCheckInRequest() { | 47 ChildPortCheckInRequest() { |
48 memset(this, 0xa5, sizeof(*this)); | 48 memset(this, 0xa5, sizeof(*this)); |
49 Head.msgh_bits = | 49 Head.msgh_bits = |
50 MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND) | MACH_MSGH_BITS_COMPLEX; | 50 MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND) | MACH_MSGH_BITS_COMPLEX; |
51 Head.msgh_size = sizeof(*this); | 51 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
52 Head.msgh_remote_port = MACH_PORT_NULL; | 52 Head.msgh_remote_port = MACH_PORT_NULL; |
53 Head.msgh_local_port = kServerLocalPort; | 53 Head.msgh_local_port = kServerLocalPort; |
54 Head.msgh_id = 10011; | 54 Head.msgh_id = 10011; |
55 msgh_body.msgh_descriptor_count = 1; | 55 msgh_body.msgh_descriptor_count = 1; |
56 port.name = kCheckInPort; | 56 port.name = kCheckInPort; |
57 port.disposition = kCheckInPortRightType; | 57 port.disposition = kCheckInPortRightType; |
58 port.type = MACH_MSG_PORT_DESCRIPTOR; | 58 port.type = MACH_MSG_PORT_DESCRIPTOR; |
59 NDR = NDR_record; | 59 NDR = NDR_record; |
60 token = kCheckInToken; | 60 token = kCheckInToken; |
61 } | 61 } |
62 | 62 |
63 mach_msg_header_t Head; | 63 mach_msg_header_t Head; |
64 mach_msg_body_t msgh_body; | 64 mach_msg_body_t msgh_body; |
65 mach_msg_port_descriptor_t port; | 65 mach_msg_port_descriptor_t port; |
66 NDR_record_t NDR; | 66 NDR_record_t NDR; |
67 child_port_token_t token; | 67 child_port_token_t token; |
| 68 mach_msg_trailer_t trailer; |
68 }; | 69 }; |
69 | 70 |
70 struct MIGReply : public mig_reply_error_t { | 71 struct MIGReply : public mig_reply_error_t { |
71 MIGReply() { | 72 MIGReply() { |
72 memset(this, 0x5a, sizeof(*this)); | 73 memset(this, 0x5a, sizeof(*this)); |
73 RetCode = KERN_FAILURE; | 74 RetCode = KERN_FAILURE; |
74 } | 75 } |
75 | 76 |
76 void Verify() { | 77 void Verify() { |
77 EXPECT_EQ(implicit_cast<mach_msg_bits_t>(MACH_MSGH_BITS(0, 0)), | 78 EXPECT_EQ(implicit_cast<mach_msg_bits_t>(MACH_MSGH_BITS(0, 0)), |
78 Head.msgh_bits); | 79 Head.msgh_bits); |
79 EXPECT_EQ(sizeof(*this), Head.msgh_size); | 80 EXPECT_EQ(sizeof(*this), Head.msgh_size); |
80 EXPECT_EQ(kMachPortNull, Head.msgh_remote_port); | 81 EXPECT_EQ(kMachPortNull, Head.msgh_remote_port); |
81 EXPECT_EQ(kMachPortNull, Head.msgh_local_port); | 82 EXPECT_EQ(kMachPortNull, Head.msgh_local_port); |
82 EXPECT_EQ(10111, Head.msgh_id); | 83 EXPECT_EQ(10111, Head.msgh_id); |
83 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); | 84 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); |
84 EXPECT_EQ(MIG_NO_REPLY, RetCode); | 85 EXPECT_EQ(MIG_NO_REPLY, RetCode); |
85 } | 86 } |
86 }; | 87 }; |
87 | 88 |
88 class MockChildPortServerInterface : public ChildPortServer::Interface { | 89 class MockChildPortServerInterface : public ChildPortServer::Interface { |
89 public: | 90 public: |
90 MOCK_METHOD5(HandleChildPortCheckIn, | 91 MOCK_METHOD6(HandleChildPortCheckIn, |
91 kern_return_t(child_port_server_t server, | 92 kern_return_t(child_port_server_t server, |
92 const child_port_token_t token, | 93 const child_port_token_t token, |
93 mach_port_t port, | 94 mach_port_t port, |
94 mach_msg_type_name_t right_type, | 95 mach_msg_type_name_t right_type, |
| 96 const mach_msg_trailer_t* trailer, |
95 bool* destroy_complex_request)); | 97 bool* destroy_complex_request)); |
96 }; | 98 }; |
97 | 99 |
98 TEST(ChildPortServer, MockChildPortCheckIn) { | 100 TEST(ChildPortServer, MockChildPortCheckIn) { |
99 MockChildPortServerInterface server_interface; | 101 MockChildPortServerInterface server_interface; |
100 ChildPortServer server(&server_interface); | 102 ChildPortServer server(&server_interface); |
101 | 103 |
102 ChildPortCheckInRequest request; | 104 ChildPortCheckInRequest request; |
103 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 105 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
104 | 106 |
105 MIGReply reply; | 107 MIGReply reply; |
106 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 108 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
107 | 109 |
108 EXPECT_CALL(server_interface, | 110 EXPECT_CALL(server_interface, |
109 HandleChildPortCheckIn(kServerLocalPort, | 111 HandleChildPortCheckIn(kServerLocalPort, |
110 kCheckInToken, | 112 kCheckInToken, |
111 kCheckInPort, | 113 kCheckInPort, |
112 kCheckInPortRightType, | 114 kCheckInPortRightType, |
| 115 Eq(&request.trailer), |
113 Pointee(Eq(false)))) | 116 Pointee(Eq(false)))) |
114 .WillOnce(Return(MIG_NO_REPLY)) | 117 .WillOnce(Return(MIG_NO_REPLY)) |
115 .RetiresOnSaturation(); | 118 .RetiresOnSaturation(); |
116 | 119 |
117 bool destroy_complex_request = false; | 120 bool destroy_complex_request = false; |
118 EXPECT_TRUE(server.MachMessageServerFunction( | 121 EXPECT_TRUE(server.MachMessageServerFunction( |
119 reinterpret_cast<mach_msg_header_t*>(&request), | 122 reinterpret_cast<mach_msg_header_t*>(&request), |
120 reinterpret_cast<mach_msg_header_t*>(&reply), | 123 reinterpret_cast<mach_msg_header_t*>(&reply), |
121 &destroy_complex_request)); | 124 &destroy_complex_request)); |
122 EXPECT_FALSE(destroy_complex_request); | 125 EXPECT_FALSE(destroy_complex_request); |
123 | 126 |
124 reply.Verify(); | 127 reply.Verify(); |
125 } | 128 } |
126 | 129 |
127 } // namespace | 130 } // namespace |
128 } // namespace test | 131 } // namespace test |
129 } // namespace crashpad | 132 } // namespace crashpad |
OLD | NEW |