Skip to content

Commit 8f71804

Browse files
feat: add flag for router IP local run (#565)
* feat: add flag for router IP local run * refactor: amend ipaddr setting, local run init fn * refactor: delete unnecessary dependency Forgot to delete a dependency and it looks like I can't squash commits, whoops 🤦 * Revert "refactor: delete unnecessary dependency" This reverts commit 1794cc6. * refactor: remove unnecessary dep (amendment) Re-pushing this amendment but without the git diff. Probably should have changed that before submitting initially. * clippy * amendment from clippy warning (needless borrow) * refactor: apply cargo fmt diffs * refactor: return URL from run test setup fn + cargo_shuttle_run() now returns a string containing the full base URL instead of port + Relevant changes have been made to tests to account for this * refactor: change flag name to be 'external' Changed as per discussion on the PR. * refactor: use passed args directly for struct * test: make sure tests align to proper folders Co-authored-by: Oddbjørn Grødem <[email protected]>
1 parent 0599a13 commit 8f71804

File tree

4 files changed

+73
-45
lines changed

4 files changed

+73
-45
lines changed

cargo-shuttle/src/args.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ pub struct RunArgs {
143143
/// port to start service on
144144
#[clap(long, default_value = "8000")]
145145
pub port: u16,
146+
/// use 0.0.0.0 instead of localhost (for usage with local external devices)
147+
#[clap(long)]
148+
pub external: bool,
146149
}
147150

148151
#[derive(Parser, Debug)]

cargo-shuttle/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,13 @@ impl Shuttle {
405405
secrets,
406406
working_directory.to_path_buf(),
407407
)?;
408-
let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), run_args.port);
408+
let addr = if run_args.external {
409+
std::net::IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))
410+
} else {
411+
Ipv4Addr::LOCALHOST.into()
412+
};
413+
414+
let addr = SocketAddr::new(addr, run_args.port);
409415

