Move rpc_context and test_response classes into their own files. (#4370)
The file nano/rpc_test/common.hpp was very confusing, a lot of stuff was dumped into one file and it was hard to read. This helps break things into more manageable pieces.
This commit is contained in:
		
					parent
					
						
							
								7c7e93166f
							
						
					
				
			
			
				commit
				
					
						5047fc8ccf
					
				
			
		
					 9 changed files with 209 additions and 166 deletions
				
			
		|  | @ -1,4 +1,14 @@ | |||
| add_executable(rpc_test common.hpp common.cpp entry.cpp receivable.cpp rpc.cpp) | ||||
| add_executable( | ||||
|   rpc_test | ||||
|   common.hpp | ||||
|   rpc_context.hpp | ||||
|   test_response.hpp | ||||
|   rpc_context.cpp | ||||
|   test_response.cpp | ||||
|   common.cpp | ||||
|   entry.cpp | ||||
|   receivable.cpp | ||||
|   rpc.cpp) | ||||
| 
 | ||||
| target_link_libraries(rpc_test test_common) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,89 +1,7 @@ | |||
| #include <nano/lib/threading.hpp> | ||||
| #include <nano/node/ipc/ipc_server.hpp> | ||||
| #include <nano/node/transport/tcp.hpp> | ||||
| #include <nano/rpc/rpc_request_processor.hpp> | ||||
| #include <nano/rpc_test/common.hpp> | ||||
| #include <nano/test_common/system.hpp> | ||||
| #include <nano/test_common/testutil.hpp> | ||||
| 
 | ||||
| #include <gtest/gtest.h> | ||||
| 
 | ||||
| #include <boost/property_tree/json_parser.hpp> | ||||
| 
 | ||||
| namespace nano | ||||
| { | ||||
| class rpc; | ||||
| 
 | ||||
| nano::test::test_response::test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a) : | ||||
| 	request (request_a), | ||||
| 	sock (io_ctx_a) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| nano::test::test_response::test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a) : | ||||
| 	request (request_a), | ||||
| 	sock (io_ctx_a) | ||||
| { | ||||
| 	run (port_a); | ||||
| } | ||||
| 
 | ||||
