test(reporting-governance): tighten deployment profile schema semantics
This commit is contained in:
@@ -43,6 +43,8 @@ spec:
|
|||||||
overdueAction: force_checkpoint
|
overdueAction: force_checkpoint
|
||||||
escalationAfterMisses: 2
|
escalationAfterMisses: 2
|
||||||
adapters:
|
adapters:
|
||||||
|
hook:
|
||||||
|
enabled: true
|
||||||
watchdog:
|
watchdog:
|
||||||
enabled: true
|
enabled: true
|
||||||
scheduleMode: cron
|
scheduleMode: cron
|
||||||
@@ -98,7 +100,15 @@ test('deployment profile schema validator rejects malformed profile', () => {
|
|||||||
metadata: { id: 'x', version: '1.0.0', runtime: 'openclaw' },
|
metadata: { id: 'x', version: '1.0.0', runtime: 'openclaw' },
|
||||||
spec: {
|
spec: {
|
||||||
package: { pluginVersion: 7 },
|
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: {
|
notifications: {
|
||||||
operatorVisibleRecoveryRequired: true,
|
operatorVisibleRecoveryRequired: true,
|
||||||
allowedTerminalStates: ['acked'],
|
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', () => {
|
test('deployment profile yaml parser covers composite nested yaml structure', () => {
|
||||||
const profile = parseDeploymentProfileYaml(complexProfileYaml);
|
const profile = parseDeploymentProfileYaml(complexProfileYaml);
|
||||||
|
|
||||||
@@ -159,7 +300,21 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
package:
|
package:
|
||||||
pluginVersion: 123
|
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:
|
notifications:
|
||||||
operatorVisibleRecoveryRequired: true
|
operatorVisibleRecoveryRequired: true
|
||||||
allowedTerminalStates:
|
allowedTerminalStates:
|
||||||
|
|||||||
@@ -42,17 +42,97 @@
|
|||||||
"adapters": {
|
"adapters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true,
|
"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": {
|
"notifications": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true,
|
"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": {
|
"audit": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"required": ["portableArtifactsRequired", "requiredArtifacts"]
|
"required": ["portableArtifactsRequired", "requiredArtifacts"],
|
||||||
|
"properties": {
|
||||||
|
"portableArtifactsRequired": { "type": "boolean" },
|
||||||
|
"requiredArtifacts": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "type": "string", "minLength": 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"capability_expectations": {
|
"capability_expectations": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
Reference in New Issue
Block a user