test(reporting-governance): tighten deployment profile schema semantics
This commit is contained in:
@@ -43,6 +43,8 @@ spec:
|
||||
overdueAction: force_checkpoint
|
||||
escalationAfterMisses: 2
|
||||
adapters:
|
||||
hook:
|
||||
enabled: true
|
||||
watchdog:
|
||||
enabled: true
|
||||
scheduleMode: cron
|
||||
@@ -98,7 +100,15 @@ test('deployment profile schema validator rejects malformed profile', () => {
|
||||
metadata: { id: 'x', version: '1.0.0', runtime: 'openclaw' },
|
||||
spec: {
|
||||
package: { pluginVersion: 7 },
|
||||
adapters: {},
|
||||
adapters: {
|
||||
hook: { enabled: true },
|
||||
watchdog: { enabled: true },
|
||||
queue: { enabled: true },
|
||||
dispatcher: { enabled: true },
|
||||
bridge: { enabled: true },
|
||||
sender: { mode: 'openclaw-cli' },
|
||||
orchestrator: { enabled: true },
|
||||
},
|
||||
notifications: {
|
||||
operatorVisibleRecoveryRequired: true,
|
||||
allowedTerminalStates: ['acked'],
|
||||
@@ -111,6 +121,137 @@ test('deployment profile schema validator rejects malformed profile', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('deployment profile schema validator rejects tightened semantic violations', () => {
|
||||
const validBase = {
|
||||
apiVersion: 'reporting-governance/v1alpha1',
|
||||
kind: 'DeploymentProfile',
|
||||
metadata: { id: 'strict', version: '1.0.0', runtime: 'openclaw' },
|
||||
spec: {
|
||||
package: { pluginVersion: '0.1.0-mainline' },
|
||||
adapters: {
|
||||
hook: { enabled: true },
|
||||
watchdog: { enabled: true },
|
||||
queue: { enabled: true },
|
||||
dispatcher: { enabled: true },
|
||||
bridge: { enabled: true },
|
||||
sender: { mode: 'openclaw-cli' },
|
||||
orchestrator: { enabled: true },
|
||||
},
|
||||
notifications: {
|
||||
operatorVisibleRecoveryRequired: true,
|
||||
allowedTerminalStates: ['acked'],
|
||||
},
|
||||
audit: {
|
||||
portableArtifactsRequired: true,
|
||||
requiredArtifacts: ['queue_items'],
|
||||
},
|
||||
capability_expectations: { required: [] },
|
||||
},
|
||||
};
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
audit: {
|
||||
portableArtifactsRequired: true,
|
||||
requiredArtifacts: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/audit\/requiredArtifacts must NOT have fewer than 1 items/
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
notifications: {
|
||||
operatorVisibleRecoveryRequired: 'yes',
|
||||
allowedTerminalStates: ['acked'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/notifications\/operatorVisibleRecoveryRequired must be boolean/
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
notifications: {
|
||||
operatorVisibleRecoveryRequired: true,
|
||||
allowedTerminalStates: ['done'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/notifications\/allowedTerminalStates\/0 must be equal to one of the allowed values/
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
audit: {
|
||||
portableArtifactsRequired: 'true',
|
||||
requiredArtifacts: ['queue_items'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/audit\/portableArtifactsRequired must be boolean/
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
adapters: {
|
||||
...validBase.spec.adapters,
|
||||
queue: { enabled: 'true' },
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/adapters\/queue\/enabled must be boolean/
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
adapters: {
|
||||
...validBase.spec.adapters,
|
||||
sender: { mode: 'shim' },
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/adapters\/sender\/mode must be equal to one of the allowed values/
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => validateDeploymentProfileSchema({
|
||||
...validBase,
|
||||
spec: {
|
||||
...validBase.spec,
|
||||
adapters: {
|
||||
watchdog: { enabled: true },
|
||||
queue: { enabled: true },
|
||||
dispatcher: { enabled: true },
|
||||
bridge: { enabled: true },
|
||||
sender: { mode: 'openclaw-cli' },
|
||||
orchestrator: { enabled: true },
|
||||
},
|
||||
},
|
||||
}),
|
||||
/deployment profile schema validation failed: .*\/spec\/adapters missing required property hook/
|
||||
);
|
||||
});
|
||||
|
||||
test('deployment profile yaml parser covers composite nested yaml structure', () => {
|
||||
const profile = parseDeploymentProfileYaml(complexProfileYaml);
|
||||
|
||||
@@ -159,7 +300,21 @@ metadata:
|
||||
spec:
|
||||
package:
|
||||
pluginVersion: 123
|
||||
adapters: {}
|
||||
adapters:
|
||||
hook:
|
||||
enabled: true
|
||||
watchdog:
|
||||
enabled: true
|
||||
queue:
|
||||
enabled: true
|
||||
dispatcher:
|
||||
enabled: true
|
||||
bridge:
|
||||
enabled: true
|
||||
sender:
|
||||
mode: openclaw-cli
|
||||
orchestrator:
|
||||
enabled: true
|
||||
notifications:
|
||||
operatorVisibleRecoveryRequired: true
|
||||
allowedTerminalStates:
|
||||
|
||||
@@ -42,17 +42,97 @@
|
||||
"adapters": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["watchdog", "queue", "dispatcher", "bridge", "sender", "orchestrator"]
|
||||
"required": ["hook", "watchdog", "queue", "dispatcher", "bridge", "sender", "orchestrator"],
|
||||
"properties": {
|
||||
"hook": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["enabled"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"watchdog": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["enabled"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"queue": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["enabled"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"dispatcher": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["enabled"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"bridge": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["enabled"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"sender": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["mode"],
|
||||
"properties": {
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": ["openclaw-cli", "shim_or_openclaw_cli", "dry-run_or_external"]
|
||||
},
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"orchestrator": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["enabled"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["operatorVisibleRecoveryRequired", "allowedTerminalStates"]
|
||||
"required": ["operatorVisibleRecoveryRequired", "allowedTerminalStates"],
|
||||
"properties": {
|
||||
"operatorVisibleRecoveryRequired": { "type": "boolean" },
|
||||
"allowedTerminalStates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["acked", "blocked", "pending_external_send"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"audit": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["portableArtifactsRequired", "requiredArtifacts"]
|
||||
"required": ["portableArtifactsRequired", "requiredArtifacts"],
|
||||
"properties": {
|
||||
"portableArtifactsRequired": { "type": "boolean" },
|
||||
"requiredArtifacts": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"capability_expectations": {
|
||||
"type": "object",
|
||||
|
||||
Reference in New Issue
Block a user