| void nano::test::test_response::run (uint16_t port_a) | ||||
| { | ||||
| 	sock.async_connect (nano::tcp_endpoint (boost::asio::ip::address_v6::loopback (), port_a), [this] (boost::system::error_code const & ec) { | ||||
| 		if (!ec) | ||||
| 		{ | ||||
| 			std::stringstream ostream; | ||||
| 			boost::property_tree::write_json (ostream, request); | ||||
| 			req.method (boost::beast::http::verb::post); | ||||
| 			req.target ("/"); | ||||
| 			req.version (11); | ||||
| 			ostream.flush (); | ||||
| 			req.body () = ostream.str (); | ||||
| 			req.prepare_payload (); | ||||
| 			boost::beast::http::async_write (sock, req, [this] (boost::system::error_code const & ec, size_t bytes_transferred) { | ||||
| 				if (!ec) | ||||
| 				{ | ||||
| 					boost::beast::http::async_read (sock, sb, resp, [this] (boost::system::error_code const & ec, size_t bytes_transferred) { | ||||
| 						if (!ec) | ||||
| 						{ | ||||
| 							std::stringstream body (resp.body ()); | ||||
| 							try | ||||
| 							{ | ||||
| 								boost::property_tree::read_json (body, json); | ||||
| 								status = 200; | ||||
| 							} | ||||
| 							catch (std::exception &) | ||||
| 							{ | ||||
| 								status = 500; | ||||
| 							} | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							status = 400; | ||||
| 						} | ||||
| 					}); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					status = 600; | ||||
| 				} | ||||
| 			}); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			status = 400; | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| nano::test::rpc_context::rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a) | ||||
| { | ||||
| 	rpc = std::move (rpc_a); | ||||
| 	ipc_server = std::move (ipc_server_a); | ||||
| 	ipc_rpc_processor = std::move (ipc_rpc_processor_a); | ||||
| 	node_rpc_config = std::move (node_rpc_config_a); | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<nano::node> nano::test::add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config, nano::node_flags const & node_flags) | ||||
| { | ||||
| 	node_config.ipc_config.transport_tcp.enabled = true; | ||||
|  | @ -111,40 +29,3 @@ void nano::test::reset_confirmation_height (nano::store::component & store, nano | |||
| 		store.confirmation_height.clear (transaction, account); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void nano::test::wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json) | ||||
| { | ||||
| 	test_response response (request, rpc_ctx.rpc->listening_port (), system.io_ctx); | ||||
| 	ASSERT_TIMELY (time, response.status != 0); | ||||
| 	ASSERT_EQ (200, response.status); | ||||
| 	response_json = response.json; | ||||
| } | ||||
| 
 | ||||
| boost::property_tree::ptree nano::test::wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time) | ||||
| { | ||||
| 	boost::property_tree::ptree response_json; | ||||
| 	wait_response_impl (system, rpc_ctx, request, time, response_json); | ||||
| 	return response_json; | ||||
| } | ||||
| 
 | ||||
| bool nano::test::check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count) | ||||
| { | ||||
| 	auto response (wait_response (system, rpc_ctx, request)); | ||||
| 	auto & blocks = response.get_child ("blocks"); | ||||
| 	return size_count == blocks.size (); | ||||
| } | ||||
| 
 | ||||
| nano::test::rpc_context nano::test::add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a) | ||||
| { | ||||
| 	auto node_rpc_config (std::make_unique<nano::node_rpc_config> ()); | ||||
| 	auto ipc_server (std::make_unique<nano::ipc::ipc_server> (*node_a, *node_rpc_config)); | ||||
| 	nano::rpc_config rpc_config (node_a->network_params.network, system.get_available_port (), true); | ||||
| 	const auto ipc_tcp_port = ipc_server->listening_tcp_port (); | ||||
| 	debug_assert (ipc_tcp_port.has_value ()); | ||||
| 	auto ipc_rpc_processor (std::make_unique<nano::ipc_rpc_processor> (system.io_ctx, rpc_config, ipc_tcp_port.value ())); | ||||
| 	auto rpc (std::make_shared<nano::rpc> (system.io_ctx, rpc_config, *ipc_rpc_processor)); | ||||
| 	rpc->start (); | ||||
| 
 | ||||
| 	return rpc_context{ rpc, ipc_server, ipc_rpc_processor, node_rpc_config }; | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1,69 +1,26 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <boost/asio/io_context.hpp> | ||||
| #include <boost/asio/ip/tcp.hpp> | ||||
| #include <boost/beast/core/flat_buffer.hpp> | ||||
| #include <boost/beast/http.hpp> | ||||
| #include <boost/property_tree/ptree.hpp> | ||||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| using namespace std::chrono_literals; | ||||
| 
 | ||||
| namespace nano | ||||
| { | ||||
| class ipc_rpc_processor; | ||||
| class node; | ||||
| class node_config; | ||||
| class node_flags; | ||||
| class node_rpc_config; | ||||
| class public_key; | ||||
| class rpc; | ||||
| using account = public_key; | ||||
| 
 | ||||
| namespace store | ||||
| { | ||||
| 	class component; | ||||
| } | ||||
| 
 | ||||
| using account = public_key; | ||||
| namespace ipc | ||||
| { | ||||
| 	class ipc_server; | ||||
| } | ||||
| namespace test | ||||
| { | ||||
| 	class system; | ||||
| 	class test_response | ||||
| 	{ | ||||
| 	public: | ||||
| 		test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a); | ||||
| 		test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a); | ||||
| 		void run (uint16_t port_a); | ||||
| 		boost::property_tree::ptree const & request; | ||||
| 		boost::asio::ip::tcp::socket sock; | ||||
| 		boost::property_tree::ptree json; | ||||
| 		boost::beast::flat_buffer sb; | ||||
| 		boost::beast::http::request<boost::beast::http::string_body> req; | ||||
| 		boost::beast::http::response<boost::beast::http::string_body> resp; | ||||
| 		std::atomic<int> status{ 0 }; | ||||
| 	}; | ||||
| 	class rpc_context | ||||
| 	{ | ||||
| 	public: | ||||
| 		rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a); | ||||
| 
 | ||||
| 		std::shared_ptr<nano::rpc> rpc; | ||||
| 		std::unique_ptr<nano::ipc::ipc_server> ipc_server; | ||||
| 		std::unique_ptr<nano::ipc_rpc_processor> ipc_rpc_processor; | ||||
| 		std::unique_ptr<nano::node_rpc_config> node_rpc_config; | ||||
| 	}; | ||||
| 
 | ||||
| 	std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config, nano::node_flags const & node_flags); | ||||
| 	std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config); | ||||
| 	std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system); | ||||
| 	void reset_confirmation_height (nano::store::component & store, nano::account const & account); | ||||
| 	void wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json); | ||||
| 	boost::property_tree::ptree wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time = 5s); | ||||
| 	bool check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count); | ||||
| 	rpc_context add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a); | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <nano/node/ipc/ipc_server.hpp> | ||||
| #include <nano/rpc/rpc_request_processor.hpp> | ||||
| #include <nano/rpc_test/common.hpp> | ||||
| #include <nano/rpc_test/rpc_context.hpp> | ||||
| #include <nano/test_common/chains.hpp> | ||||
| #include <nano/test_common/system.hpp> | ||||
| #include <nano/test_common/testutil.hpp> | ||||
|  |  | |||
|  | @ -12,6 +12,8 @@ | |||
| #include <nano/rpc/rpc.hpp> | ||||
| #include <nano/rpc/rpc_request_processor.hpp> | ||||
| #include <nano/rpc_test/common.hpp> | ||||
| #include <nano/rpc_test/rpc_context.hpp> | ||||
| #include <nano/rpc_test/test_response.hpp> | ||||
| #include <nano/test_common/network.hpp> | ||||
| #include <nano/test_common/system.hpp> | ||||
| #include <nano/test_common/telemetry.hpp> | ||||
|  |  | |||
							
								
								
									
										57
									
								
								nano/rpc_test/rpc_context.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								nano/rpc_test/rpc_context.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | |||
