Skip to content

Commit 68faf6c

Browse files
authored
Add more tests (#13)
* Add more tests
1 parent e979807 commit 68faf6c

File tree

11 files changed

+628
-217
lines changed

11 files changed

+628
-217
lines changed

.github/workflows/coverage.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,39 @@
1-
name: coverage
1+
name: Coverage
22

33
on: [push]
44

55
jobs:
66
test:
77
name: coverage
8-
runs-on: ubuntu-latest
8+
runs-on: ubuntu-22.04
99
container:
1010
image: xd009642/tarpaulin:develop-nightly
1111
options: --security-opt seccomp=unconfined
1212
steps:
1313
- uses: actions/checkout@v4
1414

15+
- name: Setup SSH for tests
16+
env:
17+
USER_TEST: usertest
18+
run: |
19+
apt update && apt install -y openssh-server
20+
service ssh start
21+
mkdir ${HOME}/.ssh
22+
ssh-keyscan -H localhost | tee -a ${HOME}/.ssh/known_hosts
23+
ssh-keygen -t ed25519 -N "" -f ${HOME}/.ssh/id_ed25519
24+
useradd -m -d /home/${USER_TEST} -N ${USER_TEST}
25+
su ${USER_TEST} -c 'mkdir /home/${USER_TEST}/.ssh'
26+
cat ${HOME}/.ssh/id_ed25519.pub | su ${USER_TEST} -c 'tee -a /home/${USER_TEST}/.ssh/authorized_keys'
27+
chmod 700 /home/${USER_TEST}/.ssh
28+
chmod 600 /home/${USER_TEST}/.ssh/authorized_keys
29+
echo "127.0.0.1 localhost2" | tee -a /etc/hosts > /dev/null
30+
1531
- name: Generate coverage report
1632
run: |
1733
cargo +nightly tarpaulin --verbose --out Xml --implicit-test-threads
1834
1935
- name: Upload coverage reports to Codecov
2036
uses: codecov/codecov-action@v5
2137
with:
22-
token: ${{secrets.CODECOV_TOKEN}}
23-
fail_ci_if_error: false
38+
token: ${{ secrets.CODECOV_TOKEN }}
39+
fail_ci_if_error: false

.github/workflows/rust.yml

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,39 @@ env:
1111

1212
jobs:
1313
build:
14-
runs-on: ubuntu-latest
14+
runs-on: ubuntu-22.04
1515

1616
steps:
17-
- uses: actions/checkout@v4
18-
19-
- name: Cache cargo dependencies
20-
uses: actions/cache@v4
21-
with:
22-
path: |
23-
~/.cargo/bin/
24-
~/.cargo/registry/index/
25-
~/.cargo/registry/cache/
26-
~/.cargo/git/db/
27-
target/
28-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
29-
30-
- name: Build
31-
run: cargo build --verbose
32-
33-
- name: Run tests
34-
run: cargo test --verbose
17+
- uses: actions/checkout@v4
18+
19+
- name: Cache cargo dependencies
20+
uses: actions/cache@v4
21+
with:
22+
path: |
23+
~/.cargo/bin/
24+
~/.cargo/registry/index/
25+
~/.cargo/registry/cache/
26+
~/.cargo/git/db/
27+
target/
28+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
29+
30+
- name: Build
31+
run: cargo build --verbose
32+
33+
- name: Setup SSH for tests
34+
env:
35+
USER_TEST: usertest
36+
run: |
37+
sudo service ssh start
38+
mkdir ${HOME}/.ssh
39+
ssh-keyscan -H localhost | tee -a ${HOME}/.ssh/known_hosts
40+
ssh-keygen -t ed25519 -N "" -f ${HOME}/.ssh/id_ed25519
41+
sudo useradd -m -d /home/${USER_TEST} -N ${USER_TEST}
42+
sudo -u ${USER_TEST} mkdir /home/${USER_TEST}/.ssh
43+
cat ${HOME}/.ssh/id_ed25519.pub | sudo -u ${USER_TEST} tee -a /home/${USER_TEST}/.ssh/authorized_keys
44+
sudo chmod 700 /home/${USER_TEST}/.ssh
45+
sudo chmod 600 /home/${USER_TEST}/.ssh/authorized_keys
46+
echo "127.0.0.1 localhost2" | sudo tee -a /etc/hosts > /dev/null
47+
48+
- name: Run tests
49+
run: cargo test --verbose

src/args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clap::Parser;
22

33
/// Your army commander
4-
#[derive(Parser, Debug)]
4+
#[derive(Parser, Debug, PartialEq)]
55
#[command(about, long_about = None)]
66
pub struct Args {
77
/// Main file location

src/lib.rs

Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod args;
22
mod defaults;
33
mod modules;
4-
mod ssh;
4+
pub mod ssh;
55
mod util;
66
mod validator;
77

@@ -389,6 +389,22 @@ pub fn print_version() {
389389
mod tests {
390390
use super::*;
391391

392+
#[test]
393+
fn test_cli_args() {
394+
let args = vec!["komandan", "--verbose", "/tmp/test/main.lua"];
395+
let args = Args::parse_from(args);
396+
assert_eq!(
397+
args,
398+
Args {
399+
chunk: None,
400+
interactive: false,
401+
verbose: true,
402+
version: false,
403+
main_file: Some("/tmp/test/main.lua".to_string()),
404+
}
405+
);
406+
}
407+
392408
#[test]
393409
fn test_setup_komandan_table() {
394410
let lua = Lua::new();
@@ -415,63 +431,6 @@ mod tests {
415431
assert!(modules_table.contains_key("download").unwrap());
416432
}
417433

418-
#[test]
419-
fn test_set_defaults() {
420-
let lua = Lua::new();
421-
setup_komandan_table(&lua).unwrap();
422-
423-
// Test setting a default value
424-
let defaults_data = lua.create_table().unwrap();
425-
defaults_data.set("user", "testuser").unwrap();
426-
set_defaults(&lua, Value::Table(defaults_data)).unwrap();
427-
428-
let defaults = lua
429-
.globals()
430-
.get::<Table>("komandan")
431-
.unwrap()
432-
.get::<Table>("defaults")
433-
.unwrap();
434-
assert_eq!(defaults.get::<String>("user").unwrap(), "testuser");
435-
436-
// Test setting multiple default values
437-
let defaults_data = lua.create_table().unwrap();
438-
defaults_data.set("port", 2222).unwrap();
439-
defaults_data.set("key", "/path/to/key").unwrap();
440-
set_defaults(&lua, Value::Table(defaults_data)).unwrap();
441-
442-
let defaults = lua
443-
.globals()
444-
.get::<Table>("komandan")
445-
.unwrap()
446-
.get::<Table>("defaults")
447-
.unwrap();
448-
assert_eq!(defaults.get::<Integer>("port").unwrap(), 2222);
449-
assert_eq!(defaults.get::<String>("key").unwrap(), "/path/to/key");
450-
451-
// Test with non-table input
452-
let result = set_defaults(
453-
&lua,
454-
Value::String(lua.create_string("not_a_table").unwrap()),
455-
);
456-
assert!(result.is_err());
457-
}
458-
459-
#[test]
460-
fn test_hostname_display() {
461-
let lua = Lua::new();
462-
463-
// Test with name
464-
let host = lua.create_table().unwrap();
465-
host.set("address", "192.168.1.1").unwrap();
466-
host.set("name", "test").unwrap();
467-
assert_eq!(hostname_display(&host), "test (192.168.1.1)");
468-
469-
// Test without name
470-
let host = lua.create_table().unwrap();
471-
host.set("address", "10.0.0.1").unwrap();
472-
assert_eq!(hostname_display(&host), "10.0.0.1");
473-
}
474-
475434
#[test]
476435
fn test_run_main_file() {
477436
let lua = Lua::new();

src/main.rs

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -43,74 +43,3 @@ async fn main() -> anyhow::Result<()> {
4343

4444
Ok(())
4545
}
46-
47-
#[cfg(test)]
48-
mod tests {
49-
use std::env;
50-
use std::io::Write;
51-
52-
use super::*;
53-
54-
#[tokio::test]
55-
async fn test_main_version() -> anyhow::Result<()> {
56-
let mut args = Args::parse_from(["komandan", "--version"]);
57-
args.version = true;
58-
59-
let mut buf = Vec::new();
60-
let result = {
61-
let writer = std::io::BufWriter::new(&mut buf);
62-
let mut writer = std::io::LineWriter::new(writer);
63-
64-
let res = main_with_args(args, &mut writer).await;
65-
writer.flush()?;
66-
res
67-
};
68-
69-
assert!(result.is_ok());
70-
71-
let output = String::from_utf8(buf)?;
72-
assert!(output.contains(env!("CARGO_PKG_VERSION")));
73-
Ok(())
74-
}
75-
76-
async fn main_with_args(args: Args, writer: &mut impl std::io::Write) -> anyhow::Result<()> {
77-
if args.version {
78-
print_version_with_writer(writer)?;
79-
return Ok(());
80-
}
81-
82-
let lua = Lua::new();
83-
84-
setup_lua_env(&lua)?;
85-
86-
let chunk = args.chunk.clone();
87-
match chunk {
88-
Some(chunk) => {
89-
lua.load(&chunk).eval::<()>()?;
90-
}
91-
None => {}
92-
}
93-
94-
match &args.main_file {
95-
Some(main_file) => {
96-
run_main_file(&lua, &main_file)?;
97-
}
98-
None => {
99-
if args.chunk.is_none() {
100-
repl(&lua);
101-
}
102-
}
103-
};
104-
105-
if args.interactive && (!args.main_file.is_none() || !&args.chunk.is_none()) {
106-
repl(&lua);
107-
}
108-
109-
Ok(())
110-
}
111-
112-
fn print_version_with_writer(writer: &mut impl std::io::Write) -> anyhow::Result<()> {
113-
writeln!(writer, "{}", env::var("CARGO_PKG_VERSION").unwrap())?;
114-
Ok(())
115-
}
116-
}

src/modules/lineinfile.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,70 @@ if [ "$STATE" = "absent" ]; then
235235
exit 0
236236
fi
237237
"#;
238+
239+
// Tests
240+
#[cfg(test)]
241+
mod tests {
242+
use super::*;
243+
244+
#[test]
245+
fn test_lineinfile_no_path() {
246+
let lua = Lua::new();
247+
let params = lua.create_table().unwrap();
248+
let result = lineinfile(&lua, params);
249+
assert!(result.is_err());
250+
assert_eq!(
251+
result.unwrap_err().to_string(),
252+
"runtime error: 'path' parameter is required"
253+
);
254+
}
255+
256+
#[test]
257+
fn test_lineinfile_invalid_state() {
258+
let lua = Lua::new();
259+
let params = lua.create_table().unwrap();
260+
params.set("path", "/tmp/test.txt").unwrap();
261+
params.set("state", "--invalid-state--").unwrap();
262+
let result = lineinfile(&lua, params);
263+
assert!(result.is_err());
264+
assert_eq!(
265+
result.unwrap_err().to_string(),
266+
"runtime error: 'state' parameter must be 'present' or 'absent'"
267+
);
268+
}
269+
270+
#[test]
271+
fn test_lineinfile_no_line_or_pattern() {
272+
let lua = Lua::new();
273+
let params = lua.create_table().unwrap();
274+
params.set("path", "/tmp/test.txt").unwrap();
275+
let result = lineinfile(&lua, params);
276+
assert!(result.is_err());
277+
assert_eq!(
278+
result.unwrap_err().to_string(),
279+
"runtime error: 'line' or 'pattern' parameter is required"
280+
);
281+
}
282+
283+
#[test]
284+
fn test_lineinfile_present() {
285+
let lua = Lua::new();
286+
let params = lua.create_table().unwrap();
287+
params.set("path", "/tmp/test.txt").unwrap();
288+
params.set("state", "present").unwrap();
289+
params.set("line", "Hello, world!").unwrap();
290+
let result = lineinfile(&lua, params);
291+
assert!(result.is_ok());
292+
}
293+
294+
#[test]
295+
fn test_lineinfile_absent() {
296+
let lua = Lua::new();
297+
let params = lua.create_table().unwrap();
298+
params.set("path", "/tmp/test.txt").unwrap();
299+
params.set("state", "absent").unwrap();
300+
params.set("line", "Hello, world!").unwrap();
301+
let result = lineinfile(&lua, params);
302+
assert!(result.is_ok());
303+
}
304+
}

src/modules/script.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,23 @@ mod tests {
8989
"runtime error: script and from_file parameters cannot be used together"
9090
);
9191
}
92+
93+
#[test]
94+
fn test_script() {
95+
let lua = Lua::new();
96+
let params = lua.create_table().unwrap();
97+
params.set("script", "echo hello").unwrap();
98+
params.set("interpreter", "bash").unwrap();
99+
let result = script(&lua, params);
100+
assert!(result.is_ok());
101+
}
102+
103+
#[test]
104+
fn test_from_file() {
105+
let lua = Lua::new();
106+
let params = lua.create_table().unwrap();
107+
params.set("from_file", "examples/run_script.lua").unwrap();
108+
let result = script(&lua, params);
109+
assert!(result.is_ok());
110+
}
92111
}

src/modules/template.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ mod tests {
129129
writeln!(temp_file, "{{ name }} is {{ age }} years old").unwrap();
130130
let lua = Lua::new();
131131
let params = lua.create_table().unwrap();
132-
params.set("src", temp_file.path().to_str().unwrap()).unwrap();
132+
params
133+
.set("src", temp_file.path().to_str().unwrap())
134+
.unwrap();
133135
params.set("dst", "/remote/file").unwrap();
134136
let vars = lua.create_table().unwrap();
135137
vars.set("name", "John").unwrap();

0 commit comments

Comments
 (0)