use test_r::test;
use crate::model::public_oplog::{
ChangeRetryPolicyParameters, CreateParameters, EndRegionParameters, ErrorParameters,
ExportedFunctionCompletedParameters, ExportedFunctionInvokedParameters,
ExportedFunctionParameters, FailedUpdateParameters, GrowMemoryParameters,
ImportedFunctionInvokedParameters, JumpParameters, LogParameters, PendingUpdateParameters,
PendingWorkerInvocationParameters, PluginInstallationDescription, PublicAttribute,
PublicAttributeValue, PublicDurableFunctionType, PublicLocalSpanData, PublicOplogEntry,
PublicRetryConfig, PublicSpanData, PublicUpdateDescription, PublicWorkerInvocation,
ResourceParameters, SnapshotBasedUpdateParameters, StringAttributeValue,
SuccessfulUpdateParameters, TimestampParameter,
};
use crate::model::{
AccountId, ComponentId, Empty, IdempotencyKey, PluginInstallationId, ProjectId, Timestamp,
WorkerId,
};
use std::collections::{BTreeMap, BTreeSet};
use uuid::Uuid;
use crate::model::invocation_context::{SpanId, TraceId};
use crate::model::oplog::{LogLevel, OplogIndex, WorkerResourceId};
use crate::model::regions::OplogRegion;
use golem_wasm_ast::analysis::analysed_type::{field, list, r#enum, record, s16, str, u64};
use golem_wasm_rpc::{Value, ValueAndType};
#[cfg(feature = "poem")]
use poem_openapi::types::ToJSON;
fn rounded_ts(ts: Timestamp) -> Timestamp {
Timestamp::from(ts.to_millis())
}
#[test]
#[cfg(feature = "poem")]
fn create_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Create(CreateParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
worker_id: WorkerId {
component_id: ComponentId(
Uuid::parse_str("13A5C8D4-F05E-4E23-B982-F4D413E181CB").unwrap(),
),
worker_name: "test1".to_string(),
},
component_version: 1,
args: vec!["a".to_string(), "b".to_string()],
env: vec![("x".to_string(), "y".to_string())]
.into_iter()
.collect(),
created_by: AccountId {
value: "account_id".to_string(),
},
wasi_config_vars: BTreeMap::from_iter(vec![("A".to_string(), "B".to_string())]).into(),
project_id: ProjectId::new_v4(),
parent: Some(WorkerId {
component_id: ComponentId(
Uuid::parse_str("13A5C8D4-F05E-4E23-B982-F4D413E181CB").unwrap(),
),
worker_name: "test2".to_string(),
}),
component_size: 100_000_000,
initial_total_linear_memory_size: 200_000_000,
initial_active_plugins: BTreeSet::from_iter(vec![PluginInstallationDescription {
installation_id: PluginInstallationId(
Uuid::parse_str("13A5C8D4-F05E-4E23-B982-F4D413E181CB").unwrap(),
),
plugin_name: "plugin1".to_string(),
plugin_version: "1".to_string(),
parameters: BTreeMap::new(),
registered: true,
}]),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn imported_function_invoked_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::ImportedFunctionInvoked(ImportedFunctionInvokedParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
function_name: "test".to_string(),
request: ValueAndType {
value: Value::String("test".to_string()),
typ: str(),
},
response: ValueAndType {
value: Value::List(vec![Value::U64(1)]),
typ: list(u64()),
},
durable_function_type: PublicDurableFunctionType::ReadRemote(Empty {}),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn exported_function_invoked_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::ExportedFunctionInvoked(ExportedFunctionInvokedParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
function_name: "test".to_string(),
request: vec![
ValueAndType {
value: Value::String("test".to_string()),
typ: str(),
},
ValueAndType {
value: Value::Record(vec![Value::S16(1), Value::S16(-1)]),
typ: record(vec![field("x", s16()), field("y", s16())]),
},
],
idempotency_key: IdempotencyKey::new("idempotency_key".to_string()),
trace_id: TraceId::generate(),
trace_states: vec!["a".to_string(), "b".to_string()],
invocation_context: vec![vec![PublicSpanData::LocalSpan(PublicLocalSpanData {
span_id: SpanId::generate(),
start: rounded_ts(Timestamp::now_utc()),
parent_id: None,
linked_context: None,
attributes: vec![PublicAttribute {
key: "a".to_string(),
value: PublicAttributeValue::String(StringAttributeValue {
value: "b".to_string(),
}),
}],
inherited: true,
})]],
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn exported_function_completed_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::ExportedFunctionCompleted(ExportedFunctionCompletedParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
response: Some(ValueAndType {
value: Value::Enum(1),
typ: r#enum(&["red", "green", "blue"]),
}),
consumed_fuel: 100,
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn suspend_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Suspend(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn error_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Error(ErrorParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
error: "test".to_string(),
retry_from: OplogIndex::INITIAL,
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn no_op_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::NoOp(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn jump_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Jump(JumpParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
jump: OplogRegion {
start: OplogIndex::from_u64(1),
end: OplogIndex::from_u64(2),
},
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn interrupted_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Interrupted(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn exited_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Exited(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn change_retry_policy_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::ChangeRetryPolicy(ChangeRetryPolicyParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
new_policy: PublicRetryConfig {
max_attempts: 10,
min_delay: std::time::Duration::from_secs(1),
max_delay: std::time::Duration::from_secs(10),
multiplier: 2.0,
max_jitter_factor: Some(0.1),
},
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn begin_atomic_region_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::BeginAtomicRegion(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn end_atomic_region_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::EndAtomicRegion(EndRegionParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
begin_index: OplogIndex::from_u64(1),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn begin_remote_write_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::BeginRemoteWrite(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn end_remote_write_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::EndRemoteWrite(EndRegionParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
begin_index: OplogIndex::from_u64(1),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn pending_worker_invocation_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::PendingWorkerInvocation(PendingWorkerInvocationParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
invocation: PublicWorkerInvocation::ExportedFunction(ExportedFunctionParameters {
idempotency_key: IdempotencyKey::new("idempotency_key".to_string()),
full_function_name: "test".to_string(),
function_input: Some(vec![
ValueAndType {
value: Value::String("test".to_string()),
typ: str(),
},
ValueAndType {
value: Value::Record(vec![Value::S16(1), Value::S16(-1)]),
typ: record(vec![field("x", s16()), field("y", s16())]),
},
]),
trace_id: TraceId::generate(),
trace_states: vec!["a".to_string(), "b".to_string()],
invocation_context: vec![vec![PublicSpanData::LocalSpan(PublicLocalSpanData {
span_id: SpanId::generate(),
start: rounded_ts(Timestamp::now_utc()),
parent_id: None,
linked_context: None,
attributes: vec![PublicAttribute {
key: "a".to_string(),
value: PublicAttributeValue::String(StringAttributeValue {
value: "b".to_string(),
}),
}],
inherited: true,
})]],
}),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn pending_update_serialization_poem_serde_equivalence_1() {
let entry = PublicOplogEntry::PendingUpdate(PendingUpdateParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
target_version: 1,
description: PublicUpdateDescription::SnapshotBased(SnapshotBasedUpdateParameters {
payload: "test".as_bytes().to_vec(),
}),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn pending_update_serialization_poem_serde_equivalence_2() {
let entry = PublicOplogEntry::PendingUpdate(PendingUpdateParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
target_version: 1,
description: PublicUpdateDescription::Automatic(Empty {}),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn successful_update_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::SuccessfulUpdate(SuccessfulUpdateParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
target_version: 1,
new_component_size: 100_000_000,
new_active_plugins: BTreeSet::from_iter(vec![PluginInstallationDescription {
installation_id: PluginInstallationId(
Uuid::parse_str("13A5C8D4-F05E-4E23-B982-F4D413E181CB").unwrap(),
),
plugin_name: "plugin1".to_string(),
plugin_version: "1".to_string(),
parameters: BTreeMap::new(),
registered: true,
}]),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn failed_update_serialization_poem_serde_equivalence_1() {
let entry = PublicOplogEntry::FailedUpdate(FailedUpdateParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
target_version: 1,
details: Some("test".to_string()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn failed_update_serialization_poem_serde_equivalence_2() {
let entry = PublicOplogEntry::FailedUpdate(FailedUpdateParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
target_version: 1,
details: None,
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn grow_memory_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::GrowMemory(GrowMemoryParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
delta: 100_000_000,
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn create_resource_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::CreateResource(ResourceParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
id: WorkerResourceId(100),
name: "test".to_string(),
owner: "owner".to_string(),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn drop_resource_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::DropResource(ResourceParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
id: WorkerResourceId(100),
name: "test".to_string(),
owner: "owner".to_string(),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn log_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Log(LogParameters {
timestamp: rounded_ts(Timestamp::now_utc()),
level: LogLevel::Stderr,
context: "test".to_string(),
message: "test".to_string(),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}
#[test]
#[cfg(feature = "poem")]
fn restart_serialization_poem_serde_equivalence() {
let entry = PublicOplogEntry::Restart(TimestampParameter {
timestamp: rounded_ts(Timestamp::now_utc()),
});
let serialized = entry.to_json_string();
let deserialized: PublicOplogEntry = serde_json::from_str(&serialized).unwrap();
assert_eq!(entry, deserialized);
}