Skip to content

Commit adb6415

Browse files
authored
Merge pull request #135 from attogram/jules/testing-improvements
feat: Add comprehensive test suite
2 parents 0813318 + 6a9f873 commit adb6415

19 files changed

+944
-4
lines changed

docs/jules.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,38 @@ This file is for me, Jules, to keep notes on how to work with this repository.
1212
* New shell scripts must be made executable with `chmod +x` before they can be run by other scripts.
1313
* The `demos/run.demos.sh` script is the standard way to generate the markdown documentation for the demos.
1414

15+
## Testing
16+
17+
### Setting up Bats
18+
19+
I have set up the Bats testing framework for this project. Here are the steps I took:
20+
21+
1. **Checked for Bats:** I first checked if Bats was installed by running `bats --version`. The command failed, indicating that Bats was not installed.
22+
2. **Installed Bats:** I installed Bats using the command `sudo apt-get update && sudo apt-get install -y bats`.
23+
3. **Verified Installation:** After the installation, I ran `bats --version` again and confirmed that it was installed correctly.
24+
4. **Created a Test File:** I created a simple test file at `tests/basic.bats` to ensure that the testing framework was working.
25+
5. **Ran the Test:** I ran the test using the command `bats tests/basic.bats` and it passed.
26+
27+
This process confirms that the testing environment is now set up and ready for use.
28+
29+
### Comprehensive Test Suite
30+
31+
I have created a comprehensive test suite for the library, covering all public and internal functions. The process involved:
32+
33+
1. **Identifying all functions:** I listed all functions from `ollama_bash_lib.sh` to ensure complete coverage.
34+
2. **Creating individual test files:** I created separate `.bats` files for each function or group of related functions in the `tests/` directory.
35+
3. **Writing test cases:** I wrote multiple test cases for each function, covering:
36+
* Positive scenarios (correct usage and expected output).
37+
* Negative scenarios (error handling, invalid input).
38+
* Edge cases.
39+
4. **Debugging and Fixing:** I encountered and fixed several issues during the testing process, including:
40+
* Incorrect assumptions about function behavior (e.g., `_is_valid_json`).
41+
* Bugs in the library code (e.g., `ollama_model_unload`).
42+
* Subshell issues in Bats tests that prevented state changes from being persisted.
43+
5. **Ensuring all tests pass:** I ran the entire test suite and ensured that all 53 tests passed successfully.
44+
45+
This comprehensive test suite will help to ensure the quality and stability of the library going forward.
46+
1547
## Documentation and Demo Structure
1648

1749
I have created a new documentation and demo structure. Here is how to keep it up-to-date:

ollama_bash_lib.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,16 +1715,17 @@ EOF
17151715
local json_payload
17161716
json_payload="$(jq -c -n \
17171717
--arg model "$model" \
1718-
--arg keep_alive '0' \
1719-
'{model: $model, keep_alive: $keep_alive}')"
1718+
--arg prompt "" \
1719+
--arg keep_alive "0" \
1720+
'{model: $model, prompt: $prompt, keep_alive: $keep_alive}')"
17201721
local result
17211722
if ! result="$(ollama_api_post -P '/api/generate' -d "$json_payload")"; then
17221723
_error "ollama_model_unload: ollama_api_post failed [$result]"
17231724
return 1
17241725
fi
17251726
local is_error
17261727
is_error="$(printf '%s' "$result" | jq -r .error)"
1727-
if [[ -n "$is_error" ]]; then
1728+
if [[ -n "$is_error" && "$is_error" != "null" ]]; then
17281729
_error "ollama_model_unload: $is_error"
17291730
return 1
17301731
fi

