|
6 | 6 | "errors"
|
7 | 7 | "os"
|
8 | 8 | "path/filepath"
|
| 9 | + "strings" |
9 | 10 | "testing"
|
10 | 11 | "time"
|
11 | 12 |
|
@@ -860,3 +861,100 @@ func TestFileStatusManager_GetWorkload_HealthyWithProxy(t *testing.T) {
|
860 | 861 | assert.Equal(t, "container started", workload.StatusContext) // Original file context preserved
|
861 | 862 | assert.Equal(t, "test-image:latest", workload.Package)
|
862 | 863 | }
|
| 864 | + |
| 865 | +func TestFileStatusManager_ListWorkloads_WithValidation(t *testing.T) { |
| 866 | + t.Parallel() |
| 867 | + |
| 868 | + ctrl := gomock.NewController(t) |
| 869 | + defer ctrl.Finish() |
| 870 | + |
| 871 | + tempDir := t.TempDir() |
| 872 | + mockRuntime := mocks.NewMockRuntime(ctrl) |
| 873 | + manager := &fileStatusManager{ |
| 874 | + baseDir: tempDir, |
| 875 | + runtime: mockRuntime, |
| 876 | + } |
| 877 | + ctx := context.Background() |
| 878 | + |
| 879 | + // Create file workloads - one healthy running, one with runtime mismatch, one with proxy down |
| 880 | + err := manager.SetWorkloadStatus(ctx, "healthy-workload", rt.WorkloadStatusRunning, "container started") |
| 881 | + require.NoError(t, err) |
| 882 | + |
| 883 | + err = manager.SetWorkloadStatus(ctx, "runtime-mismatch", rt.WorkloadStatusRunning, "container started") |
| 884 | + require.NoError(t, err) |
| 885 | + |
| 886 | + err = manager.SetWorkloadStatus(ctx, "proxy-down", rt.WorkloadStatusRunning, "container started") |
| 887 | + require.NoError(t, err) |
| 888 | + |
| 889 | + // Mock runtime containers |
| 890 | + runtimeContainers := []rt.ContainerInfo{ |
| 891 | + { |
| 892 | + Name: "healthy-workload", |
| 893 | + Image: "healthy:latest", |
| 894 | + Status: "Up 5 minutes", |
| 895 | + State: rt.WorkloadStatusRunning, |
| 896 | + Labels: map[string]string{ |
| 897 | + "toolhive": "true", |
| 898 | + "toolhive-name": "healthy-workload", |
| 899 | + }, |
| 900 | + }, |
| 901 | + { |
| 902 | + Name: "runtime-mismatch", |
| 903 | + Image: "mismatch:latest", |
| 904 | + Status: "Exited (0) 1 minute ago", |
| 905 | + State: rt.WorkloadStatusStopped, // Runtime says stopped, file says running |
| 906 | + Labels: map[string]string{ |
| 907 | + "toolhive": "true", |
| 908 | + "toolhive-name": "runtime-mismatch", |
| 909 | + }, |
| 910 | + }, |
| 911 | + { |
| 912 | + Name: "proxy-down", |
| 913 | + Image: "proxy:latest", |
| 914 | + Status: "Up 3 minutes", |
| 915 | + State: rt.WorkloadStatusRunning, |
| 916 | + Labels: map[string]string{ |
| 917 | + "toolhive": "true", |
| 918 | + "toolhive-name": "proxy-down", |
| 919 | + "toolhive-basename": "proxy-down", // This will trigger proxy check |
| 920 | + }, |
| 921 | + }, |
| 922 | + } |
| 923 | + |
| 924 | + mockRuntime.EXPECT().ListWorkloads(gomock.Any()).Return(runtimeContainers, nil) |
| 925 | + |
| 926 | + // List all workloads |
| 927 | + workloads, err := manager.ListWorkloads(ctx, true, nil) |
| 928 | + require.NoError(t, err) |
| 929 | + |
| 930 | + // Should have 3 workloads |
| 931 | + require.Len(t, workloads, 3) |
| 932 | + |
| 933 | + // Create a map for easier assertion |
| 934 | + workloadMap := make(map[string]core.Workload) |
| 935 | + for _, w := range workloads { |
| 936 | + workloadMap[w.Name] = w |
| 937 | + } |
| 938 | + |
| 939 | + // Verify healthy workload remains running |
| 940 | + healthyWorkload, exists := workloadMap["healthy-workload"] |
| 941 | + require.True(t, exists) |
| 942 | + assert.Equal(t, rt.WorkloadStatusRunning, healthyWorkload.Status) |
| 943 | + |
| 944 | + // Verify runtime mismatch workload is marked unhealthy (status might be updated async) |
| 945 | + // We'll check for either unhealthy or the original status with mismatch context |
| 946 | + runtimeMismatch, exists := workloadMap["runtime-mismatch"] |
| 947 | + require.True(t, exists) |
| 948 | + // The workload should either be marked unhealthy or have a status context indicating the issue |
| 949 | + isValidatedUnhealthy := runtimeMismatch.Status == rt.WorkloadStatusUnhealthy || |
| 950 | + strings.Contains(runtimeMismatch.StatusContext, "mismatch") |
| 951 | + assert.True(t, isValidatedUnhealthy, "Runtime mismatch workload should be detected as unhealthy") |
| 952 | + |
| 953 | + // Verify proxy down workload is detected (proxy.IsRunning will return false for non-existent proxy) |
| 954 | + proxyDown, exists := workloadMap["proxy-down"] |
| 955 | + require.True(t, exists) |
| 956 | + // Similar check - should be unhealthy or have proxy-related context |
| 957 | + isProxyValidated := proxyDown.Status == rt.WorkloadStatusUnhealthy || |
| 958 | + strings.Contains(proxyDown.StatusContext, "proxy") |
| 959 | + assert.True(t, isProxyValidated, "Proxy down workload should be detected as unhealthy") |
| 960 | +} |
0 commit comments