410416
trace!("loading project");
411417
println!(

cargo-shuttle/tests/integration/run.rs

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,18 @@ use std::{fs::canonicalize, process::exit, time::Duration};
55
use tokio::time::sleep;
66

77
/// creates a `cargo-shuttle` run instance with some reasonable defaults set.
8-
async fn cargo_shuttle_run(working_directory: &str) -> u16 {
8+
async fn cargo_shuttle_run(working_directory: &str, external: bool) -> String {
99
let working_directory = canonicalize(working_directory).unwrap();
10+
1011
let port = pick_unused_port().unwrap();
11-
let run_args = RunArgs { port };
12+
13+
let url = if !external {
14+
format!("http://localhost:{port}")
15+
} else {
16+
format!("http://0.0.0.0:{port}")
17+
};
18+
19+
let run_args = RunArgs { port, external };
1220

1321
let runner = Shuttle::new().unwrap().run(Args {
1422
api_url: Some("http://shuttle.invalid:80".to_string()),
@@ -34,28 +42,23 @@ async fn cargo_shuttle_run(working_directory: &str) -> u16 {
3442
tokio::spawn(runner);
3543

3644
// Wait for service to be responsive
37-
while (reqwest::Client::new()
38-
.get(format!("http://localhost:{port}"))
39-
.send()
40-
.await)
41-
.is_err()
42-
{
45+
while (reqwest::Client::new().get(url.clone()).send().await).is_err() {
4346
println!(
4447
"waiting for '{}' to start up...",
4548
working_directory.display()
4649
);
4750
sleep(Duration::from_millis(350)).await;
4851
}
4952

50-
port
53+
url
5154
}
5255

5356
#[tokio::test(flavor = "multi_thread")]
5457
async fn rocket_hello_world() {
55-
let port = cargo_shuttle_run("../examples/rocket/hello-world").await;
58+
let url = cargo_shuttle_run("../examples/rocket/hello-world", false).await;
5659

5760
let request_text = reqwest::Client::new()
58-
.get(format!("http://localhost:{port}/hello"))
61+
.get(format!("{url}/hello"))
5962
.send()
6063
.await
6164
.unwrap()
@@ -68,10 +71,10 @@ async fn rocket_hello_world() {
6871

6972
#[tokio::test(flavor = "multi_thread")]
7073
async fn rocket_secrets() {
71-
let port = cargo_shuttle_run("../examples/rocket/secrets").await;
74+
let url = cargo_shuttle_run("../examples/rocket/secrets", false).await;
7275

7376
let request_text = reqwest::Client::new()
74-
.get(format!("http://localhost:{port}/secret"))
77+
.get(format!("{url}/secret"))
7578
.send()
7679
.await
7780
.unwrap()
@@ -85,11 +88,11 @@ async fn rocket_secrets() {
8588
// This example uses a shared Postgres. Thus local runs should create a docker container for it.
8689
#[tokio::test(flavor = "multi_thread")]
8790
async fn rocket_postgres() {
88-
let port = cargo_shuttle_run("../examples/rocket/postgres").await;
91+
let url = cargo_shuttle_run("../examples/rocket/postgres", false).await;
8992
let client = reqwest::Client::new();
9093

9194
let post_text = client
92-
.post(format!("http://localhost:{port}/todo"))
95+
.post(format!("{url}/todo"))
9396
.body("{\"note\": \"Deploy to shuttle\"}")
9497
.send()
9598
.await
@@ -101,7 +104,7 @@ async fn rocket_postgres() {
101104
assert_eq!(post_text, "{\"id\":1,\"note\":\"Deploy to shuttle\"}");
102105

103106
let request_text = client
104-
.get(format!("http://localhost:{port}/todo/1"))
107+
.get(format!("{url}/todo/1"))
105108
.send()
106109
.await
107110
.unwrap()
@@ -114,11 +117,11 @@ async fn rocket_postgres() {
114117

115118
#[tokio::test(flavor = "multi_thread")]
116119
async fn rocket_authentication() {
117-
let port = cargo_shuttle_run("../examples/rocket/authentication").await;
120+
let url = cargo_shuttle_run("../examples/rocket/authentication", false).await;
118121
let client = reqwest::Client::new();
119122

120123
let public_text = client
121-
.get(format!("http://localhost:{port}/public"))
124+
.get(format!("{url}/public"))
122125
.send()
123126
.await
124127
.unwrap()
@@ -132,7 +135,7 @@ async fn rocket_authentication() {
132135
);
133136

134137
let private_status = client
135-
.get(format!("http://localhost:{port}/private"))
138+
.get(format!("{url}/private"))
136139
.send()
137140
.await
138141
.unwrap()
@@ -141,7 +144,7 @@ async fn rocket_authentication() {
141144
assert_eq!(private_status, StatusCode::FORBIDDEN);
142145

143146
let body = client
144-
.post(format!("http://localhost:{port}/login"))
147+
.post(format!("{url}/login"))
145148
.body("{\"username\": \"username\", \"password\": \"password\"}")
146149
.send()
147150
.await
@@ -153,7 +156,7 @@ async fn rocket_authentication() {
153156
let token = format!("Bearer {}", json["token"].as_str().unwrap());
154157

155158
let private_text = client
156-
.get(format!("http://localhost:{port}/private"))
159+
.get(format!("{url}/private"))
157160
.header("Authorization", token)
158161
.send()
159162
.await
@@ -170,10 +173,10 @@ async fn rocket_authentication() {
170173

171174
#[tokio::test(flavor = "multi_thread")]
172175
async fn actix_web_hello_world() {
173-
let port = cargo_shuttle_run("../examples/actix-web/hello-world").await;
176+
let url = cargo_shuttle_run("../examples/actix-web/hello-world", false).await;
174177

175178
let request_text = reqwest::Client::new()
176-
.get(format!("http://localhost:{port}/hello"))
179+
.get(format!("{url}/hello"))
177180
.send()
178181
.await
179182
.unwrap()
@@ -186,10 +189,10 @@ async fn actix_web_hello_world() {
186189

187190
#[tokio::test(flavor = "multi_thread")]
188191
async fn axum_hello_world() {
189-
let port = cargo_shuttle_run("../examples/axum/hello-world").await;
192+
let url = cargo_shuttle_run("../examples/axum/hello-world", false).await;
190193

191194
let request_text = reqwest::Client::new()
192-
.get(format!("http://localhost:{port}/hello"))
195+
.get(format!("{url}/hello"))
193196
.send()
194197
.await
195198
.unwrap()
@@ -202,10 +205,10 @@ async fn axum_hello_world() {
202205

203206
#[tokio::test(flavor = "multi_thread")]
204207
async fn tide_hello_world() {
205-
let port = cargo_shuttle_run("../examples/tide/hello-world").await;
208+
let url = cargo_shuttle_run("../examples/tide/hello-world", false).await;
206209

207210
let request_text = reqwest::Client::new()
208-
.get(format!("http://localhost:{port}/hello"))
211+
.get(format!("{url}/hello"))
209212
.send()
210213
.await
211214
.unwrap()
@@ -218,10 +221,10 @@ async fn tide_hello_world() {
218221

219222
#[tokio::test(flavor = "multi_thread")]
220223
async fn tower_hello_world() {
221-
let port = cargo_shuttle_run("../examples/tower/hello-world").await;
224+
let url = cargo_shuttle_run("../examples/tower/hello-world", false).await;
222225

223226
let request_text = reqwest::Client::new()
224-
.get(format!("http://localhost:{port}/hello"))
227+
.get(format!("{url}/hello"))
225228
.send()
226229
.await
227230
.unwrap()
@@ -234,10 +237,10 @@ async fn tower_hello_world() {
234237

235238
#[tokio::test(flavor = "multi_thread")]
236239
async fn warp_hello_world() {
237-
let port = cargo_shuttle_run("../examples/warp/hello-world").await;
240+
let url = cargo_shuttle_run("../examples/warp/hello-world", false).await;
238241

239242
let request_text = reqwest::Client::new()
240-
.get(format!("http://localhost:{port}/hello"))
243+
.get(format!("{url}/hello"))
241244
.send()
242245
.await
243246
.unwrap()
@@ -250,10 +253,10 @@ async fn warp_hello_world() {
250253

251254
#[tokio::test(flavor = "multi_thread")]
252255
async fn poem_hello_world() {
253-
let port = cargo_shuttle_run("../examples/poem/hello-world").await;
256+
let url = cargo_shuttle_run("../examples/poem/hello-world", false).await;
254257

255258
let request_text = reqwest::Client::new()
256-
.get(format!("http://localhost:{port}/hello"))
259+
.get(format!("{url}/hello"))
257260
.send()
258261
.await
259262
.unwrap()
@@ -267,11 +270,11 @@ async fn poem_hello_world() {
267270
// This example uses a shared Postgres. Thus local runs should create a docker container for it.
268271
#[tokio::test(flavor = "multi_thread")]
269272
async fn poem_postgres() {
270-
let port = cargo_shuttle_run("../examples/poem/postgres").await;
273+
let url = cargo_shuttle_run("../examples/poem/postgres", false).await;
271274
let client = reqwest::Client::new();
272275

273276
let post_text = client
274-
.post(format!("http://localhost:{port}/todo"))
277+
.post(format!("{url}/todo"))
275278
.body("{\"note\": \"Deploy to shuttle\"}")
276279
.header("content-type", "application/json")
277280
.send()
@@ -284,7 +287,7 @@ async fn poem_postgres() {
284287
assert_eq!(post_text, "{\"id\":1,\"note\":\"Deploy to shuttle\"}");
285288

286289
let request_text = client
287-
.get(format!("http://localhost:{port}/todo/1"))
290+
.get(format!("{url}/todo/1"))
288291
.send()
289292
.await
290293
.unwrap()
@@ -298,12 +301,12 @@ async fn poem_postgres() {
298301
// This example uses a shared MongoDb. Thus local runs should create a docker container for it.
299302
#[tokio::test(flavor = "multi_thread")]
300303
async fn poem_mongodb() {
301-
let port = cargo_shuttle_run("../examples/poem/mongodb").await;
304+
let url = cargo_shuttle_run("../examples/poem/mongodb", false).await;
302305
let client = reqwest::Client::new();
303306

304307
// Post a todo note and get the persisted todo objectId
305308
let post_text = client
306-
.post(format!("http://localhost:{port}/todo"))
309+
.post(format!("{url}/todo"))
307310
.body("{\"note\": \"Deploy to shuttle\"}")
308311
.header("content-type", "application/json")
309312
.send()
@@ -317,7 +320,7 @@ async fn poem_mongodb() {
317320
assert_eq!(post_text.len(), 24);
318321

319322
let request_text = client
320-
.get(format!("http://localhost:{port}/todo/{post_text}"))
323+
.get(format!("{url}/todo/{post_text}"))
321324
.send()
322325
.await
323326
.unwrap()
@@ -330,10 +333,10 @@ async fn poem_mongodb() {
330333

331334
#[tokio::test(flavor = "multi_thread")]
332335
async fn salvo_hello_world() {
333-
let port = cargo_shuttle_run("../examples/salvo/hello-world").await;
336+
let url = cargo_shuttle_run("../examples/salvo/hello-world", false).await;
334337

335338
let request_text = reqwest::Client::new()
336-
.get(format!("http://localhost:{port}/hello"))
339+
.get(format!("{url}/hello"))
337340
.send()
338341
.await
339342
.unwrap()
@@ -346,10 +349,10 @@ async fn salvo_hello_world() {
346349

347350
#[tokio::test(flavor = "multi_thread")]
348351
async fn thruster_hello_world() {
349-
let port = cargo_shuttle_run("../examples/thruster/hello-world").await;
352+
let url = cargo_shuttle_run("../examples/thruster/hello-world", false).await;
350353

351354
let request_text = reqwest::Client::new()
352-
.get(format!("http://localhost:{port}/hello"))
355+
.get(format!("{url}/hello"))
353356
.send()
354357
.await
355358
.unwrap()
@@ -359,3 +362,19 @@ async fn thruster_hello_world() {
359362

360363
assert_eq!(request_text, "Hello, World!");
361364
}
365+
366+
#[tokio::test(flavor = "multi_thread")]
367+
async fn rocket_hello_world_with_router_ip() {
368+
let url = cargo_shuttle_run("../examples/rocket/hello-world", true).await;
369+
370+
let request_text = reqwest::Client::new()
371+
.get(format!("{url}/hello"))
372+
.send()
373+
.await
374+
.unwrap()
375+
.text()
376+
.await
377+
.unwrap();
378+
379+
assert_eq!(request_text, "Hello, world!");
380+
}

service/tests/integration/helpers/loader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ pub fn build_so_create_loader(resources: &str, crate_name: &str) -> Result<Loade
2424

2525
let so_path = crate_dir.join("target/release").join(lib_name);
2626

27-
Loader::from_so_file(&so_path)
27+
Loader::from_so_file(so_path)
2828
}

0 commit comments

Comments
 (0)