Skip to content

Commit

Permalink
chore: add test for compute_calls_instructions_len (#1183)
Browse files Browse the repository at this point in the history
Close #1129.

I added a test case for an empty (random) contract, would like some
feedback on what kinds of non-empty contracts to test.

### Checklist
- [x] I have linked to any relevant issues.
- [x] I have updated the documentation.
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added necessary labels.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: MujkicA <[email protected]>
Co-authored-by: iqdecay <[email protected]>
Co-authored-by: hal3e <[email protected]>
Co-authored-by: Ahmed Sagdati <[email protected]>
  • Loading branch information
5 people authored Dec 15, 2023
1 parent c69cb81 commit f74e9bb
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions packages/fuels-programs/src/call_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,4 +946,112 @@ mod test {
expected_asset_id_amounts
)
}

mod compute_calls_instructions_len {
use fuel_asm::Instruction;
use fuels_core::types::{enum_variants::EnumVariants, param_types::ParamType};

use crate::{call_utils::compute_calls_instructions_len, contract::ContractCall};

// movi, movi, lw, movi + call (for gas)
const BASE_INSTRUCTION_COUNT: usize = 5;
// 2 instructions (movi and lw) added in get_single_call_instructions when gas_offset is set
const GAS_OFFSET_INSTRUCTION_COUNT: usize = 2;
// 4 instructions (lw, lw, muli, retd) added by extract_data_receipt
const EXTRACT_DATA_RECEIPT_INSTRUCTION_COUNT: usize = 4;
// 4 instructions (movi, lw, jnef, retd) added by extract_heap_data
const EXTRACT_HEAP_DATA_INSTRUCTION_COUNT: usize = 4;

#[test]
fn test_simple() {
let call = ContractCall::new_with_random_id();
let instructions_len = compute_calls_instructions_len(&[call]).unwrap();
assert_eq!(instructions_len, Instruction::SIZE * BASE_INSTRUCTION_COUNT);
}

#[test]
fn test_with_gas_offset() {
let mut call = ContractCall::new_with_random_id();
call.call_parameters = call.call_parameters.with_gas_forwarded(0);
let instructions_len = compute_calls_instructions_len(&[call]).unwrap();
assert_eq!(
instructions_len,
Instruction::SIZE * (BASE_INSTRUCTION_COUNT + GAS_OFFSET_INSTRUCTION_COUNT)
);
}

#[test]
fn test_with_heap_type() {
let output_params = vec![
ParamType::Vector(Box::new(ParamType::U8)),
ParamType::String,
ParamType::Bytes,
];
for output_param in output_params {
let mut call = ContractCall::new_with_random_id();
call.output_param = output_param;
let instructions_len = compute_calls_instructions_len(&[call]).unwrap();
assert_eq!(
instructions_len,
Instruction::SIZE
* (BASE_INSTRUCTION_COUNT + EXTRACT_DATA_RECEIPT_INSTRUCTION_COUNT)
);
}
}

#[test]
fn test_with_gas_offset_and_heap_type() {
let mut call = ContractCall::new_with_random_id();
call.call_parameters = call.call_parameters.with_gas_forwarded(0);
call.output_param = ParamType::Vector(Box::new(ParamType::U8));
let instructions_len = compute_calls_instructions_len(&[call]).unwrap();
assert_eq!(
instructions_len,
// combines extra instructions from two above tests
Instruction::SIZE
* (BASE_INSTRUCTION_COUNT
+ GAS_OFFSET_INSTRUCTION_COUNT
+ EXTRACT_DATA_RECEIPT_INSTRUCTION_COUNT)
);
}

#[test]
fn test_with_enum_with_heap_and_non_heap_variant() {
let variant_sets = vec![
vec![ParamType::Vector(Box::new(ParamType::U8)), ParamType::U8],
vec![ParamType::String, ParamType::U8],
vec![ParamType::Bytes, ParamType::U8],
];
for variant_set in variant_sets {
let mut call = ContractCall::new_with_random_id();
call.output_param = ParamType::Enum {
variants: EnumVariants::new(variant_set).unwrap(),
generics: Vec::new(),
};
let instructions_len = compute_calls_instructions_len(&[call]).unwrap();
assert_eq!(
instructions_len,
Instruction::SIZE
* (BASE_INSTRUCTION_COUNT
+ EXTRACT_DATA_RECEIPT_INSTRUCTION_COUNT
+ EXTRACT_HEAP_DATA_INSTRUCTION_COUNT)
);
}
}

#[test]
fn test_with_enum_with_only_non_heap_variants() {
let mut call = ContractCall::new_with_random_id();
call.output_param = ParamType::Enum {
variants: EnumVariants::new(vec![ParamType::Bool, ParamType::U8]).unwrap(),
generics: Vec::new(),
};
let instructions_len = compute_calls_instructions_len(&[call]).unwrap();
assert_eq!(
instructions_len,
// no extra instructions if there are no heap type variants
Instruction::SIZE * BASE_INSTRUCTION_COUNT
);
}
}
}

0 comments on commit f74e9bb

Please sign in to comment.