Test against mock rpc server
This commit is contained in:
parent
fec725bc52
commit
c455c1fbbe
7 changed files with 82 additions and 289 deletions
|
|
@ -2,7 +2,7 @@ use super::*;
|
|||
use anyhow::Context;
|
||||
use std::time::Duration;
|
||||
|
||||
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(5);
|
||||
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
||||
|
||||
pub struct App {
|
||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||
|
|
@ -58,7 +58,16 @@ impl AsyncComponent for App {
|
|||
root: Self::Root,
|
||||
sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
let daemon_client = Arc::new(Mutex::new(daemon::daemon_connect().await.ok()));
|
||||
// TODO: RPC REFACTOR (Handle Error)
|
||||
let mut daemon_client_connected = false;
|
||||
let daemon_client = Arc::new(Mutex::new(
|
||||
daemon::daemon_connect()
|
||||
.await
|
||||
.inspect(|_| {
|
||||
daemon_client_connected = true;
|
||||
})
|
||||
.ok(),
|
||||
));
|
||||
|
||||
let main_screen = main_screen::MainScreen::builder()
|
||||
.launch(main_screen::MainScreenInit {
|
||||
|
|
@ -72,6 +81,17 @@ impl AsyncComponent for App {
|
|||
})
|
||||
.forward(sender.input_sender(), |_| AppMsg::None);
|
||||
|
||||
if !daemon_client_connected {
|
||||
main_screen
|
||||
.sender()
|
||||
.send(main_screen::MainScreenMsg::DaemonDisconnect)
|
||||
.unwrap();
|
||||
settings_screen
|
||||
.sender()
|
||||
.send(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
let view_stack = adw::ViewStack::new();
|
||||
|
|
@ -126,15 +146,20 @@ impl AsyncComponent for App {
|
|||
let mut daemon_client = self.daemon_client.lock().await;
|
||||
let mut disconnected_daemon_client = false;
|
||||
|
||||
if let Some(daemon_client) = daemon_client.as_mut() {
|
||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||
if let Err(_e) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
||||
disconnected_daemon_client = true;
|
||||
self.main_screen
|
||||
.emit(main_screen::MainScreenMsg::DaemonDisconnect);
|
||||
self.settings_screen
|
||||
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||
if let Some(client) = daemon_client.as_mut() {
|
||||
let mut client = tunnel_client::TunnelClient::new(client);
|
||||
|
||||
if let Ok(mut res) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
||||
let stream = res.get_mut();
|
||||
while let Ok(Some(_)) = stream.message().await {}
|
||||
}
|
||||
|
||||
*daemon_client = None;
|
||||
disconnected_daemon_client = true;
|
||||
self.main_screen
|
||||
.emit(main_screen::MainScreenMsg::DaemonDisconnect);
|
||||
self.settings_screen
|
||||
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||
}
|
||||
|
||||
if disconnected_daemon_client || daemon_client.is_none() {
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ mod switch;
|
|||
|
||||
pub use network_card::{NetworkCard, NetworkCardInit};
|
||||
pub use networks::{Networks, NetworksInit};
|
||||
pub use switch::{Switch, SwitchInit, SwitchMsg};
|
||||
pub use switch::{Switch, SwitchInit};
|
||||
|
|
|
|||
|
|
@ -86,30 +86,28 @@ impl AsyncComponent for NetworkCard {
|
|||
async fn update(
|
||||
&mut self,
|
||||
msg: Self::Input,
|
||||
sender: AsyncComponentSender<Self>,
|
||||
_: AsyncComponentSender<Self>,
|
||||
_root: &Self::Root,
|
||||
) {
|
||||
match msg {
|
||||
NetworkCardMsg::NetworkDelete => {
|
||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||
client
|
||||
let _ = client
|
||||
.network_delete(burrow_rpc::NetworkDeleteRequest { id: self.id })
|
||||
.await
|
||||
.unwrap();
|
||||
.await;
|
||||
}
|
||||
}
|
||||
NetworkCardMsg::MoveUp => {
|
||||
if self.index.checked_sub(1).is_some() {
|
||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||
client
|
||||
let _ = client
|
||||
.network_reorder(burrow_rpc::NetworkReorderRequest {
|
||||
id: self.id,
|
||||
index: self.index as i32 - 1,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,13 +115,12 @@ impl AsyncComponent for NetworkCard {
|
|||
if self.index + 1 < self.index_max {
|
||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||
client
|
||||
let _ = client
|
||||
.network_reorder(burrow_rpc::NetworkReorderRequest {
|
||||
id: self.id,
|
||||
index: self.index as i32 + 1,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ pub struct Networks {
|
|||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||
network_cards: Vec<AsyncController<NetworkCard>>,
|
||||
networks_list_box: gtk::ListBox,
|
||||
|
||||
_network_state_worker: WorkerController<AsyncNetworkStateHandler>,
|
||||
}
|
||||
|
||||
pub struct NetworksInit {
|
||||
|
|
@ -94,6 +96,10 @@ impl AsyncComponent for Networks {
|
|||
daemon_client: init.daemon_client,
|
||||
network_cards,
|
||||
networks_list_box: widgets.networks.clone(),
|
||||
|
||||
_network_state_worker: AsyncNetworkStateHandler::builder()
|
||||
.detach_worker(())
|
||||
.forward(sender.input_sender(), |msg| msg),
|
||||
};
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
|
|
@ -132,7 +138,7 @@ impl AsyncComponent for Networks {
|
|||
NetworksMsg::NetworkAdd => {
|
||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||
client.network_add(burrow_rpc::Empty {}).await.unwrap();
|
||||
let _ = client.network_add(burrow_rpc::Empty {}).await;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -147,7 +153,8 @@ impl Worker for AsyncNetworkStateHandler {
|
|||
type Input = ();
|
||||
type Output = NetworksMsg;
|
||||
|
||||
fn init(_: Self::Init, _sender: ComponentSender<Self>) -> Self {
|
||||
fn init(_: Self::Init, sender: ComponentSender<Self>) -> Self {
|
||||
sender.input(());
|
||||
Self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
|||
pub struct Switch {
|
||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||
switch: gtk::Switch,
|
||||
switch_screen: gtk::Box,
|
||||
disconnected_banner: adw::Banner,
|
||||
|
||||
_tunnel_state_worker: WorkerController<AsyncTunnelStateHandler>,
|
||||
}
|
||||
|
|
@ -19,8 +17,6 @@ pub struct SwitchInit {
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum SwitchMsg {
|
||||
None,
|
||||
DaemonReconnect,
|
||||
DaemonDisconnect,
|
||||
Start,
|
||||
Stop,
|
||||
SwitchSetStart,
|
||||
|
|
@ -51,7 +47,6 @@ impl AsyncComponent for Switch {
|
|||
},
|
||||
},
|
||||
|
||||
#[name(switch_screen)]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
|
|
@ -80,37 +75,12 @@ impl AsyncComponent for Switch {
|
|||
root: Self::Root,
|
||||
sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
let mut initial_daemon_server_down = false;
|
||||
|
||||
if let Some(daemon_client) = init.daemon_client.lock().await.as_mut() {
|
||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||
if client
|
||||
.tunnel_status(burrow_rpc::Empty {})
|
||||
.await
|
||||
.as_mut()
|
||||
.is_err()
|
||||
{
|
||||
initial_daemon_server_down = true;
|
||||
}
|
||||
} else {
|
||||
initial_daemon_server_down = true;
|
||||
}
|
||||
|
||||
let switch_sender = sender.clone();
|
||||
let widgets = view_output!();
|
||||
|
||||
if initial_daemon_server_down {
|
||||
*init.daemon_client.lock().await = None;
|
||||
widgets.switch.set_active(false);
|
||||
widgets.switch_screen.set_sensitive(false);
|
||||
widgets.setup_banner.set_revealed(true);
|
||||
}
|
||||
|
||||
let model = Switch {
|
||||
daemon_client: init.daemon_client,
|
||||
switch: widgets.switch.clone(),
|
||||
switch_screen: widgets.switch_screen.clone(),
|
||||
disconnected_banner: widgets.setup_banner.clone(),
|
||||
_tunnel_state_worker: AsyncTunnelStateHandler::builder()
|
||||
.detach_worker(())
|
||||
.forward(sender.input_sender(), |_| SwitchMsg::None),
|
||||
|
|
@ -127,20 +97,16 @@ impl AsyncComponent for Switch {
|
|||
_: AsyncComponentSender<Self>,
|
||||
_root: &Self::Root,
|
||||
) {
|
||||
let mut disconnected_daemon_client = false;
|
||||
|
||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||
match msg {
|
||||
Self::Input::Start => {
|
||||
if let Err(_e) = client.tunnel_start(burrow_rpc::Empty {}).await {
|
||||
disconnected_daemon_client = true;
|
||||
}
|
||||
// TODO: Figure out best way for error handling.
|
||||
let _ = client.tunnel_start(burrow_rpc::Empty {}).await;
|
||||
}
|
||||
Self::Input::Stop => {
|
||||
if let Err(_e) = client.tunnel_stop(burrow_rpc::Empty {}).await {
|
||||
disconnected_daemon_client = true;
|
||||
}
|
||||
// TODO: Figure out best way for error handling.
|
||||
let _ = client.tunnel_stop(burrow_rpc::Empty {}).await;
|
||||
}
|
||||
Self::Input::SwitchSetStart => {
|
||||
self.switch.set_active(true);
|
||||
|
|
@ -150,19 +116,6 @@ impl AsyncComponent for Switch {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
disconnected_daemon_client = true;
|
||||
}
|
||||
|
||||
if msg == Self::Input::DaemonReconnect {
|
||||
self.disconnected_banner.set_revealed(false);
|
||||
self.switch_screen.set_sensitive(true);
|
||||
}
|
||||
|
||||
if disconnected_daemon_client || msg == Self::Input::DaemonDisconnect {
|
||||
*self.daemon_client.lock().await = None;
|
||||
self.switch_screen.set_sensitive(false);
|
||||
self.disconnected_banner.set_revealed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -174,7 +127,8 @@ impl Worker for AsyncTunnelStateHandler {
|
|||
type Input = ();
|
||||
type Output = SwitchMsg;
|
||||
|
||||
fn init(_: Self::Init, _sender: ComponentSender<Self>) -> Self {
|
||||
fn init(_: Self::Init, sender: ComponentSender<Self>) -> Self {
|
||||
sender.input(());
|
||||
Self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use super::*;
|
||||
|
||||
pub struct MainScreen {
|
||||
switch: AsyncController<main::Switch>,
|
||||
networks: AsyncController<main::Networks>,
|
||||
_switch: AsyncController<main::Switch>,
|
||||
_networks: AsyncController<main::Networks>,
|
||||
content_box: gtk::Box,
|
||||
daemon_status_banner: adw::Banner,
|
||||
}
|
||||
|
||||
pub struct MainScreenInit {
|
||||
|
|
@ -29,17 +31,17 @@ impl AsyncComponent for MainScreen {
|
|||
set_valign: Align::Fill,
|
||||
set_valign: Align::Center,
|
||||
|
||||
// gtk::Box {
|
||||
// set_orientation: gtk::Orientation::Vertical,
|
||||
// set_spacing: 5,
|
||||
// set_margin_all: 5,
|
||||
// set_valign: Align::Start,
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
set_margin_all: 5,
|
||||
set_valign: Align::Start,
|
||||
|
||||
// #[name(setup_banner)]
|
||||
// adw::Banner {
|
||||
// set_title: "Burrow is not running!",
|
||||
// },
|
||||
// },
|
||||
#[name(daemon_status_banner)]
|
||||
adw::Banner {
|
||||
set_title: "Burrow is not running!",
|
||||
},
|
||||
},
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
|
|
@ -86,7 +88,12 @@ impl AsyncComponent for MainScreen {
|
|||
widgets.content.append(networks.widget());
|
||||
widgets.content.append(switch.widget());
|
||||
|
||||
let model = MainScreen { switch, networks };
|
||||
let model = MainScreen {
|
||||
_switch: switch,
|
||||
_networks: networks,
|
||||
content_box: widgets.content.clone(),
|
||||
daemon_status_banner: widgets.daemon_status_banner.clone(),
|
||||
};
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
}
|
||||
|
|
@ -99,10 +106,12 @@ impl AsyncComponent for MainScreen {
|
|||
) {
|
||||
match msg {
|
||||
MainScreenMsg::DaemonDisconnect => {
|
||||
self.switch.emit(main::SwitchMsg::DaemonDisconnect);
|
||||
self.daemon_status_banner.set_revealed(true);
|
||||
self.content_box.set_sensitive(false);
|
||||
}
|
||||
MainScreenMsg::DaemonReconnect => {
|
||||
self.switch.emit(main::SwitchMsg::DaemonReconnect);
|
||||
self.daemon_status_banner.set_revealed(false);
|
||||
self.content_box.set_sensitive(true);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,199 +0,0 @@
|
|||
use super::*;
|
||||
use std::{
|
||||
thread::{self, JoinHandle},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
||||
|
||||
pub struct SwitchScreen {
|
||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||
switch: gtk::Switch,
|
||||
switch_screen: gtk::Box,
|
||||
disconnected_banner: adw::Banner,
|
||||
tunnel_state_worker: JoinHandle<()>,
|
||||
}
|
||||
|
||||
pub struct SwitchScreenInit {
|
||||
pub daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum SwitchScreenMsg {
|
||||
DaemonReconnect,
|
||||
DaemonDisconnect,
|
||||
Start,
|
||||
Stop,
|
||||
TunnelStateStopped,
|
||||
TunnelStateRunning,
|
||||
}
|
||||
|
||||
#[relm4::component(pub, async)]
|
||||
impl AsyncComponent for SwitchScreen {
|
||||
type Init = SwitchScreenInit;
|
||||
type Input = SwitchScreenMsg;
|
||||
type Output = ();
|
||||
type CommandOutput = SwitchScreenMsg;
|
||||
|
||||
view! {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_valign: Align::Fill,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
set_margin_all: 5,
|
||||
set_valign: Align::Start,
|
||||
|
||||
#[name(setup_banner)]
|
||||
adw::Banner {
|
||||
set_title: "Burrow is not running!",
|
||||
},
|
||||
},
|
||||
|
||||
#[name(switch_screen)]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
set_margin_all: 5,
|
||||
set_valign: Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Burrow Switch",
|
||||
},
|
||||
|
||||
#[name(switch)]
|
||||
gtk::Switch {
|
||||
set_halign: Align::Center,
|
||||
set_hexpand: false,
|
||||
set_vexpand: false,
|
||||
connect_active_notify => move |switch|
|
||||
switch_sender.input(if switch.is_active() { SwitchScreenMsg::Start } else { SwitchScreenMsg::Stop })
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn init(
|
||||
init: Self::Init,
|
||||
root: Self::Root,
|
||||
sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
let mut initial_daemon_server_down = false;
|
||||
|
||||
if let Some(daemon_client) = init.daemon_client.lock().await.as_mut() {
|
||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||
if client
|
||||
.tunnel_status(burrow_rpc::Empty {})
|
||||
.await
|
||||
.as_mut()
|
||||
.is_err()
|
||||
{
|
||||
initial_daemon_server_down = true;
|
||||
}
|
||||
} else {
|
||||
initial_daemon_server_down = true;
|
||||
}
|
||||
|
||||
let switch_sender = sender.clone();
|
||||
let tunnel_state_sender = sender.clone();
|
||||
let widgets = view_output!();
|
||||
|
||||
if initial_daemon_server_down {
|
||||
*init.daemon_client.lock().await = None;
|
||||
widgets.switch.set_active(false);
|
||||
widgets.switch_screen.set_sensitive(false);
|
||||
widgets.setup_banner.set_revealed(true);
|
||||
}
|
||||
|
||||
let model = SwitchScreen {
|
||||
daemon_client: init.daemon_client,
|
||||
switch: widgets.switch.clone(),
|
||||
switch_screen: widgets.switch_screen.clone(),
|
||||
disconnected_banner: widgets.setup_banner.clone(),
|
||||
tunnel_state_worker: thread::spawn(move || {
|
||||
tunnel_state_worker(tunnel_state_sender);
|
||||
}),
|
||||
};
|
||||
|
||||
widgets.switch.set_active(false);
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
async fn update(
|
||||
&mut self,
|
||||
msg: Self::Input,
|
||||
_: AsyncComponentSender<Self>,
|
||||
_root: &Self::Root,
|
||||
) {
|
||||
let mut disconnected_daemon_client = false;
|
||||
|
||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||
match msg {
|
||||
Self::Input::Start => {
|
||||
if let Err(e) = client.tunnel_start(burrow_rpc::Empty {}).await {
|
||||
disconnected_daemon_client = true;
|
||||
}
|
||||
}
|
||||
Self::Input::Stop => {
|
||||
if let Err(e) = client.tunnel_stop(burrow_rpc::Empty {}).await {
|
||||
disconnected_daemon_client = true;
|
||||
}
|
||||
}
|
||||
Self::Input::TunnelStateStopped => {
|
||||
self.switch.set_active(false);
|
||||
}
|
||||
Self::Input::TunnelStateRunning => {
|
||||
self.switch.set_active(true);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
disconnected_daemon_client = true;
|
||||
}
|
||||
|
||||
if msg == Self::Input::DaemonReconnect {
|
||||
self.disconnected_banner.set_revealed(false);
|
||||
self.switch_screen.set_sensitive(true);
|
||||
}
|
||||
|
||||
if disconnected_daemon_client || msg == Self::Input::DaemonDisconnect {
|
||||
*self.daemon_client.lock().await = None;
|
||||
self.switch_screen.set_sensitive(false);
|
||||
self.disconnected_banner.set_revealed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tunnel_state_worker(sender: AsyncComponentSender<SwitchScreen>) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let task = rt.spawn(async move {
|
||||
loop {
|
||||
let sender = sender.input_sender();
|
||||
let conn = daemon::daemon_connect().await;
|
||||
if let Ok(conn) = conn {
|
||||
let mut client = tunnel_client::TunnelClient::new(conn);
|
||||
if let Ok(mut res) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
||||
let stream = res.get_mut();
|
||||
while let Ok(Some(msg)) = stream.message().await {
|
||||
match msg.state() {
|
||||
burrow_rpc::State::Stopped => {
|
||||
sender.send(SwitchScreenMsg::TunnelStateStopped)
|
||||
}
|
||||
burrow_rpc::State::Running => {
|
||||
sender.send(SwitchScreenMsg::TunnelStateRunning)
|
||||
}
|
||||
}
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
tokio::time::sleep(RECONNECT_POLL_TIME).await;
|
||||
}
|
||||
});
|
||||
rt.block_on(task).unwrap();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue