Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions src/core/wxc_common/src/config_contract_adapters/dev/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::wire;
use mxc_config_contract::dev as contract;
use mxc_config_contract::ContractVersion;

pub(super) fn convert_version(value: contract::Version) -> &'static str {
match value {
contract::Version::V0_8_0Alpha => ContractVersion::V0_8_0Alpha.as_str(),
}
}

pub(super) fn convert_process(value: contract::Process) -> wire::Process {
let contract::Process {
command_line,
cwd,
env,
timeout,
} = value;
wire::Process {
command_line: Some(command_line.into_inner()),
cwd: cwd.into_option(),
env: env.into_option(),
timeout: timeout.into_option(),
}
}

pub(super) fn convert_filesystem(value: contract::Filesystem) -> wire::Filesystem {
let contract::Filesystem {
readwrite_paths,
readonly_paths,
denied_paths,
} = value;
wire::Filesystem {
readwrite_paths: readwrite_paths.into_option(),
readonly_paths: readonly_paths.into_option(),
denied_paths: denied_paths.into_option(),
}
}

fn convert_default_network_policy(value: contract::DefaultNetworkPolicy) -> wire::NetworkPolicy {
match value {
contract::DefaultNetworkPolicy::Allow => wire::NetworkPolicy::Allow,
contract::DefaultNetworkPolicy::Block => wire::NetworkPolicy::Block,
}
}

fn convert_network_enforcement_mode(
value: contract::NetworkEnforcementMode,
) -> wire::NetworkEnforcement {
match value {
contract::NetworkEnforcementMode::Capabilities => wire::NetworkEnforcement::Capabilities,
contract::NetworkEnforcementMode::Firewall => wire::NetworkEnforcement::Firewall,
contract::NetworkEnforcementMode::Both => wire::NetworkEnforcement::Both,
}
}

pub(super) fn convert_network(value: contract::Network) -> wire::Network {
let contract::Network {
default_policy,
enforcement_mode,
allow_local_network,
allowed_hosts,
blocked_hosts,
proxy,
} = value;
wire::Network {
default_policy: default_policy
.into_option()
.map(convert_default_network_policy),
enforcement_mode: enforcement_mode
.into_option()
.map(convert_network_enforcement_mode),
allow_local_network: allow_local_network.into_option(),
allowed_hosts: allowed_hosts.into_option(),
blocked_hosts: blocked_hosts.into_option(),
proxy: proxy.into_option().map(convert_proxy),
}
}

fn convert_proxy(value: contract::NetworkProxy) -> wire::Proxy {
match value {
contract::NetworkProxy::Localhost(port) => wire::Proxy {
localhost: Some(port.get()),
builtin_test_server: None,
url: None,
},
contract::NetworkProxy::BuiltinTestServer(contract::True) => wire::Proxy {
localhost: None,
builtin_test_server: Some(true),
url: None,
},
contract::NetworkProxy::Url(url) => wire::Proxy {
localhost: None,
builtin_test_server: None,
url: Some(url),
},
}
}

pub(super) fn convert_telemetry(value: contract::Telemetry) -> wire::Telemetry {
let contract::Telemetry { enabled } = value;
wire::Telemetry {
enabled: enabled.into_option(),
}
}
239 changes: 238 additions & 1 deletion src/core/wxc_common/src/config_contract_adapters/dev/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,241 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

pub(crate) mod one_shot;
mod common;
mod one_shot;
mod state_aware;

use crate::state_aware_wire::StateAwareWireInput;
use crate::wire;

use mxc_config_contract::dev as contract;

pub(crate) enum AdaptedWireRequest {
OneShot(wire::MxcConfig),
StateAware(StateAwareWireInput),
}

fn adapt_state_aware_wire(
config: wire::MxcConfig,
source_text: &str,
) -> Result<AdaptedWireRequest, serde_json::Error> {
state_aware::into_state_aware_wire_input(config, source_text)
.map(AdaptedWireRequest::StateAware)
}

pub(crate) fn adapt_request(
request: contract::Request,
source_text: &str,
) -> Result<AdaptedWireRequest, serde_json::Error> {
match request {
contract::Request::OneShot(request) => {
Ok(AdaptedWireRequest::OneShot(one_shot::into_wire(*request)))
}
contract::Request::Provision(request) => {
adapt_state_aware_wire(state_aware::provision_into_wire(request), source_text)
}
contract::Request::Start(request) => {
adapt_state_aware_wire(state_aware::start_into_wire(request), source_text)
}
contract::Request::Exec(request) => {
adapt_state_aware_wire(state_aware::exec_into_wire(request), source_text)
}
contract::Request::Stop(request) => {
adapt_state_aware_wire(state_aware::stop_into_wire(request), source_text)
}
contract::Request::Deprovision(request) => {
adapt_state_aware_wire(state_aware::deprovision_into_wire(request), source_text)
}
}
}

