Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (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 | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 | |
| 15 #include "util/mach/child_port_server.h" | |
| 16 | |
| 17 #include <string.h> | |
| 18 | |
| 19 #include "gmock/gmock.h" | |
| 20 #include "gtest/gtest.h" | |
| 21 #include "util/mach/mach_extensions.h" | |
| 22 | |
| 23 namespace crashpad { | |
| 24 namespace test { | |
| 25 namespace { | |
| 26 | |
| 27 using testing::Eq; | |
| 28 using testing::Pointee; | |
| 29 using testing::Return; | |
| 30 | |
| 31 // Fake Mach ports. These aren’t used as ports in these tests, they’re just used | |
| 32 // as cookies to make sure that the correct values get passed to the correct | |
| 33 // places. | |
| 34 const mach_port_t kServerLocalPort = 0x05050505; | |
| 35 const mach_port_t kCheckInPort = 0x06060606; | |
| 36 | |
| 37 // Other fake values. | |
| 38 const mach_msg_type_name_t kCheckInPortRightType = MACH_MSG_TYPE_PORT_SEND; | |
| 39 const child_port_token_t kCheckInToken = 0xfedcba9876543210; | |
| 40 | |
| 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 | |
| 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. | |
| 45 | |
| 46 struct __attribute__((packed, aligned(4))) ChildPortCheckInRequest { | |
| 47 mach_msg_header_t Head; | |
| 48 mach_msg_body_t msgh_body; | |
| 49 mach_msg_port_descriptor_t port; | |
| 50 NDR_record_t NDR; | |
| 51 child_port_token_t token; | |
| 52 | |
| 53 void InitializeForTesting() { | |
|
Robert Sesek
2014/11/25 18:56:51
Just make this the constructor instead?
Mark Mentovai
2014/11/25 19:29:36
Robert Sesek wrote:
| |
| 54 memset(this, 0xa5, sizeof(*this)); | |
| 55 Head.msgh_bits = | |
| 56 MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND) | MACH_MSGH_BITS_COMPLEX; | |
| 57 Head.msgh_size = sizeof(*this); | |
| 58 Head.msgh_remote_port = MACH_PORT_NULL; | |
| 59 Head.msgh_local_port = kServerLocalPort; | |
| 60 Head.msgh_id = 10011; | |
| 61 msgh_body.msgh_descriptor_count = 1; | |
| 62 port.name = kCheckInPort; | |
| 63 port.disposition = kCheckInPortRightType; | |
| 64 port.type = MACH_MSG_PORT_DESCRIPTOR; | |
| 65 NDR = NDR_record; | |
| 66 token = kCheckInToken; | |
| 67 } | |
| 68 }; | |
| 69 | |
| 70 struct __attribute__((packed, aligned(4))) MIGReply { | |
| 71 mach_msg_header_t Head; | |
| 72 NDR_record_t NDR; | |
| 73 kern_return_t RetCode; | |
| 74 | |
| 75 void InitializeForTesting() { | |
| 76 memset(this, 0x5a, sizeof(*this)); | |
| 77 RetCode = KERN_FAILURE; | |
| 78 } | |
| 79 | |
| 80 void Verify() { | |
| 81 EXPECT_EQ(implicit_cast<mach_msg_bits_t>(MACH_MSGH_BITS(0, 0)), | |
| 82 Head.msgh_bits); | |
| 83 EXPECT_EQ(sizeof(*this), Head.msgh_size); | |
| 84 EXPECT_EQ(kMachPortNull, Head.msgh_remote_port); | |
| 85 EXPECT_EQ(kMachPortNull, Head.msgh_local_port); | |
| 86 EXPECT_EQ(10111, Head.msgh_id); | |
| 87 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); | |
| 88 EXPECT_EQ(MIG_NO_REPLY, RetCode); | |
| 89 } | |
| 90 }; | |
| 91 | |
| 92 class MockChildPortServerInterface : public ChildPortServer::Interface { | |
| 93 public: | |
| 94 MOCK_METHOD5(HandleChildPortCheckIn, | |
| 95 kern_return_t(child_port_server_t server, | |
| 96 const child_port_token_t token, | |
| 97 mach_port_t port, | |
| 98 mach_msg_type_name_t right_type, | |
| 99 bool* destroy_complex_request)); | |
| 100 }; | |
| 101 | |
| 102 TEST(ChildPortServer, MockChildPortCheckIn) { | |
|
Mark Mentovai
2014/11/25 17:27:31
I also added this bonus test.
| |
| 103 MockChildPortServerInterface server_interface; | |
| 104 ChildPortServer server(&server_interface); | |
| 105 | |
| 106 ChildPortCheckInRequest request; | |
| 107 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | |
| 108 request.InitializeForTesting(); | |
| 109 | |
| 110 MIGReply reply; | |
| 111 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | |
| 112 reply.InitializeForTesting(); | |
| 113 | |
| 114 EXPECT_CALL(server_interface, | |
| 115 HandleChildPortCheckIn(kServerLocalPort, | |
| 116 kCheckInToken, | |
| 117 kCheckInPort, | |
| 118 kCheckInPortRightType, | |
| 119 Pointee(Eq(false)))) | |
| 120 .WillOnce(Return(MIG_NO_REPLY)) | |
| 121 .RetiresOnSaturation(); | |
| 122 | |
| 123 bool destroy_complex_request = false; | |
| 124 EXPECT_TRUE(server.MachMessageServerFunction( | |
| 125 reinterpret_cast<mach_msg_header_t*>(&request), | |
| 126 reinterpret_cast<mach_msg_header_t*>(&reply), | |
| 127 &destroy_complex_request)); | |
| 128 EXPECT_FALSE(destroy_complex_request); | |
| 129 | |
| 130 reply.Verify(); | |
| 131 } | |
| 132 | |
| 133 } // namespace | |
| 134 } // namespace test | |
| 135 } // namespace crashpad | |
| OLD | NEW |