update/
channel.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::args;
6use anyhow::{Context, Error};
7use fidl_fuchsia_update_channelcontrol::{ChannelControlMarker, ChannelControlProxy};
8use fuchsia_component::client::connect_to_protocol;
9
10pub async fn handle_channel_control_cmd(cmd: args::channel::Command) -> Result<(), Error> {
11    let channel_control = connect_to_protocol::<ChannelControlMarker>()
12        .context("Failed to connect to channel control service")?;
13    handle_channel_control_cmd_impl(cmd, &channel_control).await
14}
15
16async fn handle_channel_control_cmd_impl(
17    cmd: args::channel::Command,
18    channel_control: &ChannelControlProxy,
19) -> Result<(), Error> {
20    match cmd {
21        args::channel::Command::Get(_) => {
22            let channel = channel_control.get_current().await?;
23            println!("current channel: {channel}");
24        }
25        args::channel::Command::Target(_) => {
26            let channel = channel_control.get_target().await?;
27            println!("target channel: {channel}");
28        }
29        args::channel::Command::Set(args::channel::Set { channel }) => {
30            channel_control.set_target(&channel).await?;
31        }
32        args::channel::Command::List(_) => {
33            let channels = channel_control.get_target_list().await?;
34            if channels.is_empty() {
35                println!("known channels list is empty.");
36            } else {
37                println!("known channels:");
38                for channel in channels {
39                    println!("{channel}");
40                }
41            }
42        }
43    }
44    Ok(())
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use assert_matches::assert_matches;
51    use fidl::endpoints::create_proxy_and_stream;
52    use fidl_fuchsia_update_channelcontrol::ChannelControlRequest;
53    use fuchsia_async as fasync;
54    use futures::prelude::*;
55
56    async fn perform_channel_control_test<V>(argument: args::channel::Command, verifier: V)
57    where
58        V: Fn(ChannelControlRequest),
59    {
60        let (proxy, mut stream) = create_proxy_and_stream::<ChannelControlMarker>();
61        let fut = async move {
62            assert_matches!(handle_channel_control_cmd_impl(argument, &proxy).await, Ok(()));
63        };
64        let stream_fut = async move {
65            let result = stream.next().await.unwrap();
66            match result {
67                Ok(cmd) => verifier(cmd),
68                err => panic!("Err in request handler: {err:?}"),
69            }
70        };
71        future::join(fut, stream_fut).await;
72    }
73
74    #[fasync::run_singlethreaded(test)]
75    async fn test_channel_get() {
76        perform_channel_control_test(args::channel::Command::Get(args::channel::Get {}), |cmd| {
77            match cmd {
78                ChannelControlRequest::GetCurrent { responder } => {
79                    responder.send("channel").unwrap();
80                }
81                request => panic!("Unexpected request: {request:?}"),
82            }
83        })
84        .await;
85    }
86
87    #[fasync::run_singlethreaded(test)]
88    async fn test_channel_target() {
89        perform_channel_control_test(
90            args::channel::Command::Target(args::channel::Target {}),
91            |cmd| match cmd {
92                ChannelControlRequest::GetTarget { responder } => {
93                    responder.send("target-channel").unwrap();
94                }
95                request => panic!("Unexpected request: {request:?}"),
96            },
97        )
98        .await;
99    }
100
101    #[fasync::run_singlethreaded(test)]
102    async fn test_channel_set() {
103        perform_channel_control_test(
104            args::channel::Command::Set(args::channel::Set { channel: "new-channel".to_string() }),
105            |cmd| match cmd {
106                ChannelControlRequest::SetTarget { channel, responder } => {
107                    assert_eq!(channel, "new-channel");
108                    responder.send().unwrap();
109                }
110                request => panic!("Unexpected request: {request:?}"),
111            },
112        )
113        .await;
114    }
115
116    #[fasync::run_singlethreaded(test)]
117    async fn test_channel_list() {
118        perform_channel_control_test(args::channel::Command::List(args::channel::List {}), |cmd| {
119            match cmd {
120                ChannelControlRequest::GetTargetList { responder } => {
121                    responder
122                        .send(&["some-channel".to_owned(), "other-channel".to_owned()])
123                        .unwrap();
124                }
125                request => panic!("Unexpected request: {request:?}"),
126            }
127        })
128        .await;
129    }
130}