litellm/litellm-rust/crates/testkit/tests/support/mod.rs
devin-ai-integration[bot] 9c10e0f985
feat(testkit): agent clients for Claude Code, Codex and opencode (#43181)
* feat(testkit): install and configure Claude Code, Codex and opencode against a gateway

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* refactor(testkit): derive targets from target-lexicon and split agents behind a trait

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* refactor(testkit): group sources into agent and install folders

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* feat(testkit): split agents into install, configure and drive with semver-aware launch

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* style(testkit): drop a needless borrow

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Yujong Lee <yujong@berri.ai>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 17:27:30 +00:00

70 lines
2 KiB
Rust

use std::collections::HashMap;
use std::io::Write;
use std::sync::atomic::{AtomicUsize, Ordering};
use litellm_testkit::{Error, Fetch};
use sha2::{Digest, Sha256};
pub struct FakeFetch {
routes: HashMap<String, Vec<u8>>,
calls: AtomicUsize,
}
impl FakeFetch {
pub fn new(routes: impl IntoIterator<Item = (String, Vec<u8>)>) -> Self {
Self {
routes: routes.into_iter().collect(),
calls: AtomicUsize::new(0),
}
}
pub fn calls(&self) -> usize {
self.calls.load(Ordering::SeqCst)
}
}
impl Fetch for FakeFetch {
async fn get(&self, url: &str) -> Result<Vec<u8>, Error> {
self.calls.fetch_add(1, Ordering::SeqCst);
self.routes.get(url).cloned().ok_or_else(|| Error::Status {
url: url.to_owned(),
status: 404,
})
}
}
impl Fetch for &FakeFetch {
async fn get(&self, url: &str) -> Result<Vec<u8>, Error> {
(*self).get(url).await
}
}
pub fn sha256(bytes: &[u8]) -> String {
format!("{:x}", Sha256::digest(bytes))
}
pub fn script_printing(output: &str) -> Vec<u8> {
format!("#!/bin/sh\necho '{output}'\n").into_bytes()
}
pub fn tar_gz(member: &str, contents: &[u8]) -> Vec<u8> {
let mut builder = tar::Builder::new(Vec::new());
let mut header = tar::Header::new_gnu();
header.set_size(contents.len() as u64);
header.set_mode(0o755);
header.set_cksum();
builder.append_data(&mut header, member, contents).unwrap();
let tarball = builder.into_inner().unwrap();
let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
encoder.write_all(&tarball).unwrap();
encoder.finish().unwrap()
}
pub fn zip_archive(member: &str, contents: &[u8]) -> Vec<u8> {
let mut writer = zip::ZipWriter::new(std::io::Cursor::new(Vec::new()));
writer
.start_file(member, zip::write::SimpleFileOptions::default())
.unwrap();
writer.write_all(contents).unwrap();
writer.finish().unwrap().into_inner()
}