Skip to content

Commit c851dc0

Browse files
authored
fix: wait works when no conditions set (#40)
Signed-off-by: Calum Murray <cmurray@redhat.com>
1 parent 47d2367 commit c851dc0

3 files changed

Lines changed: 113 additions & 6 deletions

File tree

pkg/extension/operations.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (e *Extension) registerOperations() {
7070
Description: "Timeout duration (e.g., 60s, 5m, default: 60s)",
7171
},
7272
},
73-
Required: []string{"apiVersion", "kind", "metadata", "condition"},
73+
Required: []string{"apiVersion", "kind", "metadata"},
7474
}),
7575
),
7676
e.handleWait,

pkg/extension/wait.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ func (e *Extension) handleWait(ctx context.Context, req *sdk.OperationRequest) (
2626
}
2727

2828
condition, _ := args["condition"].(string)
29-
if condition == "" {
30-
return sdk.Failure(fmt.Errorf("condition is required")), nil
31-
}
3229

3330
status, _ := args["status"].(string)
3431
if status == "" {
@@ -66,6 +63,11 @@ func (e *Extension) handleWait(ctx context.Context, req *sdk.OperationRequest) (
6663
return false, nil // Keep polling on transient errors
6764
}
6865

66+
// No condition specified — resource exists, that's enough
67+
if condition == "" {
68+
return true, nil
69+
}
70+
6971
conditions, found, err := unstructured.NestedSlice(obj.Object, "status", "conditions")
7072
if err != nil || !found {
7173
lastStatus = "NoConditions"
@@ -92,6 +94,16 @@ func (e *Extension) handleWait(ctx context.Context, req *sdk.OperationRequest) (
9294
})
9395

9496
if err != nil {
97+
if condition == "" {
98+
e.LogError(ctx, "Resource wait timed out", map[string]any{
99+
"kind": ref.kind,
100+
"name": ref.name,
101+
})
102+
return sdk.FailureWithMessage(
103+
fmt.Sprintf("Resource %s/%s not found", ref.kind, ref.name),
104+
fmt.Errorf("timed out waiting for %s/%s to exist", ref.kind, ref.name),
105+
), nil
106+
}
95107
e.LogError(ctx, "Condition wait timed out", map[string]any{
96108
"kind": ref.kind,
97109
"name": ref.name,
@@ -104,6 +116,14 @@ func (e *Extension) handleWait(ctx context.Context, req *sdk.OperationRequest) (
104116
), nil
105117
}
106118

119+
if condition == "" {
120+
e.LogInfo(ctx, "Resource exists", map[string]any{
121+
"kind": ref.kind,
122+
"name": ref.name,
123+
})
124+
return sdk.Success(fmt.Sprintf("%s/%s exists", ref.kind, ref.name)), nil
125+
}
126+
107127
e.LogInfo(ctx, "Condition met", map[string]any{
108128
"kind": ref.kind,
109129
"name": ref.name,

pkg/extension/wait_test.go

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package extension
22

33
import (
44
"context"
5+
"fmt"
56
"testing"
67

78
"github.com/mcpchecker/mcpchecker/pkg/extension/sdk"
@@ -65,13 +66,99 @@ func TestHandleWait(t *testing.T) {
6566
wantSuccess: false,
6667
},
6768
{
68-
name: "missing condition field",
69+
name: "missing condition field checks existence",
6970
args: map[string]any{
7071
"apiVersion": "v1",
7172
"kind": "Pod",
7273
"metadata": map[string]any{"name": "test"},
74+
"timeout": "1s",
75+
},
76+
client: &mockClient{
77+
getFn: func(ctx context.Context, gvr schema.GroupVersionResource, name, namespace string) (*unstructured.Unstructured, error) {
78+
return &unstructured.Unstructured{
79+
Object: map[string]any{
80+
"apiVersion": "v1",
81+
"kind": "Pod",
82+
"metadata": map[string]any{"name": "test"},
83+
},
84+
}, nil
85+
},
86+
},
87+
wantSuccess: true,
88+
},
89+
{
90+
name: "no condition - resource not found times out",
91+
args: map[string]any{
92+
"apiVersion": "v1",
93+
"kind": "Pod",
94+
"metadata": map[string]any{"name": "test"},
95+
"timeout": "1s",
96+
},
97+
client: &mockClient{
98+
getFn: func(ctx context.Context, gvr schema.GroupVersionResource, name, namespace string) (*unstructured.Unstructured, error) {
99+
return nil, fmt.Errorf("not found")
100+
},
101+
},
102+
wantSuccess: false,
103+
},
104+
{
105+
name: "no condition - succeeds when resource exists",
106+
args: map[string]any{
107+
"apiVersion": "networking.istio.io/v1",
108+
"kind": "Gateway",
109+
"metadata": map[string]any{"name": "my-gateway", "namespace": "istio-system"},
110+
"timeout": "2s",
111+
},
112+
client: &mockClient{
113+
getFn: func(ctx context.Context, gvr schema.GroupVersionResource, name, namespace string) (*unstructured.Unstructured, error) {
114+
return &unstructured.Unstructured{
115+
Object: map[string]any{
116+
"apiVersion": "networking.istio.io/v1",
117+
"kind": "Gateway",
118+
"metadata": map[string]any{
119+
"name": "my-gateway",
120+
"namespace": "istio-system",
121+
},
122+
"spec": map[string]any{
123+
"selector": map[string]any{
124+
"istio": "ingressgateway",
125+
},
126+
},
127+
},
128+
}, nil
129+
},
130+
},
131+
wantSuccess: true,
132+
},
133+
{
134+
name: "resource without status.conditions times out (e.g. Istio Gateway)",
135+
args: map[string]any{
136+
"apiVersion": "networking.istio.io/v1",
137+
"kind": "Gateway",
138+
"metadata": map[string]any{"name": "my-gateway", "namespace": "istio-system"},
139+
"condition": "Available",
140+
"status": "True",
141+
"timeout": "2s",
142+
},
143+
client: &mockClient{
144+
getFn: func(ctx context.Context, gvr schema.GroupVersionResource, name, namespace string) (*unstructured.Unstructured, error) {
145+
return &unstructured.Unstructured{
146+
Object: map[string]any{
147+
"apiVersion": "networking.istio.io/v1",
148+
"kind": "Gateway",
149+
"metadata": map[string]any{
150+
"name": "my-gateway",
151+
"namespace": "istio-system",
152+
},
153+
"spec": map[string]any{
154+
"selector": map[string]any{
155+
"istio": "ingressgateway",
156+
},
157+
},
158+
},
159+
}, nil
160+
},
73161
},
74-
client: &mockClient{},
75162
wantSuccess: false,
76163
},
77164
}

0 commit comments

Comments
 (0)