#[cfg(test)]
mod tests {
use super::*;

fn adapt_json(json: &str) -> AdaptedWireRequest {
let request = contract::parse_request(json).unwrap();
adapt_request(request, json).unwrap()
}

#[test]
fn one_shot_request_adapts_to_one_shot() {
let json = r#"{
"version": "0.8.0-alpha",
"process": {
"commandLine": "echo hello"
}
}"#;

let AdaptedWireRequest::OneShot(adapted) = adapt_json(json) else {
panic!("expected one-shot request");
};

assert_eq!(adapted.version, Some("0.8.0-alpha".to_string()));
assert!(adapted.process.is_some());

let process = adapted.process.unwrap();
assert_eq!(process.command_line, Some("echo hello".to_string()));
assert!(process.cwd.is_none());
assert!(process.env.is_none());
assert!(process.timeout.is_none());
}

#[test]
fn provision_request_adapts_to_state_aware() {
let json = r#"{
"version": "0.8.0-alpha",
"phase": "provision",
"containment": "windows_sandbox",
"experimental": {
"telemetry": {
"enabled": false
}
}
}"#;

let AdaptedWireRequest::StateAware(adapted) = adapt_json(json) else {
panic!("expected state-aware request");
};

assert_eq!(adapted.config.version, Some("0.8.0-alpha".to_string()));
assert!(matches!(adapted.config.phase, Some(wire::Phase::Provision)));
assert_eq!(
adapted.experimental_raw,
Some(serde_json::json!({
"telemetry": {"enabled": false}
}))
);
assert_eq!(adapted.source_text.as_ref(), json);
}

#[test]
fn start_request_adapts_to_state_aware() {
let json = r#"{
"version": "0.8.0-alpha",
"phase": "start",
"sandboxId": "sandbox-id",
"experimental": {
"telemetry": {
"enabled": false
}
}
}"#;

let AdaptedWireRequest::StateAware(adapted) = adapt_json(json) else {
panic!("expected state-aware request");
};

assert_eq!(adapted.config.version, Some("0.8.0-alpha".to_string()));
assert!(matches!(adapted.config.phase, Some(wire::Phase::Start)));
assert_eq!(adapted.config.sandbox_id, Some("sandbox-id".to_string()));
assert_eq!(
adapted.experimental_raw,
Some(serde_json::json!({
"telemetry": {"enabled": false}
}))
);
assert_eq!(adapted.source_text.as_ref(), json);
}

#[test]
fn exec_request_adapts_to_state_aware() {
let json = r#"{
"version": "0.8.0-alpha",
"phase": "exec",
"sandboxId": "sandbox-id",
"process": {
"commandLine": "echo hello"
},
"experimental": {
"telemetry": {
"enabled": false
}
}
}"#;

let AdaptedWireRequest::StateAware(adapted) = adapt_json(json) else {
panic!("expected state-aware request");
};

assert_eq!(adapted.config.version, Some("0.8.0-alpha".to_string()));
assert!(matches!(adapted.config.phase, Some(wire::Phase::Exec)));
assert_eq!(adapted.config.sandbox_id, Some("sandbox-id".to_string()));
assert!(adapted.config.process.is_some());

let process = adapted.config.process.unwrap();
assert_eq!(process.command_line, Some("echo hello".to_string()));
assert!(process.cwd.is_none());
assert!(process.env.is_none());
assert!(process.timeout.is_none());

assert_eq!(
adapted.experimental_raw,
Some(serde_json::json!({
"telemetry": {"enabled": false}
}))
);
assert_eq!(adapted.source_text.as_ref(), json);
}

#[test]
fn stop_request_adapts_to_state_aware() {
let json = r#"{
"version": "0.8.0-alpha",
"phase": "stop",
"sandboxId": "sandbox-id",
"experimental": {
"telemetry": {
"enabled": false
}
}
}"#;

let AdaptedWireRequest::StateAware(adapted) = adapt_json(json) else {
panic!("expected state-aware request");
};

assert_eq!(adapted.config.version, Some("0.8.0-alpha".to_string()));
assert!(matches!(adapted.config.phase, Some(wire::Phase::Stop)));
assert_eq!(adapted.config.sandbox_id, Some("sandbox-id".to_string()));
assert_eq!(
adapted.experimental_raw,
Some(serde_json::json!({
"telemetry": {"enabled": false}
}))
);
assert_eq!(adapted.source_text.as_ref(), json);
}

#[test]
fn deprovision_request_adapts_to_state_aware() {
let json = r#"{
"version": "0.8.0-alpha",
"phase": "deprovision",
"sandboxId": "sandbox-id",
"experimental": {
"telemetry": {
"enabled": false
}
}
}"#;

let AdaptedWireRequest::StateAware(adapted) = adapt_json(json) else {
panic!("expected state-aware request");
};

assert_eq!(adapted.config.version, Some("0.8.0-alpha".to_string()));
assert!(matches!(
adapted.config.phase,
Some(wire::Phase::Deprovision)
));
assert_eq!(adapted.config.sandbox_id, Some("sandbox-id".to_string()));
assert_eq!(
adapted.experimental_raw,
Some(serde_json::json!({
"telemetry": {"enabled": false}
}))
);
assert_eq!(adapted.source_text.as_ref(), json);
}
}
Loading
Loading