1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
Copyright 2020-2021 Kunal Mehta <legoktm@member.fsf.org>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//! The `rocket_healthz` crate provides a macro to easily add
//! a `/healthz` endpoint to your [Rocket](https://rocket.rs/)
//! project. The endpoint responds with HTTP 200 and the plain
//! text `OK`. You can use it for health checks when you want to
//! verify that the server is running.
//!
//! ```rust
//! #[macro_use] extern crate rocket;
//! rocket_healthz::healthz!();
//!
//! #[launch]
//! fn rocket() -> rocket::Rocket {
//!     rocket::ignite().mount("/", routes![healthz])
//! }
//! ```
//!
//! The macro defines the route, but it still needs to be
//! mounted manually for now.
//!
//! The macro also defines an integration test so the `/healthz`
//! route will be automatically tested. This currently requires
//! the existence of a function named `rocket()` that returns
//! `rocket::Rocket`.

#[macro_export]
macro_rules! healthz {
    () => {
        #[rocket::get("/healthz")]
        fn healthz() -> String {
            "OK".to_string()
        }

        #[cfg(test)]
        mod rocket_healthz_tests {
            use super::rocket;
            use rocket::http::Status;

            #[test]
            fn test_healthz() {
                use rocket::local::blocking::Client;
                // FIXME: don't hardcode rocket() as launch
                let client = Client::tracked(rocket()).unwrap();
                let resp = client.get("/healthz").dispatch();
                assert_eq!(resp.status(), Status::Ok);
                assert_eq!(resp.into_string().unwrap(), "OK".to_string());
            }
        }
    };
}

#[cfg(test)]
mod tests {
    use super::*;

    healthz!();

    // To satisfy test_healthz
    fn rocket() -> rocket::Rocket {
        rocket::ignite().mount("/", rocket::routes![healthz])
    }

    #[test]
    fn test() {
        assert_eq!(healthz(), "OK".to_string());
    }
}