tests/README.md

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,80 @@
1-
Future home of BATS test suite for Ollama Bash Lib
1+
# Ollama Bash Lib - Testing
2+
3+
This directory contains the test suite for the Ollama Bash Lib. The tests are written using the [Bats (Bash Automated Testing System)](https://github.com/bats-core/bats-core).
4+
5+
## Setting up the Test Environment
6+
7+
To run the tests, you will need to have Bats installed.
8+
9+
### Installing Bats
10+
11+
You can install Bats using your system's package manager.
12+
13+
**For Debian/Ubuntu:**
14+
```bash
15+
sudo apt-get update
16+
sudo apt-get install -y bats
17+
```
18+
19+
**For macOS (using Homebrew):**
20+
```bash
21+
brew install bats-core
22+
```
23+
24+
For other systems, please refer to the [official Bats installation guide](https://github.com/bats-core/bats-core#installing-bats-from-source).
25+
26+
After installation, you can verify that Bats is installed correctly by running:
27+
```bash
28+
bats --version
29+
```
30+
31+
## Running Tests
32+
33+
To run the entire test suite, navigate to the root of the repository and run:
34+
```bash
35+
bats tests/
36+
```
37+
38+
This will execute all the `.bats` files in the `tests` directory.
39+
40+
To run a specific test file, you can pass the path to the file as an argument:
41+
```bash
42+
bats tests/some_test_file.bats
43+
```
44+
45+
## Creating New Tests
46+
47+
To create new tests, you should create a new file in the `tests` directory with a `.bats` extension. It is recommended to create a separate file for each function or group of related functions. For example, tests for the `ollama_generate` function should be in a file named `tests/ollama_generate.bats`.
48+
49+
### Test File Structure
50+
51+
A basic test file looks like this:
52+
53+
```bash
54+
#!/usr/bin/env bats
55+
56+
# Load the Ollama Bash Lib
57+
source ./ollama_bash_lib.sh
58+
59+
# A basic test case
60+
@test "A descriptive name for your test" {
61+
# Run a command or function
62+
run some_function_to_test "with some arguments"
63+
64+
# Add assertions to check the output
65+
[ "$status" -eq 0 ] # Check the exit status
66+
[ "$output" = "expected output" ] # Check the output string
67+
}
68+
```
69+
70+
### Writing Tests
71+
72+
- **Load the Library:** Make sure to source the `ollama_bash_lib.sh` at the beginning of your test file so that you can call the library functions.
73+
- **Test Names:** Use descriptive names for your tests in the `@test` directive.
74+
- **`run` command:** Use the `run` command to execute the function you want to test. This captures the `status` and `output` of the command.
75+
- **Assertions:** Use assertions to check the results of your test. Bats provides special variables that you can use for assertions:
76+
- `$status`: The exit status of the command.
77+
- `$output`: The combined content of stdout and stderr from the command.
78+
- `$lines`: An array containing each line of the output.
79+
80+
For more advanced testing techniques, please refer to the [official Bats documentation](https://bats-core.readthedocs.io/en/stable/).

tests/basic.bats

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bats
2+
3+
@test "hello world" {
4+
run echo "hello world"
5+
[ "$status" -eq 0 ]
6+
[ "$output" = "hello world" ]
7+
}

tests/call_curl.bats

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env bats
2+
3+
source ./ollama_bash_lib.sh
4+
5+
@test "_call_curl: should return error for invalid method" {
6+
run _call_curl "INVALID_METHOD" "/api/tags"
7+
[ "$status" -ne 0 ]
8+
}
9+
10+
@test "_call_curl: should return error for invalid API path" {
11+
run _call_curl "GET" "invalid path"
12+
[ "$status" -ne 0 ]
13+
}
14+
15+
@test "_call_curl: should return error for invalid JSON body" {
16+
run _call_curl "POST" "/api/generate" '{"invalid json'
17+
[ "$status" -ne 0 ]
18+
}
19+
20+
@test "_call_curl: should make a successful GET request" {
21+
# This will make a real request to the running Ollama instance
22+
run _call_curl "GET" "/api/tags"
23+
[ "$status" -eq 0 ]
24+
_is_valid_json "$output"
25+
local is_valid_json_status=$?
26+
[ "$is_valid_json_status" -eq 0 ]
27+
}
28+
29+
@test "_call_curl: should make a successful POST request" {
30+
# This will make a real request to the running Ollama instance
31+
run _call_curl "POST" "/api/show" '{"model": "phi3"}'
32+
[ "$status" -eq 0 ]
33+
_is_valid_json "$output"
34+
local is_valid_json_status=$?
35+
[ "$is_valid_json_status" -eq 0 ]
36+
}

tests/internal_helpers.bats

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env bats
2+
3+
source ./ollama_bash_lib.sh
4+
5+
@test "_redact: should redact sensitive information" {
6+
OBL_TURBO_KEY="test_key"
7+
run _redact "this is a test with test_key"
8+
[ "$status" -eq 0 ]
9+
[[ "$output" == *"this is a test with [REDACTED]"* ]]
10+
}
11+
12+
@test "_exists: should return 0 for existing commands" {
13+
run _exists "echo"
14+
[ "$status" -eq 0 ]
15+
}
16+
17+
@test "_exists: should return 1 for non-existing commands" {
18+
run _exists "non_existent_command"
19+
[ "$status" -eq 1 ]
20+
}
21+
22+
@test "_is_valid_url: should return 0 for valid URLs" {
23+
run _is_valid_url "http://localhost:11434"
24+
[ "$status" -eq 0 ]
25+
run _is_valid_url "https://example.com"
26+
[ "$status" -eq 0 ]
27+
}
28+
29+
@test "_is_valid_url: should return 1 for invalid URLs" {
30+
run _is_valid_url "not a url"
31+
[ "$status" -eq 1 ]
32+
run _is_valid_url "http:://invalid"
33+
[ "$status" -eq 1 ]
34+
}

tests/internal_model_helpers.bats

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bats
2+
3+
source ./ollama_bash_lib.sh
4+
5+
@test "_ollama_generate_json_payload: should create a valid JSON payload" {
6+
run _ollama_generate_json_payload "phi3" "test prompt"
7+
[ "$status" -eq 0 ]
8+
_is_valid_json "$output"
9+
local is_valid_json_status=$?
10+
[ "$is_valid_json_status" -eq 0 ]
11+
[[ "$output" =~ "phi3" ]]
12+
[[ "$output" =~ "test prompt" ]]
13+
}
14+
15+
@test "_is_valid_model: should return 0 for valid model names" {
16+
run _is_valid_model "phi3:latest"
17+
[ "$status" -eq 0 ]
18+
[ "$output" = "phi3:latest" ]
19+
}
20+
21+
@test "_is_valid_model: should return 1 for invalid model names" {
22+
run _is_valid_model "invalid name with spaces"
23+
[ "$status" -eq 1 ]
24+
[ -z "$output" ]
25+
}
26+
27+
@test "_is_valid_model: should return a random model when input is empty" {
28+
run _is_valid_model ""
29+
[ "$status" -eq 0 ]
30+
[ -n "$output" ]
31+
}

tests/is_valid_json.bats

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env bats
2+
3+
source ./ollama_bash_lib.sh
4+
5+
@test "_is_valid_json: should return 0 for valid and truthy JSON" {
6+
run _is_valid_json '{"key": "value"}'
7+
[ "$status" -eq 0 ]
8+
run _is_valid_json '{"key": 0}'
9+
[ "$status" -eq 0 ]
10+
run _is_valid_json '{"key": true}'
11+
[ "$status" -eq 0 ]
12+
}
13+
14+
@test "_is_valid_json: should return 1 for invalid JSON syntax" {
15+
run _is_valid_json '{"key": "value"'
16+
[ "$status" -ne 0 ]
17+
}
18+
19+
@test "_is_valid_json: should return 1 for an empty string" {
20+
run _is_valid_json ""
21+
[ "$status" -ne 0 ]
22+
}
23+
24+
@test "_is_valid_json: should return 1 for 'null' as the top-level value" {
25+
run _is_valid_json 'null'
26+
[ "$status" -eq 1 ]
27+
}
28+
29+
@test "_is_valid_json: should return 1 for 'false' as the top-level value" {
30+
run _is_valid_json 'false'
31+
[ "$status" -eq 1 ]
32+
}
33+
34+
@test "_is_valid_json: should return 0 for JSON containing 'null' but not as the top-level value" {
35+
run _is_valid_json '{"key": null}'
36+
[ "$status" -eq 0 ]
37+
}
38+
39+
@test "_is_valid_json: should return 0 for JSON containing 'false' but not as the top-level value" {
40+
run _is_valid_json '{"key": false}'
41+
[ "$status" -eq 0 ]
42+
}

tests/ollama_api_ping.bats

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bats
2+
3+
source ./ollama_bash_lib.sh
4+
5+
@test "ollama_api_ping: should succeed when the API is running" {
6+
run ollama_api_ping
7+
[ "$status" -eq 0 ]
8+
}

tests/ollama_app.bats

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bats
2+
3+
source ./ollama_bash_lib.sh
4+
5+
@test "ollama_app_installed: should return 0" {
6+
run ollama_app_installed
7+
[ "$status" -eq 0 ]
8+
}
9+
10+
@test "ollama_app_turbo: should toggle turbo mode" {
11+
# I can't test the interactive prompt for the key, so I'll set it in the environment
12+
export OBL_TURBO_KEY="test_key"
13+
14+
ollama_app_turbo -m on
15+
[ "$OBL_API" = "https://ollama.com" ]
16+
17+
ollama_app_turbo -m off
18+
[ "$OBL_API" = "http://localhost:11434" ]
19+
}
20+
21+
@test "ollama_app_vars: should return a list of variables" {
22+
run ollama_app_vars
23+
[ "$status" -eq 0 ]
24+
[ -n "$output" ]
25+
}

0 commit comments

Comments
 (0)