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 "oneapi/tbb/flow_graph.h" 24 #include "oneapi/tbb/task_arena.h" 25 #include "oneapi/tbb/global_control.h" 26 27 #include "conformance_flowgraph.h" 28 29 //! \file conformance_queue_node.cpp 30 //! \brief Test for [flow_graph.queue_node] specification 31 32 /* 33 TODO: implement missing conformance tests for queue_node: 34 - [ ] The copy constructor and copy assignment are called for the node's type template parameter. 35 - [ ] Improve `test_forwarding()'. 36 - [ ] Improve tests of the constructors. 37 - [ ] Improve `test_buffering' by checking that additional `try_get()' does not receive the same 38 value. 39 - [ ] Based on the decision about the details for `try_put()' and `try_get()' write corresponding 40 tests. 41 */ 42 43 template<typename T> 44 void test_inheritance(){ 45 using namespace oneapi::tbb::flow; 46 47 CHECK_MESSAGE( (std::is_base_of<graph_node, queue_node<T>>::value), "queue_node should be derived from graph_node"); 48 CHECK_MESSAGE( (std::is_base_of<receiver<T>, queue_node<T>>::value), "queue_node should be derived from receiver<T>"); 49 CHECK_MESSAGE( (std::is_base_of<sender<T>, queue_node<T>>::value), "queue_node should be derived from sender<T>"); 50 } 51 52 void test_copies(){ 53 using namespace oneapi::tbb::flow; 54 55 graph g; 56 queue_node<int> n(g); 57 queue_node<int> n2(n); 58 59 } 60 61 void test_buffering(){ 62 oneapi::tbb::flow::graph g; 63 64 oneapi::tbb::flow::queue_node<int> node(g); 65 oneapi::tbb::flow::limiter_node<int> rejecter(g, 0); 66 67 oneapi::tbb::flow::make_edge(node, rejecter); 68 node.try_put(1); 69 g.wait_for_all(); 70 71 int tmp = -1; 72 CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get after rejection should succeed"); 73 CHECK_MESSAGE( (tmp == 1), "try_get after rejection should set value"); 74 } 75 76 void test_forwarding(){ 77 oneapi::tbb::flow::graph g; 78 79 oneapi::tbb::flow::queue_node<int> node1(g); 80 test_push_receiver<int> node2(g); 81 test_push_receiver<int> node3(g); 82 83 oneapi::tbb::flow::make_edge(node1, node2); 84 oneapi::tbb::flow::make_edge(node1, node3); 85 86 node1.try_put(1); 87 g.wait_for_all(); 88 89 int c2 = get_count(node2), c3 = get_count(node3); 90 CHECK_MESSAGE( (c2 != c3 ), "Only one descendant the node needs to receive"); 91 CHECK_MESSAGE( (c2 + c3 == 1 ), "All messages need to be received"); 92 } 93 94 void test_queue_node(){ 95 oneapi::tbb::flow::graph g; 96 97 oneapi::tbb::flow::queue_node<int> node(g); 98 node.try_put(1); 99 node.try_put(2); 100 g.wait_for_all(); 101 102 int tmp = -1; 103 CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get should succeed"); 104 CHECK_MESSAGE( (tmp == 1), "try_get should set correct value"); 105 106 tmp = -1; 107 CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get should succeed"); 108 CHECK_MESSAGE( (tmp == 2), "try_get should set correct value"); 109 } 110 111 void test_double_reserve(){ 112 oneapi::tbb::flow::graph g; 113 114 oneapi::tbb::flow::queue_node<int> node(g); 115 116 int tmp = -1; 117 node.try_reserve(tmp); 118 CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 119 node.try_reserve(tmp); 120 CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 121 122 g.reset(); 123 124 node.try_reserve(tmp); 125 CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 126 node.try_reserve(tmp); 127 CHECK_MESSAGE((tmp == -1), "Should not be delivered"); 128 } 129 130 //! Test multiple reserves 131 //! \brief \ref error_guessing 132 TEST_CASE("queue_node double reserve"){ 133 test_double_reserve(); 134 } 135 136 //! Test message logic 137 //! \brief \ref requirement 138 TEST_CASE("queue_node messages"){ 139 test_queue_node(); 140 } 141 142 //! Test single-push 143 //! \brief \ref requirement 144 TEST_CASE("queue_node buffering"){ 145 test_forwarding(); 146 } 147 148 //! Test buffering 149 //! \brief \ref requirement 150 TEST_CASE("queue_node buffering"){ 151 test_buffering(); 152 } 153 154 //! Test copy constructor 155 //! \brief \ref interface 156 TEST_CASE("queue_node copy constructor"){ 157 test_copies(); 158 } 159 160 //! Test inheritance relations 161 //! \brief \ref interface 162 TEST_CASE("queue_node superclasses"){ 163 test_inheritance<int>(); 164 test_inheritance<void*>(); 165 } 166 167