pub(crate) fn test_complex_upgrader<VM: TestedVm>() {
    let mut storage = get_empty_storage();
    let upgrade_bytecode = TestContract::complex_upgrade().bytecode.to_vec();
    let bytecode_hash = BytecodeHash::for_bytecode(&upgrade_bytecode).value();
    let msg_sender_test_bytecode = TestContract::msg_sender_test().bytecode.to_vec();
    let msg_sender_test_hash = BytecodeHash::for_bytecode(&msg_sender_test_bytecode).value();
    // Let's assume that the bytecode for the implementation of the complex upgrade
    // is already deployed in some address in user space
    let upgrade_impl = Address::repeat_byte(1);
    let account_code_key = get_code_key(&upgrade_impl);
    storage.set_value(get_known_code_key(&bytecode_hash), u256_to_h256(1.into()));
    storage.set_value(
        get_known_code_key(&msg_sender_test_hash),
        u256_to_h256(1.into()),
    );
    storage.set_value(account_code_key, bytecode_hash);
    storage.store_factory_dep(bytecode_hash, upgrade_bytecode);
    storage.store_factory_dep(msg_sender_test_hash, msg_sender_test_bytecode);

    let mut vm = VmTesterBuilder::new()
        .with_storage(storage)
        .with_execution_mode(TxExecutionMode::VerifyExecute)
        .with_rich_accounts(1)
        .build::<VM>();

    let address_to_deploy1 = Address::repeat_byte(0xfe);
    let address_to_deploy2 = Address::repeat_byte(0xff);

    let transaction = get_complex_upgrade_tx(
        upgrade_impl,
        address_to_deploy1,
        address_to_deploy2,
        bytecode_hash,
    );

    vm.vm.push_transaction(transaction);
    let result = vm.vm.execute(InspectExecutionMode::OneTx);
    assert!(
        !result.result.is_failed(),
        "The force upgrade was not successful"
    );

    let expected_slots = [
        (
            get_code_key(&address_to_deploy1),
            h256_to_u256(bytecode_hash),
        ),
        (
            get_code_key(&address_to_deploy2),
            h256_to_u256(bytecode_hash),
        ),
    ];
    // Verify that the bytecode has been set correctly
    vm.vm.verify_required_storage(&expected_slots);
}
Here we show how the work with the complex upgrader could be done.
core/lib/multivm/src/versions/testonly/upgrade.rs