1*51c0b2f7Stbbdev /* 2*51c0b2f7Stbbdev Copyright (c) 2020 Intel Corporation 3*51c0b2f7Stbbdev 4*51c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License"); 5*51c0b2f7Stbbdev you may not use this file except in compliance with the License. 6*51c0b2f7Stbbdev You may obtain a copy of the License at 7*51c0b2f7Stbbdev 8*51c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0 9*51c0b2f7Stbbdev 10*51c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software 11*51c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS, 12*51c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*51c0b2f7Stbbdev See the License for the specific language governing permissions and 14*51c0b2f7Stbbdev limitations under the License. 15*51c0b2f7Stbbdev */ 16*51c0b2f7Stbbdev 17*51c0b2f7Stbbdev 18*51c0b2f7Stbbdev #include "common/test.h" 19*51c0b2f7Stbbdev 20*51c0b2f7Stbbdev #include "common/utils.h" 21*51c0b2f7Stbbdev #include "common/graph_utils.h" 22*51c0b2f7Stbbdev 23*51c0b2f7Stbbdev #include "tbb/flow_graph.h" 24*51c0b2f7Stbbdev #include "tbb/task_arena.h" 25*51c0b2f7Stbbdev #include "tbb/global_control.h" 26*51c0b2f7Stbbdev 27*51c0b2f7Stbbdev #include "conformance_flowgraph.h" 28*51c0b2f7Stbbdev 29*51c0b2f7Stbbdev //! \file conformance_queue_node.cpp 30*51c0b2f7Stbbdev //! \brief Test for [flow_graph.queue_node] specification 31*51c0b2f7Stbbdev 32*51c0b2f7Stbbdev /* 33*51c0b2f7Stbbdev TODO: implement missing conformance tests for queue_node: 34*51c0b2f7Stbbdev - [ ] The copy constructor and copy assignment are called for the node's type template parameter. 35*51c0b2f7Stbbdev - [ ] Improve `test_forwarding()'. 36*51c0b2f7Stbbdev - [ ] Improve tests of the constructors. 37*51c0b2f7Stbbdev - [ ] Improve `test_buffering' by checking that additional `try_get()' does not receive the same 38*51c0b2f7Stbbdev value. 39*51c0b2f7Stbbdev - [ ] Based on the decision about the details for `try_put()' and `try_get()' write corresponding 40*51c0b2f7Stbbdev tests. 41*51c0b2f7Stbbdev */ 42*51c0b2f7Stbbdev 43*51c0b2f7Stbbdev template<typename T> 44*51c0b2f7Stbbdev void test_inheritance(){ 45*51c0b2f7Stbbdev using namespace tbb::flow; 46*51c0b2f7Stbbdev 47*51c0b2f7Stbbdev CHECK_MESSAGE( (std::is_base_of<graph_node, queue_node<T>>::value), "queue_node should be derived from graph_node"); 48*51c0b2f7Stbbdev CHECK_MESSAGE( (std::is_base_of<receiver<T>, queue_node<T>>::value), "queue_node should be derived from receiver<T>"); 49*51c0b2f7Stbbdev CHECK_MESSAGE( (std::is_base_of<sender<T>, queue_node<T>>::value), "queue_node should be derived from sender<T>"); 50*51c0b2f7Stbbdev } 51*51c0b2f7Stbbdev 52*51c0b2f7Stbbdev void test_copies(){ 53*51c0b2f7Stbbdev using namespace tbb::flow; 54*51c0b2f7Stbbdev 55*51c0b2f7Stbbdev graph g; 56*51c0b2f7Stbbdev queue_node<int> n(g); 57*51c0b2f7Stbbdev queue_node<int> n2(n); 58*51c0b2f7Stbbdev 59*51c0b2f7Stbbdev } 60*51c0b2f7Stbbdev 61*51c0b2f7Stbbdev void test_buffering(){ 62*51c0b2f7Stbbdev tbb::flow::graph g; 63*51c0b2f7Stbbdev 64*51c0b2f7Stbbdev tbb::flow::queue_node<int> node(g); 65*51c0b2f7Stbbdev tbb::flow::limiter_node<int> rejecter(g, 0); 66*51c0b2f7Stbbdev 67*51c0b2f7Stbbdev tbb::flow::make_edge(node, rejecter); 68*51c0b2f7Stbbdev node.try_put(1); 69*51c0b2f7Stbbdev g.wait_for_all(); 70*51c0b2f7Stbbdev 71*51c0b2f7Stbbdev int tmp = -1; 72*51c0b2f7Stbbdev CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get after rejection should succeed"); 73*51c0b2f7Stbbdev CHECK_MESSAGE( (tmp == 1), "try_get after rejection should set value"); 74*51c0b2f7Stbbdev } 75*51c0b2f7Stbbdev 76*51c0b2f7Stbbdev void test_forwarding(){ 77*51c0b2f7Stbbdev tbb::flow::graph g; 78*51c0b2f7Stbbdev 79*51c0b2f7Stbbdev tbb::flow::queue_node<int> node1(g); 80*51c0b2f7Stbbdev test_push_receiver<int> node2(g); 81*51c0b2f7Stbbdev test_push_receiver<int> node3(g); 82*51c0b2f7Stbbdev 83*51c0b2f7Stbbdev tbb::flow::make_edge(node1, node2); 84*51c0b2f7Stbbdev tbb::flow::make_edge(node1, node3); 85*51c0b2f7Stbbdev 86*51c0b2f7Stbbdev node1.try_put(1); 87*51c0b2f7Stbbdev g.wait_for_all(); 88*51c0b2f7Stbbdev 89*51c0b2f7Stbbdev int c2 = get_count(node2), c3 = get_count(node3); 90*51c0b2f7Stbbdev CHECK_MESSAGE( (c2 != c3 ), "Only one descendant the node needs to receive"); 91*51c0b2f7Stbbdev CHECK_MESSAGE( (c2 + c3 == 1 ), "All messages need to be received"); 92*51c0b2f7Stbbdev } 93*51c0b2f7Stbbdev 94*51c0b2f7Stbbdev void test_queue_node(){ 95*51c0b2f7Stbbdev tbb::flow::graph g; 96*51c0b2f7Stbbdev 97*51c0b2f7Stbbdev tbb::flow::queue_node<int> node(g); 98*51c0b2f7Stbbdev node.try_put(1); 99*51c0b2f7Stbbdev node.try_put(2); 100*51c0b2f7Stbbdev g.wait_for_all(); 101*51c0b2f7Stbbdev 102*51c0b2f7Stbbdev int tmp = -1; 103*51c0b2f7Stbbdev CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get should succeed"); 104*51c0b2f7Stbbdev CHECK_MESSAGE( (tmp == 1), "try_get should set correct value"); 105*51c0b2f7Stbbdev 106*51c0b2f7Stbbdev tmp = -1; 107*51c0b2f7Stbbdev CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get should succeed"); 108*51c0b2f7Stbbdev CHECK_MESSAGE( (tmp == 2), "try_get should set correct value"); 109*51c0b2f7Stbbdev } 110*51c0b2f7Stbbdev 111*51c0b2f7Stbbdev void test_double_reserve(){ 112*51c0b2f7Stbbdev tbb::flow::graph g; 113*51c0b2f7Stbbdev 114*51c0b2f7Stbbdev tbb::flow::queue_node<int> node(g); 115*51c0b2f7Stbbdev 116*51c0b2f7Stbbdev int tmp = -1; 117*51c0b2f7Stbbdev node.try_reserve(tmp); 118*51c0b2f7Stbbdev CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 119*51c0b2f7Stbbdev node.try_reserve(tmp); 120*51c0b2f7Stbbdev CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 121*51c0b2f7Stbbdev 122*51c0b2f7Stbbdev g.reset(); 123*51c0b2f7Stbbdev 124*51c0b2f7Stbbdev node.try_reserve(tmp); 125*51c0b2f7Stbbdev CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 126*51c0b2f7Stbbdev node.try_reserve(tmp); 127*51c0b2f7Stbbdev CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 128*51c0b2f7Stbbdev } 129*51c0b2f7Stbbdev 130*51c0b2f7Stbbdev //! Test multiple reserves 131*51c0b2f7Stbbdev //! \brief \ref error_guessing 132*51c0b2f7Stbbdev TEST_CASE("queue_node double reserve"){ 133*51c0b2f7Stbbdev test_double_reserve(); 134*51c0b2f7Stbbdev } 135*51c0b2f7Stbbdev 136*51c0b2f7Stbbdev //! Test message logic 137*51c0b2f7Stbbdev //! \brief \ref requirement 138*51c0b2f7Stbbdev TEST_CASE("queue_node messages"){ 139*51c0b2f7Stbbdev test_queue_node(); 140*51c0b2f7Stbbdev } 141*51c0b2f7Stbbdev 142*51c0b2f7Stbbdev //! Test single-push 143*51c0b2f7Stbbdev //! \brief \ref requirement 144*51c0b2f7Stbbdev TEST_CASE("queue_node buffering"){ 145*51c0b2f7Stbbdev test_forwarding(); 146*51c0b2f7Stbbdev } 147*51c0b2f7Stbbdev 148*51c0b2f7Stbbdev //! Test buffering 149*51c0b2f7Stbbdev //! \brief \ref requirement 150*51c0b2f7Stbbdev TEST_CASE("queue_node buffering"){ 151*51c0b2f7Stbbdev test_buffering(); 152*51c0b2f7Stbbdev } 153*51c0b2f7Stbbdev 154*51c0b2f7Stbbdev //! Test copy constructor 155*51c0b2f7Stbbdev //! \brief \ref interface 156*51c0b2f7Stbbdev TEST_CASE("queue_node copy constructor"){ 157*51c0b2f7Stbbdev test_copies(); 158*51c0b2f7Stbbdev } 159*51c0b2f7Stbbdev 160*51c0b2f7Stbbdev //! Test inheritance relations 161*51c0b2f7Stbbdev //! \brief \ref interface 162*51c0b2f7Stbbdev TEST_CASE("queue_node superclasses"){ 163*51c0b2f7Stbbdev test_inheritance<int>(); 164*51c0b2f7Stbbdev test_inheritance<void*>(); 165*51c0b2f7Stbbdev } 166*51c0b2f7Stbbdev 167