1 //  Copyright (c) 2007-2014 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <hpx/hpx_init.hpp>
7 #include <hpx/include/lcos.hpp>
8 #include <hpx/include/async.hpp>
9 #include <hpx/include/components.hpp>
10 #include <hpx/util/lightweight_test.hpp>
11 
12 #include <cstddef>
13 #include <set>
14 #include <string>
15 #include <utility>
16 #include <vector>
17 
18 ///////////////////////////////////////////////////////////////////////////////
19 struct test_server
20   : hpx::components::simple_component_base<test_server>
21 {
test_servertest_server22     test_server()
23     {}
24 
calltest_server25     hpx::id_type call() const
26     {
27         return hpx::find_here();
28     }
29     HPX_DEFINE_COMPONENT_ACTION(test_server, call, call_action);
30 };
31 
32 typedef hpx::components::simple_component<test_server> server_type;
33 HPX_REGISTER_COMPONENT(server_type, test_server);
34 
35 typedef test_server::call_action call_action;
36 HPX_REGISTER_ACTION(call_action);
37 
38 struct test_client
39   : hpx::components::client_base<test_client, test_server>
40 {
41     typedef hpx::components::client_base<test_client, test_server>
42         base_type;
43 
test_clienttest_client44     test_client() {}
45 
46     template <typename ... Ts>
test_clienttest_client47     test_client(Ts && ...vs)
48       : base_type(std::forward<Ts>(vs)...)
49     {}
50 
calltest_client51     hpx::id_type call() const { return call_action()(this->get_id()); }
52 };
53 
54 ///////////////////////////////////////////////////////////////////////////////
test_find_all_clients_from_basename()55 void test_find_all_clients_from_basename()
56 {
57     char const* basename = "/find_all_clients_from_prefix_test/";
58 
59     test_client t1 = test_client::create(hpx::find_here());
60 
61     // register our component with AGAS
62     HPX_TEST((hpx::register_with_basename(basename, t1).get()));
63 
64     // wait for all localities to register their component
65     std::vector<hpx::id_type> localities = hpx::find_all_localities();
66 
67     std::vector<test_client> all_clients =
68         hpx::find_all_from_basename<test_client>(basename, localities.size());
69     HPX_TEST_EQ(all_clients.size(), localities.size());
70 
71     // retrieve all component ids
72     std::set<hpx::id_type> component_localities;
73     for (test_client& c : all_clients)
74     {
75         hpx::id_type locality = c.call();
76         std::pair<std::set<hpx::id_type>::iterator, bool> p =
77             component_localities.insert(locality);
78 
79         HPX_TEST(p.second);     // every id should be unique
80     }
81     HPX_TEST_EQ(component_localities.size(), localities.size());
82 
83     // make sure that components are on all localities
84     for (hpx::id_type const& id : localities)
85     {
86         HPX_TEST(component_localities.find(id) != component_localities.end());
87     }
88 }
89 
test_find_clients_from_basename()90 void test_find_clients_from_basename()
91 {
92     char const* basename = "/find_clients_from_prefix_test/";
93 
94     test_client t1 = test_client::create(hpx::find_here());
95 
96     // register our component with AGAS
97     HPX_TEST((hpx::register_with_basename(basename, t1).get()));
98 
99     // wait for all localities to register their component
100     std::vector<hpx::id_type> localities = hpx::find_all_localities();
101 
102     std::vector<std::size_t> sequence_nrs;
103     sequence_nrs.reserve(localities.size());
104     for (hpx::id_type const& locality : localities)
105     {
106         sequence_nrs.push_back(hpx::naming::get_locality_id_from_id(locality));
107     }
108 
109     std::vector<test_client> clients =
110         hpx::find_from_basename<test_client>(basename, sequence_nrs);
111     HPX_TEST_EQ(clients.size(), sequence_nrs.size());
112 
113     // retrieve all component ids
114     std::set<hpx::id_type> component_localities;
115     for (test_client& c : clients)
116     {
117         hpx::id_type locality = c.call();
118         std::pair<std::set<hpx::id_type>::iterator, bool> p =
119             component_localities.insert(locality);
120 
121         HPX_TEST(p.second);     // every id should be unique
122     }
123     HPX_TEST_EQ(component_localities.size(), localities.size());
124 
125     // make sure that components are on all localities
126     for (hpx::id_type const& id : localities)
127     {
128         HPX_TEST(component_localities.find(id) != component_localities.end());
129     }
130 }
131 
test_find_client_from_basename()132 void test_find_client_from_basename()
133 {
134     char const* basename = "/find_client_from_prefix_test/";
135 
136     test_client t1 = test_client::create(hpx::find_here());
137 
138     // register our component with AGAS
139     HPX_TEST((hpx::register_with_basename(basename, t1).get()));
140 
141     // wait for all localities to register their component
142     std::vector<hpx::id_type> localities = hpx::find_all_localities();
143 
144     std::vector<std::size_t> sequence_nrs;
145     std::vector<test_client> clients;
146     sequence_nrs.reserve(localities.size());
147     clients.reserve(localities.size());
148 
149     for (hpx::id_type const& locality : localities)
150     {
151         std::size_t nr = hpx::naming::get_locality_id_from_id(locality);
152         sequence_nrs.push_back(nr);
153         clients.push_back(hpx::find_from_basename<test_client>(basename, nr));
154     }
155 
156     HPX_TEST_EQ(clients.size(), sequence_nrs.size());
157 
158     // retrieve all component ids
159     std::set<hpx::id_type> component_localities;
160     for (test_client& c : clients)
161     {
162         hpx::id_type locality = c.call();
163         std::pair<std::set<hpx::id_type>::iterator, bool> p =
164             component_localities.insert(locality);
165 
166         HPX_TEST(p.second);     // every id should be unique
167     }
168     HPX_TEST_EQ(component_localities.size(), localities.size());
169 
170     // make sure that components are on all localities
171     for (hpx::id_type const& id : localities)
172     {
173         HPX_TEST(component_localities.find(id) != component_localities.end());
174     }
175 }
176 
hpx_main()177 int hpx_main()
178 {
179     test_find_client_from_basename();
180     test_find_clients_from_basename();
181     test_find_all_clients_from_basename();
182     return hpx::finalize();
183 }
184 
main(int argc,char * argv[])185 int main(int argc, char* argv[])
186 {
187     std::vector<std::string> const cfg = {
188         "hpx.run_hpx_main!=1"
189     };
190 
191     // Initialize and run HPX
192     HPX_TEST_EQ_MSG(hpx::init(argc, argv, cfg), 0,
193         "HPX main exited with non-zero status");
194 
195     return hpx::util::report_errors();
196 }
197 
198