Skip to content

Commit 08c3935

Browse files
committed
test: cover agentos actor plugin contracts
1 parent 39b1570 commit 08c3935

10 files changed

Lines changed: 596 additions & 413 deletions

File tree

crates/agentos-actor-plugin/src/actions/mod.rs

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ fn decode_args_impl<T: DeserializeOwned>(args: &[u8]) -> Result<T> {
122122
.context("decode action args from cbor")?;
123123
let value = revive_undefined_envelopes(value);
124124
let mut normalized = Vec::new();
125-
ciborium::into_writer(&value, &mut normalized)
126-
.context("re-encode revived action args")?;
125+
ciborium::into_writer(&value, &mut normalized).context("re-encode revived action args")?;
127126
abi::codec::decode_positional(&normalized)
128127
}
129128

@@ -664,6 +663,93 @@ pub mod contract {
664663
.collect()
665664
}
666665

666+
pub fn encoded_invalid_client_arg_variants(name: &str) -> Result<Vec<(&'static str, Vec<u8>)>> {
667+
let variants = match name {
668+
"readFile"
669+
| "stat"
670+
| "mkdir"
671+
| "readdir"
672+
| "readdirEntries"
673+
| "exists"
674+
| "readdirRecursive"
675+
| "closeShell"
676+
| "waitShell"
677+
| "cancelCronJob"
678+
| "closeSession"
679+
| "getSessionEvents"
680+
| "expireSignedPreviewUrl" => {
681+
vec![("path/id must be a string", json!([42]))]
682+
}
683+
"writeFile" | "writeShell" => {
684+
vec![(
685+
"content must be string or Uint8Array",
686+
json!(["/workspace/file.txt", { "bad": true }]),
687+
)]
688+
}
689+
"move" => vec![(
690+
"destination must be a string",
691+
json!(["/workspace/a.txt", 42]),
692+
)],
693+
"deleteFile" => vec![(
694+
"recursive option must be boolean",
695+
json!(["/workspace/file.txt", { "recursive": "yes" }]),
696+
)],
697+
"writeFiles" => vec![(
698+
"entry path must be a string",
699+
json!([[{ "path": 42, "content": "a" }]]),
700+
)],
701+
"readFiles" => vec![("paths must be strings", json!([[42]]))],
702+
"exec" => vec![(
703+
"env option values must be strings",
704+
json!(["echo hello", { "env": { "A": 42 } }]),
705+
)],
706+
"spawn" => vec![("args must be strings", json!(["node", [42]]))],
707+
"waitProcess" | "killProcess" | "stopProcess" | "getProcess" | "closeProcessStdin" => {
708+
vec![("pid must be a number", json!(["42"]))]
709+
}
710+
"listProcesses"
711+
| "allProcesses"
712+
| "processTree"
713+
| "listCronJobs"
714+
| "listPersistedSessions"
715+
| "listMounts"
716+
| "listSoftware" => vec![(
717+
"zero-arg action must not accept extras",
718+
json!(["unexpected"]),
719+
)],
720+
"writeProcessStdin" => {
721+
vec![(
722+
"stdin content must be string or Uint8Array",
723+
json!([42, { "bad": true }]),
724+
)]
725+
}
726+
"openShell" => vec![("cols option must be numeric", json!([{ "cols": "wide" }]))],
727+
"resizeShell" => vec![("cols must be numeric", json!(["shell-1", "80", 24]))],
728+
"vmFetch" => vec![("port must be numeric", json!(["3000", "http://127.0.0.1/"]))],
729+
"scheduleCron" => vec![(
730+
"cron job requires a schedule/action shape",
731+
json!([{ "id": "job-1" }]),
732+
)],
733+
"createSession" => vec![("agent type must be a string", json!([42]))],
734+
"sendPrompt" => vec![(
735+
"prompt must be a string",
736+
json!(["session-1", { "text": "hello" }]),
737+
)],
738+
"respondPermission" => vec![(
739+
"permission response must be a string",
740+
json!(["session-1", "permission-1", 42]),
741+
)],
742+
"createSignedPreviewUrl" => vec![("ttl must be numeric", json!([3000, "60"]))],
743+
other => return Err(anyhow!("unknown action {other}")),
744+
};
745+
variants
746+
.into_iter()
747+
.map(|(case, value)| {
748+
abi::codec::encode_positional(&value).map(|encoded| (case, encoded))
749+
})
750+
.collect()
751+
}
752+
667753
pub fn encode_sample_reply(name: &str) -> Result<Vec<u8>> {
668754
match name {
669755
"readFile" => encode(&serde_bytes::ByteBuf::from(vec![1, 2, 3])),

crates/agentos-actor-plugin/src/config.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,14 @@ fn read_package_software_info(path: &str) -> Option<SoftwareInfoDto> {
221221
/// reader in `vfs::package_format`. A corrupt or truncated package is logged
222222
/// (host-visible) and skipped rather than silently vanishing from listings.
223223
fn read_aospkg_software_info(path: &str) -> Option<SoftwareInfoDto> {
224-
let manifest = match vfs::package_format::read_manifest_chunk_from_file(std::path::Path::new(
225-
path,
226-
)) {
227-
Ok(manifest) => manifest,
228-
Err(error) => {
229-
tracing::warn!(%path, %error, "skipping unreadable .aospkg in listSoftware");
230-
return None;
231-
}
232-
};
224+
let manifest =
225+
match vfs::package_format::read_manifest_chunk_from_file(std::path::Path::new(path)) {
226+
Ok(manifest) => manifest,
227+
Err(error) => {
228+
tracing::warn!(%path, %error, "skipping unreadable .aospkg in listSoftware");
229+
return None;
230+
}
231+
};
233232
Some(SoftwareInfoDto {
234233
package: manifest.name,
235234
kind: if manifest.agent.is_some() {

0 commit comments

Comments
 (0)