testcontainers_modules/solr/mod.rs
1use testcontainers::{core::WaitFor, Image};
2
3/// Port that the [`Apache Solr`] container has internally
4/// Can be rebound externally via [`testcontainers::core::ImageExt::with_mapped_port`]
5///
6/// [`Apache Solr`]: https://solr.apache.org/
7pub const SOLR_PORT: u16 = 8983;
8
9const NAME: &str = "solr";
10const TAG: &str = "9.5.0-slim";
11
12/// Module to work with [`Solr`] inside of tests.
13///
14/// Starts an instance of Solr based on the official [`Solr docker image`].
15///
16/// By default Solr is exposed via HTTP on Port 8983 ([`SOLR_PORT`]) and has no access control. Please refer to the [`Solr reference guide`] for more informations on how to interact with the API.
17///
18/// # Example
19/// ```
20/// use testcontainers_modules::{solr, testcontainers::runners::SyncRunner};
21///
22/// let solr_instance = solr::Solr::default().start().unwrap();
23/// let host_port = solr_instance.get_host_port_ipv4(solr::SOLR_PORT).unwrap();
24///
25/// let solr_url = format!("http://127.0.0.1:{}", host_port);
26///
27/// // use HTTP client to interact with the solr API
28/// ```
29///
30/// [`Solr`]: https://solr.apache.org/
31/// [`Solr docker image`]: https://hub.docker.com/_/solr
32/// [`Solr reference guide`]: https://solr.apache.org/guide/solr/latest/
33#[derive(Debug, Default, Clone)]
34pub struct Solr {
35 /// (remove if there is another variable)
36 /// Field is included to prevent this struct to be a unit struct.
37 /// This allows extending functionality (and thus further variables) without breaking changes
38 _priv: (),
39}
40
41impl Image for Solr {
42 fn name(&self) -> &str {
43 NAME
44 }
45
46 fn tag(&self) -> &str {
47 TAG
48 }
49
50 fn ready_conditions(&self) -> Vec<WaitFor> {
51 vec![WaitFor::message_on_stdout("o.e.j.s.Server Started Server")]
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use reqwest::{self, StatusCode};
58 use testcontainers::runners::SyncRunner;
59
60 use super::*;
61
62 #[test]
63 fn solr_ping() -> Result<(), Box<dyn std::error::Error + 'static>> {
64 let solr_image = Solr::default();
65 let container = solr_image.start()?;
66 let host_ip = container.get_host()?;
67 let host_port = container.get_host_port_ipv4(SOLR_PORT)?;
68
69 let url = format!("http://{host_ip}:{host_port}/solr/admin/cores?action=STATUS");
70 let res = reqwest::blocking::get(url).expect("valid HTTP response");
71
72 assert_eq!(res.status(), StatusCode::OK);
73
74 let json: serde_json::Value = res.json().expect("valid JSON body");
75
76 assert_eq!(json["responseHeader"]["status"], 0);
77 Ok(())
78 }
79}