| #include <nano/lib/threading.hpp> | ||||
| #include <nano/node/ipc/ipc_server.hpp> | ||||
| #include <nano/node/transport/tcp.hpp> | ||||
| #include <nano/rpc/rpc_request_processor.hpp> | ||||
| #include <nano/rpc_test/common.hpp> | ||||
| #include <nano/rpc_test/rpc_context.hpp> | ||||
| #include <nano/rpc_test/test_response.hpp> | ||||
| #include <nano/test_common/system.hpp> | ||||
| #include <nano/test_common/testutil.hpp> | ||||
| 
 | ||||
| #include <gtest/gtest.h> | ||||
| 
 | ||||
| #include <boost/property_tree/json_parser.hpp> | ||||
| 
 | ||||
| nano::test::rpc_context::rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a) | ||||
| { | ||||
| 	rpc = std::move (rpc_a); | ||||
| 	ipc_server = std::move (ipc_server_a); | ||||
| 	ipc_rpc_processor = std::move (ipc_rpc_processor_a); | ||||
| 	node_rpc_config = std::move (node_rpc_config_a); | ||||
| } | ||||
| 
 | ||||
| void nano::test::wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json) | ||||
| { | ||||
| 	test_response response (request, rpc_ctx.rpc->listening_port (), system.io_ctx); | ||||
| 	ASSERT_TIMELY (time, response.status != 0); | ||||
| 	ASSERT_EQ (200, response.status); | ||||
| 	response_json = response.json; | ||||
| } | ||||
| 
 | ||||
| boost::property_tree::ptree nano::test::wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time) | ||||
| { | ||||
| 	boost::property_tree::ptree response_json; | ||||
| 	wait_response_impl (system, rpc_ctx, request, time, response_json); | ||||
| 	return response_json; | ||||
| } | ||||
| 
 | ||||
| bool nano::test::check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count) | ||||
| { | ||||
| 	auto response (wait_response (system, rpc_ctx, request)); | ||||
| 	auto & blocks = response.get_child ("blocks"); | ||||
| 	return size_count == blocks.size (); | ||||
| } | ||||
| 
 | ||||
| nano::test::rpc_context nano::test::add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a) | ||||
| { | ||||
| 	auto node_rpc_config (std::make_unique<nano::node_rpc_config> ()); | ||||
| 	auto ipc_server (std::make_unique<nano::ipc::ipc_server> (*node_a, *node_rpc_config)); | ||||
| 	nano::rpc_config rpc_config (node_a->network_params.network, system.get_available_port (), true); | ||||
| 	const auto ipc_tcp_port = ipc_server->listening_tcp_port (); | ||||
| 	debug_assert (ipc_tcp_port.has_value ()); | ||||
| 	auto ipc_rpc_processor (std::make_unique<nano::ipc_rpc_processor> (system.io_ctx, rpc_config, ipc_tcp_port.value ())); | ||||
| 	auto rpc (std::make_shared<nano::rpc> (system.io_ctx, rpc_config, *ipc_rpc_processor)); | ||||
| 	rpc->start (); | ||||
| 
 | ||||
| 	return rpc_context{ rpc, ipc_server, ipc_rpc_processor, node_rpc_config }; | ||||
| } | ||||
							
								
								
									
										40
									
								
								nano/rpc_test/rpc_context.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								nano/rpc_test/rpc_context.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <boost/property_tree/ptree.hpp> | ||||
| 
 | ||||
