blob: e8df466e921cde0158e3c7f08d2b2ad7d659ab44 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! Predicted server-state mutations emitted by op modules on commit.
//!
//! Name-keyed throughout. Server emits empty reply bodies, so the
//! workload cannot recover server-assigned numeric ids; shadow lookups
//! address entities by name (`WireIdentifier::named`). Id-keyed effects
//! return once reply-body parsing lands.
use server_common::sharding::IggyNamespace;
#[derive(Debug, Clone)]
pub enum Effect {
None,
AddStream {
name: String,
},
RemoveStream {
name: String,
},
AddTopic {
stream: String,
name: String,
partitions: u32,
},
RemoveTopic {
stream: String,
name: String,
},
AddPartitions {
stream: String,
topic: String,
count: u32,
},
RemovePartitions {
stream: String,
topic: String,
count: u32,
},
AddUser {
name: String,
},
RemoveUser {
name: String,
},
AddPat {
name: String,
},
RemovePat {
name: String,
},
AddConsumerGroup {
stream: String,
topic: String,
name: String,
},
RemoveConsumerGroup {
stream: String,
topic: String,
name: String,
},
SendCommitted {
ns: IggyNamespace,
count: u64,
},
OffsetStored {
key: (IggyNamespace, u8, u32),
value: u64,
},
OffsetDeleted {
key: (IggyNamespace, u8, u32),
},
RenameStream {
old: String,
new: String,
},
RenameTopic {
stream: String,
old: String,
new: String,
},
RenameUser {
old: String,
new: String,
/// Carries the current password through the rename so the
/// shadow re-keys `passwords` under `new` without loss.
password: String,
},
/// Password rotated; shadow updates `passwords` so the next
/// `ChangePassword` sample reads the new value.
PasswordChanged {
user: String,
new_password: String,
},
}
/// Side-effects the driver must run against the simulator. Returned by
/// `Shadow::apply` so the auditor stays pure (no `&mut Simulator`).
#[derive(Debug, Clone)]
pub enum SimCommand {
/// Reserved hook: no op currently emits this. Will be wired when a
/// workload-driven namespace-creation op lands (today, namespaces are
/// pre-seeded by the test fixture via `Simulator::init_partition`).
InitPartition { ns: IggyNamespace },
}
#[derive(Debug, Clone)]
pub struct ApplyResult {
pub sim_commands: Vec<SimCommand>,
/// `true` when the shadow actually mutated; `false` when the effect
/// was a no-op (e.g. `AddTopic` after parent stream removed, or a
/// `Rename*` whose `old` key is gone).
pub applied: bool,
}
impl Default for ApplyResult {
fn default() -> Self {
Self {
sim_commands: Vec::new(),
applied: true,
}
}
}