1package ollama
2
3import (
4 "context"
5 "testing"
6 "time"
7)
8
9func TestCLIListModels(t *testing.T) {
10 if !IsInstalled() {
11 t.Skip("Ollama is not installed, skipping CLI test")
12 }
13
14 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
15 defer cancel()
16
17 models, err := CLIListModels(ctx)
18 if err != nil {
19 t.Fatalf("Failed to list models via CLI: %v", err)
20 }
21
22 t.Logf("Found %d models via CLI", len(models))
23 for _, model := range models {
24 t.Logf(" - %s", model.Name)
25 }
26}
27
28func TestCLIListRunningModels(t *testing.T) {
29 if !IsInstalled() {
30 t.Skip("Ollama is not installed, skipping CLI test")
31 }
32
33 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
34 defer cancel()
35
36 // Ensure Ollama is running
37 if !IsRunning(ctx) {
38 t.Log("Starting Ollama service...")
39 if err := StartOllamaService(ctx); err != nil {
40 t.Fatalf("Failed to start Ollama service: %v", err)
41 }
42 defer cleanupProcesses()
43 }
44
45 runningModels, err := CLIListRunningModels(ctx)
46 if err != nil {
47 t.Fatalf("Failed to list running models via CLI: %v", err)
48 }
49
50 t.Logf("Found %d running models via CLI", len(runningModels))
51 for _, model := range runningModels {
52 t.Logf(" - %s", model)
53 }
54}
55
56func TestCLIStopAllModels(t *testing.T) {
57 if !IsInstalled() {
58 t.Skip("Ollama is not installed, skipping CLI test")
59 }
60
61 ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
62 defer cancel()
63
64 // Ensure Ollama is running
65 if !IsRunning(ctx) {
66 t.Log("Starting Ollama service...")
67 if err := StartOllamaService(ctx); err != nil {
68 t.Fatalf("Failed to start Ollama service: %v", err)
69 }
70 defer cleanupProcesses()
71 }
72
73 // Get available models
74 models, err := GetModels(ctx)
75 if err != nil {
76 t.Fatalf("Failed to get models: %v", err)
77 }
78
79 if len(models) == 0 {
80 t.Skip("No models available, skipping CLI stop test")
81 }
82
83 // Pick a small model for testing
84 testModel := models[0].ID
85 for _, model := range models {
86 if model.ID == "phi3:3.8b" || model.ID == "llama3.2:3b" {
87 testModel = model.ID
88 break
89 }
90 }
91
92 t.Logf("Testing CLI stop with model: %s", testModel)
93
94 // Check if model is running
95 running, err := CLIIsModelRunning(ctx, testModel)
96 if err != nil {
97 t.Fatalf("Failed to check if model is running: %v", err)
98 }
99
100 // If not running, start it
101 if !running {
102 t.Log("Starting model for CLI stop test...")
103 if err := StartModel(ctx, testModel); err != nil {
104 t.Fatalf("Failed to start model: %v", err)
105 }
106
107 // Verify it's now running
108 running, err = CLIIsModelRunning(ctx, testModel)
109 if err != nil {
110 t.Fatalf("Failed to check if model is running after start: %v", err)
111 }
112 if !running {
113 t.Fatal("Model failed to start")
114 }
115 t.Log("Model started successfully")
116 } else {
117 t.Log("Model was already running")
118 }
119
120 // Now test CLI stop
121 t.Log("Testing CLI stop all models...")
122 if err := CLIStopAllModels(ctx); err != nil {
123 t.Fatalf("Failed to stop all models via CLI: %v", err)
124 }
125
126 // Give some time for models to stop
127 time.Sleep(2 * time.Second)
128
129 // Check if model is still running
130 running, err = CLIIsModelRunning(ctx, testModel)
131 if err != nil {
132 t.Fatalf("Failed to check if model is running after stop: %v", err)
133 }
134
135 if running {
136 t.Error("Model is still running after CLI stop")
137 } else {
138 t.Log("Model successfully stopped via CLI")
139 }
140}
141
142func TestCLIvsHTTPPerformance(t *testing.T) {
143 if !IsInstalled() {
144 t.Skip("Ollama is not installed, skipping performance test")
145 }
146
147 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
148 defer cancel()
149
150 // Ensure Ollama is running
151 if !IsRunning(ctx) {
152 t.Log("Starting Ollama service...")
153 if err := StartOllamaService(ctx); err != nil {
154 t.Fatalf("Failed to start Ollama service: %v", err)
155 }
156 defer cleanupProcesses()
157 }
158
159 results, err := BenchmarkCLIvsHTTP(ctx)
160 if err != nil {
161 t.Fatalf("Failed to benchmark CLI vs HTTP: %v", err)
162 }
163
164 t.Log("Performance Comparison (CLI vs HTTP):")
165 for operation, duration := range results {
166 t.Logf(" %s: %v", operation, duration)
167 }
168
169 // Compare HTTP vs CLI for model listing
170 httpTime := results["HTTP_GetModels"]
171 cliTime := results["CLI_ListModels"]
172
173 if httpTime < cliTime {
174 t.Logf("HTTP is faster for listing models (%v vs %v)", httpTime, cliTime)
175 } else {
176 t.Logf("CLI is faster for listing models (%v vs %v)", cliTime, httpTime)
177 }
178
179 // Compare HTTP vs CLI for running models
180 httpRunningTime := results["HTTP_GetRunningModels"]
181 cliRunningTime := results["CLI_ListRunningModels"]
182
183 if httpRunningTime < cliRunningTime {
184 t.Logf("HTTP is faster for listing running models (%v vs %v)", httpRunningTime, cliRunningTime)
185 } else {
186 t.Logf("CLI is faster for listing running models (%v vs %v)", cliRunningTime, httpRunningTime)
187 }
188}
189
190func TestCLICleanupVsHTTPCleanup(t *testing.T) {
191 if !IsInstalled() {
192 t.Skip("Ollama is not installed, skipping cleanup comparison test")
193 }
194
195 ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
196 defer cancel()
197
198 // Ensure Ollama is running
199 if !IsRunning(ctx) {
200 t.Log("Starting Ollama service...")
201 if err := StartOllamaService(ctx); err != nil {
202 t.Fatalf("Failed to start Ollama service: %v", err)
203 }
204 defer cleanupProcesses()
205 }
206
207 // Get available models
208 models, err := GetModels(ctx)
209 if err != nil {
210 t.Fatalf("Failed to get models: %v", err)
211 }
212
213 if len(models) == 0 {
214 t.Skip("No models available, skipping cleanup comparison test")
215 }
216
217 // Pick a small model for testing
218 testModel := models[0].ID
219 for _, model := range models {
220 if model.ID == "phi3:3.8b" || model.ID == "llama3.2:3b" {
221 testModel = model.ID
222 break
223 }
224 }
225
226 t.Logf("Testing cleanup comparison with model: %s", testModel)
227
228 // Test 1: HTTP-based cleanup
229 t.Log("Testing HTTP-based cleanup...")
230
231 // Start model
232 if err := StartModel(ctx, testModel); err != nil {
233 t.Fatalf("Failed to start model: %v", err)
234 }
235
236 // Verify it's loaded
237 loaded, err := IsModelLoaded(ctx, testModel)
238 if err != nil {
239 t.Fatalf("Failed to check if model is loaded: %v", err)
240 }
241 if !loaded {
242 t.Fatal("Model failed to load")
243 }
244
245 // Time HTTP cleanup
246 start := time.Now()
247 cleanupProcesses()
248 httpCleanupTime := time.Since(start)
249
250 // Give time for cleanup
251 time.Sleep(2 * time.Second)
252
253 // Check if model is still loaded
254 loaded, err = IsModelLoaded(ctx, testModel)
255 if err != nil {
256 t.Fatalf("Failed to check if model is loaded after HTTP cleanup: %v", err)
257 }
258
259 httpCleanupWorked := !loaded
260
261 // Test 2: CLI-based cleanup
262 t.Log("Testing CLI-based cleanup...")
263
264 // Start model again
265 if err := StartModel(ctx, testModel); err != nil {
266 t.Fatalf("Failed to start model for CLI test: %v", err)
267 }
268
269 // Verify it's loaded
270 loaded, err = IsModelLoaded(ctx, testModel)
271 if err != nil {
272 t.Fatalf("Failed to check if model is loaded: %v", err)
273 }
274 if !loaded {
275 t.Fatal("Model failed to load for CLI test")
276 }
277
278 // Time CLI cleanup
279 start = time.Now()
280 if err := CLICleanupProcesses(ctx); err != nil {
281 t.Fatalf("CLI cleanup failed: %v", err)
282 }
283 cliCleanupTime := time.Since(start)
284
285 // Give time for cleanup
286 time.Sleep(2 * time.Second)
287
288 // Check if model is still loaded
289 loaded, err = IsModelLoaded(ctx, testModel)
290 if err != nil {
291 t.Fatalf("Failed to check if model is loaded after CLI cleanup: %v", err)
292 }
293
294 cliCleanupWorked := !loaded
295
296 // Compare results
297 t.Log("Cleanup Comparison Results:")
298 t.Logf(" HTTP cleanup: %v (worked: %v)", httpCleanupTime, httpCleanupWorked)
299 t.Logf(" CLI cleanup: %v (worked: %v)", cliCleanupTime, cliCleanupWorked)
300
301 if httpCleanupWorked && cliCleanupWorked {
302 if httpCleanupTime < cliCleanupTime {
303 t.Logf("HTTP cleanup is faster and both work")
304 } else {
305 t.Logf("CLI cleanup is faster and both work")
306 }
307 } else if httpCleanupWorked && !cliCleanupWorked {
308 t.Logf("HTTP cleanup works better (CLI cleanup failed)")
309 } else if !httpCleanupWorked && cliCleanupWorked {
310 t.Logf("CLI cleanup works better (HTTP cleanup failed)")
311 } else {
312 t.Logf("Both cleanup methods failed")
313 }
314}