1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include "src/core/lib/iomgr/port.h" 20 21 #include "src/core/lib/iomgr/buffer_list.h" 22 23 #include <grpc/grpc.h> 24 25 #include "test/core/util/test_config.h" 26 27 #ifdef GRPC_LINUX_ERRQUEUE 28 29 static void TestShutdownFlushesListVerifier(void* arg, 30 grpc_core::Timestamps* ts, 31 grpc_error* error) { 32 GPR_ASSERT(error == GRPC_ERROR_NONE); 33 GPR_ASSERT(arg != nullptr); 34 gpr_atm* done = reinterpret_cast<gpr_atm*>(arg); 35 gpr_atm_rel_store(done, static_cast<gpr_atm>(1)); 36 } 37 38 /** Tests that all TracedBuffer elements in the list are flushed out on 39 * shutdown. 40 * Also tests that arg is passed correctly. 41 */ 42 static void TestShutdownFlushesList() { 43 grpc_core::grpc_tcp_set_write_timestamps_callback( 44 TestShutdownFlushesListVerifier); 45 grpc_core::TracedBuffer* list = nullptr; 46 #define NUM_ELEM 5 47 gpr_atm verifier_called[NUM_ELEM]; 48 for (auto i = 0; i < NUM_ELEM; i++) { 49 gpr_atm_rel_store(&verifier_called[i], static_cast<gpr_atm>(0)); 50 grpc_core::TracedBuffer::AddNewEntry( 51 &list, i, static_cast<void*>(&verifier_called[i])); 52 } 53 grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); 54 GPR_ASSERT(list == nullptr); 55 for (auto i = 0; i < NUM_ELEM; i++) { 56 GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == 57 static_cast<gpr_atm>(1)); 58 } 59 } 60 61 static void TestVerifierCalledOnAckVerifier(void* arg, 62 grpc_core::Timestamps* ts, 63 grpc_error* error) { 64 GPR_ASSERT(error == GRPC_ERROR_NONE); 65 GPR_ASSERT(arg != nullptr); 66 GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); 67 GPR_ASSERT(ts->acked_time.tv_sec == 123); 68 GPR_ASSERT(ts->acked_time.tv_nsec == 456); 69 gpr_atm* done = reinterpret_cast<gpr_atm*>(arg); 70 gpr_atm_rel_store(done, static_cast<gpr_atm>(1)); 71 } 72 73 /** Tests that the timestamp verifier is called on an ACK timestamp. 74 */ 75 static void TestVerifierCalledOnAck() { 76 struct sock_extended_err serr; 77 serr.ee_data = 213; 78 serr.ee_info = grpc_core::SCM_TSTAMP_ACK; 79 struct grpc_core::scm_timestamping tss; 80 tss.ts[0].tv_sec = 123; 81 tss.ts[0].tv_nsec = 456; 82 grpc_core::grpc_tcp_set_write_timestamps_callback( 83 TestVerifierCalledOnAckVerifier); 84 grpc_core::TracedBuffer* list = nullptr; 85 gpr_atm verifier_called; 86 gpr_atm_rel_store(&verifier_called, static_cast<gpr_atm>(0)); 87 grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); 88 grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); 89 GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast<gpr_atm>(1)); 90 GPR_ASSERT(list == nullptr); 91 grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); 92 } 93 94 static void TestTcpBufferList() { 95 TestVerifierCalledOnAck(); 96 TestShutdownFlushesList(); 97 } 98 99 int main(int argc, char** argv) { 100 grpc_test_init(argc, argv); 101 grpc_init(); 102 TestTcpBufferList(); 103 grpc_shutdown(); 104 return 0; 105 } 106 107 #else /* GRPC_LINUX_ERRQUEUE */ 108 109 int main(int argc, char** argv) { return 0; } 110 111 #endif /* GRPC_LINUX_ERRQUEUE */ 112