-
-
Notifications
You must be signed in to change notification settings - Fork 1
Test "kubectl logs" #9
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
mod test; | ||
use test::prelude::*; | ||
|
||
struct EchoService<'a> { | ||
client: &'a TestKubeClient, | ||
pod: TemporaryResource<'a, Pod>, | ||
} | ||
|
||
impl<'a> EchoService<'a> { | ||
pub fn new(client: &'a TestKubeClient, log_output: &[&str]) -> Self { | ||
setup_repository(&client); | ||
|
||
/// Newline character for LOG_OUTPUT | ||
/// | ||
/// Source code: \\\\\\\\n | ||
/// Pod spec: \\\\n | ||
/// Systemd unit file: \\n | ||
/// echo-service: \n | ||
/// Journal: separate entries | ||
const NEWLINE: &str = "\\\\\\\\n"; | ||
|
||
let pod = TemporaryResource::new( | ||
&client, | ||
&formatdoc! {r#" | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: agent-logs-integration-test-{id} | ||
spec: | ||
containers: | ||
- name: echo-service | ||
image: echo-service:1.0.0 | ||
command: | ||
- echo-service-1.0.0/start.sh | ||
env: | ||
- name: LOG_OUTPUT | ||
value: "{log_output}" | ||
tolerations: | ||
- key: kubernetes.io/arch | ||
operator: Equal | ||
value: stackable-linux | ||
"#, | ||
id = Uuid::new_v4(), | ||
log_output = log_output.join(NEWLINE) | ||
}, | ||
); | ||
|
||
client.verify_pod_condition(&pod, "Ready"); | ||
|
||
EchoService { client, pod } | ||
} | ||
|
||
pub fn get_logs(&self, params: &LogParams) -> Vec<String> { | ||
self.client.get_logs(&self.pod, params) | ||
} | ||
} | ||
|
||
#[test] | ||
fn all_logs_should_be_retrievable() { | ||
let client = TestKubeClient::new(); | ||
|
||
let log_output = vec!["line 1", "line 2", "line 3"]; | ||
let echo_service = EchoService::new(&client, &log_output); | ||
|
||
let logs = echo_service.get_logs(&LogParams::default()); | ||
assert_equals(&["line 1", "line 2", "line 3"], &logs); | ||
} | ||
|
||
#[test] | ||
fn the_tail_of_logs_should_be_retrievable() { | ||
let client = TestKubeClient::new(); | ||
|
||
let log_output = vec!["line 1", "line 2", "line 3"]; | ||
let echo_service = EchoService::new(&client, &log_output); | ||
|
||
let with_tail_lines = |tail_lines| LogParams { | ||
tail_lines: Some(tail_lines), | ||
..Default::default() | ||
}; | ||
|
||
let logs = echo_service.get_logs(&with_tail_lines(0)); | ||
assert_that(&logs).is_empty(); | ||
|
||
let logs = echo_service.get_logs(&with_tail_lines(1)); | ||
assert_equals(&["line 3"], &logs); | ||
|
||
let logs = echo_service.get_logs(&with_tail_lines(2)); | ||
assert_equals(&["line 2", "line 3"], &logs); | ||
|
||
let logs = echo_service.get_logs(&with_tail_lines(3)); | ||
assert_equals(&["line 1", "line 2", "line 3"], &logs); | ||
|
||
let logs = echo_service.get_logs(&with_tail_lines(4)); | ||
assert_equals(&["line 1", "line 2", "line 3"], &logs); | ||
} | ||
|
||
#[test] | ||
fn non_ascii_characters_should_be_handled_correctly() { | ||
let client = TestKubeClient::new(); | ||
|
||
let log_output = vec!["Spade: ♠", "Heart: ♥", "Diamond: ♦", "Club: ♣"]; | ||
let echo_service = EchoService::new(&client, &log_output); | ||
|
||
let logs = echo_service.get_logs(&LogParams::default()); | ||
assert_equals(&["Spade: ♠", "Heart: ♥", "Diamond: ♦", "Club: ♣"], &logs); | ||
} | ||
|
||
fn assert_equals(expected: &[&str], actual: &[String]) { | ||
assert_that(&actual.iter().map(String::as_ref).collect::<Vec<_>>()) | ||
.equals_iterator(&expected.iter()); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,47 +5,27 @@ use test::prelude::*; | |
fn service_should_be_started_successfully() { | ||
let client = TestKubeClient::new(); | ||
|
||
create_repository(&client); | ||
|
||
// Remove pod if it still exists from a previous test run. | ||
if let Some(pod) = client.find::<Pod>("agent-integration-test") { | ||
client.delete(pod); | ||
}; | ||
|
||
let pod = client.create(indoc! {r#" | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: agent-integration-test | ||
spec: | ||
containers: | ||
- name: test-service | ||
image: test-service:0.1.0 | ||
command: | ||
- test-service-0.1.0/start.sh | ||
tolerations: | ||
- key: kubernetes.io/arch | ||
operator: Equal | ||
value: stackable-linux | ||
"#}); | ||
setup_repository(&client); | ||
|
||
let pod = TemporaryResource::new( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have removed the check for an existing object - which I understand to be due to the new usage of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was also my first thought. But if it is not possible to delete a resource for the first time why should it be possible to delete it the second (or third) time? Sure, time passes and the system could have changed to allow the deletion meanwhile, but when do you stop trying? In the former code the resource was not deleted if the test case failed/panicked. So it was necessary to do the check. With the introduction of One remaining problem is that system signals like SIGINT are not handled. If the user presses Ctrl+C while the tests are running, chances are high that pods remain. As the pods often have unique names with UUIDs included, the former existence check would not help. It would be necessary to implement correct signal handling, e.g. with the ctrlc crate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The main scenario that I considered was network trouble that makes Kubernetes briefly unavailable during the test which causes the test to fail without removing the resource. |
||
&client, | ||
indoc! {" | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: agent-service-integration-test | ||
spec: | ||
containers: | ||
- name: noop-service | ||
image: noop-service:1.0.0 | ||
command: | ||
- noop-service-1.0.0/start.sh | ||
tolerations: | ||
- key: kubernetes.io/arch | ||
operator: Equal | ||
value: stackable-linux | ||
"}, | ||
); | ||
|
||
client.verify_pod_condition(&pod, "Ready"); | ||
|
||
client.delete(pod); | ||
} | ||
|
||
fn create_repository(client: &TestKubeClient) { | ||
client.apply_crd(&Repository::crd()); | ||
|
||
client.apply::<Repository>(indoc!(" | ||
apiVersion: stable.stackable.de/v1 | ||
kind: Repository | ||
metadata: | ||
name: integration-test-repository | ||
namespace: default | ||
spec: | ||
repo_type: StackableRepo | ||
properties: | ||
url: https://raw.githubusercontent.com/stackabletech/integration-test-repo/6d784f1fb433123cb3b1d5cd7364a4553246d749/ | ||
")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for documenting this, I can only imagine the pain that went into these five lines!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the layers which eat backslashes are under our control. We could try to make them less voracious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not worth the effort unless it creates issues.