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