@@ -268,6 +268,7 @@ static VALUE _native_is_object_recorded(DDTRACE_UNUSED VALUE _self, VALUE record
268268static VALUE _native_heap_recorder_reset_last_update (DDTRACE_UNUSED VALUE _self , VALUE recorder_instance );
269269static VALUE _native_recorder_after_gc_step (DDTRACE_UNUSED VALUE _self , VALUE recorder_instance );
270270static VALUE _native_benchmark_intern (DDTRACE_UNUSED VALUE _self , VALUE recorder_instance , VALUE string , VALUE times , VALUE use_all );
271+ static VALUE _native_test_managed_string_storage_produces_valid_profiles (DDTRACE_UNUSED VALUE _self );
271272
272273void stack_recorder_init (VALUE profiling_module ) {
273274 VALUE stack_recorder_class = rb_define_class_under (profiling_module , "StackRecorder" , rb_cObject );
@@ -303,6 +304,7 @@ void stack_recorder_init(VALUE profiling_module) {
303304 rb_define_singleton_method (testing_module , "_native_heap_recorder_reset_last_update" , _native_heap_recorder_reset_last_update , 1 );
304305 rb_define_singleton_method (testing_module , "_native_recorder_after_gc_step" , _native_recorder_after_gc_step , 1 );
305306 rb_define_singleton_method (testing_module , "_native_benchmark_intern" , _native_benchmark_intern , 4 );
307+ rb_define_singleton_method (testing_module , "_native_test_managed_string_storage_produces_valid_profiles" , _native_test_managed_string_storage_produces_valid_profiles , 0 );
306308
307309 ok_symbol = ID2SYM (rb_intern_const ("ok" ));
308310 error_symbol = ID2SYM (rb_intern_const ("error" ));
@@ -1051,3 +1053,92 @@ static VALUE _native_benchmark_intern(DDTRACE_UNUSED VALUE _self, VALUE recorder
10511053
10521054 return Qtrue ;
10531055}
1056+
1057+ // See comments in rspec test for details on what we're testing here.
1058+ static VALUE _native_test_managed_string_storage_produces_valid_profiles (DDTRACE_UNUSED VALUE _self ) {
1059+ ddog_prof_ManagedStringStorageNewResult string_storage = ddog_prof_ManagedStringStorage_new ();
1060+
1061+ if (string_storage .tag == DDOG_PROF_MANAGED_STRING_STORAGE_NEW_RESULT_ERR ) {
1062+ rb_raise (rb_eRuntimeError , "Failed to initialize string storage: %" PRIsVALUE , get_error_details_and_drop (& string_storage .err ));
1063+ }
1064+
1065+ ddog_prof_Slice_ValueType sample_types = {.ptr = all_value_types , .len = ALL_VALUE_TYPES_COUNT };
1066+ ddog_prof_Profile_NewResult profile = ddog_prof_Profile_with_string_storage (sample_types , NULL , NULL , string_storage .ok );
1067+
1068+ if (profile .tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR ) {
1069+ rb_raise (rb_eRuntimeError , "Failed to initialize profile: %" PRIsVALUE , get_error_details_and_drop (& profile .err ));
1070+ }
1071+
1072+ ddog_prof_ManagedStringId hello = intern_or_raise (string_storage .ok , DDOG_CHARSLICE_C ("hello" ));
1073+ ddog_prof_ManagedStringId world = intern_or_raise (string_storage .ok , DDOG_CHARSLICE_C ("world" ));
1074+ ddog_prof_ManagedStringId key = intern_or_raise (string_storage .ok , DDOG_CHARSLICE_C ("key" ));
1075+
1076+ int64_t metric_values [] = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
1077+ ddog_prof_Label labels [] = {{.key_id = key , .str_id = key }};
1078+
1079+ ddog_prof_Location locations [] = {
1080+ (ddog_prof_Location ) {
1081+ .mapping = {.filename = DDOG_CHARSLICE_C ("" ), .build_id = DDOG_CHARSLICE_C ("" ), .build_id_id = {}},
1082+ .function = {
1083+ .name = DDOG_CHARSLICE_C ("" ),
1084+ .name_id = hello ,
1085+ .filename = DDOG_CHARSLICE_C ("" ),
1086+ .filename_id = world ,
1087+ },
1088+ .line = 1 ,
1089+ }
1090+ };
1091+
1092+ ddog_prof_Profile_Result result = ddog_prof_Profile_add (
1093+ & profile .ok ,
1094+ (ddog_prof_Sample ) {
1095+ .locations = (ddog_prof_Slice_Location ) { .ptr = locations , .len = 1 },
1096+ .values = (ddog_Slice_I64 ) {.ptr = metric_values , .len = 8 },
1097+ .labels = (ddog_prof_Slice_Label ) { .ptr = labels , .len = 1 }
1098+ },
1099+ 0
1100+ );
1101+
1102+ if (result .tag == DDOG_PROF_PROFILE_RESULT_ERR ) {
1103+ rb_raise (rb_eArgError , "Failed to record sample: %" PRIsVALUE , get_error_details_and_drop (& result .err ));
1104+ }
1105+
1106+ ddog_Timespec finish_timestamp = system_epoch_now_timespec ();
1107+ ddog_prof_Profile_SerializeResult serialize_result = ddog_prof_Profile_serialize (& profile .ok , & finish_timestamp , NULL , NULL );
1108+
1109+ if (serialize_result .tag == DDOG_PROF_PROFILE_SERIALIZE_RESULT_ERR ) {
1110+ rb_raise (rb_eRuntimeError , "Failed to serialize: %" PRIsVALUE , get_error_details_and_drop (& serialize_result .err ));
1111+ }
1112+
1113+ ddog_prof_MaybeError advance_gen_result = ddog_prof_ManagedStringStorage_advance_gen (string_storage .ok );
1114+
1115+ if (advance_gen_result .tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR ) {
1116+ rb_raise (rb_eRuntimeError , "Failed to advance string storage gen: %" PRIsVALUE , get_error_details_and_drop (& advance_gen_result .some ));
1117+ }
1118+
1119+ VALUE encoded_pprof_1 = ruby_string_from_vec_u8 (serialize_result .ok .buffer );
1120+
1121+ result = ddog_prof_Profile_add (
1122+ & profile .ok ,
1123+ (ddog_prof_Sample ) {
1124+ .locations = (ddog_prof_Slice_Location ) { .ptr = locations , .len = 1 },
1125+ .values = (ddog_Slice_I64 ) {.ptr = metric_values , .len = 8 },
1126+ .labels = (ddog_prof_Slice_Label ) { .ptr = labels , .len = 1 }
1127+ },
1128+ 0
1129+ );
1130+
1131+ if (result .tag == DDOG_PROF_PROFILE_RESULT_ERR ) {
1132+ rb_raise (rb_eArgError , "Failed to record sample: %" PRIsVALUE , get_error_details_and_drop (& result .err ));
1133+ }
1134+
1135+ serialize_result = ddog_prof_Profile_serialize (& profile .ok , & finish_timestamp , NULL , NULL );
1136+
1137+ if (serialize_result .tag == DDOG_PROF_PROFILE_SERIALIZE_RESULT_ERR ) {
1138+ rb_raise (rb_eArgError , "Failed to serialize: %" PRIsVALUE , get_error_details_and_drop (& serialize_result .err ));
1139+ }
1140+
1141+ VALUE encoded_pprof_2 = ruby_string_from_vec_u8 (serialize_result .ok .buffer );
1142+
1143+ return rb_ary_new_from_args (2 , encoded_pprof_1 , encoded_pprof_2 );
1144+ }
0 commit comments