xref: /tonic/interop/src/bin/client.rs (revision f276934d)
1 use interop::client;
2 use std::{str::FromStr, time::Duration};
3 use tonic::transport::Endpoint;
4 use tonic::transport::{Certificate, ClientTlsConfig};
5 
6 #[derive(Debug)]
7 struct Opts {
8     use_tls: bool,
9     test_case: Vec<Testcase>,
10 }
11 
12 impl Opts {
13     fn parse() -> Result<Self, pico_args::Error> {
14         let mut pargs = pico_args::Arguments::from_env();
15         Ok(Self {
16             use_tls: pargs.contains("--use_tls"),
17             test_case: pargs.value_from_fn("--test_case", |test_case| {
18                 test_case.split(',').map(Testcase::from_str).collect()
19             })?,
20         })
21     }
22 }
23 
24 #[tokio::main]
25 async fn main() -> Result<(), Box<dyn std::error::Error>> {
26     interop::trace_init();
27 
28     let matches = Opts::parse()?;
29 
30     let test_cases = matches.test_case;
31 
32     #[allow(unused_mut)]
33     let mut endpoint = Endpoint::from_static("http://localhost:10000")
34         .timeout(Duration::from_secs(5))
35         .concurrency_limit(30);
36 
37     if matches.use_tls {
38         let pem = std::fs::read_to_string("interop/data/ca.pem")?;
39         let ca = Certificate::from_pem(pem);
40         endpoint = endpoint.tls_config(
41             ClientTlsConfig::new()
42                 .ca_certificate(ca)
43                 .domain_name("foo.test.google.fr"),
44         )?;
45     }
46 
47     let channel = endpoint.connect().await?;
48 
49     let mut client = client::TestClient::new(channel.clone());
50     let mut unimplemented_client = client::UnimplementedClient::new(channel);
51 
52     let mut failures = Vec::new();
53 
54     for test_case in test_cases {
55         println!("{:?}:", test_case);
56         let mut test_results = Vec::new();
57 
58         match test_case {
59             Testcase::EmptyUnary => client::empty_unary(&mut client, &mut test_results).await,
60             Testcase::LargeUnary => client::large_unary(&mut client, &mut test_results).await,
61             Testcase::ClientStreaming => {
62                 client::client_streaming(&mut client, &mut test_results).await
63             }
64             Testcase::ServerStreaming => {
65                 client::server_streaming(&mut client, &mut test_results).await
66             }
67             Testcase::PingPong => client::ping_pong(&mut client, &mut test_results).await,
68             Testcase::EmptyStream => client::empty_stream(&mut client, &mut test_results).await,
69             Testcase::StatusCodeAndMessage => {
70                 client::status_code_and_message(&mut client, &mut test_results).await
71             }
72             Testcase::SpecialStatusMessage => {
73                 client::special_status_message(&mut client, &mut test_results).await
74             }
75             Testcase::UnimplementedMethod => {
76                 client::unimplemented_method(&mut client, &mut test_results).await
77             }
78             Testcase::UnimplementedService => {
79                 client::unimplemented_service(&mut unimplemented_client, &mut test_results).await
80             }
81             Testcase::CustomMetadata => {
82                 client::custom_metadata(&mut client, &mut test_results).await
83             }
84             _ => unimplemented!(),
85         }
86 
87         for result in test_results {
88             println!("  {}", result);
89 
90             if result.is_failed() {
91                 failures.push(result);
92             }
93         }
94     }
95 
96     if !failures.is_empty() {
97         println!("{} tests failed", failures.len());
98         std::process::exit(1);
99     }
100 
101     Ok(())
102 }
103 
104 #[derive(Debug, strum::EnumString)]
105 #[strum(serialize_all = "snake_case")]
106 enum Testcase {
107     EmptyUnary,
108     CacheableUnary,
109     LargeUnary,
110     ClientCompressedUnary,
111     ServerCompressedUnary,
112     ClientStreaming,
113     ClientCompressedStreaming,
114     ServerStreaming,
115     ServerCompressedStreaming,
116     PingPong,
117     EmptyStream,
118     ComputeEngineCreds,
119     JwtTokenCreds,
120     Oauth2AuthToken,
121     PerRpcCreds,
122     CustomMetadata,
123     StatusCodeAndMessage,
124     SpecialStatusMessage,
125     UnimplementedMethod,
126     UnimplementedService,
127     CancelAfterBegin,
128     CancelAfterFirstResponse,
129     TimeoutOnSleepingServer,
130     ConcurrentLargeUnary,
131 }
132