1 /* 2 Copyright (c) 2020-2021 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 #if __INTEL_COMPILER && _MSC_VER 18 #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated 19 #endif 20 21 #include "common/test.h" 22 23 #include "common/utils.h" 24 #include "common/graph_utils.h" 25 26 #include "oneapi/tbb/flow_graph.h" 27 #include "oneapi/tbb/task_arena.h" 28 #include "oneapi/tbb/global_control.h" 29 30 #include "conformance_flowgraph.h" 31 32 //! \file conformance_priority_queue_node.cpp 33 //! \brief Test for [flow_graph.priority_queue_node] specification 34 35 /* 36 TODO: implement missing conformance tests for priority_queue_node: 37 - [ ] Explicit test that `size_type' is defined and accessible. 38 - [ ] The copy constructor and copy assignment are called for the node's type template parameter. 39 - [ ] Check `Compare' type requirements from [alg.sorting] ISO C++. 40 - [ ] Write tests for the constructors. 41 - [ ] Based on the reconsideration of the `try_put()' and `try_get()' methods, rethink the testing of these methods. - [ ] Improve `test_buffering' by checking that additional `try_get()' does not receive the same 42 value. 43 */ 44 45 template<typename T> 46 void test_inheritance(){ 47 using namespace oneapi::tbb::flow; 48 49 CHECK_MESSAGE( (std::is_base_of<graph_node, priority_queue_node<T>>::value), "priority_queue_node should be derived from graph_node"); 50 CHECK_MESSAGE( (std::is_base_of<receiver<T>, priority_queue_node<T>>::value), "priority_queue_node should be derived from receiver<T>"); 51 CHECK_MESSAGE( (std::is_base_of<sender<T>, priority_queue_node<T>>::value), "priority_queue_node should be derived from sender<T>"); 52 } 53 54 void test_copies(){ 55 using namespace oneapi::tbb::flow; 56 57 graph g; 58 priority_queue_node<int> n(g); 59 priority_queue_node<int> n2(n); 60 61 } 62 63 void test_buffering(){ 64 oneapi::tbb::flow::graph g; 65 66 oneapi::tbb::flow::priority_queue_node<int> node(g); 67 oneapi::tbb::flow::limiter_node<int> rejecter(g, 0); 68 69 oneapi::tbb::flow::make_edge(node, rejecter); 70 node.try_put(1); 71 g.wait_for_all(); 72 73 int tmp = -1; 74 CHECK_MESSAGE( (node.try_get(tmp) == true), "try_get after rejection should succeed"); 75 CHECK_MESSAGE( (tmp == 1), "try_get after rejection should set value"); 76 } 77 78 void test_forwarding(){ 79 oneapi::tbb::flow::graph g; 80 81 oneapi::tbb::flow::priority_queue_node<int> node1(g); 82 test_push_receiver<int> node2(g); 83 test_push_receiver<int> node3(g); 84 85 oneapi::tbb::flow::make_edge(node1, node2); 86 oneapi::tbb::flow::make_edge(node1, node3); 87 88 node1.try_put(1); 89 g.wait_for_all(); 90 91 int c2 = get_count(node2), c3 = get_count(node3); 92 CHECK_MESSAGE( (c2 != c3 ), "Only one descendant the node needs to receive"); 93 CHECK_MESSAGE( (c2 + c3 == 1 ), "All messages need to be received"); 94 } 95 96 void test_behavior(){ 97 oneapi::tbb::flow::graph g; 98 99 oneapi::tbb::flow::priority_queue_node<int, std::greater<int>> node(g); 100 101 node.try_put(2); 102 node.try_put(3); 103 node.try_put(1); 104 g.wait_for_all(); 105 106 int tmp = -1; 107 CHECK_MESSAGE( (node.try_get(tmp)), "Get should succeed"); 108 CHECK_MESSAGE( (tmp == 1), "Values should get sorted"); 109 CHECK_MESSAGE( (node.try_get(tmp)), "Get should succeed"); 110 CHECK_MESSAGE( (tmp == 2), "Values should get sorted"); 111 CHECK_MESSAGE( (node.try_get(tmp)), "Get should succeed"); 112 CHECK_MESSAGE( (tmp == 3), "Values should get sorted"); 113 } 114 115 //! Test priority_queue_node messages 116 //! \brief \ref requirement 117 TEST_CASE("priority_queue_node messages"){ 118 test_behavior(); 119 } 120 121 //! Test priority_queue_node single-push 122 //! \brief \ref requirement 123 TEST_CASE("priority_queue_node single-push"){ 124 test_forwarding(); 125 } 126 127 //! Test priority_queue_node buffering 128 //! \brief \ref requirement 129 TEST_CASE("priority_queue_node buffering"){ 130 test_buffering(); 131 } 132 133 //! Test copy constructor 134 //! \brief \ref interface 135 TEST_CASE("priority_queue_node copy constructor"){ 136 test_copies(); 137 } 138 139 //! Test inheritance relations 140 //! \brief \ref interface 141 TEST_CASE("priority_queue_node superclasses"){ 142 test_inheritance<int>(); 143 test_inheritance<void*>(); 144 } 145 146