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