123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133openSTMmoduleMakeExt(Spec:SpecExt)=structopenUtilopenQCheckopenInternal.Make(Spec)[@alert"-internal"]letcheck_obs=check_obsletall_interleavings_ok(seq_pref,cmds1,cmds2)=all_interleavings_okseq_prefcmds1cmds2Spec.init_stateletarb_cmds_triple=arb_cmds_tripleletarb_triple=arb_tripleletarb_triple_asymseq_lenpar_lenarb0arb1arb2=letarb_triple=arb_tripleseq_lenpar_lenarb0arb1arb2inset_print(print_triple_vertical~center_prefix:falseSpec.show_cmd)arb_triple(* operate over arrays to avoid needless allocation underway *)letinterp_sut_ressutcs=letcs_arr=Array.of_listcsinletres_arr=Array.map(func->Domain.cpu_relax();Spec.runcsut)cs_arrinList.combinecs(Array.to_listres_arr)letrun_parseq_prefcmds1cmds2=letsut=Spec.init_sut()inletpref_obs=Spec.wrap_cmd_seq@@fun()->interp_sut_ressutseq_prefinletbarrier=Atomic.make2inletmaincmds()=Spec.wrap_cmd_seq@@fun()->Atomic.decrbarrier;whileAtomic.getbarrier<>0doDomain.cpu_relax()done;tryOk(interp_sut_ressutcmds)withexn->Errorexninletdom1=Domain.spawn(maincmds1)inletdom2=Domain.spawn(maincmds2)inletobs1=Domain.joindom1inletobs2=Domain.joindom2inlet()=Spec.cleanupsutinletobs1=matchobs1withOkv->v|Errorexn->raiseexninletobs2=matchobs2withOkv->v|Errorexn->raiseexninpref_obs,obs1,obs2letagree_prop_par(seq_pref,cmds1,cmds2)=letpref_obs,obs1,obs2=run_parseq_prefcmds1cmds2incheck_obspref_obsobs1obs2Spec.init_state||Test.fail_reportf" Results incompatible with linearized model\n\n%s"@@print_triple_vertical~fig_indent:5~res_width:35(fun(c,r)->Printf.sprintf"%s : %s"(Spec.show_cmdc)(show_resr))(pref_obs,obs1,obs2)letstress_prop_par(seq_pref,cmds1,cmds2)=let_=run_parseq_prefcmds1cmds2intrueletagree_prop_par_asym(seq_pref,cmds1,cmds2)=letsut=Spec.init_sut()inletpref_obs=Spec.wrap_cmd_seq@@fun()->interp_sut_ressutseq_prefinletwait=Atomic.make2inletchild_dom=Domain.spawn(fun()->Spec.wrap_cmd_seq@@fun()->Atomic.decrwait;whileAtomic.getwait<>0doDomain.cpu_relax()done;tryOk(interp_sut_ressutcmds2)withexn->Errorexn)inletparent_obs=Spec.wrap_cmd_seq@@fun()->Atomic.decrwait;whileAtomic.getwait<>0doDomain.cpu_relax()done;tryOk(interp_sut_ressutcmds1)withexn->Errorexninletchild_obs=Domain.joinchild_dominlet()=Spec.cleanupsutinletparent_obs=matchparent_obswithOkv->v|Errorexn->raiseexninletchild_obs=matchchild_obswithOkv->v|Errorexn->raiseexnincheck_obspref_obsparent_obschild_obsSpec.init_state||Test.fail_reportf" Results incompatible with linearized model:\n\n%s"@@print_triple_vertical~fig_indent:5~res_width:35~center_prefix:false(fun(c,r)->Printf.sprintf"%s : %s"(Spec.show_cmdc)(show_resr))(pref_obs,parent_obs,child_obs)(* Common magic constants *)letrep_count=25(* No. of repetitions of the non-deterministic property *)letretries=10(* Additional factor of repetition during shrinking *)letseq_len=20(* max length of the sequential prefix *)letpar_len=12(* max length of the parallel cmd lists *)letagree_test_par~count~name=letmax_gen=3*countin(* precond filtering may require extra generation: max. 3*count though *)Test.make~retries~max_gen~count~name(arb_cmds_tripleseq_lenpar_len)(funtriple->assume(all_interleavings_oktriple);repeatrep_countagree_prop_partriple)(* 25 times each, then 25 * 10 times when shrinking *)letstress_test_par~count~name=letmax_gen=3*countin(* precond filtering may require extra generation: max. 3*count though *)Test.make~retries~max_gen~count~name(arb_cmds_tripleseq_lenpar_len)(funtriple->assume(all_interleavings_oktriple);repeatrep_countstress_prop_partriple)(* 25 times each, then 25 * 10 times when shrinking *)letneg_agree_test_par~count~name=letmax_gen=3*countin(* precond filtering may require extra generation: max. 3*count though *)Test.make_neg~retries~max_gen~count~name(arb_cmds_tripleseq_lenpar_len)(funtriple->assume(all_interleavings_oktriple);repeatrep_countagree_prop_partriple)(* 25 times each, then 25 * 10 times when shrinking *)letagree_test_par_asym~count~name=letmax_gen=3*countin(* precond filtering may require extra generation: max. 3*count though *)Test.make~retries~max_gen~count~name(arb_cmds_tripleseq_lenpar_len)(funtriple->assume(all_interleavings_oktriple);repeatrep_countagree_prop_par_asymtriple)(* 25 times each, then 25 * 10 times when shrinking *)letneg_agree_test_par_asym~count~name=letmax_gen=3*countin(* precond filtering may require extra generation: max. 3*count though *)Test.make_neg~retries~max_gen~count~name(arb_cmds_tripleseq_lenpar_len)(funtriple->assume(all_interleavings_oktriple);repeatrep_countagree_prop_par_asymtriple)(* 25 times each, then 25 * 10 times when shrinking *)endmoduleMake(Spec:Spec)=MakeExt(structincludeSpecDefaultsincludeSpecend)