@@ -35,12 +35,13 @@ use ic_types::{
35
35
} ,
36
36
nominal_cycles:: NominalCycles ,
37
37
time:: UNIX_EPOCH ,
38
- CanisterId , Cycles , PrincipalId , RegistryVersion ,
38
+ CanisterId , Cycles , PrincipalId , RegistryVersion , CountBytes
39
39
} ;
40
40
use ic_types_test_utils:: ids:: { canister_test_id, node_test_id, subnet_test_id, user_test_id} ;
41
41
use ic_universal_canister:: { call_args, wasm, UNIVERSAL_CANISTER_WASM } ;
42
42
use maplit:: btreemap;
43
43
use std:: mem:: size_of;
44
+ use more_asserts:: assert_gt;
44
45
45
46
#[ cfg( test) ]
46
47
mod canister_task;
@@ -885,6 +886,176 @@ fn get_canister_status_of_nonexisting_canister() {
885
886
assert_eq ! ( ErrorCode :: CanisterNotFound , err. code( ) ) ;
886
887
}
887
888
889
+ fn get_canister_status ( test : & mut ExecutionTest , canister_id : CanisterId ) -> CanisterStatusResultV2 {
890
+ match test. canister_status ( canister_id) . unwrap ( ) {
891
+ WasmResult :: Reply ( reply) => CanisterStatusResultV2 :: decode ( & reply) . unwrap ( ) ,
892
+ WasmResult :: Reject ( msg) => panic ! ( "{}" , msg) ,
893
+ }
894
+ }
895
+
896
+ #[ test]
897
+ fn get_canister_status_memory_metrics ( ) {
898
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
899
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
900
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
901
+
902
+ let wasm_memory_size = csr. wasm_memory_size ( ) ;
903
+ let stable_memory_size = csr. stable_memory_size ( ) ;
904
+ let global_memory_size = csr. global_memory_size ( ) ;
905
+ let wasm_binary_size = csr. wasm_binary_size ( ) ;
906
+ let custom_sections_size = csr. custom_sections_size ( ) ;
907
+
908
+ let execution_memory_size = wasm_memory_size + stable_memory_size + global_memory_size + wasm_binary_size + custom_sections_size;
909
+
910
+ let canister_history_size = csr. canister_history_size ( ) ;
911
+ let wasm_chunk_store_size = csr. wasm_chunk_store_size ( ) ;
912
+ let snapshots_size = csr. snapshots_size ( ) ;
913
+
914
+ let system_memory_size = canister_history_size + wasm_chunk_store_size + snapshots_size;
915
+
916
+ let memory_size = csr. memory_size ( ) ;
917
+ assert_eq ! ( memory_size, execution_memory_size + system_memory_size) ;
918
+ }
919
+
920
+ #[ test]
921
+ fn get_canister_status_memory_metrics_wasm_memory_size ( ) {
922
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
923
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
924
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
925
+
926
+ assert_eq ! (
927
+ get_canister_status( & mut test, canister_id) . wasm_memory_size( ) ,
928
+ csr. wasm_memory_size( )
929
+ ) ;
930
+
931
+ let canister_status_args = Encode ! ( & CanisterIdRecord :: from( canister_id) ) . unwrap ( ) ;
932
+ let get_canister_status = wasm ( )
933
+ . call_simple (
934
+ ic00:: IC_00 ,
935
+ Method :: CanisterStatus ,
936
+ call_args ( ) . other_side ( canister_status_args) ,
937
+ )
938
+ . build ( ) ;
939
+ let result = test. ingress ( canister_id, "update" , get_canister_status) ;
940
+ let reply = get_reply ( result) ;
941
+ let updated_csr = CanisterStatusResultV2 :: decode ( & reply) . unwrap ( ) ;
942
+
943
+ assert_gt ! (
944
+ updated_csr. wasm_memory_size( ) ,
945
+ csr. wasm_memory_size( )
946
+ ) ;
947
+ }
948
+
949
+ #[ test]
950
+ fn get_canister_status_memory_metrics_stable_memory_size ( ) {
951
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
952
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
953
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
954
+ test. ingress (
955
+ canister_id,
956
+ "update" ,
957
+ wasm ( )
958
+ . stable64_grow ( 1 )
959
+ . stable64_read ( WASM_PAGE_SIZE_IN_BYTES as u64 - 1 , 1 )
960
+ . push_bytes ( & [ ] )
961
+ . append_and_reply ( )
962
+ . build ( ) ,
963
+ ) . unwrap ( ) ;
964
+ assert_eq ! (
965
+ get_canister_status( & mut test, canister_id) . stable_memory_size( ) ,
966
+ csr. stable_memory_size( ) + NumBytes :: from( WASM_PAGE_SIZE_IN_BYTES as u64 )
967
+ ) ;
968
+ }
969
+
970
+ #[ test]
971
+ fn get_canister_status_memory_metrics_global_memory_size ( ) {
972
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
973
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
974
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
975
+ let exported_globals = test. execution_state ( canister_id) . exported_globals . clone ( ) ;
976
+ assert_eq ! (
977
+ csr. global_memory_size( ) ,
978
+ NumBytes :: new( 8 * exported_globals. len( ) as u64 )
979
+ ) ;
980
+ }
981
+
982
+ #[ test]
983
+ fn get_canister_status_memory_metrics_wasm_binary_size ( ) {
984
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
985
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
986
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
987
+ assert_eq ! (
988
+ csr. wasm_binary_size( ) ,
989
+ NumBytes :: new( UNIVERSAL_CANISTER_WASM . len( ) as u64 )
990
+ ) ;
991
+ }
992
+
993
+ #[ test]
994
+ fn get_canister_status_memory_metrics_custom_sections_size ( ) {
995
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
996
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
997
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
998
+ let metadata = test. execution_state ( canister_id) . metadata . clone ( ) ;
999
+ assert_eq ! (
1000
+ csr. custom_sections_size( ) ,
1001
+ NumBytes :: new(
1002
+ metadata. custom_sections( )
1003
+ . iter( )
1004
+ . map( |( k, v) | k. len( ) + v. count_bytes( ) )
1005
+ . sum:: <usize >( ) as u64
1006
+ ) ,
1007
+ ) ;
1008
+ }
1009
+
1010
+ #[ test]
1011
+ fn get_canister_status_memory_metrics_canister_history_size ( ) {
1012
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
1013
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
1014
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
1015
+ test. set_controller ( canister_id, test. user_id ( ) . get ( ) ) . unwrap ( ) ;
1016
+ let memory_difference = NumBytes :: from ( ( size_of :: < CanisterChange > ( ) + size_of :: < PrincipalId > ( ) ) as u64 ) ;
1017
+ assert_eq ! (
1018
+ get_canister_status( & mut test, canister_id) . canister_history_size( ) ,
1019
+ csr. canister_history_size( ) + memory_difference
1020
+ ) ;
1021
+ }
1022
+
1023
+ #[ test]
1024
+ fn get_canister_status_memory_metrics_wasm_chunk_store_size ( ) {
1025
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
1026
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
1027
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
1028
+ test. subnet_message (
1029
+ "upload_chunk" ,
1030
+ UploadChunkArgs {
1031
+ canister_id : canister_id. into ( ) ,
1032
+ chunk : vec ! [ 1 , 2 , 3 , 4 , 5 ] ,
1033
+ } . encode ( ) ,
1034
+ ) . unwrap ( ) ;
1035
+ assert_gt ! (
1036
+ get_canister_status( & mut test, canister_id) . wasm_chunk_store_size( ) ,
1037
+ csr. wasm_chunk_store_size( )
1038
+ ) ;
1039
+ }
1040
+
1041
+ #[ test]
1042
+ fn get_canister_status_memory_metrics_snapshots_size ( ) {
1043
+ let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
1044
+ let canister_id = test. universal_canister ( ) . unwrap ( ) ;
1045
+ let csr: CanisterStatusResultV2 = get_canister_status ( & mut test, canister_id) ;
1046
+ test. subnet_message (
1047
+ "take_canister_snapshot" ,
1048
+ TakeCanisterSnapshotArgs {
1049
+ canister_id : canister_id. into ( ) ,
1050
+ replace_snapshot : None ,
1051
+ } . encode ( )
1052
+ ) . unwrap ( ) ;
1053
+ assert_gt ! (
1054
+ get_canister_status( & mut test, canister_id) . snapshots_size( ) ,
1055
+ csr. snapshots_size( )
1056
+ ) ;
1057
+ }
1058
+
888
1059
#[ test]
889
1060
fn deposit_cycles_to_non_existing_canister_fails ( ) {
890
1061
let mut test = ExecutionTestBuilder :: new ( ) . build ( ) ;
0 commit comments