| namespace nano | ||||
| { | ||||
| class ipc_rpc_processor; | ||||
| class node; | ||||
| class node_rpc_config; | ||||
| class public_key; | ||||
| class rpc; | ||||
| using account = public_key; | ||||
| 
 | ||||
| namespace ipc | ||||
| { | ||||
| 	class ipc_server; | ||||
| } | ||||
| 
 | ||||
| namespace test | ||||
| { | ||||
| 	class system; | ||||
| 	class rpc_context | ||||
| 	{ | ||||
| 	public: | ||||
| 		rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a); | ||||
| 
 | ||||
| 		std::shared_ptr<nano::rpc> rpc; | ||||
| 		std::unique_ptr<nano::ipc::ipc_server> ipc_server; | ||||
| 		std::unique_ptr<nano::ipc_rpc_processor> ipc_rpc_processor; | ||||
| 		std::unique_ptr<nano::node_rpc_config> node_rpc_config; | ||||
| 	}; | ||||
| 
 | ||||
| 	void wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json); | ||||
| 
 | ||||
| 	boost::property_tree::ptree wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time = 5s); | ||||
| 
 | ||||
| 	bool check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count); | ||||
| 	rpc_context add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a); | ||||
| } | ||||
| } | ||||
							
								
								
									
										71
									
								
								nano/rpc_test/test_response.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								nano/rpc_test/test_response.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | |||
| #include <nano/node/ipc/ipc_server.hpp> | ||||
| #include <nano/rpc/rpc_request_processor.hpp> | ||||
| #include <nano/rpc_test/test_response.hpp> | ||||
| #include <nano/test_common/system.hpp> | ||||
| #include <nano/test_common/testutil.hpp> | ||||
| 
 | ||||
| #include <gtest/gtest.h> | ||||
| 
 | ||||
| #include <boost/property_tree/json_parser.hpp> | ||||
| 
 | ||||
| nano::test::test_response::test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a) : | ||||
| 	request (request_a), | ||||
| 	sock (io_ctx_a) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| nano::test::test_response::test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a) : | ||||
| 	request (request_a), | ||||
| 	sock (io_ctx_a) | ||||
| { | ||||
| 	run (port_a); | ||||
| } | ||||
| 
 | ||||
| void nano::test::test_response::run (uint16_t port_a) | ||||
| { | ||||
| 	sock.async_connect (nano::tcp_endpoint (boost::asio::ip::address_v6::loopback (), port_a), [this] (boost::system::error_code const & ec) { | ||||
| 		if (!ec) | ||||
| 		{ | ||||
| 			std::stringstream ostream; | ||||
| 			boost::property_tree::write_json (ostream, request); | ||||
| 			req.method (boost::beast::http::verb::post); | ||||
| 			req.target ("/"); | ||||
| 			req.version (11); | ||||
| 			ostream.flush (); | ||||
| 			req.body () = ostream.str (); | ||||
| 			req.prepare_payload (); | ||||
| 			boost::beast::http::async_write (sock, req, [this] (boost::system::error_code const & ec, size_t bytes_transferred) { | ||||
| 				if (!ec) | ||||
| 				{ | ||||
| 					boost::beast::http::async_read (sock, sb, resp, [this] (boost::system::error_code const & ec, size_t bytes_transferred) { | ||||
| 						if (!ec) | ||||
| 						{ | ||||
| 							std::stringstream body (resp.body ()); | ||||
| 							try | ||||
| 							{ | ||||
| 								boost::property_tree::read_json (body, json); | ||||
| 								status = 200; | ||||
| 							} | ||||
| 							catch (std::exception &) | ||||
| 							{ | ||||
| 								status = 500; | ||||
| 							} | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							status = 400; | ||||
| 						} | ||||
| 					}); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					status = 600; | ||||
| 				} | ||||
| 			}); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			status = 400; | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
							
								
								
									
										24
									
								
								nano/rpc_test/test_response.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								nano/rpc_test/test_response.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <boost/asio/ip/tcp.hpp> | ||||
| #include <boost/beast/core/flat_buffer.hpp> | ||||
| #include <boost/beast/http.hpp> | ||||
| #include <boost/property_tree/ptree.hpp> | ||||
| 
 | ||||
| namespace nano::test | ||||
| { | ||||
| class test_response | ||||
| { | ||||
| public: | ||||
| 	test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a); | ||||
| 	test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a); | ||||
| 	void run (uint16_t port_a); | ||||
| 	boost::property_tree::ptree const & request; | ||||
| 	boost::asio::ip::tcp::socket sock; | ||||
| 	boost::property_tree::ptree json; | ||||
| 	boost::beast::flat_buffer sb; | ||||
| 	boost::beast::http::request<boost::beast::http::string_body> req; | ||||
| 	boost::beast::http::response<boost::beast::http::string_body> resp; | ||||
| 	std::atomic<int> status{ 0 }; | ||||
| }; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dimitrios Siganos
				Dimitrios Siganos