@@ -909,3 +909,119 @@ func TestVerifyLibraries(t *testing.T) {
909
909
})
910
910
}
911
911
}
912
+
913
+ func TestRandomArchProbabilities (t * testing.T ) {
914
+ ctx := context .Background ()
915
+
916
+ tests := []struct {
917
+ validArchs spec.ArchSet
918
+ arm64Probability float64
919
+ fipsProbability float64
920
+ expectedDistribution map [vm.CPUArch ]float64
921
+ }{
922
+ {
923
+ validArchs : spec .AllArchs ,
924
+ arm64Probability : 0.3 ,
925
+ fipsProbability : 0.2 ,
926
+ expectedDistribution : map [vm.CPUArch ]float64 {
927
+ vm .ArchAMD64 : 0.56 ,
928
+ vm .ArchARM64 : 0.3 ,
929
+ vm .ArchFIPS : 0.14 ,
930
+ },
931
+ },
932
+ {
933
+ validArchs : spec .AllExceptFIPS ,
934
+ arm64Probability : 0.4 ,
935
+ fipsProbability : 0.1 ,
936
+ expectedDistribution : map [vm.CPUArch ]float64 {
937
+ vm .ArchAMD64 : 0.57447 ,
938
+ vm .ArchARM64 : 0.42553 ,
939
+ },
940
+ },
941
+ {
942
+ validArchs : spec .OnlyAMD64 ,
943
+ arm64Probability : 0.5 ,
944
+ fipsProbability : 0.3 ,
945
+ expectedDistribution : map [vm.CPUArch ]float64 {
946
+ vm .ArchAMD64 : 1.0 , // Only valid architecture
947
+ },
948
+ },
949
+ {
950
+ validArchs : spec .OnlyARM64 ,
951
+ arm64Probability : 0.5 ,
952
+ fipsProbability : 0.3 ,
953
+ expectedDistribution : map [vm.CPUArch ]float64 {
954
+ vm .ArchARM64 : 1.0 , // Only valid architecture
955
+ },
956
+ },
957
+ {
958
+ validArchs : spec .OnlyFIPS ,
959
+ arm64Probability : 0.2 ,
960
+ fipsProbability : 0.0 ,
961
+ expectedDistribution : map [vm.CPUArch ]float64 {
962
+ vm .ArchAMD64 : 1.0 , // Should fall back to AMD64
963
+ },
964
+ },
965
+ {
966
+ validArchs : spec .AllExceptFIPS ,
967
+ arm64Probability : 0.0 ,
968
+ fipsProbability : 1.0 ,
969
+ expectedDistribution : map [vm.CPUArch ]float64 {
970
+ vm .ArchAMD64 : 1.0 , // Should fall back to AMD64
971
+ },
972
+ },
973
+ {
974
+ validArchs : spec .AllExceptFIPS ,
975
+ arm64Probability : 0.5 ,
976
+ fipsProbability : 1.0 ,
977
+ expectedDistribution : map [vm.CPUArch ]float64 {
978
+ vm .ArchARM64 : 1.0 ,
979
+ },
980
+ },
981
+ {
982
+ validArchs : spec .Archs (spec .ArchAMD64 , spec .ArchFIPS ),
983
+ arm64Probability : 0.3 ,
984
+ fipsProbability : 0.4 ,
985
+ expectedDistribution : map [vm.CPUArch ]float64 {
986
+ vm .ArchAMD64 : 0.6 ,
987
+ vm .ArchFIPS : 0.4 ,
988
+ },
989
+ },
990
+ {
991
+ validArchs : spec .Archs (spec .ArchARM64 , spec .ArchFIPS ),
992
+ arm64Probability : 0.6 ,
993
+ fipsProbability : 0.2 ,
994
+ expectedDistribution : map [vm.CPUArch ]float64 {
995
+ vm .ArchARM64 : 0.88235 ,
996
+ vm .ArchFIPS : 0.11765 ,
997
+ },
998
+ },
999
+ }
1000
+
1001
+ // Since this is a statistical test, we want to use a fixed seed to avoid flakes,
1002
+ // i.e. a 99% confidence interval would be expected to fail when stressed 100 times.
1003
+ //
1004
+ // We can run this manually with a random seed for more confidence in our distribution:
1005
+ // prng, _ := randutil.NewTestRand()
1006
+ prng := rand .New (rand .NewSource (12345 ))
1007
+ for _ , test := range tests {
1008
+ t .Run (fmt .Sprintf ("%s/arm=%d%%/fips=%d%%" , test .validArchs , int (test .arm64Probability * 100 ), int (test .fipsProbability * 100 )), func (t * testing.T ) {
1009
+ const numSamples = 10000
1010
+ counts := make (map [vm.CPUArch ]int )
1011
+
1012
+ // Generate samples
1013
+ for i := 0 ; i < numSamples ; i ++ {
1014
+ arch := randomArch (ctx , nilLogger (), test .validArchs , prng , test .arm64Probability , test .fipsProbability )
1015
+ counts [arch ]++
1016
+ }
1017
+
1018
+ for expectedArch , expectedProb := range test .expectedDistribution {
1019
+ actualCount := float64 (counts [expectedArch ])
1020
+ actualProb := actualCount / float64 (numSamples )
1021
+
1022
+ tolerance := 0.02
1023
+ require .InDelta (t , expectedProb , actualProb , tolerance )
1024
+ }
1025
+ })
1026
+ }
1027
+ }
0 commit comments