@@ -1070,3 +1070,90 @@ test_summary_count{name="foo"} 2
1070
1070
)
1071
1071
}
1072
1072
}
1073
+
1074
+ // collidingCollector is a collection of prometheus.Collectors,
1075
+ // and is itself a prometheus.Collector.
1076
+ type collidingCollector struct {
1077
+ i int
1078
+ name string
1079
+
1080
+ a , b , c , d prometheus.Collector
1081
+ }
1082
+
1083
+ // Describe satisifies part of the prometheus.Collector interface.
1084
+ func (m * collidingCollector ) Describe (desc chan <- * prometheus.Desc ) {
1085
+ m .a .Describe (desc )
1086
+ m .b .Describe (desc )
1087
+ m .c .Describe (desc )
1088
+ m .d .Describe (desc )
1089
+ }
1090
+
1091
+ // Collect satisifies part of the prometheus.Collector interface.
1092
+ func (m * collidingCollector ) Collect (metric chan <- prometheus.Metric ) {
1093
+ m .a .Collect (metric )
1094
+ m .b .Collect (metric )
1095
+ m .c .Collect (metric )
1096
+ m .d .Collect (metric )
1097
+ }
1098
+
1099
+ // TestAlreadyRegistered will fail with the old, weaker hash function. It is
1100
+ // taken from https://play.golang.org/p/HpV7YE6LI_4 , authored by @awilliams.
1101
+ func TestAlreadyRegisteredCollision (t * testing.T ) {
1102
+
1103
+ reg := prometheus .NewRegistry ()
1104
+
1105
+ for i := 0 ; i < 10000 ; i ++ {
1106
+ // A collector should be considered unique if its name and const
1107
+ // label values are unique.
1108
+
1109
+ name := fmt .Sprintf ("test-collector-%010d" , i )
1110
+
1111
+ collector := collidingCollector {
1112
+ i : i ,
1113
+ name : name ,
1114
+
1115
+ a : prometheus .NewCounter (prometheus.CounterOpts {
1116
+ Name : "my_collector_a" ,
1117
+ ConstLabels : prometheus.Labels {
1118
+ "name" : name ,
1119
+ "type" : "test" ,
1120
+ },
1121
+ }),
1122
+ b : prometheus .NewCounter (prometheus.CounterOpts {
1123
+ Name : "my_collector_b" ,
1124
+ ConstLabels : prometheus.Labels {
1125
+ "name" : name ,
1126
+ "type" : "test" ,
1127
+ },
1128
+ }),
1129
+ c : prometheus .NewCounter (prometheus.CounterOpts {
1130
+ Name : "my_collector_c" ,
1131
+ ConstLabels : prometheus.Labels {
1132
+ "name" : name ,
1133
+ "type" : "test" ,
1134
+ },
1135
+ }),
1136
+ d : prometheus .NewCounter (prometheus.CounterOpts {
1137
+ Name : "my_collector_d" ,
1138
+ ConstLabels : prometheus.Labels {
1139
+ "name" : name ,
1140
+ "type" : "test" ,
1141
+ },
1142
+ }),
1143
+ }
1144
+
1145
+ // Register should not fail, since each collector has a unique
1146
+ // set of sub-collectors, determined by their names and const label values.
1147
+ if err := reg .Register (& collector ); err != nil {
1148
+ alreadyRegErr , ok := err .(prometheus.AlreadyRegisteredError )
1149
+ if ! ok {
1150
+ t .Fatal (err )
1151
+ }
1152
+
1153
+ previous := alreadyRegErr .ExistingCollector .(* collidingCollector )
1154
+ current := alreadyRegErr .NewCollector .(* collidingCollector )
1155
+
1156
+ t .Errorf ("Unexpected registration error: %q\n previous collector: %s (i=%d)\n current collector %s (i=%d)" , alreadyRegErr , previous .name , previous .i , current .name , current .i )
1157
+ }
1158
+ }
1159
+ }
0 commit comments