##// END OF EJS Templates
branching: merge stable into default
Raphaël Gomès -
r50139:cd51d495 merge default
parent child Browse files
Show More
@@ -1,229 +1,230 b''
1 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A=
1 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A=
2 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk=
2 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk=
3 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys=
3 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys=
4 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4=
4 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4=
5 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I=
5 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I=
6 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU=
6 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU=
7 bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0=
7 bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0=
8 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE=
8 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE=
9 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc=
9 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc=
10 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu
10 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu
11 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE
11 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE
12 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx
12 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx
13 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx
13 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx
14 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje
14 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje
15 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM
15 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM
16 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA
16 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA
17 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m
17 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m
18 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw
18 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw
19 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq
19 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq
20 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O
20 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O
21 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh
21 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh
22 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW
22 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW
23 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk
23 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk
24 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO
24 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO
25 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy
25 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy
26 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL
26 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL
27 bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd
27 bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd
28 c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf
28 c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf
29 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A=
29 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A=
30 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4=
30 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4=
31 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
31 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
32 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
32 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
33 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
33 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
34 e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
34 e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
35 a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok=
35 a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok=
36 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg=
36 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg=
37 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4=
37 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4=
38 aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0=
38 aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0=
39 b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is=
39 b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is=
40 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI=
40 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI=
41 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU=
41 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU=
42 de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4=
42 de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4=
43 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik=
43 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik=
44 d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM=
44 d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM=
45 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg=
45 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg=
46 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
46 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
47 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4=
47 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4=
48 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo=
48 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo=
49 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0=
49 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0=
50 db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y=
50 db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y=
51 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q=
51 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q=
52 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q=
52 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q=
53 b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc=
53 b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc=
54 d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono=
54 d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono=
55 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg=
55 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg=
56 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0=
56 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0=
57 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w=
57 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w=
58 b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA=
58 b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA=
59 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM=
59 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM=
60 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc=
60 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc=
61 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k=
61 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k=
62 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38=
62 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38=
63 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0=
63 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0=
64 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM=
64 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM=
65 a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0=
65 a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0=
66 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg=
66 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg=
67 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA=
67 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA=
68 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM=
68 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM=
69 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg=
69 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg=
70 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I=
70 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I=
71 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU=
71 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU=
72 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM=
72 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM=
73 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI=
73 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI=
74 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI=
74 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI=
75 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk=
75 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk=
76 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4=
76 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4=
77 f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
77 f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
78 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
78 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
79 335a558f81dc73afeab4d7be63617392b130117f 0 iQIVAwUAUiZrIyBXgaxoKi1yAQK2iw//cquNqqSkc8Re5/TZT9I6NH+lh6DbOKjJP0Xl1Wqq0K+KSIUgZG4G32ovaEb2l5X0uY+3unRPiZ0ebl0YSw4Fb2ZiPIADXLBTOYRrY2Wwd3tpJeGI6wEgZt3SfcITV/g7NJrCjT3FlYoSOIayrExM80InSdcEM0Q3Rx6HKzY2acyxzgZeAtAW5ohFvHilSvY6p5Gcm4+QptMxvw45GPdreUmjeXZxNXNXZ8P+MjMz/QJbai/N7PjmK8lqnhkBsT48Ng/KhhmOkGntNJ2/ImBWLFGcWngSvJ7sfWwnyhndvGhe0Hq1NcCf7I8TjNDxU5TR+m+uW7xjXdLoDbUjBdX4sKXnh8ZjbYiODKBOrrDq25cf8nA/tnpKyE/qsVy60kOk6loY4XKiYmn1V49Ta0emmDx0hqo3HgxHHsHX0NDnGdWGol7cPRET0RzVobKq1A0jnrhPooWidvLh9bPzLonrWDo+ib+DuySoRkuYUK4pgZJ2mbg6daFOBEZygkSyRB8bo1UQUP7EgQDrWe4khb/5GHEfDkrQz3qu/sXvc0Ir1mOUWBFPHC2DjjCn/oMJuUkG1SwM8l2Bfv7h67ssES6YQ2+RjOix4yid7EXS/Ogl45PzCIPSI5+BbNs10JhE0w5uErBHlF53EDTe/TSLc+GU6DB6PP6dH912Njdr3jpNSUQ=
79 335a558f81dc73afeab4d7be63617392b130117f 0 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
@@ -1,242 +1,243 b''
1 d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f
1 d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f
2 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e
2 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e
3 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d
3 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d
4 b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c
4 b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c
5 f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5
5 f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5
6 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b
6 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b
7 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6
7 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
14 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1
14 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1
15 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2
15 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2
16 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3
16 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3
17 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4
17 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4
18 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5
18 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5
19 bae2e9c838e90a393bae3973a7850280413e091a 1.0
19 bae2e9c838e90a393bae3973a7850280413e091a 1.0
20 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1
20 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1
21 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2
21 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2
22 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1
22 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1
23 3773e510d433969e277b1863c317b674cbee2065 1.1.1
23 3773e510d433969e277b1863c317b674cbee2065 1.1.1
24 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2
24 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2
25 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2
25 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2
26 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1
26 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1
27 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3
27 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3
28 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1
28 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1
29 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4
29 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4
30 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1
30 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1
31 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2
31 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2
32 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3
32 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3
33 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5
33 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5
34 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1
34 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1
35 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2
35 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2
36 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3
36 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3
37 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4
37 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4
38 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6
38 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6
39 bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1
39 bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1
40 c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2
40 c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2
41 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3
41 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3
42 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4
42 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4
43 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
43 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
44 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
44 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
45 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
45 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
46 e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
46 e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
47 a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4
47 a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4
48 2b2155623ee2559caf288fd333f30475966c4525 1.7.5
48 2b2155623ee2559caf288fd333f30475966c4525 1.7.5
49 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8
49 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8
50 aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1
50 aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1
51 b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2
51 b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2
52 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3
52 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3
53 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4
53 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4
54 de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9
54 de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9
55 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1
55 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1
56 d629f1e89021103f1753addcef6b310e4435b184 1.9.2
56 d629f1e89021103f1753addcef6b310e4435b184 1.9.2
57 351a9292e430e35766c552066ed3e87c557b803b 1.9.3
57 351a9292e430e35766c552066ed3e87c557b803b 1.9.3
58 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
58 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
59 41453d55b481ddfcc1dacb445179649e24ca861d 2.0
59 41453d55b481ddfcc1dacb445179649e24ca861d 2.0
60 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1
60 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1
61 6344043924497cd06d781d9014c66802285072e4 2.0.2
61 6344043924497cd06d781d9014c66802285072e4 2.0.2
62 db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc
62 db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc
63 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1
63 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1
64 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1
64 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1
65 b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2
65 b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2
66 d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc
66 d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc
67 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2
67 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2
68 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1
68 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1
69 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2
69 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2
70 b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3
70 b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3
71 a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc
71 a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc
72 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3
72 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3
73 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1
73 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1
74 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2
74 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2
75 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc
75 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc
76 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4
76 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4
77 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1
77 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1
78 a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2
78 a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2
79 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc
79 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc
80 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5
80 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5
81 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1
81 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1
82 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2
82 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2
83 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3
83 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3
84 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4
84 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4
85 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc
85 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc
86 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6
86 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6
87 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1
87 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1
88 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2
88 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2
89 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3
89 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3
90 f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
90 f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
91 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
91 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
92 335a558f81dc73afeab4d7be63617392b130117f 2.7.1
92 335a558f81dc73afeab4d7be63617392b130117f 2.7.1
93 e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
93 e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
94 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc
94 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc
95 d825e4025e39d1c39db943cdc89818abd0a87c27 2.8
95 d825e4025e39d1c39db943cdc89818abd0a87c27 2.8
96 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1
96 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1
97 ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2
97 ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2
98 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc
98 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc
99 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9
99 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9
100 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1
100 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1
101 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2
101 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2
102 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc
102 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc
103 2195ac506c6ababe86985b932f4948837c0891b5 3.0
103 2195ac506c6ababe86985b932f4948837c0891b5 3.0
104 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1
104 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1
105 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2
105 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2
106 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc
106 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc
107 3178e49892020336491cdc6945885c4de26ffa8b 3.1
107 3178e49892020336491cdc6945885c4de26ffa8b 3.1
108 5dc91146f35369949ea56b40172308158b59063a 3.1.1
108 5dc91146f35369949ea56b40172308158b59063a 3.1.1
109 f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2
109 f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
114 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3
114 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3
115 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4
115 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4
116 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc
116 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc
117 fbdd5195528fae4f41feebc1838215c110b25d6a 3.3
117 fbdd5195528fae4f41feebc1838215c110b25d6a 3.3
118 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1
118 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1
119 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2
119 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2
120 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3
120 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3
121 e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc
121 e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc
122 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4
122 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4
123 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1
123 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1
124 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2
124 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2
125 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc
125 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc
126 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5
126 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5
127 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1
127 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1
128 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2
128 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2
129 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc
129 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc
130 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6
130 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6
131 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1
131 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1
132 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2
132 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2
133 ea389970c08449440587712117f178d33bab3f1e 3.6.3
133 ea389970c08449440587712117f178d33bab3f1e 3.6.3
134 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
134 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
139 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc
139 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc
140 f85de28eae32e7d3064b1a1321309071bbaaa069 3.8
140 f85de28eae32e7d3064b1a1321309071bbaaa069 3.8
141 a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1
141 a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1
142 aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2
142 aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2
143 a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3
143 a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3
144 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4
144 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4
145 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc
145 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc
146 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9
146 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9
147 ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1
147 ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1
148 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2
148 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2
149 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
149 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
150 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
150 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
151 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
151 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
152 e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
152 e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
153 a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc
153 a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc
154 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1
154 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1
155 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1
155 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1
156 ed5b25874d998ababb181a939dd37a16ea644435 4.1.2
156 ed5b25874d998ababb181a939dd37a16ea644435 4.1.2
157 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3
157 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3
158 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc
158 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc
159 bb96d4a497432722623ae60d9bc734a1e360179e 4.2
159 bb96d4a497432722623ae60d9bc734a1e360179e 4.2
160 c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1
160 c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1
161 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2
161 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2
162 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc
162 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc
163 5544af8622863796a0027566f6b646e10d522c4c 4.3
163 5544af8622863796a0027566f6b646e10d522c4c 4.3
164 943c91326b23954e6e1c6960d0239511f9530258 4.2.3
164 943c91326b23954e6e1c6960d0239511f9530258 4.2.3
165 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1
165 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1
166 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2
166 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
176 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3
176 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3
177 ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0
177 ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0
178 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1
178 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1
179 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6
179 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6
180 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1
180 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1
181 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2
181 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2
182 e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0
182 e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0
183 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7
183 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7
184 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1
184 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1
185 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2
185 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2
186 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0
186 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0
187 a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8
187 a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8
188 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1
188 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1
189 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2
189 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2
190 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
190 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
191 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
191 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
192 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
192 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
193 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
193 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
194 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0
194 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0
195 c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1
195 c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1
196 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2
196 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2
197 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0
197 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0
198 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1
198 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1
199 a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1
199 a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1
200 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2
200 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2
201 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0
201 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0
202 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2
202 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2
203 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1
203 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1
204 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2
204 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2
205 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0
205 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0
206 e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1
206 e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1
207 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3
207 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3
208 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1
208 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1
209 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2
209 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2
210 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0
210 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0
211 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
211 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
212 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
212 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
213 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
213 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
214 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
214 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
215 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5
215 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5
216 f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1
216 f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1
217 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2
217 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
@@ -1,154 +1,160 b''
1 # narrowwirepeer.py - passes narrow spec with unbundle command
1 # narrowwirepeer.py - passes narrow spec with unbundle command
2 #
2 #
3 # Copyright 2017 Google, Inc.
3 # Copyright 2017 Google, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 from mercurial import (
9 from mercurial import (
10 bundle2,
10 bundle2,
11 error,
11 error,
12 exchange,
12 extensions,
13 extensions,
13 hg,
14 hg,
14 narrowspec,
15 narrowspec,
15 wireprototypes,
16 wireprototypes,
16 wireprotov1peer,
17 wireprotov1peer,
17 wireprotov1server,
18 wireprotov1server,
18 )
19 )
19
20
20 from . import narrowbundle2
21 from . import narrowbundle2
21
22
22
23
23 def uisetup():
24 def uisetup():
24 wireprotov1peer.wirepeer.narrow_widen = peernarrowwiden
25 wireprotov1peer.wirepeer.narrow_widen = peernarrowwiden
25
26
26
27
27 def reposetup(repo):
28 def reposetup(repo):
28 def wirereposetup(ui, peer):
29 def wirereposetup(ui, peer):
29 def wrapped(orig, cmd, *args, **kwargs):
30 def wrapped(orig, cmd, *args, **kwargs):
30 if cmd == b'unbundle':
31 if cmd == b'unbundle':
31 # TODO: don't blindly add include/exclude wireproto
32 # TODO: don't blindly add include/exclude wireproto
32 # arguments to unbundle.
33 # arguments to unbundle.
33 include, exclude = repo.narrowpats
34 include, exclude = repo.narrowpats
34 kwargs["includepats"] = b','.join(include)
35 kwargs["includepats"] = b','.join(include)
35 kwargs["excludepats"] = b','.join(exclude)
36 kwargs["excludepats"] = b','.join(exclude)
36 return orig(cmd, *args, **kwargs)
37 return orig(cmd, *args, **kwargs)
37
38
38 extensions.wrapfunction(peer, b'_calltwowaystream', wrapped)
39 extensions.wrapfunction(peer, b'_calltwowaystream', wrapped)
39
40
40 hg.wirepeersetupfuncs.append(wirereposetup)
41 hg.wirepeersetupfuncs.append(wirereposetup)
41
42
42
43
43 @wireprotov1server.wireprotocommand(
44 @wireprotov1server.wireprotocommand(
44 b'narrow_widen',
45 b'narrow_widen',
45 b'oldincludes oldexcludes'
46 b'oldincludes oldexcludes'
46 b' newincludes newexcludes'
47 b' newincludes newexcludes'
47 b' commonheads cgversion'
48 b' commonheads cgversion'
48 b' known ellipses',
49 b' known ellipses',
49 permission=b'pull',
50 permission=b'pull',
50 )
51 )
51 def narrow_widen(
52 def narrow_widen(
52 repo,
53 repo,
53 proto,
54 proto,
54 oldincludes,
55 oldincludes,
55 oldexcludes,
56 oldexcludes,
56 newincludes,
57 newincludes,
57 newexcludes,
58 newexcludes,
58 commonheads,
59 commonheads,
59 cgversion,
60 cgversion,
60 known,
61 known,
61 ellipses,
62 ellipses,
62 ):
63 ):
63 """wireprotocol command to send data when a narrow clone is widen. We will
64 """wireprotocol command to send data when a narrow clone is widen. We will
64 be sending a changegroup here.
65 be sending a changegroup here.
65
66
66 The current set of arguments which are required:
67 The current set of arguments which are required:
67 oldincludes: the old includes of the narrow copy
68 oldincludes: the old includes of the narrow copy
68 oldexcludes: the old excludes of the narrow copy
69 oldexcludes: the old excludes of the narrow copy
69 newincludes: the new includes of the narrow copy
70 newincludes: the new includes of the narrow copy
70 newexcludes: the new excludes of the narrow copy
71 newexcludes: the new excludes of the narrow copy
71 commonheads: list of heads which are common between the server and client
72 commonheads: list of heads which are common between the server and client
72 cgversion(maybe): the changegroup version to produce
73 cgversion(maybe): the changegroup version to produce
73 known: list of nodes which are known on the client (used in ellipses cases)
74 known: list of nodes which are known on the client (used in ellipses cases)
74 ellipses: whether to send ellipses data or not
75 ellipses: whether to send ellipses data or not
75 """
76 """
76
77
77 preferuncompressed = False
78 preferuncompressed = False
78 try:
79 try:
79
80
80 def splitpaths(data):
81 def splitpaths(data):
81 # work around ''.split(',') => ['']
82 # work around ''.split(',') => ['']
82 return data.split(b',') if data else []
83 return data.split(b',') if data else []
83
84
84 oldincludes = splitpaths(oldincludes)
85 oldincludes = splitpaths(oldincludes)
85 newincludes = splitpaths(newincludes)
86 newincludes = splitpaths(newincludes)
86 oldexcludes = splitpaths(oldexcludes)
87 oldexcludes = splitpaths(oldexcludes)
87 newexcludes = splitpaths(newexcludes)
88 newexcludes = splitpaths(newexcludes)
89
90 # enforce narrow acl if set
91 if repo.ui.has_section(exchange._NARROWACL_SECTION):
92 exchange.applynarrowacl(repo, {'includepats': newincludes})
93
88 # validate the patterns
94 # validate the patterns
89 narrowspec.validatepatterns(set(oldincludes))
95 narrowspec.validatepatterns(set(oldincludes))
90 narrowspec.validatepatterns(set(newincludes))
96 narrowspec.validatepatterns(set(newincludes))
91 narrowspec.validatepatterns(set(oldexcludes))
97 narrowspec.validatepatterns(set(oldexcludes))
92 narrowspec.validatepatterns(set(newexcludes))
98 narrowspec.validatepatterns(set(newexcludes))
93
99
94 common = wireprototypes.decodelist(commonheads)
100 common = wireprototypes.decodelist(commonheads)
95 known = wireprototypes.decodelist(known)
101 known = wireprototypes.decodelist(known)
96 if ellipses == b'0':
102 if ellipses == b'0':
97 ellipses = False
103 ellipses = False
98 else:
104 else:
99 ellipses = bool(ellipses)
105 ellipses = bool(ellipses)
100 cgversion = cgversion
106 cgversion = cgversion
101
107
102 bundler = bundle2.bundle20(repo.ui)
108 bundler = bundle2.bundle20(repo.ui)
103 newmatch = narrowspec.match(
109 newmatch = narrowspec.match(
104 repo.root, include=newincludes, exclude=newexcludes
110 repo.root, include=newincludes, exclude=newexcludes
105 )
111 )
106 oldmatch = narrowspec.match(
112 oldmatch = narrowspec.match(
107 repo.root, include=oldincludes, exclude=oldexcludes
113 repo.root, include=oldincludes, exclude=oldexcludes
108 )
114 )
109 if not ellipses:
115 if not ellipses:
110 bundle2.widen_bundle(
116 bundle2.widen_bundle(
111 bundler,
117 bundler,
112 repo,
118 repo,
113 oldmatch,
119 oldmatch,
114 newmatch,
120 newmatch,
115 common,
121 common,
116 known,
122 known,
117 cgversion,
123 cgversion,
118 ellipses,
124 ellipses,
119 )
125 )
120 else:
126 else:
121 narrowbundle2.generate_ellipses_bundle2_for_widening(
127 narrowbundle2.generate_ellipses_bundle2_for_widening(
122 bundler,
128 bundler,
123 repo,
129 repo,
124 oldmatch,
130 oldmatch,
125 newmatch,
131 newmatch,
126 cgversion,
132 cgversion,
127 common,
133 common,
128 known,
134 known,
129 )
135 )
130 except error.Abort as exc:
136 except error.Abort as exc:
131 bundler = bundle2.bundle20(repo.ui)
137 bundler = bundle2.bundle20(repo.ui)
132 manargs = [(b'message', exc.message)]
138 manargs = [(b'message', exc.message)]
133 advargs = []
139 advargs = []
134 if exc.hint is not None:
140 if exc.hint is not None:
135 advargs.append((b'hint', exc.hint))
141 advargs.append((b'hint', exc.hint))
136 bundler.addpart(bundle2.bundlepart(b'error:abort', manargs, advargs))
142 bundler.addpart(bundle2.bundlepart(b'error:abort', manargs, advargs))
137 preferuncompressed = True
143 preferuncompressed = True
138
144
139 chunks = bundler.getchunks()
145 chunks = bundler.getchunks()
140 return wireprototypes.streamres(
146 return wireprototypes.streamres(
141 gen=chunks, prefer_uncompressed=preferuncompressed
147 gen=chunks, prefer_uncompressed=preferuncompressed
142 )
148 )
143
149
144
150
145 def peernarrowwiden(remote, **kwargs):
151 def peernarrowwiden(remote, **kwargs):
146 for ch in ('commonheads', 'known'):
152 for ch in ('commonheads', 'known'):
147 kwargs[ch] = wireprototypes.encodelist(kwargs[ch])
153 kwargs[ch] = wireprototypes.encodelist(kwargs[ch])
148
154
149 for ch in ('oldincludes', 'newincludes', 'oldexcludes', 'newexcludes'):
155 for ch in ('oldincludes', 'newincludes', 'oldexcludes', 'newexcludes'):
150 kwargs[ch] = b','.join(kwargs[ch])
156 kwargs[ch] = b','.join(kwargs[ch])
151
157
152 kwargs['ellipses'] = b'%i' % bool(kwargs['ellipses'])
158 kwargs['ellipses'] = b'%i' % bool(kwargs['ellipses'])
153 f = remote._callcompressable(b'narrow_widen', **kwargs)
159 f = remote._callcompressable(b'narrow_widen', **kwargs)
154 return bundle2.getunbundler(remote.ui, f)
160 return bundle2.getunbundler(remote.ui, f)
@@ -1,749 +1,749 b''
1 # chgserver.py - command server extension for cHg
1 # chgserver.py - command server extension for cHg
2 #
2 #
3 # Copyright 2011 Yuya Nishihara <yuya@tcha.org>
3 # Copyright 2011 Yuya Nishihara <yuya@tcha.org>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """command server extension for cHg
8 """command server extension for cHg
9
9
10 'S' channel (read/write)
10 'S' channel (read/write)
11 propagate ui.system() request to client
11 propagate ui.system() request to client
12
12
13 'attachio' command
13 'attachio' command
14 attach client's stdio passed by sendmsg()
14 attach client's stdio passed by sendmsg()
15
15
16 'chdir' command
16 'chdir' command
17 change current directory
17 change current directory
18
18
19 'setenv' command
19 'setenv' command
20 replace os.environ completely
20 replace os.environ completely
21
21
22 'setumask' command (DEPRECATED)
22 'setumask' command (DEPRECATED)
23 'setumask2' command
23 'setumask2' command
24 set umask
24 set umask
25
25
26 'validate' command
26 'validate' command
27 reload the config and check if the server is up to date
27 reload the config and check if the server is up to date
28
28
29 Config
29 Config
30 ------
30 ------
31
31
32 ::
32 ::
33
33
34 [chgserver]
34 [chgserver]
35 # how long (in seconds) should an idle chg server exit
35 # how long (in seconds) should an idle chg server exit
36 idletimeout = 3600
36 idletimeout = 3600
37
37
38 # whether to skip config or env change checks
38 # whether to skip config or env change checks
39 skiphash = False
39 skiphash = False
40 """
40 """
41
41
42
42
43 import inspect
43 import inspect
44 import os
44 import os
45 import re
45 import re
46 import socket
46 import socket
47 import stat
47 import stat
48 import struct
48 import struct
49 import time
49 import time
50
50
51 from .i18n import _
51 from .i18n import _
52 from .pycompat import (
52 from .pycompat import (
53 getattr,
53 getattr,
54 setattr,
54 setattr,
55 )
55 )
56 from .node import hex
56 from .node import hex
57
57
58 from . import (
58 from . import (
59 commandserver,
59 commandserver,
60 encoding,
60 encoding,
61 error,
61 error,
62 extensions,
62 extensions,
63 pycompat,
63 pycompat,
64 util,
64 util,
65 )
65 )
66
66
67 from .utils import (
67 from .utils import (
68 hashutil,
68 hashutil,
69 procutil,
69 procutil,
70 stringutil,
70 stringutil,
71 )
71 )
72
72
73
73
74 def _hashlist(items):
74 def _hashlist(items):
75 """return sha1 hexdigest for a list"""
75 """return sha1 hexdigest for a list"""
76 return hex(hashutil.sha1(stringutil.pprint(items)).digest())
76 return hex(hashutil.sha1(stringutil.pprint(items)).digest())
77
77
78
78
79 # sensitive config sections affecting confighash
79 # sensitive config sections affecting confighash
80 _configsections = [
80 _configsections = [
81 b'alias', # affects global state commands.table
81 b'alias', # affects global state commands.table
82 b'diff-tools', # affects whether gui or not in extdiff's uisetup
82 b'diff-tools', # affects whether gui or not in extdiff's uisetup
83 b'eol', # uses setconfig('eol', ...)
83 b'eol', # uses setconfig('eol', ...)
84 b'extdiff', # uisetup will register new commands
84 b'extdiff', # uisetup will register new commands
85 b'extensions',
85 b'extensions',
86 b'fastannotate', # affects annotate command and adds fastannonate cmd
86 b'fastannotate', # affects annotate command and adds fastannonate cmd
87 b'merge-tools', # affects whether gui or not in extdiff's uisetup
87 b'merge-tools', # affects whether gui or not in extdiff's uisetup
88 b'schemes', # extsetup will update global hg.schemes
88 b'schemes', # extsetup will update global hg.schemes
89 ]
89 ]
90
90
91 _configsectionitems = [
91 _configsectionitems = [
92 (b'commands', b'show.aliasprefix'), # show.py reads it in extsetup
92 (b'commands', b'show.aliasprefix'), # show.py reads it in extsetup
93 ]
93 ]
94
94
95 # sensitive environment variables affecting confighash
95 # sensitive environment variables affecting confighash
96 _envre = re.compile(
96 _envre = re.compile(
97 br'''\A(?:
97 br'''\A(?:
98 CHGHG
98 CHGHG
99 |HG(?:DEMANDIMPORT|EMITWARNINGS|MODULEPOLICY|PROF|RCPATH)?
99 |HG(?:DEMANDIMPORT|EMITWARNINGS|MODULEPOLICY|PROF|RCPATH)?
100 |HG(?:ENCODING|PLAIN).*
100 |HG(?:ENCODING|PLAIN).*
101 |LANG(?:UAGE)?
101 |LANG(?:UAGE)?
102 |LC_.*
102 |LC_.*
103 |LD_.*
103 |LD_.*
104 |PATH
104 |PATH
105 |PYTHON.*
105 |PYTHON.*
106 |TERM(?:INFO)?
106 |TERM(?:INFO)?
107 |TZ
107 |TZ
108 )\Z''',
108 )\Z''',
109 re.X,
109 re.X,
110 )
110 )
111
111
112
112
113 def _confighash(ui):
113 def _confighash(ui):
114 """return a quick hash for detecting config/env changes
114 """return a quick hash for detecting config/env changes
115
115
116 confighash is the hash of sensitive config items and environment variables.
116 confighash is the hash of sensitive config items and environment variables.
117
117
118 for chgserver, it is designed that once confighash changes, the server is
118 for chgserver, it is designed that once confighash changes, the server is
119 not qualified to serve its client and should redirect the client to a new
119 not qualified to serve its client and should redirect the client to a new
120 server. different from mtimehash, confighash change will not mark the
120 server. different from mtimehash, confighash change will not mark the
121 server outdated and exit since the user can have different configs at the
121 server outdated and exit since the user can have different configs at the
122 same time.
122 same time.
123 """
123 """
124 sectionitems = []
124 sectionitems = []
125 for section in _configsections:
125 for section in _configsections:
126 sectionitems.append(ui.configitems(section))
126 sectionitems.append(ui.configitems(section))
127 for section, item in _configsectionitems:
127 for section, item in _configsectionitems:
128 sectionitems.append(ui.config(section, item))
128 sectionitems.append(ui.config(section, item))
129 sectionhash = _hashlist(sectionitems)
129 sectionhash = _hashlist(sectionitems)
130 # If $CHGHG is set, the change to $HG should not trigger a new chg server
130 # If $CHGHG is set, the change to $HG should not trigger a new chg server
131 if b'CHGHG' in encoding.environ:
131 if b'CHGHG' in encoding.environ:
132 ignored = {b'HG'}
132 ignored = {b'HG'}
133 else:
133 else:
134 ignored = set()
134 ignored = set()
135 envitems = [
135 envitems = [
136 (k, v)
136 (k, v)
137 for k, v in encoding.environ.items()
137 for k, v in encoding.environ.items()
138 if _envre.match(k) and k not in ignored
138 if _envre.match(k) and k not in ignored
139 ]
139 ]
140 envhash = _hashlist(sorted(envitems))
140 envhash = _hashlist(sorted(envitems))
141 return sectionhash[:6] + envhash[:6]
141 return sectionhash[:6] + envhash[:6]
142
142
143
143
144 def _getmtimepaths(ui):
144 def _getmtimepaths(ui):
145 """get a list of paths that should be checked to detect change
145 """get a list of paths that should be checked to detect change
146
146
147 The list will include:
147 The list will include:
148 - extensions (will not cover all files for complex extensions)
148 - extensions (will not cover all files for complex extensions)
149 - mercurial/__version__.py
149 - mercurial/__version__.py
150 - python binary
150 - python binary
151 """
151 """
152 modules = [m for n, m in extensions.extensions(ui)]
152 modules = [m for n, m in extensions.extensions(ui)]
153 try:
153 try:
154 from . import __version__
154 from . import __version__
155
155
156 modules.append(__version__)
156 modules.append(__version__)
157 except ImportError:
157 except ImportError:
158 pass
158 pass
159 files = []
159 files = []
160 if pycompat.sysexecutable:
160 if pycompat.sysexecutable:
161 files.append(pycompat.sysexecutable)
161 files.append(pycompat.sysexecutable)
162 for m in modules:
162 for m in modules:
163 try:
163 try:
164 files.append(pycompat.fsencode(inspect.getabsfile(m)))
164 files.append(pycompat.fsencode(inspect.getabsfile(m)))
165 except TypeError:
165 except TypeError:
166 pass
166 pass
167 return sorted(set(files))
167 return sorted(set(files))
168
168
169
169
170 def _mtimehash(paths):
170 def _mtimehash(paths):
171 """return a quick hash for detecting file changes
171 """return a quick hash for detecting file changes
172
172
173 mtimehash calls stat on given paths and calculate a hash based on size and
173 mtimehash calls stat on given paths and calculate a hash based on size and
174 mtime of each file. mtimehash does not read file content because reading is
174 mtime of each file. mtimehash does not read file content because reading is
175 expensive. therefore it's not 100% reliable for detecting content changes.
175 expensive. therefore it's not 100% reliable for detecting content changes.
176 it's possible to return different hashes for same file contents.
176 it's possible to return different hashes for same file contents.
177 it's also possible to return a same hash for different file contents for
177 it's also possible to return a same hash for different file contents for
178 some carefully crafted situation.
178 some carefully crafted situation.
179
179
180 for chgserver, it is designed that once mtimehash changes, the server is
180 for chgserver, it is designed that once mtimehash changes, the server is
181 considered outdated immediately and should no longer provide service.
181 considered outdated immediately and should no longer provide service.
182
182
183 mtimehash is not included in confighash because we only know the paths of
183 mtimehash is not included in confighash because we only know the paths of
184 extensions after importing them (there is imp.find_module but that faces
184 extensions after importing them (there is imp.find_module but that faces
185 race conditions). We need to calculate confighash without importing.
185 race conditions). We need to calculate confighash without importing.
186 """
186 """
187
187
188 def trystat(path):
188 def trystat(path):
189 try:
189 try:
190 st = os.stat(path)
190 st = os.stat(path)
191 return (st[stat.ST_MTIME], st.st_size)
191 return (st[stat.ST_MTIME], st.st_size)
192 except OSError:
192 except OSError:
193 # could be ENOENT, EPERM etc. not fatal in any case
193 # could be ENOENT, EPERM etc. not fatal in any case
194 pass
194 pass
195
195
196 return _hashlist(pycompat.maplist(trystat, paths))[:12]
196 return _hashlist(pycompat.maplist(trystat, paths))[:12]
197
197
198
198
199 class hashstate:
199 class hashstate:
200 """a structure storing confighash, mtimehash, paths used for mtimehash"""
200 """a structure storing confighash, mtimehash, paths used for mtimehash"""
201
201
202 def __init__(self, confighash, mtimehash, mtimepaths):
202 def __init__(self, confighash, mtimehash, mtimepaths):
203 self.confighash = confighash
203 self.confighash = confighash
204 self.mtimehash = mtimehash
204 self.mtimehash = mtimehash
205 self.mtimepaths = mtimepaths
205 self.mtimepaths = mtimepaths
206
206
207 @staticmethod
207 @staticmethod
208 def fromui(ui, mtimepaths=None):
208 def fromui(ui, mtimepaths=None):
209 if mtimepaths is None:
209 if mtimepaths is None:
210 mtimepaths = _getmtimepaths(ui)
210 mtimepaths = _getmtimepaths(ui)
211 confighash = _confighash(ui)
211 confighash = _confighash(ui)
212 mtimehash = _mtimehash(mtimepaths)
212 mtimehash = _mtimehash(mtimepaths)
213 ui.log(
213 ui.log(
214 b'cmdserver',
214 b'cmdserver',
215 b'confighash = %s mtimehash = %s\n',
215 b'confighash = %s mtimehash = %s\n',
216 confighash,
216 confighash,
217 mtimehash,
217 mtimehash,
218 )
218 )
219 return hashstate(confighash, mtimehash, mtimepaths)
219 return hashstate(confighash, mtimehash, mtimepaths)
220
220
221
221
222 def _newchgui(srcui, csystem, attachio):
222 def _newchgui(srcui, csystem, attachio):
223 class chgui(srcui.__class__):
223 class chgui(srcui.__class__):
224 def __init__(self, src=None):
224 def __init__(self, src=None):
225 super(chgui, self).__init__(src)
225 super(chgui, self).__init__(src)
226 if src:
226 if src:
227 self._csystem = getattr(src, '_csystem', csystem)
227 self._csystem = getattr(src, '_csystem', csystem)
228 else:
228 else:
229 self._csystem = csystem
229 self._csystem = csystem
230
230
231 def _runsystem(self, cmd, environ, cwd, out):
231 def _runsystem(self, cmd, environ, cwd, out):
232 # fallback to the original system method if
232 # fallback to the original system method if
233 # a. the output stream is not stdout (e.g. stderr, cStringIO),
233 # a. the output stream is not stdout (e.g. stderr, cStringIO),
234 # b. or stdout is redirected by protectfinout(),
234 # b. or stdout is redirected by protectfinout(),
235 # because the chg client is not aware of these situations and
235 # because the chg client is not aware of these situations and
236 # will behave differently (i.e. write to stdout).
236 # will behave differently (i.e. write to stdout).
237 if (
237 if (
238 out is not self.fout
238 out is not self.fout
239 or not util.safehasattr(self.fout, b'fileno')
239 or not util.safehasattr(self.fout, b'fileno')
240 or self.fout.fileno() != procutil.stdout.fileno()
240 or self.fout.fileno() != procutil.stdout.fileno()
241 or self._finoutredirected
241 or self._finoutredirected
242 ):
242 ):
243 return procutil.system(cmd, environ=environ, cwd=cwd, out=out)
243 return procutil.system(cmd, environ=environ, cwd=cwd, out=out)
244 self.flush()
244 self.flush()
245 return self._csystem(cmd, procutil.shellenviron(environ), cwd)
245 return self._csystem(cmd, procutil.shellenviron(environ), cwd)
246
246
247 def _runpager(self, cmd, env=None):
247 def _runpager(self, cmd, env=None):
248 self._csystem(
248 self._csystem(
249 cmd,
249 cmd,
250 procutil.shellenviron(env),
250 procutil.shellenviron(env),
251 type=b'pager',
251 type=b'pager',
252 cmdtable={b'attachio': attachio},
252 cmdtable={b'attachio': attachio},
253 )
253 )
254 return True
254 return True
255
255
256 return chgui(srcui)
256 return chgui(srcui)
257
257
258
258
259 def _loadnewui(srcui, args, cdebug):
259 def _loadnewui(srcui, args, cdebug):
260 from . import dispatch # avoid cycle
260 from . import dispatch # avoid cycle
261
261
262 newui = srcui.__class__.load()
262 newui = srcui.__class__.load()
263 for a in [b'fin', b'fout', b'ferr', b'environ']:
263 for a in [b'fin', b'fout', b'ferr', b'environ']:
264 setattr(newui, a, getattr(srcui, a))
264 setattr(newui, a, getattr(srcui, a))
265 if util.safehasattr(srcui, b'_csystem'):
265 if util.safehasattr(srcui, b'_csystem'):
266 newui._csystem = srcui._csystem
266 newui._csystem = srcui._csystem
267
267
268 # command line args
268 # command line args
269 options = dispatch._earlyparseopts(newui, args)
269 options = dispatch._earlyparseopts(newui, args)
270 dispatch._parseconfig(newui, options[b'config'])
270 dispatch._parseconfig(newui, options[b'config'])
271
271
272 # stolen from tortoisehg.util.copydynamicconfig()
272 # stolen from tortoisehg.util.copydynamicconfig()
273 for section, name, value in srcui.walkconfig():
273 for section, name, value in srcui.walkconfig():
274 source = srcui.configsource(section, name)
274 source = srcui.configsource(section, name)
275 if b':' in source or source == b'--config' or source.startswith(b'$'):
275 if b':' in source or source == b'--config' or source.startswith(b'$'):
276 # path:line or command line, or environ
276 # path:line or command line, or environ
277 continue
277 continue
278 newui.setconfig(section, name, value, source)
278 newui.setconfig(section, name, value, source)
279
279
280 # load wd and repo config, copied from dispatch.py
280 # load wd and repo config, copied from dispatch.py
281 cwd = options[b'cwd']
281 cwd = options[b'cwd']
282 cwd = cwd and os.path.realpath(cwd) or None
282 cwd = cwd and os.path.realpath(cwd) or None
283 rpath = options[b'repository']
283 rpath = options[b'repository']
284 path, newlui = dispatch._getlocal(newui, rpath, wd=cwd)
284 path, newlui = dispatch._getlocal(newui, rpath, wd=cwd)
285
285
286 extensions.populateui(newui)
286 extensions.populateui(newui)
287 commandserver.setuplogging(newui, fp=cdebug)
287 commandserver.setuplogging(newui, fp=cdebug)
288 if newui is not newlui:
288 if newui is not newlui:
289 extensions.populateui(newlui)
289 extensions.populateui(newlui)
290 commandserver.setuplogging(newlui, fp=cdebug)
290 commandserver.setuplogging(newlui, fp=cdebug)
291
291
292 return (newui, newlui)
292 return (newui, newlui)
293
293
294
294
295 class channeledsystem:
295 class channeledsystem:
296 """Propagate ui.system() request in the following format:
296 """Propagate ui.system() request in the following format:
297
297
298 payload length (unsigned int),
298 payload length (unsigned int),
299 type, '\0',
299 type, '\0',
300 cmd, '\0',
300 cmd, '\0',
301 cwd, '\0',
301 cwd, '\0',
302 envkey, '=', val, '\0',
302 envkey, '=', val, '\0',
303 ...
303 ...
304 envkey, '=', val
304 envkey, '=', val
305
305
306 if type == 'system', waits for:
306 if type == 'system', waits for:
307
307
308 exitcode length (unsigned int),
308 exitcode length (unsigned int),
309 exitcode (int)
309 exitcode (int)
310
310
311 if type == 'pager', repetitively waits for a command name ending with '\n'
311 if type == 'pager', repetitively waits for a command name ending with '\n'
312 and executes it defined by cmdtable, or exits the loop if the command name
312 and executes it defined by cmdtable, or exits the loop if the command name
313 is empty.
313 is empty.
314 """
314 """
315
315
316 def __init__(self, in_, out, channel):
316 def __init__(self, in_, out, channel):
317 self.in_ = in_
317 self.in_ = in_
318 self.out = out
318 self.out = out
319 self.channel = channel
319 self.channel = channel
320
320
321 def __call__(self, cmd, environ, cwd=None, type=b'system', cmdtable=None):
321 def __call__(self, cmd, environ, cwd=None, type=b'system', cmdtable=None):
322 args = [type, cmd, util.abspath(cwd or b'.')]
322 args = [type, cmd, util.abspath(cwd or b'.')]
323 args.extend(b'%s=%s' % (k, v) for k, v in environ.items())
323 args.extend(b'%s=%s' % (k, v) for k, v in environ.items())
324 data = b'\0'.join(args)
324 data = b'\0'.join(args)
325 self.out.write(struct.pack(b'>cI', self.channel, len(data)))
325 self.out.write(struct.pack(b'>cI', self.channel, len(data)))
326 self.out.write(data)
326 self.out.write(data)
327 self.out.flush()
327 self.out.flush()
328
328
329 if type == b'system':
329 if type == b'system':
330 length = self.in_.read(4)
330 length = self.in_.read(4)
331 (length,) = struct.unpack(b'>I', length)
331 (length,) = struct.unpack(b'>I', length)
332 if length != 4:
332 if length != 4:
333 raise error.Abort(_(b'invalid response'))
333 raise error.Abort(_(b'invalid response'))
334 (rc,) = struct.unpack(b'>i', self.in_.read(4))
334 (rc,) = struct.unpack(b'>i', self.in_.read(4))
335 return rc
335 return rc
336 elif type == b'pager':
336 elif type == b'pager':
337 while True:
337 while True:
338 cmd = self.in_.readline()[:-1]
338 cmd = self.in_.readline()[:-1]
339 if not cmd:
339 if not cmd:
340 break
340 break
341 if cmdtable and cmd in cmdtable:
341 if cmdtable and cmd in cmdtable:
342 cmdtable[cmd]()
342 cmdtable[cmd]()
343 else:
343 else:
344 raise error.Abort(_(b'unexpected command: %s') % cmd)
344 raise error.Abort(_(b'unexpected command: %s') % cmd)
345 else:
345 else:
346 raise error.ProgrammingError(b'invalid S channel type: %s' % type)
346 raise error.ProgrammingError(b'invalid S channel type: %s' % type)
347
347
348
348
349 _iochannels = [
349 _iochannels = [
350 # server.ch, ui.fp, mode
350 # server.ch, ui.fp, mode
351 (b'cin', b'fin', 'rb'),
351 (b'cin', b'fin', 'rb'),
352 (b'cout', b'fout', 'wb'),
352 (b'cout', b'fout', 'wb'),
353 (b'cerr', b'ferr', 'wb'),
353 (b'cerr', b'ferr', 'wb'),
354 ]
354 ]
355
355
356
356
357 class chgcmdserver(commandserver.server):
357 class chgcmdserver(commandserver.server):
358 def __init__(
358 def __init__(
359 self, ui, repo, fin, fout, sock, prereposetups, hashstate, baseaddress
359 self, ui, repo, fin, fout, sock, prereposetups, hashstate, baseaddress
360 ):
360 ):
361 super(chgcmdserver, self).__init__(
361 super(chgcmdserver, self).__init__(
362 _newchgui(ui, channeledsystem(fin, fout, b'S'), self.attachio),
362 _newchgui(ui, channeledsystem(fin, fout, b'S'), self.attachio),
363 repo,
363 repo,
364 fin,
364 fin,
365 fout,
365 fout,
366 prereposetups,
366 prereposetups,
367 )
367 )
368 self.clientsock = sock
368 self.clientsock = sock
369 self._ioattached = False
369 self._ioattached = False
370 self._oldios = [] # original (self.ch, ui.fp, fd) before "attachio"
370 self._oldios = [] # original (self.ch, ui.fp, fd) before "attachio"
371 self.hashstate = hashstate
371 self.hashstate = hashstate
372 self.baseaddress = baseaddress
372 self.baseaddress = baseaddress
373 if hashstate is not None:
373 if hashstate is not None:
374 self.capabilities = self.capabilities.copy()
374 self.capabilities = self.capabilities.copy()
375 self.capabilities[b'validate'] = chgcmdserver.validate
375 self.capabilities[b'validate'] = chgcmdserver.validate
376
376
377 def cleanup(self):
377 def cleanup(self):
378 super(chgcmdserver, self).cleanup()
378 super(chgcmdserver, self).cleanup()
379 # dispatch._runcatch() does not flush outputs if exception is not
379 # dispatch._runcatch() does not flush outputs if exception is not
380 # handled by dispatch._dispatch()
380 # handled by dispatch._dispatch()
381 self.ui.flush()
381 self.ui.flush()
382 self._restoreio()
382 self._restoreio()
383 self._ioattached = False
383 self._ioattached = False
384
384
385 def attachio(self):
385 def attachio(self):
386 """Attach to client's stdio passed via unix domain socket; all
386 """Attach to client's stdio passed via unix domain socket; all
387 channels except cresult will no longer be used
387 channels except cresult will no longer be used
388 """
388 """
389 # tell client to sendmsg() with 1-byte payload, which makes it
389 # tell client to sendmsg() with 1-byte payload, which makes it
390 # distinctive from "attachio\n" command consumed by client.read()
390 # distinctive from "attachio\n" command consumed by client.read()
391 self.clientsock.sendall(struct.pack(b'>cI', b'I', 1))
391 self.clientsock.sendall(struct.pack(b'>cI', b'I', 1))
392 clientfds = util.recvfds(self.clientsock.fileno())
392 clientfds = util.recvfds(self.clientsock.fileno())
393 self.ui.log(b'chgserver', b'received fds: %r\n', clientfds)
393 self.ui.log(b'chgserver', b'received fds: %r\n', clientfds)
394
394
395 ui = self.ui
395 ui = self.ui
396 ui.flush()
396 ui.flush()
397 self._saveio()
397 self._saveio()
398 for fd, (cn, fn, mode) in zip(clientfds, _iochannels):
398 for fd, (cn, fn, mode) in zip(clientfds, _iochannels):
399 assert fd > 0
399 assert fd > 0
400 fp = getattr(ui, fn)
400 fp = getattr(ui, fn)
401 os.dup2(fd, fp.fileno())
401 os.dup2(fd, fp.fileno())
402 os.close(fd)
402 os.close(fd)
403 if self._ioattached:
403 if self._ioattached:
404 continue
404 continue
405 # reset buffering mode when client is first attached. as we want
405 # reset buffering mode when client is first attached. as we want
406 # to see output immediately on pager, the mode stays unchanged
406 # to see output immediately on pager, the mode stays unchanged
407 # when client re-attached. ferr is unchanged because it should
407 # when client re-attached. ferr is unchanged because it should
408 # be unbuffered no matter if it is a tty or not.
408 # be unbuffered no matter if it is a tty or not.
409 if fn == b'ferr':
409 if fn == b'ferr':
410 newfp = fp
410 newfp = fp
411 else:
411 else:
412 # On Python 3, the standard library doesn't offer line-buffered
412 # On Python 3, the standard library doesn't offer line-buffered
413 # binary streams, so wrap/unwrap it.
413 # binary streams, so wrap/unwrap it.
414 if fp.isatty():
414 if fp.isatty():
415 newfp = procutil.make_line_buffered(fp)
415 newfp = procutil.make_line_buffered(fp)
416 else:
416 else:
417 newfp = procutil.unwrap_line_buffered(fp)
417 newfp = procutil.unwrap_line_buffered(fp)
418 if newfp is not fp:
418 if newfp is not fp:
419 setattr(ui, fn, newfp)
419 setattr(ui, fn, newfp)
420 setattr(self, cn, newfp)
420 setattr(self, cn, newfp)
421
421
422 self._ioattached = True
422 self._ioattached = True
423 self.cresult.write(struct.pack(b'>i', len(clientfds)))
423 self.cresult.write(struct.pack(b'>i', len(clientfds)))
424
424
425 def _saveio(self):
425 def _saveio(self):
426 if self._oldios:
426 if self._oldios:
427 return
427 return
428 ui = self.ui
428 ui = self.ui
429 for cn, fn, _mode in _iochannels:
429 for cn, fn, _mode in _iochannels:
430 ch = getattr(self, cn)
430 ch = getattr(self, cn)
431 fp = getattr(ui, fn)
431 fp = getattr(ui, fn)
432 fd = os.dup(fp.fileno())
432 fd = os.dup(fp.fileno())
433 self._oldios.append((ch, fp, fd))
433 self._oldios.append((ch, fp, fd))
434
434
435 def _restoreio(self):
435 def _restoreio(self):
436 if not self._oldios:
436 if not self._oldios:
437 return
437 return
438 nullfd = os.open(os.devnull, os.O_WRONLY)
438 nullfd = os.open(os.devnull, os.O_WRONLY)
439 ui = self.ui
439 ui = self.ui
440 for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
440 for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
441 try:
441 try:
442 if 'w' in mode:
442 if 'w' in mode:
443 # Discard buffered data which couldn't be flushed because
443 # Discard buffered data which couldn't be flushed because
444 # of EPIPE. The data should belong to the current session
444 # of EPIPE. The data should belong to the current session
445 # and should never persist.
445 # and should never persist.
446 os.dup2(nullfd, fp.fileno())
446 os.dup2(nullfd, fp.fileno())
447 fp.flush()
447 fp.flush()
448 os.dup2(fd, fp.fileno())
448 os.dup2(fd, fp.fileno())
449 os.close(fd)
449 except OSError as err:
450 except OSError as err:
450 # According to issue6330, running chg on heavy loaded systems
451 # According to issue6330, running chg on heavy loaded systems
451 # can lead to EBUSY. [man dup2] indicates that, on Linux,
452 # can lead to EBUSY. [man dup2] indicates that, on Linux,
452 # EBUSY comes from a race condition between open() and dup2().
453 # EBUSY comes from a race condition between open() and dup2().
453 # However it's not clear why open() race occurred for
454 # However it's not clear why open() race occurred for
454 # newfd=stdin/out/err.
455 # newfd=stdin/out/err.
455 self.ui.log(
456 self.ui.log(
456 b'chgserver',
457 b'chgserver',
457 b'got %s while duplicating %s\n',
458 b'got %s while duplicating %s\n',
458 stringutil.forcebytestr(err),
459 stringutil.forcebytestr(err),
459 fn,
460 fn,
460 )
461 )
461 os.close(fd)
462 setattr(self, cn, ch)
462 setattr(self, cn, ch)
463 setattr(ui, fn, fp)
463 setattr(ui, fn, fp)
464 os.close(nullfd)
464 os.close(nullfd)
465 del self._oldios[:]
465 del self._oldios[:]
466
466
467 def validate(self):
467 def validate(self):
468 """Reload the config and check if the server is up to date
468 """Reload the config and check if the server is up to date
469
469
470 Read a list of '\0' separated arguments.
470 Read a list of '\0' separated arguments.
471 Write a non-empty list of '\0' separated instruction strings or '\0'
471 Write a non-empty list of '\0' separated instruction strings or '\0'
472 if the list is empty.
472 if the list is empty.
473 An instruction string could be either:
473 An instruction string could be either:
474 - "unlink $path", the client should unlink the path to stop the
474 - "unlink $path", the client should unlink the path to stop the
475 outdated server.
475 outdated server.
476 - "redirect $path", the client should attempt to connect to $path
476 - "redirect $path", the client should attempt to connect to $path
477 first. If it does not work, start a new server. It implies
477 first. If it does not work, start a new server. It implies
478 "reconnect".
478 "reconnect".
479 - "exit $n", the client should exit directly with code n.
479 - "exit $n", the client should exit directly with code n.
480 This may happen if we cannot parse the config.
480 This may happen if we cannot parse the config.
481 - "reconnect", the client should close the connection and
481 - "reconnect", the client should close the connection and
482 reconnect.
482 reconnect.
483 If neither "reconnect" nor "redirect" is included in the instruction
483 If neither "reconnect" nor "redirect" is included in the instruction
484 list, the client can continue with this server after completing all
484 list, the client can continue with this server after completing all
485 the instructions.
485 the instructions.
486 """
486 """
487 args = self._readlist()
487 args = self._readlist()
488 errorraised = False
488 errorraised = False
489 detailed_exit_code = 255
489 detailed_exit_code = 255
490 try:
490 try:
491 self.ui, lui = _loadnewui(self.ui, args, self.cdebug)
491 self.ui, lui = _loadnewui(self.ui, args, self.cdebug)
492 except error.RepoError as inst:
492 except error.RepoError as inst:
493 # RepoError can be raised while trying to read shared source
493 # RepoError can be raised while trying to read shared source
494 # configuration
494 # configuration
495 self.ui.error(_(b"abort: %s\n") % stringutil.forcebytestr(inst))
495 self.ui.error(_(b"abort: %s\n") % stringutil.forcebytestr(inst))
496 if inst.hint:
496 if inst.hint:
497 self.ui.error(_(b"(%s)\n") % inst.hint)
497 self.ui.error(_(b"(%s)\n") % inst.hint)
498 errorraised = True
498 errorraised = True
499 except error.Error as inst:
499 except error.Error as inst:
500 if inst.detailed_exit_code is not None:
500 if inst.detailed_exit_code is not None:
501 detailed_exit_code = inst.detailed_exit_code
501 detailed_exit_code = inst.detailed_exit_code
502 self.ui.error(inst.format())
502 self.ui.error(inst.format())
503 errorraised = True
503 errorraised = True
504
504
505 if errorraised:
505 if errorraised:
506 self.ui.flush()
506 self.ui.flush()
507 exit_code = 255
507 exit_code = 255
508 if self.ui.configbool(b'ui', b'detailed-exit-code'):
508 if self.ui.configbool(b'ui', b'detailed-exit-code'):
509 exit_code = detailed_exit_code
509 exit_code = detailed_exit_code
510 self.cresult.write(b'exit %d' % exit_code)
510 self.cresult.write(b'exit %d' % exit_code)
511 return
511 return
512 newhash = hashstate.fromui(lui, self.hashstate.mtimepaths)
512 newhash = hashstate.fromui(lui, self.hashstate.mtimepaths)
513 insts = []
513 insts = []
514 if newhash.mtimehash != self.hashstate.mtimehash:
514 if newhash.mtimehash != self.hashstate.mtimehash:
515 addr = _hashaddress(self.baseaddress, self.hashstate.confighash)
515 addr = _hashaddress(self.baseaddress, self.hashstate.confighash)
516 insts.append(b'unlink %s' % addr)
516 insts.append(b'unlink %s' % addr)
517 # mtimehash is empty if one or more extensions fail to load.
517 # mtimehash is empty if one or more extensions fail to load.
518 # to be compatible with hg, still serve the client this time.
518 # to be compatible with hg, still serve the client this time.
519 if self.hashstate.mtimehash:
519 if self.hashstate.mtimehash:
520 insts.append(b'reconnect')
520 insts.append(b'reconnect')
521 if newhash.confighash != self.hashstate.confighash:
521 if newhash.confighash != self.hashstate.confighash:
522 addr = _hashaddress(self.baseaddress, newhash.confighash)
522 addr = _hashaddress(self.baseaddress, newhash.confighash)
523 insts.append(b'redirect %s' % addr)
523 insts.append(b'redirect %s' % addr)
524 self.ui.log(b'chgserver', b'validate: %s\n', stringutil.pprint(insts))
524 self.ui.log(b'chgserver', b'validate: %s\n', stringutil.pprint(insts))
525 self.cresult.write(b'\0'.join(insts) or b'\0')
525 self.cresult.write(b'\0'.join(insts) or b'\0')
526
526
527 def chdir(self):
527 def chdir(self):
528 """Change current directory
528 """Change current directory
529
529
530 Note that the behavior of --cwd option is bit different from this.
530 Note that the behavior of --cwd option is bit different from this.
531 It does not affect --config parameter.
531 It does not affect --config parameter.
532 """
532 """
533 path = self._readstr()
533 path = self._readstr()
534 if not path:
534 if not path:
535 return
535 return
536 self.ui.log(b'chgserver', b"chdir to '%s'\n", path)
536 self.ui.log(b'chgserver', b"chdir to '%s'\n", path)
537 os.chdir(path)
537 os.chdir(path)
538
538
539 def setumask(self):
539 def setumask(self):
540 """Change umask (DEPRECATED)"""
540 """Change umask (DEPRECATED)"""
541 # BUG: this does not follow the message frame structure, but kept for
541 # BUG: this does not follow the message frame structure, but kept for
542 # backward compatibility with old chg clients for some time
542 # backward compatibility with old chg clients for some time
543 self._setumask(self._read(4))
543 self._setumask(self._read(4))
544
544
545 def setumask2(self):
545 def setumask2(self):
546 """Change umask"""
546 """Change umask"""
547 data = self._readstr()
547 data = self._readstr()
548 if len(data) != 4:
548 if len(data) != 4:
549 raise ValueError(b'invalid mask length in setumask2 request')
549 raise ValueError(b'invalid mask length in setumask2 request')
550 self._setumask(data)
550 self._setumask(data)
551
551
552 def _setumask(self, data):
552 def _setumask(self, data):
553 mask = struct.unpack(b'>I', data)[0]
553 mask = struct.unpack(b'>I', data)[0]
554 self.ui.log(b'chgserver', b'setumask %r\n', mask)
554 self.ui.log(b'chgserver', b'setumask %r\n', mask)
555 util.setumask(mask)
555 util.setumask(mask)
556
556
557 def runcommand(self):
557 def runcommand(self):
558 # pager may be attached within the runcommand session, which should
558 # pager may be attached within the runcommand session, which should
559 # be detached at the end of the session. otherwise the pager wouldn't
559 # be detached at the end of the session. otherwise the pager wouldn't
560 # receive EOF.
560 # receive EOF.
561 globaloldios = self._oldios
561 globaloldios = self._oldios
562 self._oldios = []
562 self._oldios = []
563 try:
563 try:
564 return super(chgcmdserver, self).runcommand()
564 return super(chgcmdserver, self).runcommand()
565 finally:
565 finally:
566 self._restoreio()
566 self._restoreio()
567 self._oldios = globaloldios
567 self._oldios = globaloldios
568
568
569 def setenv(self):
569 def setenv(self):
570 """Clear and update os.environ
570 """Clear and update os.environ
571
571
572 Note that not all variables can make an effect on the running process.
572 Note that not all variables can make an effect on the running process.
573 """
573 """
574 l = self._readlist()
574 l = self._readlist()
575 try:
575 try:
576 newenv = dict(s.split(b'=', 1) for s in l)
576 newenv = dict(s.split(b'=', 1) for s in l)
577 except ValueError:
577 except ValueError:
578 raise ValueError(b'unexpected value in setenv request')
578 raise ValueError(b'unexpected value in setenv request')
579 self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys()))
579 self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys()))
580
580
581 encoding.environ.clear()
581 encoding.environ.clear()
582 encoding.environ.update(newenv)
582 encoding.environ.update(newenv)
583
583
584 capabilities = commandserver.server.capabilities.copy()
584 capabilities = commandserver.server.capabilities.copy()
585 capabilities.update(
585 capabilities.update(
586 {
586 {
587 b'attachio': attachio,
587 b'attachio': attachio,
588 b'chdir': chdir,
588 b'chdir': chdir,
589 b'runcommand': runcommand,
589 b'runcommand': runcommand,
590 b'setenv': setenv,
590 b'setenv': setenv,
591 b'setumask': setumask,
591 b'setumask': setumask,
592 b'setumask2': setumask2,
592 b'setumask2': setumask2,
593 }
593 }
594 )
594 )
595
595
596 if util.safehasattr(procutil, b'setprocname'):
596 if util.safehasattr(procutil, b'setprocname'):
597
597
598 def setprocname(self):
598 def setprocname(self):
599 """Change process title"""
599 """Change process title"""
600 name = self._readstr()
600 name = self._readstr()
601 self.ui.log(b'chgserver', b'setprocname: %r\n', name)
601 self.ui.log(b'chgserver', b'setprocname: %r\n', name)
602 procutil.setprocname(name)
602 procutil.setprocname(name)
603
603
604 capabilities[b'setprocname'] = setprocname
604 capabilities[b'setprocname'] = setprocname
605
605
606
606
607 def _tempaddress(address):
607 def _tempaddress(address):
608 return b'%s.%d.tmp' % (address, os.getpid())
608 return b'%s.%d.tmp' % (address, os.getpid())
609
609
610
610
611 def _hashaddress(address, hashstr):
611 def _hashaddress(address, hashstr):
612 # if the basename of address contains '.', use only the left part. this
612 # if the basename of address contains '.', use only the left part. this
613 # makes it possible for the client to pass 'server.tmp$PID' and follow by
613 # makes it possible for the client to pass 'server.tmp$PID' and follow by
614 # an atomic rename to avoid locking when spawning new servers.
614 # an atomic rename to avoid locking when spawning new servers.
615 dirname, basename = os.path.split(address)
615 dirname, basename = os.path.split(address)
616 basename = basename.split(b'.', 1)[0]
616 basename = basename.split(b'.', 1)[0]
617 return b'%s-%s' % (os.path.join(dirname, basename), hashstr)
617 return b'%s-%s' % (os.path.join(dirname, basename), hashstr)
618
618
619
619
620 class chgunixservicehandler:
620 class chgunixservicehandler:
621 """Set of operations for chg services"""
621 """Set of operations for chg services"""
622
622
623 pollinterval = 1 # [sec]
623 pollinterval = 1 # [sec]
624
624
625 def __init__(self, ui):
625 def __init__(self, ui):
626 self.ui = ui
626 self.ui = ui
627
627
628 # TODO: use PEP 526 syntax (`_hashstate: hashstate` at the class level)
628 # TODO: use PEP 526 syntax (`_hashstate: hashstate` at the class level)
629 # when 3.5 support is dropped.
629 # when 3.5 support is dropped.
630 self._hashstate = None # type: hashstate
630 self._hashstate = None # type: hashstate
631 self._baseaddress = None # type: bytes
631 self._baseaddress = None # type: bytes
632 self._realaddress = None # type: bytes
632 self._realaddress = None # type: bytes
633
633
634 self._idletimeout = ui.configint(b'chgserver', b'idletimeout')
634 self._idletimeout = ui.configint(b'chgserver', b'idletimeout')
635 self._lastactive = time.time()
635 self._lastactive = time.time()
636
636
637 def bindsocket(self, sock, address):
637 def bindsocket(self, sock, address):
638 self._inithashstate(address)
638 self._inithashstate(address)
639 self._checkextensions()
639 self._checkextensions()
640 self._bind(sock)
640 self._bind(sock)
641 self._createsymlink()
641 self._createsymlink()
642 # no "listening at" message should be printed to simulate hg behavior
642 # no "listening at" message should be printed to simulate hg behavior
643
643
644 def _inithashstate(self, address):
644 def _inithashstate(self, address):
645 self._baseaddress = address
645 self._baseaddress = address
646 if self.ui.configbool(b'chgserver', b'skiphash'):
646 if self.ui.configbool(b'chgserver', b'skiphash'):
647 self._hashstate = None
647 self._hashstate = None
648 self._realaddress = address
648 self._realaddress = address
649 return
649 return
650 self._hashstate = hashstate.fromui(self.ui)
650 self._hashstate = hashstate.fromui(self.ui)
651 self._realaddress = _hashaddress(address, self._hashstate.confighash)
651 self._realaddress = _hashaddress(address, self._hashstate.confighash)
652
652
653 def _checkextensions(self):
653 def _checkextensions(self):
654 if not self._hashstate:
654 if not self._hashstate:
655 return
655 return
656 if extensions.notloaded():
656 if extensions.notloaded():
657 # one or more extensions failed to load. mtimehash becomes
657 # one or more extensions failed to load. mtimehash becomes
658 # meaningless because we do not know the paths of those extensions.
658 # meaningless because we do not know the paths of those extensions.
659 # set mtimehash to an illegal hash value to invalidate the server.
659 # set mtimehash to an illegal hash value to invalidate the server.
660 self._hashstate.mtimehash = b''
660 self._hashstate.mtimehash = b''
661
661
662 def _bind(self, sock):
662 def _bind(self, sock):
663 # use a unique temp address so we can stat the file and do ownership
663 # use a unique temp address so we can stat the file and do ownership
664 # check later
664 # check later
665 tempaddress = _tempaddress(self._realaddress)
665 tempaddress = _tempaddress(self._realaddress)
666 util.bindunixsocket(sock, tempaddress)
666 util.bindunixsocket(sock, tempaddress)
667 self._socketstat = os.stat(tempaddress)
667 self._socketstat = os.stat(tempaddress)
668 sock.listen(socket.SOMAXCONN)
668 sock.listen(socket.SOMAXCONN)
669 # rename will replace the old socket file if exists atomically. the
669 # rename will replace the old socket file if exists atomically. the
670 # old server will detect ownership change and exit.
670 # old server will detect ownership change and exit.
671 util.rename(tempaddress, self._realaddress)
671 util.rename(tempaddress, self._realaddress)
672
672
673 def _createsymlink(self):
673 def _createsymlink(self):
674 if self._baseaddress == self._realaddress:
674 if self._baseaddress == self._realaddress:
675 return
675 return
676 tempaddress = _tempaddress(self._baseaddress)
676 tempaddress = _tempaddress(self._baseaddress)
677 os.symlink(os.path.basename(self._realaddress), tempaddress)
677 os.symlink(os.path.basename(self._realaddress), tempaddress)
678 util.rename(tempaddress, self._baseaddress)
678 util.rename(tempaddress, self._baseaddress)
679
679
680 def _issocketowner(self):
680 def _issocketowner(self):
681 try:
681 try:
682 st = os.stat(self._realaddress)
682 st = os.stat(self._realaddress)
683 return (
683 return (
684 st.st_ino == self._socketstat.st_ino
684 st.st_ino == self._socketstat.st_ino
685 and st[stat.ST_MTIME] == self._socketstat[stat.ST_MTIME]
685 and st[stat.ST_MTIME] == self._socketstat[stat.ST_MTIME]
686 )
686 )
687 except OSError:
687 except OSError:
688 return False
688 return False
689
689
690 def unlinksocket(self, address):
690 def unlinksocket(self, address):
691 if not self._issocketowner():
691 if not self._issocketowner():
692 return
692 return
693 # it is possible to have a race condition here that we may
693 # it is possible to have a race condition here that we may
694 # remove another server's socket file. but that's okay
694 # remove another server's socket file. but that's okay
695 # since that server will detect and exit automatically and
695 # since that server will detect and exit automatically and
696 # the client will start a new server on demand.
696 # the client will start a new server on demand.
697 util.tryunlink(self._realaddress)
697 util.tryunlink(self._realaddress)
698
698
699 def shouldexit(self):
699 def shouldexit(self):
700 if not self._issocketowner():
700 if not self._issocketowner():
701 self.ui.log(
701 self.ui.log(
702 b'chgserver', b'%s is not owned, exiting.\n', self._realaddress
702 b'chgserver', b'%s is not owned, exiting.\n', self._realaddress
703 )
703 )
704 return True
704 return True
705 if time.time() - self._lastactive > self._idletimeout:
705 if time.time() - self._lastactive > self._idletimeout:
706 self.ui.log(b'chgserver', b'being idle too long. exiting.\n')
706 self.ui.log(b'chgserver', b'being idle too long. exiting.\n')
707 return True
707 return True
708 return False
708 return False
709
709
710 def newconnection(self):
710 def newconnection(self):
711 self._lastactive = time.time()
711 self._lastactive = time.time()
712
712
713 def createcmdserver(self, repo, conn, fin, fout, prereposetups):
713 def createcmdserver(self, repo, conn, fin, fout, prereposetups):
714 return chgcmdserver(
714 return chgcmdserver(
715 self.ui,
715 self.ui,
716 repo,
716 repo,
717 fin,
717 fin,
718 fout,
718 fout,
719 conn,
719 conn,
720 prereposetups,
720 prereposetups,
721 self._hashstate,
721 self._hashstate,
722 self._baseaddress,
722 self._baseaddress,
723 )
723 )
724
724
725
725
726 def chgunixservice(ui, repo, opts):
726 def chgunixservice(ui, repo, opts):
727 # CHGINTERNALMARK is set by chg client. It is an indication of things are
727 # CHGINTERNALMARK is set by chg client. It is an indication of things are
728 # started by chg so other code can do things accordingly, like disabling
728 # started by chg so other code can do things accordingly, like disabling
729 # demandimport or detecting chg client started by chg client. When executed
729 # demandimport or detecting chg client started by chg client. When executed
730 # here, CHGINTERNALMARK is no longer useful and hence dropped to make
730 # here, CHGINTERNALMARK is no longer useful and hence dropped to make
731 # environ cleaner.
731 # environ cleaner.
732 if b'CHGINTERNALMARK' in encoding.environ:
732 if b'CHGINTERNALMARK' in encoding.environ:
733 del encoding.environ[b'CHGINTERNALMARK']
733 del encoding.environ[b'CHGINTERNALMARK']
734 # Python3.7+ "coerces" the LC_CTYPE environment variable to a UTF-8 one if
734 # Python3.7+ "coerces" the LC_CTYPE environment variable to a UTF-8 one if
735 # it thinks the current value is "C". This breaks the hash computation and
735 # it thinks the current value is "C". This breaks the hash computation and
736 # causes chg to restart loop.
736 # causes chg to restart loop.
737 if b'CHGORIG_LC_CTYPE' in encoding.environ:
737 if b'CHGORIG_LC_CTYPE' in encoding.environ:
738 encoding.environ[b'LC_CTYPE'] = encoding.environ[b'CHGORIG_LC_CTYPE']
738 encoding.environ[b'LC_CTYPE'] = encoding.environ[b'CHGORIG_LC_CTYPE']
739 del encoding.environ[b'CHGORIG_LC_CTYPE']
739 del encoding.environ[b'CHGORIG_LC_CTYPE']
740 elif b'CHG_CLEAR_LC_CTYPE' in encoding.environ:
740 elif b'CHG_CLEAR_LC_CTYPE' in encoding.environ:
741 if b'LC_CTYPE' in encoding.environ:
741 if b'LC_CTYPE' in encoding.environ:
742 del encoding.environ[b'LC_CTYPE']
742 del encoding.environ[b'LC_CTYPE']
743 del encoding.environ[b'CHG_CLEAR_LC_CTYPE']
743 del encoding.environ[b'CHG_CLEAR_LC_CTYPE']
744
744
745 if repo:
745 if repo:
746 # one chgserver can serve multiple repos. drop repo information
746 # one chgserver can serve multiple repos. drop repo information
747 ui.setconfig(b'bundle', b'mainreporoot', b'', b'repo')
747 ui.setconfig(b'bundle', b'mainreporoot', b'', b'repo')
748 h = chgunixservicehandler(ui)
748 h = chgunixservicehandler(ui)
749 return commandserver.unixforkingservice(ui, repo=None, opts=opts, handler=h)
749 return commandserver.unixforkingservice(ui, repo=None, opts=opts, handler=h)
@@ -1,4004 +1,4009 b''
1 #!/usr/bin/env python3
1 #!/usr/bin/env python3
2 #
2 #
3 # run-tests.py - Run a set of tests on Mercurial
3 # run-tests.py - Run a set of tests on Mercurial
4 #
4 #
5 # Copyright 2006 Olivia Mackall <olivia@selenic.com>
5 # Copyright 2006 Olivia Mackall <olivia@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 # Modifying this script is tricky because it has many modes:
10 # Modifying this script is tricky because it has many modes:
11 # - serial (default) vs parallel (-jN, N > 1)
11 # - serial (default) vs parallel (-jN, N > 1)
12 # - no coverage (default) vs coverage (-c, -C, -s)
12 # - no coverage (default) vs coverage (-c, -C, -s)
13 # - temp install (default) vs specific hg script (--with-hg, --local)
13 # - temp install (default) vs specific hg script (--with-hg, --local)
14 # - tests are a mix of shell scripts and Python scripts
14 # - tests are a mix of shell scripts and Python scripts
15 #
15 #
16 # If you change this script, it is recommended that you ensure you
16 # If you change this script, it is recommended that you ensure you
17 # haven't broken it by running it in various modes with a representative
17 # haven't broken it by running it in various modes with a representative
18 # sample of test scripts. For example:
18 # sample of test scripts. For example:
19 #
19 #
20 # 1) serial, no coverage, temp install:
20 # 1) serial, no coverage, temp install:
21 # ./run-tests.py test-s*
21 # ./run-tests.py test-s*
22 # 2) serial, no coverage, local hg:
22 # 2) serial, no coverage, local hg:
23 # ./run-tests.py --local test-s*
23 # ./run-tests.py --local test-s*
24 # 3) serial, coverage, temp install:
24 # 3) serial, coverage, temp install:
25 # ./run-tests.py -c test-s*
25 # ./run-tests.py -c test-s*
26 # 4) serial, coverage, local hg:
26 # 4) serial, coverage, local hg:
27 # ./run-tests.py -c --local test-s* # unsupported
27 # ./run-tests.py -c --local test-s* # unsupported
28 # 5) parallel, no coverage, temp install:
28 # 5) parallel, no coverage, temp install:
29 # ./run-tests.py -j2 test-s*
29 # ./run-tests.py -j2 test-s*
30 # 6) parallel, no coverage, local hg:
30 # 6) parallel, no coverage, local hg:
31 # ./run-tests.py -j2 --local test-s*
31 # ./run-tests.py -j2 --local test-s*
32 # 7) parallel, coverage, temp install:
32 # 7) parallel, coverage, temp install:
33 # ./run-tests.py -j2 -c test-s* # currently broken
33 # ./run-tests.py -j2 -c test-s* # currently broken
34 # 8) parallel, coverage, local install:
34 # 8) parallel, coverage, local install:
35 # ./run-tests.py -j2 -c --local test-s* # unsupported (and broken)
35 # ./run-tests.py -j2 -c --local test-s* # unsupported (and broken)
36 # 9) parallel, custom tmp dir:
36 # 9) parallel, custom tmp dir:
37 # ./run-tests.py -j2 --tmpdir /tmp/myhgtests
37 # ./run-tests.py -j2 --tmpdir /tmp/myhgtests
38 # 10) parallel, pure, tests that call run-tests:
38 # 10) parallel, pure, tests that call run-tests:
39 # ./run-tests.py --pure `grep -l run-tests.py *.t`
39 # ./run-tests.py --pure `grep -l run-tests.py *.t`
40 #
40 #
41 # (You could use any subset of the tests: test-s* happens to match
41 # (You could use any subset of the tests: test-s* happens to match
42 # enough that it's worth doing parallel runs, few enough that it
42 # enough that it's worth doing parallel runs, few enough that it
43 # completes fairly quickly, includes both shell and Python scripts, and
43 # completes fairly quickly, includes both shell and Python scripts, and
44 # includes some scripts that run daemon processes.)
44 # includes some scripts that run daemon processes.)
45
45
46
46
47 import argparse
47 import argparse
48 import collections
48 import collections
49 import contextlib
49 import contextlib
50 import difflib
50 import difflib
51 import distutils.version as version
51 import distutils.version as version
52 import errno
52 import errno
53 import functools
53 import functools
54 import json
54 import json
55 import multiprocessing
55 import multiprocessing
56 import os
56 import os
57 import platform
57 import platform
58 import queue
58 import queue
59 import random
59 import random
60 import re
60 import re
61 import shlex
61 import shlex
62 import shutil
62 import shutil
63 import signal
63 import signal
64 import socket
64 import socket
65 import subprocess
65 import subprocess
66 import sys
66 import sys
67 import sysconfig
67 import sysconfig
68 import tempfile
68 import tempfile
69 import threading
69 import threading
70 import time
70 import time
71 import unittest
71 import unittest
72 import uuid
72 import uuid
73 import xml.dom.minidom as minidom
73 import xml.dom.minidom as minidom
74
74
75 if sys.version_info < (3, 5, 0):
75 if sys.version_info < (3, 5, 0):
76 print(
76 print(
77 '%s is only supported on Python 3.5+, not %s'
77 '%s is only supported on Python 3.5+, not %s'
78 % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3]))
78 % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3]))
79 )
79 )
80 sys.exit(70) # EX_SOFTWARE from `man 3 sysexit`
80 sys.exit(70) # EX_SOFTWARE from `man 3 sysexit`
81
81
82 WINDOWS = os.name == r'nt'
82 WINDOWS = os.name == r'nt'
83 shellquote = shlex.quote
83 shellquote = shlex.quote
84
84
85
85
86 processlock = threading.Lock()
86 processlock = threading.Lock()
87
87
88 pygmentspresent = False
88 pygmentspresent = False
89 try: # is pygments installed
89 try: # is pygments installed
90 import pygments
90 import pygments
91 import pygments.lexers as lexers
91 import pygments.lexers as lexers
92 import pygments.lexer as lexer
92 import pygments.lexer as lexer
93 import pygments.formatters as formatters
93 import pygments.formatters as formatters
94 import pygments.token as token
94 import pygments.token as token
95 import pygments.style as style
95 import pygments.style as style
96
96
97 if WINDOWS:
97 if WINDOWS:
98 hgpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
98 hgpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
99 sys.path.append(hgpath)
99 sys.path.append(hgpath)
100 try:
100 try:
101 from mercurial import win32 # pytype: disable=import-error
101 from mercurial import win32 # pytype: disable=import-error
102
102
103 # Don't check the result code because it fails on heptapod, but
103 # Don't check the result code because it fails on heptapod, but
104 # something is able to convert to color anyway.
104 # something is able to convert to color anyway.
105 win32.enablevtmode()
105 win32.enablevtmode()
106 finally:
106 finally:
107 sys.path = sys.path[:-1]
107 sys.path = sys.path[:-1]
108
108
109 pygmentspresent = True
109 pygmentspresent = True
110 difflexer = lexers.DiffLexer()
110 difflexer = lexers.DiffLexer()
111 terminal256formatter = formatters.Terminal256Formatter()
111 terminal256formatter = formatters.Terminal256Formatter()
112 except ImportError:
112 except ImportError:
113 pass
113 pass
114
114
115 if pygmentspresent:
115 if pygmentspresent:
116
116
117 class TestRunnerStyle(style.Style):
117 class TestRunnerStyle(style.Style):
118 default_style = ""
118 default_style = ""
119 skipped = token.string_to_tokentype("Token.Generic.Skipped")
119 skipped = token.string_to_tokentype("Token.Generic.Skipped")
120 failed = token.string_to_tokentype("Token.Generic.Failed")
120 failed = token.string_to_tokentype("Token.Generic.Failed")
121 skippedname = token.string_to_tokentype("Token.Generic.SName")
121 skippedname = token.string_to_tokentype("Token.Generic.SName")
122 failedname = token.string_to_tokentype("Token.Generic.FName")
122 failedname = token.string_to_tokentype("Token.Generic.FName")
123 styles = {
123 styles = {
124 skipped: '#e5e5e5',
124 skipped: '#e5e5e5',
125 skippedname: '#00ffff',
125 skippedname: '#00ffff',
126 failed: '#7f0000',
126 failed: '#7f0000',
127 failedname: '#ff0000',
127 failedname: '#ff0000',
128 }
128 }
129
129
130 class TestRunnerLexer(lexer.RegexLexer):
130 class TestRunnerLexer(lexer.RegexLexer):
131 testpattern = r'[\w-]+\.(t|py)(#[a-zA-Z0-9_\-\.]+)?'
131 testpattern = r'[\w-]+\.(t|py)(#[a-zA-Z0-9_\-\.]+)?'
132 tokens = {
132 tokens = {
133 'root': [
133 'root': [
134 (r'^Skipped', token.Generic.Skipped, 'skipped'),
134 (r'^Skipped', token.Generic.Skipped, 'skipped'),
135 (r'^Failed ', token.Generic.Failed, 'failed'),
135 (r'^Failed ', token.Generic.Failed, 'failed'),
136 (r'^ERROR: ', token.Generic.Failed, 'failed'),
136 (r'^ERROR: ', token.Generic.Failed, 'failed'),
137 ],
137 ],
138 'skipped': [
138 'skipped': [
139 (testpattern, token.Generic.SName),
139 (testpattern, token.Generic.SName),
140 (r':.*', token.Generic.Skipped),
140 (r':.*', token.Generic.Skipped),
141 ],
141 ],
142 'failed': [
142 'failed': [
143 (testpattern, token.Generic.FName),
143 (testpattern, token.Generic.FName),
144 (r'(:| ).*', token.Generic.Failed),
144 (r'(:| ).*', token.Generic.Failed),
145 ],
145 ],
146 }
146 }
147
147
148 runnerformatter = formatters.Terminal256Formatter(style=TestRunnerStyle)
148 runnerformatter = formatters.Terminal256Formatter(style=TestRunnerStyle)
149 runnerlexer = TestRunnerLexer()
149 runnerlexer = TestRunnerLexer()
150
150
151 origenviron = os.environ.copy()
151 origenviron = os.environ.copy()
152
152
153
153
154 xrange = range # we use xrange in one place, and we'd rather not use range
154 xrange = range # we use xrange in one place, and we'd rather not use range
155
155
156
156
157 def _sys2bytes(p):
157 def _sys2bytes(p):
158 if p is None:
158 if p is None:
159 return p
159 return p
160 return p.encode('utf-8')
160 return p.encode('utf-8')
161
161
162
162
163 def _bytes2sys(p):
163 def _bytes2sys(p):
164 if p is None:
164 if p is None:
165 return p
165 return p
166 return p.decode('utf-8')
166 return p.decode('utf-8')
167
167
168
168
169 osenvironb = getattr(os, 'environb', None)
169 osenvironb = getattr(os, 'environb', None)
170 if osenvironb is None:
170 if osenvironb is None:
171 # Windows lacks os.environb, for instance. A proxy over the real thing
171 # Windows lacks os.environb, for instance. A proxy over the real thing
172 # instead of a copy allows the environment to be updated via bytes on
172 # instead of a copy allows the environment to be updated via bytes on
173 # all platforms.
173 # all platforms.
174 class environbytes:
174 class environbytes:
175 def __init__(self, strenv):
175 def __init__(self, strenv):
176 self.__len__ = strenv.__len__
176 self.__len__ = strenv.__len__
177 self.clear = strenv.clear
177 self.clear = strenv.clear
178 self._strenv = strenv
178 self._strenv = strenv
179
179
180 def __getitem__(self, k):
180 def __getitem__(self, k):
181 v = self._strenv.__getitem__(_bytes2sys(k))
181 v = self._strenv.__getitem__(_bytes2sys(k))
182 return _sys2bytes(v)
182 return _sys2bytes(v)
183
183
184 def __setitem__(self, k, v):
184 def __setitem__(self, k, v):
185 self._strenv.__setitem__(_bytes2sys(k), _bytes2sys(v))
185 self._strenv.__setitem__(_bytes2sys(k), _bytes2sys(v))
186
186
187 def __delitem__(self, k):
187 def __delitem__(self, k):
188 self._strenv.__delitem__(_bytes2sys(k))
188 self._strenv.__delitem__(_bytes2sys(k))
189
189
190 def __contains__(self, k):
190 def __contains__(self, k):
191 return self._strenv.__contains__(_bytes2sys(k))
191 return self._strenv.__contains__(_bytes2sys(k))
192
192
193 def __iter__(self):
193 def __iter__(self):
194 return iter([_sys2bytes(k) for k in iter(self._strenv)])
194 return iter([_sys2bytes(k) for k in iter(self._strenv)])
195
195
196 def get(self, k, default=None):
196 def get(self, k, default=None):
197 v = self._strenv.get(_bytes2sys(k), _bytes2sys(default))
197 v = self._strenv.get(_bytes2sys(k), _bytes2sys(default))
198 return _sys2bytes(v)
198 return _sys2bytes(v)
199
199
200 def pop(self, k, default=None):
200 def pop(self, k, default=None):
201 v = self._strenv.pop(_bytes2sys(k), _bytes2sys(default))
201 v = self._strenv.pop(_bytes2sys(k), _bytes2sys(default))
202 return _sys2bytes(v)
202 return _sys2bytes(v)
203
203
204 osenvironb = environbytes(os.environ)
204 osenvironb = environbytes(os.environ)
205
205
206 getcwdb = getattr(os, 'getcwdb')
206 getcwdb = getattr(os, 'getcwdb')
207 if not getcwdb or WINDOWS:
207 if not getcwdb or WINDOWS:
208 getcwdb = lambda: _sys2bytes(os.getcwd())
208 getcwdb = lambda: _sys2bytes(os.getcwd())
209
209
210
210
211 if WINDOWS:
211 if WINDOWS:
212 _getcwdb = getcwdb
212 _getcwdb = getcwdb
213
213
214 def getcwdb():
214 def getcwdb():
215 cwd = _getcwdb()
215 cwd = _getcwdb()
216 if re.match(b'^[a-z]:', cwd):
216 if re.match(b'^[a-z]:', cwd):
217 # os.getcwd() is inconsistent on the capitalization of the drive
217 # os.getcwd() is inconsistent on the capitalization of the drive
218 # letter, so adjust it. see https://bugs.python.org/issue40368
218 # letter, so adjust it. see https://bugs.python.org/issue40368
219 cwd = cwd[0:1].upper() + cwd[1:]
219 cwd = cwd[0:1].upper() + cwd[1:]
220 return cwd
220 return cwd
221
221
222
222
223 # For Windows support
223 # For Windows support
224 wifexited = getattr(os, "WIFEXITED", lambda x: False)
224 wifexited = getattr(os, "WIFEXITED", lambda x: False)
225
225
226 # Whether to use IPv6
226 # Whether to use IPv6
227 def checksocketfamily(name, port=20058):
227 def checksocketfamily(name, port=20058):
228 """return true if we can listen on localhost using family=name
228 """return true if we can listen on localhost using family=name
229
229
230 name should be either 'AF_INET', or 'AF_INET6'.
230 name should be either 'AF_INET', or 'AF_INET6'.
231 port being used is okay - EADDRINUSE is considered as successful.
231 port being used is okay - EADDRINUSE is considered as successful.
232 """
232 """
233 family = getattr(socket, name, None)
233 family = getattr(socket, name, None)
234 if family is None:
234 if family is None:
235 return False
235 return False
236 try:
236 try:
237 s = socket.socket(family, socket.SOCK_STREAM)
237 s = socket.socket(family, socket.SOCK_STREAM)
238 s.bind(('localhost', port))
238 s.bind(('localhost', port))
239 s.close()
239 s.close()
240 return True
240 return True
241 except (socket.error, OSError) as exc:
241 except (socket.error, OSError) as exc:
242 if exc.errno == errno.EADDRINUSE:
242 if exc.errno == errno.EADDRINUSE:
243 return True
243 return True
244 elif exc.errno in (
244 elif exc.errno in (
245 errno.EADDRNOTAVAIL,
245 errno.EADDRNOTAVAIL,
246 errno.EPROTONOSUPPORT,
246 errno.EPROTONOSUPPORT,
247 errno.EAFNOSUPPORT,
247 errno.EAFNOSUPPORT,
248 ):
248 ):
249 return False
249 return False
250 else:
250 else:
251 raise
251 raise
252 else:
252 else:
253 return False
253 return False
254
254
255
255
256 # useipv6 will be set by parseargs
256 # useipv6 will be set by parseargs
257 useipv6 = None
257 useipv6 = None
258
258
259
259
260 def checkportisavailable(port):
260 def checkportisavailable(port):
261 """return true if a port seems free to bind on localhost"""
261 """return true if a port seems free to bind on localhost"""
262 if useipv6:
262 if useipv6:
263 family = socket.AF_INET6
263 family = socket.AF_INET6
264 else:
264 else:
265 family = socket.AF_INET
265 family = socket.AF_INET
266 try:
266 try:
267 with contextlib.closing(socket.socket(family, socket.SOCK_STREAM)) as s:
267 with contextlib.closing(socket.socket(family, socket.SOCK_STREAM)) as s:
268 s.bind(('localhost', port))
268 s.bind(('localhost', port))
269 return True
269 return True
270 except socket.error as exc:
270 except socket.error as exc:
271 if WINDOWS and exc.errno == errno.WSAEACCES:
271 if WINDOWS and exc.errno == errno.WSAEACCES:
272 return False
272 return False
273 # TODO: make a proper exception handler after dropping py2. This
273 # TODO: make a proper exception handler after dropping py2. This
274 # works because socket.error is an alias for OSError on py3,
274 # works because socket.error is an alias for OSError on py3,
275 # which is also the baseclass of PermissionError.
275 # which is also the baseclass of PermissionError.
276 elif isinstance(exc, PermissionError):
276 elif isinstance(exc, PermissionError):
277 return False
277 return False
278 if exc.errno not in (
278 if exc.errno not in (
279 errno.EADDRINUSE,
279 errno.EADDRINUSE,
280 errno.EADDRNOTAVAIL,
280 errno.EADDRNOTAVAIL,
281 errno.EPROTONOSUPPORT,
281 errno.EPROTONOSUPPORT,
282 ):
282 ):
283 raise
283 raise
284 return False
284 return False
285
285
286
286
287 closefds = os.name == 'posix'
287 closefds = os.name == 'posix'
288
288
289
289
290 def Popen4(cmd, wd, timeout, env=None):
290 def Popen4(cmd, wd, timeout, env=None):
291 processlock.acquire()
291 processlock.acquire()
292 p = subprocess.Popen(
292 p = subprocess.Popen(
293 _bytes2sys(cmd),
293 _bytes2sys(cmd),
294 shell=True,
294 shell=True,
295 bufsize=-1,
295 bufsize=-1,
296 cwd=_bytes2sys(wd),
296 cwd=_bytes2sys(wd),
297 env=env,
297 env=env,
298 close_fds=closefds,
298 close_fds=closefds,
299 stdin=subprocess.PIPE,
299 stdin=subprocess.PIPE,
300 stdout=subprocess.PIPE,
300 stdout=subprocess.PIPE,
301 stderr=subprocess.STDOUT,
301 stderr=subprocess.STDOUT,
302 )
302 )
303 processlock.release()
303 processlock.release()
304
304
305 p.fromchild = p.stdout
305 p.fromchild = p.stdout
306 p.tochild = p.stdin
306 p.tochild = p.stdin
307 p.childerr = p.stderr
307 p.childerr = p.stderr
308
308
309 p.timeout = False
309 p.timeout = False
310 if timeout:
310 if timeout:
311
311
312 def t():
312 def t():
313 start = time.time()
313 start = time.time()
314 while time.time() - start < timeout and p.returncode is None:
314 while time.time() - start < timeout and p.returncode is None:
315 time.sleep(0.1)
315 time.sleep(0.1)
316 p.timeout = True
316 p.timeout = True
317 vlog('# Timout reached for process %d' % p.pid)
317 vlog('# Timout reached for process %d' % p.pid)
318 if p.returncode is None:
318 if p.returncode is None:
319 terminate(p)
319 terminate(p)
320
320
321 threading.Thread(target=t).start()
321 threading.Thread(target=t).start()
322
322
323 return p
323 return p
324
324
325
325
326 if sys.executable:
326 if sys.executable:
327 sysexecutable = sys.executable
327 sysexecutable = sys.executable
328 elif os.environ.get('PYTHONEXECUTABLE'):
328 elif os.environ.get('PYTHONEXECUTABLE'):
329 sysexecutable = os.environ['PYTHONEXECUTABLE']
329 sysexecutable = os.environ['PYTHONEXECUTABLE']
330 elif os.environ.get('PYTHON'):
330 elif os.environ.get('PYTHON'):
331 sysexecutable = os.environ['PYTHON']
331 sysexecutable = os.environ['PYTHON']
332 else:
332 else:
333 raise AssertionError('Could not find Python interpreter')
333 raise AssertionError('Could not find Python interpreter')
334
334
335 PYTHON = _sys2bytes(sysexecutable.replace('\\', '/'))
335 PYTHON = _sys2bytes(sysexecutable.replace('\\', '/'))
336 IMPL_PATH = b'PYTHONPATH'
336 IMPL_PATH = b'PYTHONPATH'
337 if 'java' in sys.platform:
337 if 'java' in sys.platform:
338 IMPL_PATH = b'JYTHONPATH'
338 IMPL_PATH = b'JYTHONPATH'
339
339
340 default_defaults = {
340 default_defaults = {
341 'jobs': ('HGTEST_JOBS', multiprocessing.cpu_count()),
341 'jobs': ('HGTEST_JOBS', multiprocessing.cpu_count()),
342 'timeout': ('HGTEST_TIMEOUT', 360),
342 'timeout': ('HGTEST_TIMEOUT', 360),
343 'slowtimeout': ('HGTEST_SLOWTIMEOUT', 1500),
343 'slowtimeout': ('HGTEST_SLOWTIMEOUT', 1500),
344 'port': ('HGTEST_PORT', 20059),
344 'port': ('HGTEST_PORT', 20059),
345 'shell': ('HGTEST_SHELL', 'sh'),
345 'shell': ('HGTEST_SHELL', 'sh'),
346 }
346 }
347
347
348 defaults = default_defaults.copy()
348 defaults = default_defaults.copy()
349
349
350
350
351 def canonpath(path):
351 def canonpath(path):
352 return os.path.realpath(os.path.expanduser(path))
352 return os.path.realpath(os.path.expanduser(path))
353
353
354
354
355 def which(exe):
355 def which(exe):
356 # shutil.which only accept bytes from 3.8
356 # shutil.which only accept bytes from 3.8
357 cmd = _bytes2sys(exe)
357 cmd = _bytes2sys(exe)
358 real_exec = shutil.which(cmd)
358 real_exec = shutil.which(cmd)
359 return _sys2bytes(real_exec)
359 return _sys2bytes(real_exec)
360
360
361
361
362 def parselistfiles(files, listtype, warn=True):
362 def parselistfiles(files, listtype, warn=True):
363 entries = dict()
363 entries = dict()
364 for filename in files:
364 for filename in files:
365 try:
365 try:
366 path = os.path.expanduser(os.path.expandvars(filename))
366 path = os.path.expanduser(os.path.expandvars(filename))
367 f = open(path, "rb")
367 f = open(path, "rb")
368 except IOError as err:
368 except IOError as err:
369 if err.errno != errno.ENOENT:
369 if err.errno != errno.ENOENT:
370 raise
370 raise
371 if warn:
371 if warn:
372 print("warning: no such %s file: %s" % (listtype, filename))
372 print("warning: no such %s file: %s" % (listtype, filename))
373 continue
373 continue
374
374
375 for line in f.readlines():
375 for line in f.readlines():
376 line = line.split(b'#', 1)[0].strip()
376 line = line.split(b'#', 1)[0].strip()
377 if line:
377 if line:
378 # Ensure path entries are compatible with os.path.relpath()
378 # Ensure path entries are compatible with os.path.relpath()
379 entries[os.path.normpath(line)] = filename
379 entries[os.path.normpath(line)] = filename
380
380
381 f.close()
381 f.close()
382 return entries
382 return entries
383
383
384
384
385 def parsettestcases(path):
385 def parsettestcases(path):
386 """read a .t test file, return a set of test case names
386 """read a .t test file, return a set of test case names
387
387
388 If path does not exist, return an empty set.
388 If path does not exist, return an empty set.
389 """
389 """
390 cases = []
390 cases = []
391 try:
391 try:
392 with open(path, 'rb') as f:
392 with open(path, 'rb') as f:
393 for l in f:
393 for l in f:
394 if l.startswith(b'#testcases '):
394 if l.startswith(b'#testcases '):
395 cases.append(sorted(l[11:].split()))
395 cases.append(sorted(l[11:].split()))
396 except IOError as ex:
396 except IOError as ex:
397 if ex.errno != errno.ENOENT:
397 if ex.errno != errno.ENOENT:
398 raise
398 raise
399 return cases
399 return cases
400
400
401
401
402 def getparser():
402 def getparser():
403 """Obtain the OptionParser used by the CLI."""
403 """Obtain the OptionParser used by the CLI."""
404 parser = argparse.ArgumentParser(usage='%(prog)s [options] [tests]')
404 parser = argparse.ArgumentParser(usage='%(prog)s [options] [tests]')
405
405
406 selection = parser.add_argument_group('Test Selection')
406 selection = parser.add_argument_group('Test Selection')
407 selection.add_argument(
407 selection.add_argument(
408 '--allow-slow-tests',
408 '--allow-slow-tests',
409 action='store_true',
409 action='store_true',
410 help='allow extremely slow tests',
410 help='allow extremely slow tests',
411 )
411 )
412 selection.add_argument(
412 selection.add_argument(
413 "--blacklist",
413 "--blacklist",
414 action="append",
414 action="append",
415 help="skip tests listed in the specified blacklist file",
415 help="skip tests listed in the specified blacklist file",
416 )
416 )
417 selection.add_argument(
417 selection.add_argument(
418 "--changed",
418 "--changed",
419 help="run tests that are changed in parent rev or working directory",
419 help="run tests that are changed in parent rev or working directory",
420 )
420 )
421 selection.add_argument(
421 selection.add_argument(
422 "-k", "--keywords", help="run tests matching keywords"
422 "-k", "--keywords", help="run tests matching keywords"
423 )
423 )
424 selection.add_argument(
424 selection.add_argument(
425 "-r", "--retest", action="store_true", help="retest failed tests"
425 "-r", "--retest", action="store_true", help="retest failed tests"
426 )
426 )
427 selection.add_argument(
427 selection.add_argument(
428 "--test-list",
428 "--test-list",
429 action="append",
429 action="append",
430 help="read tests to run from the specified file",
430 help="read tests to run from the specified file",
431 )
431 )
432 selection.add_argument(
432 selection.add_argument(
433 "--whitelist",
433 "--whitelist",
434 action="append",
434 action="append",
435 help="always run tests listed in the specified whitelist file",
435 help="always run tests listed in the specified whitelist file",
436 )
436 )
437 selection.add_argument(
437 selection.add_argument(
438 'tests', metavar='TESTS', nargs='*', help='Tests to run'
438 'tests', metavar='TESTS', nargs='*', help='Tests to run'
439 )
439 )
440
440
441 harness = parser.add_argument_group('Test Harness Behavior')
441 harness = parser.add_argument_group('Test Harness Behavior')
442 harness.add_argument(
442 harness.add_argument(
443 '--bisect-repo',
443 '--bisect-repo',
444 metavar='bisect_repo',
444 metavar='bisect_repo',
445 help=(
445 help=(
446 "Path of a repo to bisect. Use together with " "--known-good-rev"
446 "Path of a repo to bisect. Use together with " "--known-good-rev"
447 ),
447 ),
448 )
448 )
449 harness.add_argument(
449 harness.add_argument(
450 "-d",
450 "-d",
451 "--debug",
451 "--debug",
452 action="store_true",
452 action="store_true",
453 help="debug mode: write output of test scripts to console"
453 help="debug mode: write output of test scripts to console"
454 " rather than capturing and diffing it (disables timeout)",
454 " rather than capturing and diffing it (disables timeout)",
455 )
455 )
456 harness.add_argument(
456 harness.add_argument(
457 "-f",
457 "-f",
458 "--first",
458 "--first",
459 action="store_true",
459 action="store_true",
460 help="exit on the first test failure",
460 help="exit on the first test failure",
461 )
461 )
462 harness.add_argument(
462 harness.add_argument(
463 "-i",
463 "-i",
464 "--interactive",
464 "--interactive",
465 action="store_true",
465 action="store_true",
466 help="prompt to accept changed output",
466 help="prompt to accept changed output",
467 )
467 )
468 harness.add_argument(
468 harness.add_argument(
469 "-j",
469 "-j",
470 "--jobs",
470 "--jobs",
471 type=int,
471 type=int,
472 help="number of jobs to run in parallel"
472 help="number of jobs to run in parallel"
473 " (default: $%s or %d)" % defaults['jobs'],
473 " (default: $%s or %d)" % defaults['jobs'],
474 )
474 )
475 harness.add_argument(
475 harness.add_argument(
476 "--keep-tmpdir",
476 "--keep-tmpdir",
477 action="store_true",
477 action="store_true",
478 help="keep temporary directory after running tests",
478 help="keep temporary directory after running tests",
479 )
479 )
480 harness.add_argument(
480 harness.add_argument(
481 '--known-good-rev',
481 '--known-good-rev',
482 metavar="known_good_rev",
482 metavar="known_good_rev",
483 help=(
483 help=(
484 "Automatically bisect any failures using this "
484 "Automatically bisect any failures using this "
485 "revision as a known-good revision."
485 "revision as a known-good revision."
486 ),
486 ),
487 )
487 )
488 harness.add_argument(
488 harness.add_argument(
489 "--list-tests",
489 "--list-tests",
490 action="store_true",
490 action="store_true",
491 help="list tests instead of running them",
491 help="list tests instead of running them",
492 )
492 )
493 harness.add_argument(
493 harness.add_argument(
494 "--loop", action="store_true", help="loop tests repeatedly"
494 "--loop", action="store_true", help="loop tests repeatedly"
495 )
495 )
496 harness.add_argument(
496 harness.add_argument(
497 '--random', action="store_true", help='run tests in random order'
497 '--random', action="store_true", help='run tests in random order'
498 )
498 )
499 harness.add_argument(
499 harness.add_argument(
500 '--order-by-runtime',
500 '--order-by-runtime',
501 action="store_true",
501 action="store_true",
502 help='run slowest tests first, according to .testtimes',
502 help='run slowest tests first, according to .testtimes',
503 )
503 )
504 harness.add_argument(
504 harness.add_argument(
505 "-p",
505 "-p",
506 "--port",
506 "--port",
507 type=int,
507 type=int,
508 help="port on which servers should listen"
508 help="port on which servers should listen"
509 " (default: $%s or %d)" % defaults['port'],
509 " (default: $%s or %d)" % defaults['port'],
510 )
510 )
511 harness.add_argument(
511 harness.add_argument(
512 '--profile-runner',
512 '--profile-runner',
513 action='store_true',
513 action='store_true',
514 help='run statprof on run-tests',
514 help='run statprof on run-tests',
515 )
515 )
516 harness.add_argument(
516 harness.add_argument(
517 "-R", "--restart", action="store_true", help="restart at last error"
517 "-R", "--restart", action="store_true", help="restart at last error"
518 )
518 )
519 harness.add_argument(
519 harness.add_argument(
520 "--runs-per-test",
520 "--runs-per-test",
521 type=int,
521 type=int,
522 dest="runs_per_test",
522 dest="runs_per_test",
523 help="run each test N times (default=1)",
523 help="run each test N times (default=1)",
524 default=1,
524 default=1,
525 )
525 )
526 harness.add_argument(
526 harness.add_argument(
527 "--shell", help="shell to use (default: $%s or %s)" % defaults['shell']
527 "--shell", help="shell to use (default: $%s or %s)" % defaults['shell']
528 )
528 )
529 harness.add_argument(
529 harness.add_argument(
530 '--showchannels', action='store_true', help='show scheduling channels'
530 '--showchannels', action='store_true', help='show scheduling channels'
531 )
531 )
532 harness.add_argument(
532 harness.add_argument(
533 "--slowtimeout",
533 "--slowtimeout",
534 type=int,
534 type=int,
535 help="kill errant slow tests after SLOWTIMEOUT seconds"
535 help="kill errant slow tests after SLOWTIMEOUT seconds"
536 " (default: $%s or %d)" % defaults['slowtimeout'],
536 " (default: $%s or %d)" % defaults['slowtimeout'],
537 )
537 )
538 harness.add_argument(
538 harness.add_argument(
539 "-t",
539 "-t",
540 "--timeout",
540 "--timeout",
541 type=int,
541 type=int,
542 help="kill errant tests after TIMEOUT seconds"
542 help="kill errant tests after TIMEOUT seconds"
543 " (default: $%s or %d)" % defaults['timeout'],
543 " (default: $%s or %d)" % defaults['timeout'],
544 )
544 )
545 harness.add_argument(
545 harness.add_argument(
546 "--tmpdir",
546 "--tmpdir",
547 help="run tests in the given temporary directory"
547 help="run tests in the given temporary directory"
548 " (implies --keep-tmpdir)",
548 " (implies --keep-tmpdir)",
549 )
549 )
550 harness.add_argument(
550 harness.add_argument(
551 "-v", "--verbose", action="store_true", help="output verbose messages"
551 "-v", "--verbose", action="store_true", help="output verbose messages"
552 )
552 )
553
553
554 hgconf = parser.add_argument_group('Mercurial Configuration')
554 hgconf = parser.add_argument_group('Mercurial Configuration')
555 hgconf.add_argument(
555 hgconf.add_argument(
556 "--chg",
556 "--chg",
557 action="store_true",
557 action="store_true",
558 help="install and use chg wrapper in place of hg",
558 help="install and use chg wrapper in place of hg",
559 )
559 )
560 hgconf.add_argument(
560 hgconf.add_argument(
561 "--chg-debug",
561 "--chg-debug",
562 action="store_true",
562 action="store_true",
563 help="show chg debug logs",
563 help="show chg debug logs",
564 )
564 )
565 hgconf.add_argument(
565 hgconf.add_argument(
566 "--rhg",
566 "--rhg",
567 action="store_true",
567 action="store_true",
568 help="install and use rhg Rust implementation in place of hg",
568 help="install and use rhg Rust implementation in place of hg",
569 )
569 )
570 hgconf.add_argument(
570 hgconf.add_argument(
571 "--pyoxidized",
571 "--pyoxidized",
572 action="store_true",
572 action="store_true",
573 help="build the hg binary using pyoxidizer",
573 help="build the hg binary using pyoxidizer",
574 )
574 )
575 hgconf.add_argument("--compiler", help="compiler to build with")
575 hgconf.add_argument("--compiler", help="compiler to build with")
576 hgconf.add_argument(
576 hgconf.add_argument(
577 '--extra-config-opt',
577 '--extra-config-opt',
578 action="append",
578 action="append",
579 default=[],
579 default=[],
580 help='set the given config opt in the test hgrc',
580 help='set the given config opt in the test hgrc',
581 )
581 )
582 hgconf.add_argument(
582 hgconf.add_argument(
583 "-l",
583 "-l",
584 "--local",
584 "--local",
585 action="store_true",
585 action="store_true",
586 help="shortcut for --with-hg=<testdir>/../hg, "
586 help="shortcut for --with-hg=<testdir>/../hg, "
587 "--with-rhg=<testdir>/../rust/target/release/rhg if --rhg is set, "
587 "--with-rhg=<testdir>/../rust/target/release/rhg if --rhg is set, "
588 "and --with-chg=<testdir>/../contrib/chg/chg if --chg is set",
588 "and --with-chg=<testdir>/../contrib/chg/chg if --chg is set",
589 )
589 )
590 hgconf.add_argument(
590 hgconf.add_argument(
591 "--ipv6",
591 "--ipv6",
592 action="store_true",
592 action="store_true",
593 help="prefer IPv6 to IPv4 for network related tests",
593 help="prefer IPv6 to IPv4 for network related tests",
594 )
594 )
595 hgconf.add_argument(
595 hgconf.add_argument(
596 "--pure",
596 "--pure",
597 action="store_true",
597 action="store_true",
598 help="use pure Python code instead of C extensions",
598 help="use pure Python code instead of C extensions",
599 )
599 )
600 hgconf.add_argument(
600 hgconf.add_argument(
601 "--rust",
601 "--rust",
602 action="store_true",
602 action="store_true",
603 help="use Rust code alongside C extensions",
603 help="use Rust code alongside C extensions",
604 )
604 )
605 hgconf.add_argument(
605 hgconf.add_argument(
606 "--no-rust",
606 "--no-rust",
607 action="store_true",
607 action="store_true",
608 help="do not use Rust code even if compiled",
608 help="do not use Rust code even if compiled",
609 )
609 )
610 hgconf.add_argument(
610 hgconf.add_argument(
611 "--with-chg",
611 "--with-chg",
612 metavar="CHG",
612 metavar="CHG",
613 help="use specified chg wrapper in place of hg",
613 help="use specified chg wrapper in place of hg",
614 )
614 )
615 hgconf.add_argument(
615 hgconf.add_argument(
616 "--with-rhg",
616 "--with-rhg",
617 metavar="RHG",
617 metavar="RHG",
618 help="use specified rhg Rust implementation in place of hg",
618 help="use specified rhg Rust implementation in place of hg",
619 )
619 )
620 hgconf.add_argument(
620 hgconf.add_argument(
621 "--with-hg",
621 "--with-hg",
622 metavar="HG",
622 metavar="HG",
623 help="test using specified hg script rather than a "
623 help="test using specified hg script rather than a "
624 "temporary installation",
624 "temporary installation",
625 )
625 )
626
626
627 reporting = parser.add_argument_group('Results Reporting')
627 reporting = parser.add_argument_group('Results Reporting')
628 reporting.add_argument(
628 reporting.add_argument(
629 "-C",
629 "-C",
630 "--annotate",
630 "--annotate",
631 action="store_true",
631 action="store_true",
632 help="output files annotated with coverage",
632 help="output files annotated with coverage",
633 )
633 )
634 reporting.add_argument(
634 reporting.add_argument(
635 "--color",
635 "--color",
636 choices=["always", "auto", "never"],
636 choices=["always", "auto", "never"],
637 default=os.environ.get('HGRUNTESTSCOLOR', 'auto'),
637 default=os.environ.get('HGRUNTESTSCOLOR', 'auto'),
638 help="colorisation: always|auto|never (default: auto)",
638 help="colorisation: always|auto|never (default: auto)",
639 )
639 )
640 reporting.add_argument(
640 reporting.add_argument(
641 "-c",
641 "-c",
642 "--cover",
642 "--cover",
643 action="store_true",
643 action="store_true",
644 help="print a test coverage report",
644 help="print a test coverage report",
645 )
645 )
646 reporting.add_argument(
646 reporting.add_argument(
647 '--exceptions',
647 '--exceptions',
648 action='store_true',
648 action='store_true',
649 help='log all exceptions and generate an exception report',
649 help='log all exceptions and generate an exception report',
650 )
650 )
651 reporting.add_argument(
651 reporting.add_argument(
652 "-H",
652 "-H",
653 "--htmlcov",
653 "--htmlcov",
654 action="store_true",
654 action="store_true",
655 help="create an HTML report of the coverage of the files",
655 help="create an HTML report of the coverage of the files",
656 )
656 )
657 reporting.add_argument(
657 reporting.add_argument(
658 "--json",
658 "--json",
659 action="store_true",
659 action="store_true",
660 help="store test result data in 'report.json' file",
660 help="store test result data in 'report.json' file",
661 )
661 )
662 reporting.add_argument(
662 reporting.add_argument(
663 "--outputdir",
663 "--outputdir",
664 help="directory to write error logs to (default=test directory)",
664 help="directory to write error logs to (default=test directory)",
665 )
665 )
666 reporting.add_argument(
666 reporting.add_argument(
667 "-n", "--nodiff", action="store_true", help="skip showing test changes"
667 "-n", "--nodiff", action="store_true", help="skip showing test changes"
668 )
668 )
669 reporting.add_argument(
669 reporting.add_argument(
670 "-S",
670 "-S",
671 "--noskips",
671 "--noskips",
672 action="store_true",
672 action="store_true",
673 help="don't report skip tests verbosely",
673 help="don't report skip tests verbosely",
674 )
674 )
675 reporting.add_argument(
675 reporting.add_argument(
676 "--time", action="store_true", help="time how long each test takes"
676 "--time", action="store_true", help="time how long each test takes"
677 )
677 )
678 reporting.add_argument("--view", help="external diff viewer")
678 reporting.add_argument("--view", help="external diff viewer")
679 reporting.add_argument(
679 reporting.add_argument(
680 "--xunit", help="record xunit results at specified path"
680 "--xunit", help="record xunit results at specified path"
681 )
681 )
682
682
683 for option, (envvar, default) in defaults.items():
683 for option, (envvar, default) in defaults.items():
684 defaults[option] = type(default)(os.environ.get(envvar, default))
684 defaults[option] = type(default)(os.environ.get(envvar, default))
685 parser.set_defaults(**defaults)
685 parser.set_defaults(**defaults)
686
686
687 return parser
687 return parser
688
688
689
689
690 def parseargs(args, parser):
690 def parseargs(args, parser):
691 """Parse arguments with our OptionParser and validate results."""
691 """Parse arguments with our OptionParser and validate results."""
692 options = parser.parse_args(args)
692 options = parser.parse_args(args)
693
693
694 # jython is always pure
694 # jython is always pure
695 if 'java' in sys.platform or '__pypy__' in sys.modules:
695 if 'java' in sys.platform or '__pypy__' in sys.modules:
696 options.pure = True
696 options.pure = True
697
697
698 if platform.python_implementation() != 'CPython' and options.rust:
698 if platform.python_implementation() != 'CPython' and options.rust:
699 parser.error('Rust extensions are only available with CPython')
699 parser.error('Rust extensions are only available with CPython')
700
700
701 if options.pure and options.rust:
701 if options.pure and options.rust:
702 parser.error('--rust cannot be used with --pure')
702 parser.error('--rust cannot be used with --pure')
703
703
704 if options.rust and options.no_rust:
704 if options.rust and options.no_rust:
705 parser.error('--rust cannot be used with --no-rust')
705 parser.error('--rust cannot be used with --no-rust')
706
706
707 if options.local:
707 if options.local:
708 if options.with_hg or options.with_rhg or options.with_chg:
708 if options.with_hg or options.with_rhg or options.with_chg:
709 parser.error(
709 parser.error(
710 '--local cannot be used with --with-hg or --with-rhg or --with-chg'
710 '--local cannot be used with --with-hg or --with-rhg or --with-chg'
711 )
711 )
712 if options.pyoxidized:
712 if options.pyoxidized:
713 parser.error('--pyoxidized does not work with --local (yet)')
713 parser.error('--pyoxidized does not work with --local (yet)')
714 testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0])))
714 testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0])))
715 reporootdir = os.path.dirname(testdir)
715 reporootdir = os.path.dirname(testdir)
716 pathandattrs = [(b'hg', 'with_hg')]
716 pathandattrs = [(b'hg', 'with_hg')]
717 if options.chg:
717 if options.chg:
718 pathandattrs.append((b'contrib/chg/chg', 'with_chg'))
718 pathandattrs.append((b'contrib/chg/chg', 'with_chg'))
719 if options.rhg:
719 if options.rhg:
720 pathandattrs.append((b'rust/target/release/rhg', 'with_rhg'))
720 pathandattrs.append((b'rust/target/release/rhg', 'with_rhg'))
721 for relpath, attr in pathandattrs:
721 for relpath, attr in pathandattrs:
722 binpath = os.path.join(reporootdir, relpath)
722 binpath = os.path.join(reporootdir, relpath)
723 if not (WINDOWS or os.access(binpath, os.X_OK)):
723 if not (WINDOWS or os.access(binpath, os.X_OK)):
724 parser.error(
724 parser.error(
725 '--local specified, but %r not found or '
725 '--local specified, but %r not found or '
726 'not executable' % binpath
726 'not executable' % binpath
727 )
727 )
728 setattr(options, attr, _bytes2sys(binpath))
728 setattr(options, attr, _bytes2sys(binpath))
729
729
730 if options.with_hg:
730 if options.with_hg:
731 options.with_hg = canonpath(_sys2bytes(options.with_hg))
731 options.with_hg = canonpath(_sys2bytes(options.with_hg))
732 if not (
732 if not (
733 os.path.isfile(options.with_hg)
733 os.path.isfile(options.with_hg)
734 and os.access(options.with_hg, os.X_OK)
734 and os.access(options.with_hg, os.X_OK)
735 ):
735 ):
736 parser.error('--with-hg must specify an executable hg script')
736 parser.error('--with-hg must specify an executable hg script')
737 if os.path.basename(options.with_hg) not in [b'hg', b'hg.exe']:
737 if os.path.basename(options.with_hg) not in [b'hg', b'hg.exe']:
738 msg = 'warning: --with-hg should specify an hg script, not: %s\n'
738 msg = 'warning: --with-hg should specify an hg script, not: %s\n'
739 msg %= _bytes2sys(os.path.basename(options.with_hg))
739 msg %= _bytes2sys(os.path.basename(options.with_hg))
740 sys.stderr.write(msg)
740 sys.stderr.write(msg)
741 sys.stderr.flush()
741 sys.stderr.flush()
742
742
743 if (options.chg or options.with_chg) and WINDOWS:
743 if (options.chg or options.with_chg) and WINDOWS:
744 parser.error('chg does not work on %s' % os.name)
744 parser.error('chg does not work on %s' % os.name)
745 if (options.rhg or options.with_rhg) and WINDOWS:
745 if (options.rhg or options.with_rhg) and WINDOWS:
746 parser.error('rhg does not work on %s' % os.name)
746 parser.error('rhg does not work on %s' % os.name)
747 if options.pyoxidized and not WINDOWS:
747 if options.pyoxidized and not WINDOWS:
748 parser.error('--pyoxidized is currently Windows only')
748 parser.error('--pyoxidized is currently Windows only')
749 if options.with_chg:
749 if options.with_chg:
750 options.chg = False # no installation to temporary location
750 options.chg = False # no installation to temporary location
751 options.with_chg = canonpath(_sys2bytes(options.with_chg))
751 options.with_chg = canonpath(_sys2bytes(options.with_chg))
752 if not (
752 if not (
753 os.path.isfile(options.with_chg)
753 os.path.isfile(options.with_chg)
754 and os.access(options.with_chg, os.X_OK)
754 and os.access(options.with_chg, os.X_OK)
755 ):
755 ):
756 parser.error('--with-chg must specify a chg executable')
756 parser.error('--with-chg must specify a chg executable')
757 if options.with_rhg:
757 if options.with_rhg:
758 options.rhg = False # no installation to temporary location
758 options.rhg = False # no installation to temporary location
759 options.with_rhg = canonpath(_sys2bytes(options.with_rhg))
759 options.with_rhg = canonpath(_sys2bytes(options.with_rhg))
760 if not (
760 if not (
761 os.path.isfile(options.with_rhg)
761 os.path.isfile(options.with_rhg)
762 and os.access(options.with_rhg, os.X_OK)
762 and os.access(options.with_rhg, os.X_OK)
763 ):
763 ):
764 parser.error('--with-rhg must specify a rhg executable')
764 parser.error('--with-rhg must specify a rhg executable')
765 if options.chg and options.with_hg:
765 if options.chg and options.with_hg:
766 # chg shares installation location with hg
766 # chg shares installation location with hg
767 parser.error(
767 parser.error(
768 '--chg does not work when --with-hg is specified '
768 '--chg does not work when --with-hg is specified '
769 '(use --with-chg instead)'
769 '(use --with-chg instead)'
770 )
770 )
771 if options.rhg and options.with_hg:
771 if options.rhg and options.with_hg:
772 # rhg shares installation location with hg
772 # rhg shares installation location with hg
773 parser.error(
773 parser.error(
774 '--rhg does not work when --with-hg is specified '
774 '--rhg does not work when --with-hg is specified '
775 '(use --with-rhg instead)'
775 '(use --with-rhg instead)'
776 )
776 )
777 if options.rhg and options.chg:
777 if options.rhg and options.chg:
778 parser.error('--rhg and --chg do not work together')
778 parser.error('--rhg and --chg do not work together')
779
779
780 if options.color == 'always' and not pygmentspresent:
780 if options.color == 'always' and not pygmentspresent:
781 sys.stderr.write(
781 sys.stderr.write(
782 'warning: --color=always ignored because '
782 'warning: --color=always ignored because '
783 'pygments is not installed\n'
783 'pygments is not installed\n'
784 )
784 )
785
785
786 if options.bisect_repo and not options.known_good_rev:
786 if options.bisect_repo and not options.known_good_rev:
787 parser.error("--bisect-repo cannot be used without --known-good-rev")
787 parser.error("--bisect-repo cannot be used without --known-good-rev")
788
788
789 global useipv6
789 global useipv6
790 if options.ipv6:
790 if options.ipv6:
791 useipv6 = checksocketfamily('AF_INET6')
791 useipv6 = checksocketfamily('AF_INET6')
792 else:
792 else:
793 # only use IPv6 if IPv4 is unavailable and IPv6 is available
793 # only use IPv6 if IPv4 is unavailable and IPv6 is available
794 useipv6 = (not checksocketfamily('AF_INET')) and checksocketfamily(
794 useipv6 = (not checksocketfamily('AF_INET')) and checksocketfamily(
795 'AF_INET6'
795 'AF_INET6'
796 )
796 )
797
797
798 options.anycoverage = options.cover or options.annotate or options.htmlcov
798 options.anycoverage = options.cover or options.annotate or options.htmlcov
799 if options.anycoverage:
799 if options.anycoverage:
800 try:
800 try:
801 import coverage
801 import coverage
802
802
803 covver = version.StrictVersion(coverage.__version__).version
803 covver = version.StrictVersion(coverage.__version__).version
804 if covver < (3, 3):
804 if covver < (3, 3):
805 parser.error('coverage options require coverage 3.3 or later')
805 parser.error('coverage options require coverage 3.3 or later')
806 except ImportError:
806 except ImportError:
807 parser.error('coverage options now require the coverage package')
807 parser.error('coverage options now require the coverage package')
808
808
809 if options.anycoverage and options.local:
809 if options.anycoverage and options.local:
810 # this needs some path mangling somewhere, I guess
810 # this needs some path mangling somewhere, I guess
811 parser.error(
811 parser.error(
812 "sorry, coverage options do not work when --local " "is specified"
812 "sorry, coverage options do not work when --local " "is specified"
813 )
813 )
814
814
815 if options.anycoverage and options.with_hg:
815 if options.anycoverage and options.with_hg:
816 parser.error(
816 parser.error(
817 "sorry, coverage options do not work when --with-hg " "is specified"
817 "sorry, coverage options do not work when --with-hg " "is specified"
818 )
818 )
819
819
820 global verbose
820 global verbose
821 if options.verbose:
821 if options.verbose:
822 verbose = ''
822 verbose = ''
823
823
824 if options.tmpdir:
824 if options.tmpdir:
825 options.tmpdir = canonpath(options.tmpdir)
825 options.tmpdir = canonpath(options.tmpdir)
826
826
827 if options.jobs < 1:
827 if options.jobs < 1:
828 parser.error('--jobs must be positive')
828 parser.error('--jobs must be positive')
829 if options.interactive and options.debug:
829 if options.interactive and options.debug:
830 parser.error("-i/--interactive and -d/--debug are incompatible")
830 parser.error("-i/--interactive and -d/--debug are incompatible")
831 if options.debug:
831 if options.debug:
832 if options.timeout != defaults['timeout']:
832 if options.timeout != defaults['timeout']:
833 sys.stderr.write('warning: --timeout option ignored with --debug\n')
833 sys.stderr.write('warning: --timeout option ignored with --debug\n')
834 if options.slowtimeout != defaults['slowtimeout']:
834 if options.slowtimeout != defaults['slowtimeout']:
835 sys.stderr.write(
835 sys.stderr.write(
836 'warning: --slowtimeout option ignored with --debug\n'
836 'warning: --slowtimeout option ignored with --debug\n'
837 )
837 )
838 options.timeout = 0
838 options.timeout = 0
839 options.slowtimeout = 0
839 options.slowtimeout = 0
840
840
841 if options.blacklist:
841 if options.blacklist:
842 options.blacklist = parselistfiles(options.blacklist, 'blacklist')
842 options.blacklist = parselistfiles(options.blacklist, 'blacklist')
843 if options.whitelist:
843 if options.whitelist:
844 options.whitelisted = parselistfiles(options.whitelist, 'whitelist')
844 options.whitelisted = parselistfiles(options.whitelist, 'whitelist')
845 else:
845 else:
846 options.whitelisted = {}
846 options.whitelisted = {}
847
847
848 if options.showchannels:
848 if options.showchannels:
849 options.nodiff = True
849 options.nodiff = True
850
850
851 return options
851 return options
852
852
853
853
854 def rename(src, dst):
854 def rename(src, dst):
855 """Like os.rename(), trade atomicity and opened files friendliness
855 """Like os.rename(), trade atomicity and opened files friendliness
856 for existing destination support.
856 for existing destination support.
857 """
857 """
858 shutil.copy(src, dst)
858 shutil.copy(src, dst)
859 os.remove(src)
859 os.remove(src)
860
860
861
861
862 def makecleanable(path):
862 def makecleanable(path):
863 """Try to fix directory permission recursively so that the entire tree
863 """Try to fix directory permission recursively so that the entire tree
864 can be deleted"""
864 can be deleted"""
865 for dirpath, dirnames, _filenames in os.walk(path, topdown=True):
865 for dirpath, dirnames, _filenames in os.walk(path, topdown=True):
866 for d in dirnames:
866 for d in dirnames:
867 p = os.path.join(dirpath, d)
867 p = os.path.join(dirpath, d)
868 try:
868 try:
869 os.chmod(p, os.stat(p).st_mode & 0o777 | 0o700) # chmod u+rwx
869 os.chmod(p, os.stat(p).st_mode & 0o777 | 0o700) # chmod u+rwx
870 except OSError:
870 except OSError:
871 pass
871 pass
872
872
873
873
874 _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
874 _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
875
875
876
876
877 def getdiff(expected, output, ref, err):
877 def getdiff(expected, output, ref, err):
878 servefail = False
878 servefail = False
879 lines = []
879 lines = []
880 for line in _unified_diff(expected, output, ref, err):
880 for line in _unified_diff(expected, output, ref, err):
881 if line.startswith(b'+++') or line.startswith(b'---'):
881 if line.startswith(b'+++') or line.startswith(b'---'):
882 line = line.replace(b'\\', b'/')
882 line = line.replace(b'\\', b'/')
883 if line.endswith(b' \n'):
883 if line.endswith(b' \n'):
884 line = line[:-2] + b'\n'
884 line = line[:-2] + b'\n'
885 lines.append(line)
885 lines.append(line)
886 if not servefail and line.startswith(
886 if not servefail and line.startswith(
887 b'+ abort: child process failed to start'
887 b'+ abort: child process failed to start'
888 ):
888 ):
889 servefail = True
889 servefail = True
890
890
891 return servefail, lines
891 return servefail, lines
892
892
893
893
894 verbose = False
894 verbose = False
895
895
896
896
897 def vlog(*msg):
897 def vlog(*msg):
898 """Log only when in verbose mode."""
898 """Log only when in verbose mode."""
899 if verbose is False:
899 if verbose is False:
900 return
900 return
901
901
902 return log(*msg)
902 return log(*msg)
903
903
904
904
905 # Bytes that break XML even in a CDATA block: control characters 0-31
905 # Bytes that break XML even in a CDATA block: control characters 0-31
906 # sans \t, \n and \r
906 # sans \t, \n and \r
907 CDATA_EVIL = re.compile(br"[\000-\010\013\014\016-\037]")
907 CDATA_EVIL = re.compile(br"[\000-\010\013\014\016-\037]")
908
908
909 # Match feature conditionalized output lines in the form, capturing the feature
909 # Match feature conditionalized output lines in the form, capturing the feature
910 # list in group 2, and the preceeding line output in group 1:
910 # list in group 2, and the preceeding line output in group 1:
911 #
911 #
912 # output..output (feature !)\n
912 # output..output (feature !)\n
913 optline = re.compile(br'(.*) \((.+?) !\)\n$')
913 optline = re.compile(br'(.*) \((.+?) !\)\n$')
914
914
915
915
916 def cdatasafe(data):
916 def cdatasafe(data):
917 """Make a string safe to include in a CDATA block.
917 """Make a string safe to include in a CDATA block.
918
918
919 Certain control characters are illegal in a CDATA block, and
919 Certain control characters are illegal in a CDATA block, and
920 there's no way to include a ]]> in a CDATA either. This function
920 there's no way to include a ]]> in a CDATA either. This function
921 replaces illegal bytes with ? and adds a space between the ]] so
921 replaces illegal bytes with ? and adds a space between the ]] so
922 that it won't break the CDATA block.
922 that it won't break the CDATA block.
923 """
923 """
924 return CDATA_EVIL.sub(b'?', data).replace(b']]>', b'] ]>')
924 return CDATA_EVIL.sub(b'?', data).replace(b']]>', b'] ]>')
925
925
926
926
927 def log(*msg):
927 def log(*msg):
928 """Log something to stdout.
928 """Log something to stdout.
929
929
930 Arguments are strings to print.
930 Arguments are strings to print.
931 """
931 """
932 with iolock:
932 with iolock:
933 if verbose:
933 if verbose:
934 print(verbose, end=' ')
934 print(verbose, end=' ')
935 for m in msg:
935 for m in msg:
936 print(m, end=' ')
936 print(m, end=' ')
937 print()
937 print()
938 sys.stdout.flush()
938 sys.stdout.flush()
939
939
940
940
941 def highlightdiff(line, color):
941 def highlightdiff(line, color):
942 if not color:
942 if not color:
943 return line
943 return line
944 assert pygmentspresent
944 assert pygmentspresent
945 return pygments.highlight(
945 return pygments.highlight(
946 line.decode('latin1'), difflexer, terminal256formatter
946 line.decode('latin1'), difflexer, terminal256formatter
947 ).encode('latin1')
947 ).encode('latin1')
948
948
949
949
950 def highlightmsg(msg, color):
950 def highlightmsg(msg, color):
951 if not color:
951 if not color:
952 return msg
952 return msg
953 assert pygmentspresent
953 assert pygmentspresent
954 return pygments.highlight(msg, runnerlexer, runnerformatter)
954 return pygments.highlight(msg, runnerlexer, runnerformatter)
955
955
956
956
957 def terminate(proc):
957 def terminate(proc):
958 """Terminate subprocess"""
958 """Terminate subprocess"""
959 vlog('# Terminating process %d' % proc.pid)
959 vlog('# Terminating process %d' % proc.pid)
960 try:
960 try:
961 proc.terminate()
961 proc.terminate()
962 except OSError:
962 except OSError:
963 pass
963 pass
964
964
965
965
966 def killdaemons(pidfile):
966 def killdaemons(pidfile):
967 import killdaemons as killmod
967 import killdaemons as killmod
968
968
969 return killmod.killdaemons(pidfile, tryhard=False, remove=True, logfn=vlog)
969 return killmod.killdaemons(pidfile, tryhard=False, remove=True, logfn=vlog)
970
970
971
971
972 # sysconfig is not thread-safe (https://github.com/python/cpython/issues/92452)
973 sysconfiglock = threading.Lock()
974
975
972 class Test(unittest.TestCase):
976 class Test(unittest.TestCase):
973 """Encapsulates a single, runnable test.
977 """Encapsulates a single, runnable test.
974
978
975 While this class conforms to the unittest.TestCase API, it differs in that
979 While this class conforms to the unittest.TestCase API, it differs in that
976 instances need to be instantiated manually. (Typically, unittest.TestCase
980 instances need to be instantiated manually. (Typically, unittest.TestCase
977 classes are instantiated automatically by scanning modules.)
981 classes are instantiated automatically by scanning modules.)
978 """
982 """
979
983
980 # Status code reserved for skipped tests (used by hghave).
984 # Status code reserved for skipped tests (used by hghave).
981 SKIPPED_STATUS = 80
985 SKIPPED_STATUS = 80
982
986
983 def __init__(
987 def __init__(
984 self,
988 self,
985 path,
989 path,
986 outputdir,
990 outputdir,
987 tmpdir,
991 tmpdir,
988 keeptmpdir=False,
992 keeptmpdir=False,
989 debug=False,
993 debug=False,
990 first=False,
994 first=False,
991 timeout=None,
995 timeout=None,
992 startport=None,
996 startport=None,
993 extraconfigopts=None,
997 extraconfigopts=None,
994 shell=None,
998 shell=None,
995 hgcommand=None,
999 hgcommand=None,
996 slowtimeout=None,
1000 slowtimeout=None,
997 usechg=False,
1001 usechg=False,
998 chgdebug=False,
1002 chgdebug=False,
999 useipv6=False,
1003 useipv6=False,
1000 ):
1004 ):
1001 """Create a test from parameters.
1005 """Create a test from parameters.
1002
1006
1003 path is the full path to the file defining the test.
1007 path is the full path to the file defining the test.
1004
1008
1005 tmpdir is the main temporary directory to use for this test.
1009 tmpdir is the main temporary directory to use for this test.
1006
1010
1007 keeptmpdir determines whether to keep the test's temporary directory
1011 keeptmpdir determines whether to keep the test's temporary directory
1008 after execution. It defaults to removal (False).
1012 after execution. It defaults to removal (False).
1009
1013
1010 debug mode will make the test execute verbosely, with unfiltered
1014 debug mode will make the test execute verbosely, with unfiltered
1011 output.
1015 output.
1012
1016
1013 timeout controls the maximum run time of the test. It is ignored when
1017 timeout controls the maximum run time of the test. It is ignored when
1014 debug is True. See slowtimeout for tests with #require slow.
1018 debug is True. See slowtimeout for tests with #require slow.
1015
1019
1016 slowtimeout overrides timeout if the test has #require slow.
1020 slowtimeout overrides timeout if the test has #require slow.
1017
1021
1018 startport controls the starting port number to use for this test. Each
1022 startport controls the starting port number to use for this test. Each
1019 test will reserve 3 port numbers for execution. It is the caller's
1023 test will reserve 3 port numbers for execution. It is the caller's
1020 responsibility to allocate a non-overlapping port range to Test
1024 responsibility to allocate a non-overlapping port range to Test
1021 instances.
1025 instances.
1022
1026
1023 extraconfigopts is an iterable of extra hgrc config options. Values
1027 extraconfigopts is an iterable of extra hgrc config options. Values
1024 must have the form "key=value" (something understood by hgrc). Values
1028 must have the form "key=value" (something understood by hgrc). Values
1025 of the form "foo.key=value" will result in "[foo] key=value".
1029 of the form "foo.key=value" will result in "[foo] key=value".
1026
1030
1027 shell is the shell to execute tests in.
1031 shell is the shell to execute tests in.
1028 """
1032 """
1029 if timeout is None:
1033 if timeout is None:
1030 timeout = defaults['timeout']
1034 timeout = defaults['timeout']
1031 if startport is None:
1035 if startport is None:
1032 startport = defaults['port']
1036 startport = defaults['port']
1033 if slowtimeout is None:
1037 if slowtimeout is None:
1034 slowtimeout = defaults['slowtimeout']
1038 slowtimeout = defaults['slowtimeout']
1035 self.path = path
1039 self.path = path
1036 self.relpath = os.path.relpath(path)
1040 self.relpath = os.path.relpath(path)
1037 self.bname = os.path.basename(path)
1041 self.bname = os.path.basename(path)
1038 self.name = _bytes2sys(self.bname)
1042 self.name = _bytes2sys(self.bname)
1039 self._testdir = os.path.dirname(path)
1043 self._testdir = os.path.dirname(path)
1040 self._outputdir = outputdir
1044 self._outputdir = outputdir
1041 self._tmpname = os.path.basename(path)
1045 self._tmpname = os.path.basename(path)
1042 self.errpath = os.path.join(self._outputdir, b'%s.err' % self.bname)
1046 self.errpath = os.path.join(self._outputdir, b'%s.err' % self.bname)
1043
1047
1044 self._threadtmp = tmpdir
1048 self._threadtmp = tmpdir
1045 self._keeptmpdir = keeptmpdir
1049 self._keeptmpdir = keeptmpdir
1046 self._debug = debug
1050 self._debug = debug
1047 self._first = first
1051 self._first = first
1048 self._timeout = timeout
1052 self._timeout = timeout
1049 self._slowtimeout = slowtimeout
1053 self._slowtimeout = slowtimeout
1050 self._startport = startport
1054 self._startport = startport
1051 self._extraconfigopts = extraconfigopts or []
1055 self._extraconfigopts = extraconfigopts or []
1052 self._shell = _sys2bytes(shell)
1056 self._shell = _sys2bytes(shell)
1053 self._hgcommand = hgcommand or b'hg'
1057 self._hgcommand = hgcommand or b'hg'
1054 self._usechg = usechg
1058 self._usechg = usechg
1055 self._chgdebug = chgdebug
1059 self._chgdebug = chgdebug
1056 self._useipv6 = useipv6
1060 self._useipv6 = useipv6
1057
1061
1058 self._aborted = False
1062 self._aborted = False
1059 self._daemonpids = []
1063 self._daemonpids = []
1060 self._finished = None
1064 self._finished = None
1061 self._ret = None
1065 self._ret = None
1062 self._out = None
1066 self._out = None
1063 self._skipped = None
1067 self._skipped = None
1064 self._testtmp = None
1068 self._testtmp = None
1065 self._chgsockdir = None
1069 self._chgsockdir = None
1066
1070
1067 self._refout = self.readrefout()
1071 self._refout = self.readrefout()
1068
1072
1069 def readrefout(self):
1073 def readrefout(self):
1070 """read reference output"""
1074 """read reference output"""
1071 # If we're not in --debug mode and reference output file exists,
1075 # If we're not in --debug mode and reference output file exists,
1072 # check test output against it.
1076 # check test output against it.
1073 if self._debug:
1077 if self._debug:
1074 return None # to match "out is None"
1078 return None # to match "out is None"
1075 elif os.path.exists(self.refpath):
1079 elif os.path.exists(self.refpath):
1076 with open(self.refpath, 'rb') as f:
1080 with open(self.refpath, 'rb') as f:
1077 return f.read().splitlines(True)
1081 return f.read().splitlines(True)
1078 else:
1082 else:
1079 return []
1083 return []
1080
1084
1081 # needed to get base class __repr__ running
1085 # needed to get base class __repr__ running
1082 @property
1086 @property
1083 def _testMethodName(self):
1087 def _testMethodName(self):
1084 return self.name
1088 return self.name
1085
1089
1086 def __str__(self):
1090 def __str__(self):
1087 return self.name
1091 return self.name
1088
1092
1089 def shortDescription(self):
1093 def shortDescription(self):
1090 return self.name
1094 return self.name
1091
1095
1092 def setUp(self):
1096 def setUp(self):
1093 """Tasks to perform before run()."""
1097 """Tasks to perform before run()."""
1094 self._finished = False
1098 self._finished = False
1095 self._ret = None
1099 self._ret = None
1096 self._out = None
1100 self._out = None
1097 self._skipped = None
1101 self._skipped = None
1098
1102
1099 try:
1103 try:
1100 os.mkdir(self._threadtmp)
1104 os.mkdir(self._threadtmp)
1101 except OSError as e:
1105 except OSError as e:
1102 if e.errno != errno.EEXIST:
1106 if e.errno != errno.EEXIST:
1103 raise
1107 raise
1104
1108
1105 name = self._tmpname
1109 name = self._tmpname
1106 self._testtmp = os.path.join(self._threadtmp, name)
1110 self._testtmp = os.path.join(self._threadtmp, name)
1107 os.mkdir(self._testtmp)
1111 os.mkdir(self._testtmp)
1108
1112
1109 # Remove any previous output files.
1113 # Remove any previous output files.
1110 if os.path.exists(self.errpath):
1114 if os.path.exists(self.errpath):
1111 try:
1115 try:
1112 os.remove(self.errpath)
1116 os.remove(self.errpath)
1113 except OSError as e:
1117 except OSError as e:
1114 # We might have raced another test to clean up a .err
1118 # We might have raced another test to clean up a .err
1115 # file, so ignore ENOENT when removing a previous .err
1119 # file, so ignore ENOENT when removing a previous .err
1116 # file.
1120 # file.
1117 if e.errno != errno.ENOENT:
1121 if e.errno != errno.ENOENT:
1118 raise
1122 raise
1119
1123
1120 if self._usechg:
1124 if self._usechg:
1121 self._chgsockdir = os.path.join(
1125 self._chgsockdir = os.path.join(
1122 self._threadtmp, b'%s.chgsock' % name
1126 self._threadtmp, b'%s.chgsock' % name
1123 )
1127 )
1124 os.mkdir(self._chgsockdir)
1128 os.mkdir(self._chgsockdir)
1125
1129
1126 def run(self, result):
1130 def run(self, result):
1127 """Run this test and report results against a TestResult instance."""
1131 """Run this test and report results against a TestResult instance."""
1128 # This function is extremely similar to unittest.TestCase.run(). Once
1132 # This function is extremely similar to unittest.TestCase.run(). Once
1129 # we require Python 2.7 (or at least its version of unittest), this
1133 # we require Python 2.7 (or at least its version of unittest), this
1130 # function can largely go away.
1134 # function can largely go away.
1131 self._result = result
1135 self._result = result
1132 result.startTest(self)
1136 result.startTest(self)
1133 try:
1137 try:
1134 try:
1138 try:
1135 self.setUp()
1139 self.setUp()
1136 except (KeyboardInterrupt, SystemExit):
1140 except (KeyboardInterrupt, SystemExit):
1137 self._aborted = True
1141 self._aborted = True
1138 raise
1142 raise
1139 except Exception:
1143 except Exception:
1140 result.addError(self, sys.exc_info())
1144 result.addError(self, sys.exc_info())
1141 return
1145 return
1142
1146
1143 success = False
1147 success = False
1144 try:
1148 try:
1145 self.runTest()
1149 self.runTest()
1146 except KeyboardInterrupt:
1150 except KeyboardInterrupt:
1147 self._aborted = True
1151 self._aborted = True
1148 raise
1152 raise
1149 except unittest.SkipTest as e:
1153 except unittest.SkipTest as e:
1150 result.addSkip(self, str(e))
1154 result.addSkip(self, str(e))
1151 # The base class will have already counted this as a
1155 # The base class will have already counted this as a
1152 # test we "ran", but we want to exclude skipped tests
1156 # test we "ran", but we want to exclude skipped tests
1153 # from those we count towards those run.
1157 # from those we count towards those run.
1154 result.testsRun -= 1
1158 result.testsRun -= 1
1155 except self.failureException as e:
1159 except self.failureException as e:
1156 # This differs from unittest in that we don't capture
1160 # This differs from unittest in that we don't capture
1157 # the stack trace. This is for historical reasons and
1161 # the stack trace. This is for historical reasons and
1158 # this decision could be revisited in the future,
1162 # this decision could be revisited in the future,
1159 # especially for PythonTest instances.
1163 # especially for PythonTest instances.
1160 if result.addFailure(self, str(e)):
1164 if result.addFailure(self, str(e)):
1161 success = True
1165 success = True
1162 except Exception:
1166 except Exception:
1163 result.addError(self, sys.exc_info())
1167 result.addError(self, sys.exc_info())
1164 else:
1168 else:
1165 success = True
1169 success = True
1166
1170
1167 try:
1171 try:
1168 self.tearDown()
1172 self.tearDown()
1169 except (KeyboardInterrupt, SystemExit):
1173 except (KeyboardInterrupt, SystemExit):
1170 self._aborted = True
1174 self._aborted = True
1171 raise
1175 raise
1172 except Exception:
1176 except Exception:
1173 result.addError(self, sys.exc_info())
1177 result.addError(self, sys.exc_info())
1174 success = False
1178 success = False
1175
1179
1176 if success:
1180 if success:
1177 result.addSuccess(self)
1181 result.addSuccess(self)
1178 finally:
1182 finally:
1179 result.stopTest(self, interrupted=self._aborted)
1183 result.stopTest(self, interrupted=self._aborted)
1180
1184
1181 def runTest(self):
1185 def runTest(self):
1182 """Run this test instance.
1186 """Run this test instance.
1183
1187
1184 This will return a tuple describing the result of the test.
1188 This will return a tuple describing the result of the test.
1185 """
1189 """
1186 env = self._getenv()
1190 env = self._getenv()
1187 self._genrestoreenv(env)
1191 self._genrestoreenv(env)
1188 self._daemonpids.append(env['DAEMON_PIDS'])
1192 self._daemonpids.append(env['DAEMON_PIDS'])
1189 self._createhgrc(env['HGRCPATH'])
1193 self._createhgrc(env['HGRCPATH'])
1190
1194
1191 vlog('# Test', self.name)
1195 vlog('# Test', self.name)
1192
1196
1193 ret, out = self._run(env)
1197 ret, out = self._run(env)
1194 self._finished = True
1198 self._finished = True
1195 self._ret = ret
1199 self._ret = ret
1196 self._out = out
1200 self._out = out
1197
1201
1198 def describe(ret):
1202 def describe(ret):
1199 if ret < 0:
1203 if ret < 0:
1200 return 'killed by signal: %d' % -ret
1204 return 'killed by signal: %d' % -ret
1201 return 'returned error code %d' % ret
1205 return 'returned error code %d' % ret
1202
1206
1203 self._skipped = False
1207 self._skipped = False
1204
1208
1205 if ret == self.SKIPPED_STATUS:
1209 if ret == self.SKIPPED_STATUS:
1206 if out is None: # Debug mode, nothing to parse.
1210 if out is None: # Debug mode, nothing to parse.
1207 missing = ['unknown']
1211 missing = ['unknown']
1208 failed = None
1212 failed = None
1209 else:
1213 else:
1210 missing, failed = TTest.parsehghaveoutput(out)
1214 missing, failed = TTest.parsehghaveoutput(out)
1211
1215
1212 if not missing:
1216 if not missing:
1213 missing = ['skipped']
1217 missing = ['skipped']
1214
1218
1215 if failed:
1219 if failed:
1216 self.fail('hg have failed checking for %s' % failed[-1])
1220 self.fail('hg have failed checking for %s' % failed[-1])
1217 else:
1221 else:
1218 self._skipped = True
1222 self._skipped = True
1219 raise unittest.SkipTest(missing[-1])
1223 raise unittest.SkipTest(missing[-1])
1220 elif ret == 'timeout':
1224 elif ret == 'timeout':
1221 self.fail('timed out')
1225 self.fail('timed out')
1222 elif ret is False:
1226 elif ret is False:
1223 self.fail('no result code from test')
1227 self.fail('no result code from test')
1224 elif out != self._refout:
1228 elif out != self._refout:
1225 # Diff generation may rely on written .err file.
1229 # Diff generation may rely on written .err file.
1226 if (
1230 if (
1227 (ret != 0 or out != self._refout)
1231 (ret != 0 or out != self._refout)
1228 and not self._skipped
1232 and not self._skipped
1229 and not self._debug
1233 and not self._debug
1230 ):
1234 ):
1231 with open(self.errpath, 'wb') as f:
1235 with open(self.errpath, 'wb') as f:
1232 for line in out:
1236 for line in out:
1233 f.write(line)
1237 f.write(line)
1234
1238
1235 # The result object handles diff calculation for us.
1239 # The result object handles diff calculation for us.
1236 with firstlock:
1240 with firstlock:
1237 if self._result.addOutputMismatch(self, ret, out, self._refout):
1241 if self._result.addOutputMismatch(self, ret, out, self._refout):
1238 # change was accepted, skip failing
1242 # change was accepted, skip failing
1239 return
1243 return
1240 if self._first:
1244 if self._first:
1241 global firsterror
1245 global firsterror
1242 firsterror = True
1246 firsterror = True
1243
1247
1244 if ret:
1248 if ret:
1245 msg = 'output changed and ' + describe(ret)
1249 msg = 'output changed and ' + describe(ret)
1246 else:
1250 else:
1247 msg = 'output changed'
1251 msg = 'output changed'
1248
1252
1249 self.fail(msg)
1253 self.fail(msg)
1250 elif ret:
1254 elif ret:
1251 self.fail(describe(ret))
1255 self.fail(describe(ret))
1252
1256
1253 def tearDown(self):
1257 def tearDown(self):
1254 """Tasks to perform after run()."""
1258 """Tasks to perform after run()."""
1255 for entry in self._daemonpids:
1259 for entry in self._daemonpids:
1256 killdaemons(entry)
1260 killdaemons(entry)
1257 self._daemonpids = []
1261 self._daemonpids = []
1258
1262
1259 if self._keeptmpdir:
1263 if self._keeptmpdir:
1260 log(
1264 log(
1261 '\nKeeping testtmp dir: %s\nKeeping threadtmp dir: %s'
1265 '\nKeeping testtmp dir: %s\nKeeping threadtmp dir: %s'
1262 % (
1266 % (
1263 _bytes2sys(self._testtmp),
1267 _bytes2sys(self._testtmp),
1264 _bytes2sys(self._threadtmp),
1268 _bytes2sys(self._threadtmp),
1265 )
1269 )
1266 )
1270 )
1267 else:
1271 else:
1268 try:
1272 try:
1269 shutil.rmtree(self._testtmp)
1273 shutil.rmtree(self._testtmp)
1270 except OSError:
1274 except OSError:
1271 # unreadable directory may be left in $TESTTMP; fix permission
1275 # unreadable directory may be left in $TESTTMP; fix permission
1272 # and try again
1276 # and try again
1273 makecleanable(self._testtmp)
1277 makecleanable(self._testtmp)
1274 shutil.rmtree(self._testtmp, True)
1278 shutil.rmtree(self._testtmp, True)
1275 shutil.rmtree(self._threadtmp, True)
1279 shutil.rmtree(self._threadtmp, True)
1276
1280
1277 if self._usechg:
1281 if self._usechg:
1278 # chgservers will stop automatically after they find the socket
1282 # chgservers will stop automatically after they find the socket
1279 # files are deleted
1283 # files are deleted
1280 shutil.rmtree(self._chgsockdir, True)
1284 shutil.rmtree(self._chgsockdir, True)
1281
1285
1282 if (
1286 if (
1283 (self._ret != 0 or self._out != self._refout)
1287 (self._ret != 0 or self._out != self._refout)
1284 and not self._skipped
1288 and not self._skipped
1285 and not self._debug
1289 and not self._debug
1286 and self._out
1290 and self._out
1287 ):
1291 ):
1288 with open(self.errpath, 'wb') as f:
1292 with open(self.errpath, 'wb') as f:
1289 for line in self._out:
1293 for line in self._out:
1290 f.write(line)
1294 f.write(line)
1291
1295
1292 vlog("# Ret was:", self._ret, '(%s)' % self.name)
1296 vlog("# Ret was:", self._ret, '(%s)' % self.name)
1293
1297
1294 def _run(self, env):
1298 def _run(self, env):
1295 # This should be implemented in child classes to run tests.
1299 # This should be implemented in child classes to run tests.
1296 raise unittest.SkipTest('unknown test type')
1300 raise unittest.SkipTest('unknown test type')
1297
1301
1298 def abort(self):
1302 def abort(self):
1299 """Terminate execution of this test."""
1303 """Terminate execution of this test."""
1300 self._aborted = True
1304 self._aborted = True
1301
1305
1302 def _portmap(self, i):
1306 def _portmap(self, i):
1303 offset = b'' if i == 0 else b'%d' % i
1307 offset = b'' if i == 0 else b'%d' % i
1304 return (br':%d\b' % (self._startport + i), b':$HGPORT%s' % offset)
1308 return (br':%d\b' % (self._startport + i), b':$HGPORT%s' % offset)
1305
1309
1306 def _getreplacements(self):
1310 def _getreplacements(self):
1307 """Obtain a mapping of text replacements to apply to test output.
1311 """Obtain a mapping of text replacements to apply to test output.
1308
1312
1309 Test output needs to be normalized so it can be compared to expected
1313 Test output needs to be normalized so it can be compared to expected
1310 output. This function defines how some of that normalization will
1314 output. This function defines how some of that normalization will
1311 occur.
1315 occur.
1312 """
1316 """
1313 r = [
1317 r = [
1314 # This list should be parallel to defineport in _getenv
1318 # This list should be parallel to defineport in _getenv
1315 self._portmap(0),
1319 self._portmap(0),
1316 self._portmap(1),
1320 self._portmap(1),
1317 self._portmap(2),
1321 self._portmap(2),
1318 (br'([^0-9])%s' % re.escape(self._localip()), br'\1$LOCALIP'),
1322 (br'([^0-9])%s' % re.escape(self._localip()), br'\1$LOCALIP'),
1319 (br'\bHG_TXNID=TXN:[a-f0-9]{40}\b', br'HG_TXNID=TXN:$ID$'),
1323 (br'\bHG_TXNID=TXN:[a-f0-9]{40}\b', br'HG_TXNID=TXN:$ID$'),
1320 ]
1324 ]
1321 r.append((self._escapepath(self._testtmp), b'$TESTTMP'))
1325 r.append((self._escapepath(self._testtmp), b'$TESTTMP'))
1322 if WINDOWS:
1326 if WINDOWS:
1323 # JSON output escapes backslashes in Windows paths, so also catch a
1327 # JSON output escapes backslashes in Windows paths, so also catch a
1324 # double-escape.
1328 # double-escape.
1325 replaced = self._testtmp.replace(b'\\', br'\\')
1329 replaced = self._testtmp.replace(b'\\', br'\\')
1326 r.append((self._escapepath(replaced), b'$STR_REPR_TESTTMP'))
1330 r.append((self._escapepath(replaced), b'$STR_REPR_TESTTMP'))
1327
1331
1328 replacementfile = os.path.join(self._testdir, b'common-pattern.py')
1332 replacementfile = os.path.join(self._testdir, b'common-pattern.py')
1329
1333
1330 if os.path.exists(replacementfile):
1334 if os.path.exists(replacementfile):
1331 data = {}
1335 data = {}
1332 with open(replacementfile, mode='rb') as source:
1336 with open(replacementfile, mode='rb') as source:
1333 # the intermediate 'compile' step help with debugging
1337 # the intermediate 'compile' step help with debugging
1334 code = compile(source.read(), replacementfile, 'exec')
1338 code = compile(source.read(), replacementfile, 'exec')
1335 exec(code, data)
1339 exec(code, data)
1336 for value in data.get('substitutions', ()):
1340 for value in data.get('substitutions', ()):
1337 if len(value) != 2:
1341 if len(value) != 2:
1338 msg = 'malformatted substitution in %s: %r'
1342 msg = 'malformatted substitution in %s: %r'
1339 msg %= (replacementfile, value)
1343 msg %= (replacementfile, value)
1340 raise ValueError(msg)
1344 raise ValueError(msg)
1341 r.append(value)
1345 r.append(value)
1342 return r
1346 return r
1343
1347
1344 def _escapepath(self, p):
1348 def _escapepath(self, p):
1345 if WINDOWS:
1349 if WINDOWS:
1346 return b''.join(
1350 return b''.join(
1347 c.isalpha()
1351 c.isalpha()
1348 and b'[%s%s]' % (c.lower(), c.upper())
1352 and b'[%s%s]' % (c.lower(), c.upper())
1349 or c in b'/\\'
1353 or c in b'/\\'
1350 and br'[/\\]'
1354 and br'[/\\]'
1351 or c.isdigit()
1355 or c.isdigit()
1352 and c
1356 and c
1353 or b'\\' + c
1357 or b'\\' + c
1354 for c in [p[i : i + 1] for i in range(len(p))]
1358 for c in [p[i : i + 1] for i in range(len(p))]
1355 )
1359 )
1356 else:
1360 else:
1357 return re.escape(p)
1361 return re.escape(p)
1358
1362
1359 def _localip(self):
1363 def _localip(self):
1360 if self._useipv6:
1364 if self._useipv6:
1361 return b'::1'
1365 return b'::1'
1362 else:
1366 else:
1363 return b'127.0.0.1'
1367 return b'127.0.0.1'
1364
1368
1365 def _genrestoreenv(self, testenv):
1369 def _genrestoreenv(self, testenv):
1366 """Generate a script that can be used by tests to restore the original
1370 """Generate a script that can be used by tests to restore the original
1367 environment."""
1371 environment."""
1368 # Put the restoreenv script inside self._threadtmp
1372 # Put the restoreenv script inside self._threadtmp
1369 scriptpath = os.path.join(self._threadtmp, b'restoreenv.sh')
1373 scriptpath = os.path.join(self._threadtmp, b'restoreenv.sh')
1370 testenv['HGTEST_RESTOREENV'] = _bytes2sys(scriptpath)
1374 testenv['HGTEST_RESTOREENV'] = _bytes2sys(scriptpath)
1371
1375
1372 # Only restore environment variable names that the shell allows
1376 # Only restore environment variable names that the shell allows
1373 # us to export.
1377 # us to export.
1374 name_regex = re.compile('^[a-zA-Z][a-zA-Z0-9_]*$')
1378 name_regex = re.compile('^[a-zA-Z][a-zA-Z0-9_]*$')
1375
1379
1376 # Do not restore these variables; otherwise tests would fail.
1380 # Do not restore these variables; otherwise tests would fail.
1377 reqnames = {'PYTHON', 'TESTDIR', 'TESTTMP'}
1381 reqnames = {'PYTHON', 'TESTDIR', 'TESTTMP'}
1378
1382
1379 with open(scriptpath, 'w') as envf:
1383 with open(scriptpath, 'w') as envf:
1380 for name, value in origenviron.items():
1384 for name, value in origenviron.items():
1381 if not name_regex.match(name):
1385 if not name_regex.match(name):
1382 # Skip environment variables with unusual names not
1386 # Skip environment variables with unusual names not
1383 # allowed by most shells.
1387 # allowed by most shells.
1384 continue
1388 continue
1385 if name in reqnames:
1389 if name in reqnames:
1386 continue
1390 continue
1387 envf.write('%s=%s\n' % (name, shellquote(value)))
1391 envf.write('%s=%s\n' % (name, shellquote(value)))
1388
1392
1389 for name in testenv:
1393 for name in testenv:
1390 if name in origenviron or name in reqnames:
1394 if name in origenviron or name in reqnames:
1391 continue
1395 continue
1392 envf.write('unset %s\n' % (name,))
1396 envf.write('unset %s\n' % (name,))
1393
1397
1394 def _getenv(self):
1398 def _getenv(self):
1395 """Obtain environment variables to use during test execution."""
1399 """Obtain environment variables to use during test execution."""
1396
1400
1397 def defineport(i):
1401 def defineport(i):
1398 offset = '' if i == 0 else '%s' % i
1402 offset = '' if i == 0 else '%s' % i
1399 env["HGPORT%s" % offset] = '%s' % (self._startport + i)
1403 env["HGPORT%s" % offset] = '%s' % (self._startport + i)
1400
1404
1401 env = os.environ.copy()
1405 env = os.environ.copy()
1402 env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or ''
1406 with sysconfiglock:
1407 env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or ''
1403 env['HGEMITWARNINGS'] = '1'
1408 env['HGEMITWARNINGS'] = '1'
1404 env['TESTTMP'] = _bytes2sys(self._testtmp)
1409 env['TESTTMP'] = _bytes2sys(self._testtmp)
1405 # the FORWARD_SLASH version is useful when running `sh` on non unix
1410 # the FORWARD_SLASH version is useful when running `sh` on non unix
1406 # system (e.g. Windows)
1411 # system (e.g. Windows)
1407 env['TESTTMP_FORWARD_SLASH'] = env['TESTTMP'].replace(os.sep, '/')
1412 env['TESTTMP_FORWARD_SLASH'] = env['TESTTMP'].replace(os.sep, '/')
1408 uid_file = os.path.join(_bytes2sys(self._testtmp), 'UID')
1413 uid_file = os.path.join(_bytes2sys(self._testtmp), 'UID')
1409 env['HGTEST_UUIDFILE'] = uid_file
1414 env['HGTEST_UUIDFILE'] = uid_file
1410 env['TESTNAME'] = self.name
1415 env['TESTNAME'] = self.name
1411 env['HOME'] = _bytes2sys(self._testtmp)
1416 env['HOME'] = _bytes2sys(self._testtmp)
1412 if WINDOWS:
1417 if WINDOWS:
1413 env['REALUSERPROFILE'] = env['USERPROFILE']
1418 env['REALUSERPROFILE'] = env['USERPROFILE']
1414 # py3.8+ ignores HOME: https://bugs.python.org/issue36264
1419 # py3.8+ ignores HOME: https://bugs.python.org/issue36264
1415 env['USERPROFILE'] = env['HOME']
1420 env['USERPROFILE'] = env['HOME']
1416 formated_timeout = _bytes2sys(b"%d" % default_defaults['timeout'][1])
1421 formated_timeout = _bytes2sys(b"%d" % default_defaults['timeout'][1])
1417 env['HGTEST_TIMEOUT_DEFAULT'] = formated_timeout
1422 env['HGTEST_TIMEOUT_DEFAULT'] = formated_timeout
1418 env['HGTEST_TIMEOUT'] = _bytes2sys(b"%d" % self._timeout)
1423 env['HGTEST_TIMEOUT'] = _bytes2sys(b"%d" % self._timeout)
1419 # This number should match portneeded in _getport
1424 # This number should match portneeded in _getport
1420 for port in xrange(3):
1425 for port in xrange(3):
1421 # This list should be parallel to _portmap in _getreplacements
1426 # This list should be parallel to _portmap in _getreplacements
1422 defineport(port)
1427 defineport(port)
1423 env["HGRCPATH"] = _bytes2sys(os.path.join(self._threadtmp, b'.hgrc'))
1428 env["HGRCPATH"] = _bytes2sys(os.path.join(self._threadtmp, b'.hgrc'))
1424 env["DAEMON_PIDS"] = _bytes2sys(
1429 env["DAEMON_PIDS"] = _bytes2sys(
1425 os.path.join(self._threadtmp, b'daemon.pids')
1430 os.path.join(self._threadtmp, b'daemon.pids')
1426 )
1431 )
1427 env["HGEDITOR"] = (
1432 env["HGEDITOR"] = (
1428 '"' + sysexecutable + '"' + ' -c "import sys; sys.exit(0)"'
1433 '"' + sysexecutable + '"' + ' -c "import sys; sys.exit(0)"'
1429 )
1434 )
1430 env["HGUSER"] = "test"
1435 env["HGUSER"] = "test"
1431 env["HGENCODING"] = "ascii"
1436 env["HGENCODING"] = "ascii"
1432 env["HGENCODINGMODE"] = "strict"
1437 env["HGENCODINGMODE"] = "strict"
1433 env["HGHOSTNAME"] = "test-hostname"
1438 env["HGHOSTNAME"] = "test-hostname"
1434 env['HGIPV6'] = str(int(self._useipv6))
1439 env['HGIPV6'] = str(int(self._useipv6))
1435 # See contrib/catapipe.py for how to use this functionality.
1440 # See contrib/catapipe.py for how to use this functionality.
1436 if 'HGTESTCATAPULTSERVERPIPE' not in env:
1441 if 'HGTESTCATAPULTSERVERPIPE' not in env:
1437 # If we don't have HGTESTCATAPULTSERVERPIPE explicitly set, pull the
1442 # If we don't have HGTESTCATAPULTSERVERPIPE explicitly set, pull the
1438 # non-test one in as a default, otherwise set to devnull
1443 # non-test one in as a default, otherwise set to devnull
1439 env['HGTESTCATAPULTSERVERPIPE'] = env.get(
1444 env['HGTESTCATAPULTSERVERPIPE'] = env.get(
1440 'HGCATAPULTSERVERPIPE', os.devnull
1445 'HGCATAPULTSERVERPIPE', os.devnull
1441 )
1446 )
1442
1447
1443 extraextensions = []
1448 extraextensions = []
1444 for opt in self._extraconfigopts:
1449 for opt in self._extraconfigopts:
1445 section, key = opt.split('.', 1)
1450 section, key = opt.split('.', 1)
1446 if section != 'extensions':
1451 if section != 'extensions':
1447 continue
1452 continue
1448 name = key.split('=', 1)[0]
1453 name = key.split('=', 1)[0]
1449 extraextensions.append(name)
1454 extraextensions.append(name)
1450
1455
1451 if extraextensions:
1456 if extraextensions:
1452 env['HGTESTEXTRAEXTENSIONS'] = ' '.join(extraextensions)
1457 env['HGTESTEXTRAEXTENSIONS'] = ' '.join(extraextensions)
1453
1458
1454 # LOCALIP could be ::1 or 127.0.0.1. Useful for tests that require raw
1459 # LOCALIP could be ::1 or 127.0.0.1. Useful for tests that require raw
1455 # IP addresses.
1460 # IP addresses.
1456 env['LOCALIP'] = _bytes2sys(self._localip())
1461 env['LOCALIP'] = _bytes2sys(self._localip())
1457
1462
1458 # This has the same effect as Py_LegacyWindowsStdioFlag in exewrapper.c,
1463 # This has the same effect as Py_LegacyWindowsStdioFlag in exewrapper.c,
1459 # but this is needed for testing python instances like dummyssh,
1464 # but this is needed for testing python instances like dummyssh,
1460 # dummysmtpd.py, and dumbhttp.py.
1465 # dummysmtpd.py, and dumbhttp.py.
1461 if WINDOWS:
1466 if WINDOWS:
1462 env['PYTHONLEGACYWINDOWSSTDIO'] = '1'
1467 env['PYTHONLEGACYWINDOWSSTDIO'] = '1'
1463
1468
1464 # Modified HOME in test environment can confuse Rust tools. So set
1469 # Modified HOME in test environment can confuse Rust tools. So set
1465 # CARGO_HOME and RUSTUP_HOME automatically if a Rust toolchain is
1470 # CARGO_HOME and RUSTUP_HOME automatically if a Rust toolchain is
1466 # present and these variables aren't already defined.
1471 # present and these variables aren't already defined.
1467 cargo_home_path = os.path.expanduser('~/.cargo')
1472 cargo_home_path = os.path.expanduser('~/.cargo')
1468 rustup_home_path = os.path.expanduser('~/.rustup')
1473 rustup_home_path = os.path.expanduser('~/.rustup')
1469
1474
1470 if os.path.exists(cargo_home_path) and b'CARGO_HOME' not in osenvironb:
1475 if os.path.exists(cargo_home_path) and b'CARGO_HOME' not in osenvironb:
1471 env['CARGO_HOME'] = cargo_home_path
1476 env['CARGO_HOME'] = cargo_home_path
1472 if (
1477 if (
1473 os.path.exists(rustup_home_path)
1478 os.path.exists(rustup_home_path)
1474 and b'RUSTUP_HOME' not in osenvironb
1479 and b'RUSTUP_HOME' not in osenvironb
1475 ):
1480 ):
1476 env['RUSTUP_HOME'] = rustup_home_path
1481 env['RUSTUP_HOME'] = rustup_home_path
1477
1482
1478 # Reset some environment variables to well-known values so that
1483 # Reset some environment variables to well-known values so that
1479 # the tests produce repeatable output.
1484 # the tests produce repeatable output.
1480 env['LANG'] = env['LC_ALL'] = env['LANGUAGE'] = 'C'
1485 env['LANG'] = env['LC_ALL'] = env['LANGUAGE'] = 'C'
1481 env['TZ'] = 'GMT'
1486 env['TZ'] = 'GMT'
1482 env["EMAIL"] = "Foo Bar <foo.bar@example.com>"
1487 env["EMAIL"] = "Foo Bar <foo.bar@example.com>"
1483 env['COLUMNS'] = '80'
1488 env['COLUMNS'] = '80'
1484 env['TERM'] = 'xterm'
1489 env['TERM'] = 'xterm'
1485
1490
1486 dropped = [
1491 dropped = [
1487 'CDPATH',
1492 'CDPATH',
1488 'CHGDEBUG',
1493 'CHGDEBUG',
1489 'EDITOR',
1494 'EDITOR',
1490 'GREP_OPTIONS',
1495 'GREP_OPTIONS',
1491 'HG',
1496 'HG',
1492 'HGMERGE',
1497 'HGMERGE',
1493 'HGPLAIN',
1498 'HGPLAIN',
1494 'HGPLAINEXCEPT',
1499 'HGPLAINEXCEPT',
1495 'HGPROF',
1500 'HGPROF',
1496 'http_proxy',
1501 'http_proxy',
1497 'no_proxy',
1502 'no_proxy',
1498 'NO_PROXY',
1503 'NO_PROXY',
1499 'PAGER',
1504 'PAGER',
1500 'VISUAL',
1505 'VISUAL',
1501 ]
1506 ]
1502
1507
1503 for k in dropped:
1508 for k in dropped:
1504 if k in env:
1509 if k in env:
1505 del env[k]
1510 del env[k]
1506
1511
1507 # unset env related to hooks
1512 # unset env related to hooks
1508 for k in list(env):
1513 for k in list(env):
1509 if k.startswith('HG_'):
1514 if k.startswith('HG_'):
1510 del env[k]
1515 del env[k]
1511
1516
1512 if self._usechg:
1517 if self._usechg:
1513 env['CHGSOCKNAME'] = os.path.join(self._chgsockdir, b'server')
1518 env['CHGSOCKNAME'] = os.path.join(self._chgsockdir, b'server')
1514 if self._chgdebug:
1519 if self._chgdebug:
1515 env['CHGDEBUG'] = 'true'
1520 env['CHGDEBUG'] = 'true'
1516
1521
1517 return env
1522 return env
1518
1523
1519 def _createhgrc(self, path):
1524 def _createhgrc(self, path):
1520 """Create an hgrc file for this test."""
1525 """Create an hgrc file for this test."""
1521 with open(path, 'wb') as hgrc:
1526 with open(path, 'wb') as hgrc:
1522 hgrc.write(b'[ui]\n')
1527 hgrc.write(b'[ui]\n')
1523 hgrc.write(b'slash = True\n')
1528 hgrc.write(b'slash = True\n')
1524 hgrc.write(b'interactive = False\n')
1529 hgrc.write(b'interactive = False\n')
1525 hgrc.write(b'detailed-exit-code = True\n')
1530 hgrc.write(b'detailed-exit-code = True\n')
1526 hgrc.write(b'merge = internal:merge\n')
1531 hgrc.write(b'merge = internal:merge\n')
1527 hgrc.write(b'mergemarkers = detailed\n')
1532 hgrc.write(b'mergemarkers = detailed\n')
1528 hgrc.write(b'promptecho = True\n')
1533 hgrc.write(b'promptecho = True\n')
1529 dummyssh = os.path.join(self._testdir, b'dummyssh')
1534 dummyssh = os.path.join(self._testdir, b'dummyssh')
1530 hgrc.write(b'ssh = "%s" "%s"\n' % (PYTHON, dummyssh))
1535 hgrc.write(b'ssh = "%s" "%s"\n' % (PYTHON, dummyssh))
1531 hgrc.write(b'timeout.warn=15\n')
1536 hgrc.write(b'timeout.warn=15\n')
1532 hgrc.write(b'[chgserver]\n')
1537 hgrc.write(b'[chgserver]\n')
1533 hgrc.write(b'idletimeout=60\n')
1538 hgrc.write(b'idletimeout=60\n')
1534 hgrc.write(b'[defaults]\n')
1539 hgrc.write(b'[defaults]\n')
1535 hgrc.write(b'[devel]\n')
1540 hgrc.write(b'[devel]\n')
1536 hgrc.write(b'all-warnings = true\n')
1541 hgrc.write(b'all-warnings = true\n')
1537 hgrc.write(b'default-date = 0 0\n')
1542 hgrc.write(b'default-date = 0 0\n')
1538 hgrc.write(b'[largefiles]\n')
1543 hgrc.write(b'[largefiles]\n')
1539 hgrc.write(
1544 hgrc.write(
1540 b'usercache = %s\n'
1545 b'usercache = %s\n'
1541 % (os.path.join(self._testtmp, b'.cache/largefiles'))
1546 % (os.path.join(self._testtmp, b'.cache/largefiles'))
1542 )
1547 )
1543 hgrc.write(b'[lfs]\n')
1548 hgrc.write(b'[lfs]\n')
1544 hgrc.write(
1549 hgrc.write(
1545 b'usercache = %s\n'
1550 b'usercache = %s\n'
1546 % (os.path.join(self._testtmp, b'.cache/lfs'))
1551 % (os.path.join(self._testtmp, b'.cache/lfs'))
1547 )
1552 )
1548 hgrc.write(b'[web]\n')
1553 hgrc.write(b'[web]\n')
1549 hgrc.write(b'address = localhost\n')
1554 hgrc.write(b'address = localhost\n')
1550 hgrc.write(b'ipv6 = %r\n' % self._useipv6)
1555 hgrc.write(b'ipv6 = %r\n' % self._useipv6)
1551 hgrc.write(b'server-header = testing stub value\n')
1556 hgrc.write(b'server-header = testing stub value\n')
1552
1557
1553 for opt in self._extraconfigopts:
1558 for opt in self._extraconfigopts:
1554 section, key = _sys2bytes(opt).split(b'.', 1)
1559 section, key = _sys2bytes(opt).split(b'.', 1)
1555 assert b'=' in key, (
1560 assert b'=' in key, (
1556 'extra config opt %s must ' 'have an = for assignment' % opt
1561 'extra config opt %s must ' 'have an = for assignment' % opt
1557 )
1562 )
1558 hgrc.write(b'[%s]\n%s\n' % (section, key))
1563 hgrc.write(b'[%s]\n%s\n' % (section, key))
1559
1564
1560 def fail(self, msg):
1565 def fail(self, msg):
1561 # unittest differentiates between errored and failed.
1566 # unittest differentiates between errored and failed.
1562 # Failed is denoted by AssertionError (by default at least).
1567 # Failed is denoted by AssertionError (by default at least).
1563 raise AssertionError(msg)
1568 raise AssertionError(msg)
1564
1569
1565 def _runcommand(self, cmd, env, normalizenewlines=False):
1570 def _runcommand(self, cmd, env, normalizenewlines=False):
1566 """Run command in a sub-process, capturing the output (stdout and
1571 """Run command in a sub-process, capturing the output (stdout and
1567 stderr).
1572 stderr).
1568
1573
1569 Return a tuple (exitcode, output). output is None in debug mode.
1574 Return a tuple (exitcode, output). output is None in debug mode.
1570 """
1575 """
1571 if self._debug:
1576 if self._debug:
1572 proc = subprocess.Popen(
1577 proc = subprocess.Popen(
1573 _bytes2sys(cmd),
1578 _bytes2sys(cmd),
1574 shell=True,
1579 shell=True,
1575 close_fds=closefds,
1580 close_fds=closefds,
1576 cwd=_bytes2sys(self._testtmp),
1581 cwd=_bytes2sys(self._testtmp),
1577 env=env,
1582 env=env,
1578 )
1583 )
1579 ret = proc.wait()
1584 ret = proc.wait()
1580 return (ret, None)
1585 return (ret, None)
1581
1586
1582 proc = Popen4(cmd, self._testtmp, self._timeout, env)
1587 proc = Popen4(cmd, self._testtmp, self._timeout, env)
1583
1588
1584 def cleanup():
1589 def cleanup():
1585 terminate(proc)
1590 terminate(proc)
1586 ret = proc.wait()
1591 ret = proc.wait()
1587 if ret == 0:
1592 if ret == 0:
1588 ret = signal.SIGTERM << 8
1593 ret = signal.SIGTERM << 8
1589 killdaemons(env['DAEMON_PIDS'])
1594 killdaemons(env['DAEMON_PIDS'])
1590 return ret
1595 return ret
1591
1596
1592 proc.tochild.close()
1597 proc.tochild.close()
1593
1598
1594 try:
1599 try:
1595 output = proc.fromchild.read()
1600 output = proc.fromchild.read()
1596 except KeyboardInterrupt:
1601 except KeyboardInterrupt:
1597 vlog('# Handling keyboard interrupt')
1602 vlog('# Handling keyboard interrupt')
1598 cleanup()
1603 cleanup()
1599 raise
1604 raise
1600
1605
1601 ret = proc.wait()
1606 ret = proc.wait()
1602 if wifexited(ret):
1607 if wifexited(ret):
1603 ret = os.WEXITSTATUS(ret)
1608 ret = os.WEXITSTATUS(ret)
1604
1609
1605 if proc.timeout:
1610 if proc.timeout:
1606 ret = 'timeout'
1611 ret = 'timeout'
1607
1612
1608 if ret:
1613 if ret:
1609 killdaemons(env['DAEMON_PIDS'])
1614 killdaemons(env['DAEMON_PIDS'])
1610
1615
1611 for s, r in self._getreplacements():
1616 for s, r in self._getreplacements():
1612 output = re.sub(s, r, output)
1617 output = re.sub(s, r, output)
1613
1618
1614 if normalizenewlines:
1619 if normalizenewlines:
1615 output = output.replace(b'\r\n', b'\n')
1620 output = output.replace(b'\r\n', b'\n')
1616
1621
1617 return ret, output.splitlines(True)
1622 return ret, output.splitlines(True)
1618
1623
1619
1624
1620 class PythonTest(Test):
1625 class PythonTest(Test):
1621 """A Python-based test."""
1626 """A Python-based test."""
1622
1627
1623 @property
1628 @property
1624 def refpath(self):
1629 def refpath(self):
1625 return os.path.join(self._testdir, b'%s.out' % self.bname)
1630 return os.path.join(self._testdir, b'%s.out' % self.bname)
1626
1631
1627 def _run(self, env):
1632 def _run(self, env):
1628 # Quote the python(3) executable for Windows
1633 # Quote the python(3) executable for Windows
1629 cmd = b'"%s" "%s"' % (PYTHON, self.path)
1634 cmd = b'"%s" "%s"' % (PYTHON, self.path)
1630 vlog("# Running", cmd.decode("utf-8"))
1635 vlog("# Running", cmd.decode("utf-8"))
1631 result = self._runcommand(cmd, env, normalizenewlines=WINDOWS)
1636 result = self._runcommand(cmd, env, normalizenewlines=WINDOWS)
1632 if self._aborted:
1637 if self._aborted:
1633 raise KeyboardInterrupt()
1638 raise KeyboardInterrupt()
1634
1639
1635 return result
1640 return result
1636
1641
1637
1642
1638 # Some glob patterns apply only in some circumstances, so the script
1643 # Some glob patterns apply only in some circumstances, so the script
1639 # might want to remove (glob) annotations that otherwise should be
1644 # might want to remove (glob) annotations that otherwise should be
1640 # retained.
1645 # retained.
1641 checkcodeglobpats = [
1646 checkcodeglobpats = [
1642 # On Windows it looks like \ doesn't require a (glob), but we know
1647 # On Windows it looks like \ doesn't require a (glob), but we know
1643 # better.
1648 # better.
1644 re.compile(br'^pushing to \$TESTTMP/.*[^)]$'),
1649 re.compile(br'^pushing to \$TESTTMP/.*[^)]$'),
1645 re.compile(br'^moving \S+/.*[^)]$'),
1650 re.compile(br'^moving \S+/.*[^)]$'),
1646 re.compile(br'^pulling from \$TESTTMP/.*[^)]$'),
1651 re.compile(br'^pulling from \$TESTTMP/.*[^)]$'),
1647 # Not all platforms have 127.0.0.1 as loopback (though most do),
1652 # Not all platforms have 127.0.0.1 as loopback (though most do),
1648 # so we always glob that too.
1653 # so we always glob that too.
1649 re.compile(br'.*\$LOCALIP.*$'),
1654 re.compile(br'.*\$LOCALIP.*$'),
1650 ]
1655 ]
1651
1656
1652 bchr = lambda x: bytes([x])
1657 bchr = lambda x: bytes([x])
1653
1658
1654 WARN_UNDEFINED = 1
1659 WARN_UNDEFINED = 1
1655 WARN_YES = 2
1660 WARN_YES = 2
1656 WARN_NO = 3
1661 WARN_NO = 3
1657
1662
1658 MARK_OPTIONAL = b" (?)\n"
1663 MARK_OPTIONAL = b" (?)\n"
1659
1664
1660
1665
1661 def isoptional(line):
1666 def isoptional(line):
1662 return line.endswith(MARK_OPTIONAL)
1667 return line.endswith(MARK_OPTIONAL)
1663
1668
1664
1669
1665 class TTest(Test):
1670 class TTest(Test):
1666 """A "t test" is a test backed by a .t file."""
1671 """A "t test" is a test backed by a .t file."""
1667
1672
1668 SKIPPED_PREFIX = b'skipped: '
1673 SKIPPED_PREFIX = b'skipped: '
1669 FAILED_PREFIX = b'hghave check failed: '
1674 FAILED_PREFIX = b'hghave check failed: '
1670 NEEDESCAPE = re.compile(br'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
1675 NEEDESCAPE = re.compile(br'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
1671
1676
1672 ESCAPESUB = re.compile(br'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
1677 ESCAPESUB = re.compile(br'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
1673 ESCAPEMAP = {bchr(i): br'\x%02x' % i for i in range(256)}
1678 ESCAPEMAP = {bchr(i): br'\x%02x' % i for i in range(256)}
1674 ESCAPEMAP.update({b'\\': b'\\\\', b'\r': br'\r'})
1679 ESCAPEMAP.update({b'\\': b'\\\\', b'\r': br'\r'})
1675
1680
1676 def __init__(self, path, *args, **kwds):
1681 def __init__(self, path, *args, **kwds):
1677 # accept an extra "case" parameter
1682 # accept an extra "case" parameter
1678 case = kwds.pop('case', [])
1683 case = kwds.pop('case', [])
1679 self._case = case
1684 self._case = case
1680 self._allcases = {x for y in parsettestcases(path) for x in y}
1685 self._allcases = {x for y in parsettestcases(path) for x in y}
1681 super(TTest, self).__init__(path, *args, **kwds)
1686 super(TTest, self).__init__(path, *args, **kwds)
1682 if case:
1687 if case:
1683 casepath = b'#'.join(case)
1688 casepath = b'#'.join(case)
1684 self.name = '%s#%s' % (self.name, _bytes2sys(casepath))
1689 self.name = '%s#%s' % (self.name, _bytes2sys(casepath))
1685 self.errpath = b'%s#%s.err' % (self.errpath[:-4], casepath)
1690 self.errpath = b'%s#%s.err' % (self.errpath[:-4], casepath)
1686 self._tmpname += b'-%s' % casepath.replace(b'#', b'-')
1691 self._tmpname += b'-%s' % casepath.replace(b'#', b'-')
1687 self._have = {}
1692 self._have = {}
1688
1693
1689 @property
1694 @property
1690 def refpath(self):
1695 def refpath(self):
1691 return os.path.join(self._testdir, self.bname)
1696 return os.path.join(self._testdir, self.bname)
1692
1697
1693 def _run(self, env):
1698 def _run(self, env):
1694 with open(self.path, 'rb') as f:
1699 with open(self.path, 'rb') as f:
1695 lines = f.readlines()
1700 lines = f.readlines()
1696
1701
1697 # .t file is both reference output and the test input, keep reference
1702 # .t file is both reference output and the test input, keep reference
1698 # output updated with the the test input. This avoids some race
1703 # output updated with the the test input. This avoids some race
1699 # conditions where the reference output does not match the actual test.
1704 # conditions where the reference output does not match the actual test.
1700 if self._refout is not None:
1705 if self._refout is not None:
1701 self._refout = lines
1706 self._refout = lines
1702
1707
1703 salt, script, after, expected = self._parsetest(lines)
1708 salt, script, after, expected = self._parsetest(lines)
1704
1709
1705 # Write out the generated script.
1710 # Write out the generated script.
1706 fname = b'%s.sh' % self._testtmp
1711 fname = b'%s.sh' % self._testtmp
1707 with open(fname, 'wb') as f:
1712 with open(fname, 'wb') as f:
1708 for l in script:
1713 for l in script:
1709 f.write(l)
1714 f.write(l)
1710
1715
1711 cmd = b'%s "%s"' % (self._shell, fname)
1716 cmd = b'%s "%s"' % (self._shell, fname)
1712 vlog("# Running", cmd.decode("utf-8"))
1717 vlog("# Running", cmd.decode("utf-8"))
1713
1718
1714 exitcode, output = self._runcommand(cmd, env)
1719 exitcode, output = self._runcommand(cmd, env)
1715
1720
1716 if self._aborted:
1721 if self._aborted:
1717 raise KeyboardInterrupt()
1722 raise KeyboardInterrupt()
1718
1723
1719 # Do not merge output if skipped. Return hghave message instead.
1724 # Do not merge output if skipped. Return hghave message instead.
1720 # Similarly, with --debug, output is None.
1725 # Similarly, with --debug, output is None.
1721 if exitcode == self.SKIPPED_STATUS or output is None:
1726 if exitcode == self.SKIPPED_STATUS or output is None:
1722 return exitcode, output
1727 return exitcode, output
1723
1728
1724 return self._processoutput(exitcode, output, salt, after, expected)
1729 return self._processoutput(exitcode, output, salt, after, expected)
1725
1730
1726 def _hghave(self, reqs):
1731 def _hghave(self, reqs):
1727 allreqs = b' '.join(reqs)
1732 allreqs = b' '.join(reqs)
1728
1733
1729 self._detectslow(reqs)
1734 self._detectslow(reqs)
1730
1735
1731 if allreqs in self._have:
1736 if allreqs in self._have:
1732 return self._have.get(allreqs)
1737 return self._have.get(allreqs)
1733
1738
1734 # TODO do something smarter when all other uses of hghave are gone.
1739 # TODO do something smarter when all other uses of hghave are gone.
1735 runtestdir = osenvironb[b'RUNTESTDIR']
1740 runtestdir = osenvironb[b'RUNTESTDIR']
1736 tdir = runtestdir.replace(b'\\', b'/')
1741 tdir = runtestdir.replace(b'\\', b'/')
1737 proc = Popen4(
1742 proc = Popen4(
1738 b'%s -c "%s/hghave %s"' % (self._shell, tdir, allreqs),
1743 b'%s -c "%s/hghave %s"' % (self._shell, tdir, allreqs),
1739 self._testtmp,
1744 self._testtmp,
1740 0,
1745 0,
1741 self._getenv(),
1746 self._getenv(),
1742 )
1747 )
1743 stdout, stderr = proc.communicate()
1748 stdout, stderr = proc.communicate()
1744 ret = proc.wait()
1749 ret = proc.wait()
1745 if wifexited(ret):
1750 if wifexited(ret):
1746 ret = os.WEXITSTATUS(ret)
1751 ret = os.WEXITSTATUS(ret)
1747 if ret == 2:
1752 if ret == 2:
1748 print(stdout.decode('utf-8'))
1753 print(stdout.decode('utf-8'))
1749 sys.exit(1)
1754 sys.exit(1)
1750
1755
1751 if ret != 0:
1756 if ret != 0:
1752 self._have[allreqs] = (False, stdout)
1757 self._have[allreqs] = (False, stdout)
1753 return False, stdout
1758 return False, stdout
1754
1759
1755 self._have[allreqs] = (True, None)
1760 self._have[allreqs] = (True, None)
1756 return True, None
1761 return True, None
1757
1762
1758 def _detectslow(self, reqs):
1763 def _detectslow(self, reqs):
1759 """update the timeout of slow test when appropriate"""
1764 """update the timeout of slow test when appropriate"""
1760 if b'slow' in reqs:
1765 if b'slow' in reqs:
1761 self._timeout = self._slowtimeout
1766 self._timeout = self._slowtimeout
1762
1767
1763 def _iftest(self, args):
1768 def _iftest(self, args):
1764 # implements "#if"
1769 # implements "#if"
1765 reqs = []
1770 reqs = []
1766 for arg in args:
1771 for arg in args:
1767 if arg.startswith(b'no-') and arg[3:] in self._allcases:
1772 if arg.startswith(b'no-') and arg[3:] in self._allcases:
1768 if arg[3:] in self._case:
1773 if arg[3:] in self._case:
1769 return False
1774 return False
1770 elif arg in self._allcases:
1775 elif arg in self._allcases:
1771 if arg not in self._case:
1776 if arg not in self._case:
1772 return False
1777 return False
1773 else:
1778 else:
1774 reqs.append(arg)
1779 reqs.append(arg)
1775 self._detectslow(reqs)
1780 self._detectslow(reqs)
1776 return self._hghave(reqs)[0]
1781 return self._hghave(reqs)[0]
1777
1782
1778 def _parsetest(self, lines):
1783 def _parsetest(self, lines):
1779 # We generate a shell script which outputs unique markers to line
1784 # We generate a shell script which outputs unique markers to line
1780 # up script results with our source. These markers include input
1785 # up script results with our source. These markers include input
1781 # line number and the last return code.
1786 # line number and the last return code.
1782 salt = b"SALT%d" % time.time()
1787 salt = b"SALT%d" % time.time()
1783
1788
1784 def addsalt(line, inpython):
1789 def addsalt(line, inpython):
1785 if inpython:
1790 if inpython:
1786 script.append(b'%s %d 0\n' % (salt, line))
1791 script.append(b'%s %d 0\n' % (salt, line))
1787 else:
1792 else:
1788 script.append(b'echo %s %d $?\n' % (salt, line))
1793 script.append(b'echo %s %d $?\n' % (salt, line))
1789
1794
1790 activetrace = []
1795 activetrace = []
1791 session = str(uuid.uuid4()).encode('ascii')
1796 session = str(uuid.uuid4()).encode('ascii')
1792 hgcatapult = os.getenv('HGTESTCATAPULTSERVERPIPE') or os.getenv(
1797 hgcatapult = os.getenv('HGTESTCATAPULTSERVERPIPE') or os.getenv(
1793 'HGCATAPULTSERVERPIPE'
1798 'HGCATAPULTSERVERPIPE'
1794 )
1799 )
1795
1800
1796 def toggletrace(cmd=None):
1801 def toggletrace(cmd=None):
1797 if not hgcatapult or hgcatapult == os.devnull:
1802 if not hgcatapult or hgcatapult == os.devnull:
1798 return
1803 return
1799
1804
1800 if activetrace:
1805 if activetrace:
1801 script.append(
1806 script.append(
1802 b'echo END %s %s >> "$HGTESTCATAPULTSERVERPIPE"\n'
1807 b'echo END %s %s >> "$HGTESTCATAPULTSERVERPIPE"\n'
1803 % (session, activetrace[0])
1808 % (session, activetrace[0])
1804 )
1809 )
1805 if cmd is None:
1810 if cmd is None:
1806 return
1811 return
1807
1812
1808 if isinstance(cmd, str):
1813 if isinstance(cmd, str):
1809 quoted = shellquote(cmd.strip())
1814 quoted = shellquote(cmd.strip())
1810 else:
1815 else:
1811 quoted = shellquote(cmd.strip().decode('utf8')).encode('utf8')
1816 quoted = shellquote(cmd.strip().decode('utf8')).encode('utf8')
1812 quoted = quoted.replace(b'\\', b'\\\\')
1817 quoted = quoted.replace(b'\\', b'\\\\')
1813 script.append(
1818 script.append(
1814 b'echo START %s %s >> "$HGTESTCATAPULTSERVERPIPE"\n'
1819 b'echo START %s %s >> "$HGTESTCATAPULTSERVERPIPE"\n'
1815 % (session, quoted)
1820 % (session, quoted)
1816 )
1821 )
1817 activetrace[0:] = [quoted]
1822 activetrace[0:] = [quoted]
1818
1823
1819 script = []
1824 script = []
1820
1825
1821 # After we run the shell script, we re-unify the script output
1826 # After we run the shell script, we re-unify the script output
1822 # with non-active parts of the source, with synchronization by our
1827 # with non-active parts of the source, with synchronization by our
1823 # SALT line number markers. The after table contains the non-active
1828 # SALT line number markers. The after table contains the non-active
1824 # components, ordered by line number.
1829 # components, ordered by line number.
1825 after = {}
1830 after = {}
1826
1831
1827 # Expected shell script output.
1832 # Expected shell script output.
1828 expected = {}
1833 expected = {}
1829
1834
1830 pos = prepos = -1
1835 pos = prepos = -1
1831
1836
1832 # True or False when in a true or false conditional section
1837 # True or False when in a true or false conditional section
1833 skipping = None
1838 skipping = None
1834
1839
1835 # We keep track of whether or not we're in a Python block so we
1840 # We keep track of whether or not we're in a Python block so we
1836 # can generate the surrounding doctest magic.
1841 # can generate the surrounding doctest magic.
1837 inpython = False
1842 inpython = False
1838
1843
1839 if self._debug:
1844 if self._debug:
1840 script.append(b'set -x\n')
1845 script.append(b'set -x\n')
1841 if os.getenv('MSYSTEM'):
1846 if os.getenv('MSYSTEM'):
1842 script.append(b'alias pwd="pwd -W"\n')
1847 script.append(b'alias pwd="pwd -W"\n')
1843
1848
1844 if hgcatapult and hgcatapult != os.devnull:
1849 if hgcatapult and hgcatapult != os.devnull:
1845 hgcatapult = hgcatapult.encode('utf8')
1850 hgcatapult = hgcatapult.encode('utf8')
1846 cataname = self.name.encode('utf8')
1851 cataname = self.name.encode('utf8')
1847
1852
1848 # Kludge: use a while loop to keep the pipe from getting
1853 # Kludge: use a while loop to keep the pipe from getting
1849 # closed by our echo commands. The still-running file gets
1854 # closed by our echo commands. The still-running file gets
1850 # reaped at the end of the script, which causes the while
1855 # reaped at the end of the script, which causes the while
1851 # loop to exit and closes the pipe. Sigh.
1856 # loop to exit and closes the pipe. Sigh.
1852 script.append(
1857 script.append(
1853 b'rtendtracing() {\n'
1858 b'rtendtracing() {\n'
1854 b' echo END %(session)s %(name)s >> %(catapult)s\n'
1859 b' echo END %(session)s %(name)s >> %(catapult)s\n'
1855 b' rm -f "$TESTTMP/.still-running"\n'
1860 b' rm -f "$TESTTMP/.still-running"\n'
1856 b'}\n'
1861 b'}\n'
1857 b'trap "rtendtracing" 0\n'
1862 b'trap "rtendtracing" 0\n'
1858 b'touch "$TESTTMP/.still-running"\n'
1863 b'touch "$TESTTMP/.still-running"\n'
1859 b'while [ -f "$TESTTMP/.still-running" ]; do sleep 1; done '
1864 b'while [ -f "$TESTTMP/.still-running" ]; do sleep 1; done '
1860 b'> %(catapult)s &\n'
1865 b'> %(catapult)s &\n'
1861 b'HGCATAPULTSESSION=%(session)s ; export HGCATAPULTSESSION\n'
1866 b'HGCATAPULTSESSION=%(session)s ; export HGCATAPULTSESSION\n'
1862 b'echo START %(session)s %(name)s >> %(catapult)s\n'
1867 b'echo START %(session)s %(name)s >> %(catapult)s\n'
1863 % {
1868 % {
1864 b'name': cataname,
1869 b'name': cataname,
1865 b'session': session,
1870 b'session': session,
1866 b'catapult': hgcatapult,
1871 b'catapult': hgcatapult,
1867 }
1872 }
1868 )
1873 )
1869
1874
1870 if self._case:
1875 if self._case:
1871 casestr = b'#'.join(self._case)
1876 casestr = b'#'.join(self._case)
1872 if isinstance(casestr, str):
1877 if isinstance(casestr, str):
1873 quoted = shellquote(casestr)
1878 quoted = shellquote(casestr)
1874 else:
1879 else:
1875 quoted = shellquote(casestr.decode('utf8')).encode('utf8')
1880 quoted = shellquote(casestr.decode('utf8')).encode('utf8')
1876 script.append(b'TESTCASE=%s\n' % quoted)
1881 script.append(b'TESTCASE=%s\n' % quoted)
1877 script.append(b'export TESTCASE\n')
1882 script.append(b'export TESTCASE\n')
1878
1883
1879 n = 0
1884 n = 0
1880 for n, l in enumerate(lines):
1885 for n, l in enumerate(lines):
1881 if not l.endswith(b'\n'):
1886 if not l.endswith(b'\n'):
1882 l += b'\n'
1887 l += b'\n'
1883 if l.startswith(b'#require'):
1888 if l.startswith(b'#require'):
1884 lsplit = l.split()
1889 lsplit = l.split()
1885 if len(lsplit) < 2 or lsplit[0] != b'#require':
1890 if len(lsplit) < 2 or lsplit[0] != b'#require':
1886 after.setdefault(pos, []).append(
1891 after.setdefault(pos, []).append(
1887 b' !!! invalid #require\n'
1892 b' !!! invalid #require\n'
1888 )
1893 )
1889 if not skipping:
1894 if not skipping:
1890 haveresult, message = self._hghave(lsplit[1:])
1895 haveresult, message = self._hghave(lsplit[1:])
1891 if not haveresult:
1896 if not haveresult:
1892 script = [b'echo "%s"\nexit 80\n' % message]
1897 script = [b'echo "%s"\nexit 80\n' % message]
1893 break
1898 break
1894 after.setdefault(pos, []).append(l)
1899 after.setdefault(pos, []).append(l)
1895 elif l.startswith(b'#if'):
1900 elif l.startswith(b'#if'):
1896 lsplit = l.split()
1901 lsplit = l.split()
1897 if len(lsplit) < 2 or lsplit[0] != b'#if':
1902 if len(lsplit) < 2 or lsplit[0] != b'#if':
1898 after.setdefault(pos, []).append(b' !!! invalid #if\n')
1903 after.setdefault(pos, []).append(b' !!! invalid #if\n')
1899 if skipping is not None:
1904 if skipping is not None:
1900 after.setdefault(pos, []).append(b' !!! nested #if\n')
1905 after.setdefault(pos, []).append(b' !!! nested #if\n')
1901 skipping = not self._iftest(lsplit[1:])
1906 skipping = not self._iftest(lsplit[1:])
1902 after.setdefault(pos, []).append(l)
1907 after.setdefault(pos, []).append(l)
1903 elif l.startswith(b'#else'):
1908 elif l.startswith(b'#else'):
1904 if skipping is None:
1909 if skipping is None:
1905 after.setdefault(pos, []).append(b' !!! missing #if\n')
1910 after.setdefault(pos, []).append(b' !!! missing #if\n')
1906 skipping = not skipping
1911 skipping = not skipping
1907 after.setdefault(pos, []).append(l)
1912 after.setdefault(pos, []).append(l)
1908 elif l.startswith(b'#endif'):
1913 elif l.startswith(b'#endif'):
1909 if skipping is None:
1914 if skipping is None:
1910 after.setdefault(pos, []).append(b' !!! missing #if\n')
1915 after.setdefault(pos, []).append(b' !!! missing #if\n')
1911 skipping = None
1916 skipping = None
1912 after.setdefault(pos, []).append(l)
1917 after.setdefault(pos, []).append(l)
1913 elif skipping:
1918 elif skipping:
1914 after.setdefault(pos, []).append(l)
1919 after.setdefault(pos, []).append(l)
1915 elif l.startswith(b' >>> '): # python inlines
1920 elif l.startswith(b' >>> '): # python inlines
1916 after.setdefault(pos, []).append(l)
1921 after.setdefault(pos, []).append(l)
1917 prepos = pos
1922 prepos = pos
1918 pos = n
1923 pos = n
1919 if not inpython:
1924 if not inpython:
1920 # We've just entered a Python block. Add the header.
1925 # We've just entered a Python block. Add the header.
1921 inpython = True
1926 inpython = True
1922 addsalt(prepos, False) # Make sure we report the exit code.
1927 addsalt(prepos, False) # Make sure we report the exit code.
1923 script.append(b'"%s" -m heredoctest <<EOF\n' % PYTHON)
1928 script.append(b'"%s" -m heredoctest <<EOF\n' % PYTHON)
1924 addsalt(n, True)
1929 addsalt(n, True)
1925 script.append(l[2:])
1930 script.append(l[2:])
1926 elif l.startswith(b' ... '): # python inlines
1931 elif l.startswith(b' ... '): # python inlines
1927 after.setdefault(prepos, []).append(l)
1932 after.setdefault(prepos, []).append(l)
1928 script.append(l[2:])
1933 script.append(l[2:])
1929 elif l.startswith(b' $ '): # commands
1934 elif l.startswith(b' $ '): # commands
1930 if inpython:
1935 if inpython:
1931 script.append(b'EOF\n')
1936 script.append(b'EOF\n')
1932 inpython = False
1937 inpython = False
1933 after.setdefault(pos, []).append(l)
1938 after.setdefault(pos, []).append(l)
1934 prepos = pos
1939 prepos = pos
1935 pos = n
1940 pos = n
1936 addsalt(n, False)
1941 addsalt(n, False)
1937 rawcmd = l[4:]
1942 rawcmd = l[4:]
1938 cmd = rawcmd.split()
1943 cmd = rawcmd.split()
1939 toggletrace(rawcmd)
1944 toggletrace(rawcmd)
1940 if len(cmd) == 2 and cmd[0] == b'cd':
1945 if len(cmd) == 2 and cmd[0] == b'cd':
1941 rawcmd = b'cd %s || exit 1\n' % cmd[1]
1946 rawcmd = b'cd %s || exit 1\n' % cmd[1]
1942 script.append(rawcmd)
1947 script.append(rawcmd)
1943 elif l.startswith(b' > '): # continuations
1948 elif l.startswith(b' > '): # continuations
1944 after.setdefault(prepos, []).append(l)
1949 after.setdefault(prepos, []).append(l)
1945 script.append(l[4:])
1950 script.append(l[4:])
1946 elif l.startswith(b' '): # results
1951 elif l.startswith(b' '): # results
1947 # Queue up a list of expected results.
1952 # Queue up a list of expected results.
1948 expected.setdefault(pos, []).append(l[2:])
1953 expected.setdefault(pos, []).append(l[2:])
1949 else:
1954 else:
1950 if inpython:
1955 if inpython:
1951 script.append(b'EOF\n')
1956 script.append(b'EOF\n')
1952 inpython = False
1957 inpython = False
1953 # Non-command/result. Queue up for merged output.
1958 # Non-command/result. Queue up for merged output.
1954 after.setdefault(pos, []).append(l)
1959 after.setdefault(pos, []).append(l)
1955
1960
1956 if inpython:
1961 if inpython:
1957 script.append(b'EOF\n')
1962 script.append(b'EOF\n')
1958 if skipping is not None:
1963 if skipping is not None:
1959 after.setdefault(pos, []).append(b' !!! missing #endif\n')
1964 after.setdefault(pos, []).append(b' !!! missing #endif\n')
1960 addsalt(n + 1, False)
1965 addsalt(n + 1, False)
1961 # Need to end any current per-command trace
1966 # Need to end any current per-command trace
1962 if activetrace:
1967 if activetrace:
1963 toggletrace()
1968 toggletrace()
1964 return salt, script, after, expected
1969 return salt, script, after, expected
1965
1970
1966 def _processoutput(self, exitcode, output, salt, after, expected):
1971 def _processoutput(self, exitcode, output, salt, after, expected):
1967 # Merge the script output back into a unified test.
1972 # Merge the script output back into a unified test.
1968 warnonly = WARN_UNDEFINED # 1: not yet; 2: yes; 3: for sure not
1973 warnonly = WARN_UNDEFINED # 1: not yet; 2: yes; 3: for sure not
1969 if exitcode != 0:
1974 if exitcode != 0:
1970 warnonly = WARN_NO
1975 warnonly = WARN_NO
1971
1976
1972 pos = -1
1977 pos = -1
1973 postout = []
1978 postout = []
1974 for out_rawline in output:
1979 for out_rawline in output:
1975 out_line, cmd_line = out_rawline, None
1980 out_line, cmd_line = out_rawline, None
1976 if salt in out_rawline:
1981 if salt in out_rawline:
1977 out_line, cmd_line = out_rawline.split(salt, 1)
1982 out_line, cmd_line = out_rawline.split(salt, 1)
1978
1983
1979 pos, postout, warnonly = self._process_out_line(
1984 pos, postout, warnonly = self._process_out_line(
1980 out_line, pos, postout, expected, warnonly
1985 out_line, pos, postout, expected, warnonly
1981 )
1986 )
1982 pos, postout = self._process_cmd_line(cmd_line, pos, postout, after)
1987 pos, postout = self._process_cmd_line(cmd_line, pos, postout, after)
1983
1988
1984 if pos in after:
1989 if pos in after:
1985 postout += after.pop(pos)
1990 postout += after.pop(pos)
1986
1991
1987 if warnonly == WARN_YES:
1992 if warnonly == WARN_YES:
1988 exitcode = False # Set exitcode to warned.
1993 exitcode = False # Set exitcode to warned.
1989
1994
1990 return exitcode, postout
1995 return exitcode, postout
1991
1996
1992 def _process_out_line(self, out_line, pos, postout, expected, warnonly):
1997 def _process_out_line(self, out_line, pos, postout, expected, warnonly):
1993 while out_line:
1998 while out_line:
1994 if not out_line.endswith(b'\n'):
1999 if not out_line.endswith(b'\n'):
1995 out_line += b' (no-eol)\n'
2000 out_line += b' (no-eol)\n'
1996
2001
1997 # Find the expected output at the current position.
2002 # Find the expected output at the current position.
1998 els = [None]
2003 els = [None]
1999 if expected.get(pos, None):
2004 if expected.get(pos, None):
2000 els = expected[pos]
2005 els = expected[pos]
2001
2006
2002 optional = []
2007 optional = []
2003 for i, el in enumerate(els):
2008 for i, el in enumerate(els):
2004 r = False
2009 r = False
2005 if el:
2010 if el:
2006 r, exact = self.linematch(el, out_line)
2011 r, exact = self.linematch(el, out_line)
2007 if isinstance(r, str):
2012 if isinstance(r, str):
2008 if r == '-glob':
2013 if r == '-glob':
2009 out_line = ''.join(el.rsplit(' (glob)', 1))
2014 out_line = ''.join(el.rsplit(' (glob)', 1))
2010 r = '' # Warn only this line.
2015 r = '' # Warn only this line.
2011 elif r == "retry":
2016 elif r == "retry":
2012 postout.append(b' ' + el)
2017 postout.append(b' ' + el)
2013 else:
2018 else:
2014 log('\ninfo, unknown linematch result: %r\n' % r)
2019 log('\ninfo, unknown linematch result: %r\n' % r)
2015 r = False
2020 r = False
2016 if r:
2021 if r:
2017 els.pop(i)
2022 els.pop(i)
2018 break
2023 break
2019 if el:
2024 if el:
2020 if isoptional(el):
2025 if isoptional(el):
2021 optional.append(i)
2026 optional.append(i)
2022 else:
2027 else:
2023 m = optline.match(el)
2028 m = optline.match(el)
2024 if m:
2029 if m:
2025 conditions = [c for c in m.group(2).split(b' ')]
2030 conditions = [c for c in m.group(2).split(b' ')]
2026
2031
2027 if not self._iftest(conditions):
2032 if not self._iftest(conditions):
2028 optional.append(i)
2033 optional.append(i)
2029 if exact:
2034 if exact:
2030 # Don't allow line to be matches against a later
2035 # Don't allow line to be matches against a later
2031 # line in the output
2036 # line in the output
2032 els.pop(i)
2037 els.pop(i)
2033 break
2038 break
2034
2039
2035 if r:
2040 if r:
2036 if r == "retry":
2041 if r == "retry":
2037 continue
2042 continue
2038 # clean up any optional leftovers
2043 # clean up any optional leftovers
2039 for i in optional:
2044 for i in optional:
2040 postout.append(b' ' + els[i])
2045 postout.append(b' ' + els[i])
2041 for i in reversed(optional):
2046 for i in reversed(optional):
2042 del els[i]
2047 del els[i]
2043 postout.append(b' ' + el)
2048 postout.append(b' ' + el)
2044 else:
2049 else:
2045 if self.NEEDESCAPE(out_line):
2050 if self.NEEDESCAPE(out_line):
2046 out_line = TTest._stringescape(
2051 out_line = TTest._stringescape(
2047 b'%s (esc)\n' % out_line.rstrip(b'\n')
2052 b'%s (esc)\n' % out_line.rstrip(b'\n')
2048 )
2053 )
2049 postout.append(b' ' + out_line) # Let diff deal with it.
2054 postout.append(b' ' + out_line) # Let diff deal with it.
2050 if r != '': # If line failed.
2055 if r != '': # If line failed.
2051 warnonly = WARN_NO
2056 warnonly = WARN_NO
2052 elif warnonly == WARN_UNDEFINED:
2057 elif warnonly == WARN_UNDEFINED:
2053 warnonly = WARN_YES
2058 warnonly = WARN_YES
2054 break
2059 break
2055 else:
2060 else:
2056 # clean up any optional leftovers
2061 # clean up any optional leftovers
2057 while expected.get(pos, None):
2062 while expected.get(pos, None):
2058 el = expected[pos].pop(0)
2063 el = expected[pos].pop(0)
2059 if el:
2064 if el:
2060 if not isoptional(el):
2065 if not isoptional(el):
2061 m = optline.match(el)
2066 m = optline.match(el)
2062 if m:
2067 if m:
2063 conditions = [c for c in m.group(2).split(b' ')]
2068 conditions = [c for c in m.group(2).split(b' ')]
2064
2069
2065 if self._iftest(conditions):
2070 if self._iftest(conditions):
2066 # Don't append as optional line
2071 # Don't append as optional line
2067 continue
2072 continue
2068 else:
2073 else:
2069 continue
2074 continue
2070 postout.append(b' ' + el)
2075 postout.append(b' ' + el)
2071 return pos, postout, warnonly
2076 return pos, postout, warnonly
2072
2077
2073 def _process_cmd_line(self, cmd_line, pos, postout, after):
2078 def _process_cmd_line(self, cmd_line, pos, postout, after):
2074 """process a "command" part of a line from unified test output"""
2079 """process a "command" part of a line from unified test output"""
2075 if cmd_line:
2080 if cmd_line:
2076 # Add on last return code.
2081 # Add on last return code.
2077 ret = int(cmd_line.split()[1])
2082 ret = int(cmd_line.split()[1])
2078 if ret != 0:
2083 if ret != 0:
2079 postout.append(b' [%d]\n' % ret)
2084 postout.append(b' [%d]\n' % ret)
2080 if pos in after:
2085 if pos in after:
2081 # Merge in non-active test bits.
2086 # Merge in non-active test bits.
2082 postout += after.pop(pos)
2087 postout += after.pop(pos)
2083 pos = int(cmd_line.split()[0])
2088 pos = int(cmd_line.split()[0])
2084 return pos, postout
2089 return pos, postout
2085
2090
2086 @staticmethod
2091 @staticmethod
2087 def rematch(el, l):
2092 def rematch(el, l):
2088 try:
2093 try:
2089 # parse any flags at the beginning of the regex. Only 'i' is
2094 # parse any flags at the beginning of the regex. Only 'i' is
2090 # supported right now, but this should be easy to extend.
2095 # supported right now, but this should be easy to extend.
2091 flags, el = re.match(br'^(\(\?i\))?(.*)', el).groups()[0:2]
2096 flags, el = re.match(br'^(\(\?i\))?(.*)', el).groups()[0:2]
2092 flags = flags or b''
2097 flags = flags or b''
2093 el = flags + b'(?:' + el + b')'
2098 el = flags + b'(?:' + el + b')'
2094 # use \Z to ensure that the regex matches to the end of the string
2099 # use \Z to ensure that the regex matches to the end of the string
2095 if WINDOWS:
2100 if WINDOWS:
2096 return re.match(el + br'\r?\n\Z', l)
2101 return re.match(el + br'\r?\n\Z', l)
2097 return re.match(el + br'\n\Z', l)
2102 return re.match(el + br'\n\Z', l)
2098 except re.error:
2103 except re.error:
2099 # el is an invalid regex
2104 # el is an invalid regex
2100 return False
2105 return False
2101
2106
2102 @staticmethod
2107 @staticmethod
2103 def globmatch(el, l):
2108 def globmatch(el, l):
2104 # The only supported special characters are * and ? plus / which also
2109 # The only supported special characters are * and ? plus / which also
2105 # matches \ on windows. Escaping of these characters is supported.
2110 # matches \ on windows. Escaping of these characters is supported.
2106 if el + b'\n' == l:
2111 if el + b'\n' == l:
2107 if os.altsep:
2112 if os.altsep:
2108 # matching on "/" is not needed for this line
2113 # matching on "/" is not needed for this line
2109 for pat in checkcodeglobpats:
2114 for pat in checkcodeglobpats:
2110 if pat.match(el):
2115 if pat.match(el):
2111 return True
2116 return True
2112 return b'-glob'
2117 return b'-glob'
2113 return True
2118 return True
2114 el = el.replace(b'$LOCALIP', b'*')
2119 el = el.replace(b'$LOCALIP', b'*')
2115 i, n = 0, len(el)
2120 i, n = 0, len(el)
2116 res = b''
2121 res = b''
2117 while i < n:
2122 while i < n:
2118 c = el[i : i + 1]
2123 c = el[i : i + 1]
2119 i += 1
2124 i += 1
2120 if c == b'\\' and i < n and el[i : i + 1] in b'*?\\/':
2125 if c == b'\\' and i < n and el[i : i + 1] in b'*?\\/':
2121 res += el[i - 1 : i + 1]
2126 res += el[i - 1 : i + 1]
2122 i += 1
2127 i += 1
2123 elif c == b'*':
2128 elif c == b'*':
2124 res += b'.*'
2129 res += b'.*'
2125 elif c == b'?':
2130 elif c == b'?':
2126 res += b'.'
2131 res += b'.'
2127 elif c == b'/' and os.altsep:
2132 elif c == b'/' and os.altsep:
2128 res += b'[/\\\\]'
2133 res += b'[/\\\\]'
2129 else:
2134 else:
2130 res += re.escape(c)
2135 res += re.escape(c)
2131 return TTest.rematch(res, l)
2136 return TTest.rematch(res, l)
2132
2137
2133 def linematch(self, el, l):
2138 def linematch(self, el, l):
2134 if el == l: # perfect match (fast)
2139 if el == l: # perfect match (fast)
2135 return True, True
2140 return True, True
2136 retry = False
2141 retry = False
2137 if isoptional(el):
2142 if isoptional(el):
2138 retry = "retry"
2143 retry = "retry"
2139 el = el[: -len(MARK_OPTIONAL)] + b"\n"
2144 el = el[: -len(MARK_OPTIONAL)] + b"\n"
2140 else:
2145 else:
2141 m = optline.match(el)
2146 m = optline.match(el)
2142 if m:
2147 if m:
2143 conditions = [c for c in m.group(2).split(b' ')]
2148 conditions = [c for c in m.group(2).split(b' ')]
2144
2149
2145 el = m.group(1) + b"\n"
2150 el = m.group(1) + b"\n"
2146 if not self._iftest(conditions):
2151 if not self._iftest(conditions):
2147 # listed feature missing, should not match
2152 # listed feature missing, should not match
2148 return "retry", False
2153 return "retry", False
2149
2154
2150 if el.endswith(b" (esc)\n"):
2155 if el.endswith(b" (esc)\n"):
2151 el = el[:-7].decode('unicode_escape') + '\n'
2156 el = el[:-7].decode('unicode_escape') + '\n'
2152 el = el.encode('latin-1')
2157 el = el.encode('latin-1')
2153 if el == l or WINDOWS and el[:-1] + b'\r\n' == l:
2158 if el == l or WINDOWS and el[:-1] + b'\r\n' == l:
2154 return True, True
2159 return True, True
2155 if el.endswith(b" (re)\n"):
2160 if el.endswith(b" (re)\n"):
2156 return (TTest.rematch(el[:-6], l) or retry), False
2161 return (TTest.rematch(el[:-6], l) or retry), False
2157 if el.endswith(b" (glob)\n"):
2162 if el.endswith(b" (glob)\n"):
2158 # ignore '(glob)' added to l by 'replacements'
2163 # ignore '(glob)' added to l by 'replacements'
2159 if l.endswith(b" (glob)\n"):
2164 if l.endswith(b" (glob)\n"):
2160 l = l[:-8] + b"\n"
2165 l = l[:-8] + b"\n"
2161 return (TTest.globmatch(el[:-8], l) or retry), False
2166 return (TTest.globmatch(el[:-8], l) or retry), False
2162 if os.altsep:
2167 if os.altsep:
2163 _l = l.replace(b'\\', b'/')
2168 _l = l.replace(b'\\', b'/')
2164 if el == _l or WINDOWS and el[:-1] + b'\r\n' == _l:
2169 if el == _l or WINDOWS and el[:-1] + b'\r\n' == _l:
2165 return True, True
2170 return True, True
2166 return retry, True
2171 return retry, True
2167
2172
2168 @staticmethod
2173 @staticmethod
2169 def parsehghaveoutput(lines):
2174 def parsehghaveoutput(lines):
2170 """Parse hghave log lines.
2175 """Parse hghave log lines.
2171
2176
2172 Return tuple of lists (missing, failed):
2177 Return tuple of lists (missing, failed):
2173 * the missing/unknown features
2178 * the missing/unknown features
2174 * the features for which existence check failed"""
2179 * the features for which existence check failed"""
2175 missing = []
2180 missing = []
2176 failed = []
2181 failed = []
2177 for line in lines:
2182 for line in lines:
2178 if line.startswith(TTest.SKIPPED_PREFIX):
2183 if line.startswith(TTest.SKIPPED_PREFIX):
2179 line = line.splitlines()[0]
2184 line = line.splitlines()[0]
2180 missing.append(_bytes2sys(line[len(TTest.SKIPPED_PREFIX) :]))
2185 missing.append(_bytes2sys(line[len(TTest.SKIPPED_PREFIX) :]))
2181 elif line.startswith(TTest.FAILED_PREFIX):
2186 elif line.startswith(TTest.FAILED_PREFIX):
2182 line = line.splitlines()[0]
2187 line = line.splitlines()[0]
2183 failed.append(_bytes2sys(line[len(TTest.FAILED_PREFIX) :]))
2188 failed.append(_bytes2sys(line[len(TTest.FAILED_PREFIX) :]))
2184
2189
2185 return missing, failed
2190 return missing, failed
2186
2191
2187 @staticmethod
2192 @staticmethod
2188 def _escapef(m):
2193 def _escapef(m):
2189 return TTest.ESCAPEMAP[m.group(0)]
2194 return TTest.ESCAPEMAP[m.group(0)]
2190
2195
2191 @staticmethod
2196 @staticmethod
2192 def _stringescape(s):
2197 def _stringescape(s):
2193 return TTest.ESCAPESUB(TTest._escapef, s)
2198 return TTest.ESCAPESUB(TTest._escapef, s)
2194
2199
2195
2200
2196 iolock = threading.RLock()
2201 iolock = threading.RLock()
2197 firstlock = threading.RLock()
2202 firstlock = threading.RLock()
2198 firsterror = False
2203 firsterror = False
2199
2204
2200 base_class = unittest.TextTestResult
2205 base_class = unittest.TextTestResult
2201
2206
2202
2207
2203 class TestResult(base_class):
2208 class TestResult(base_class):
2204 """Holds results when executing via unittest."""
2209 """Holds results when executing via unittest."""
2205
2210
2206 def __init__(self, options, *args, **kwargs):
2211 def __init__(self, options, *args, **kwargs):
2207 super(TestResult, self).__init__(*args, **kwargs)
2212 super(TestResult, self).__init__(*args, **kwargs)
2208
2213
2209 self._options = options
2214 self._options = options
2210
2215
2211 # unittest.TestResult didn't have skipped until 2.7. We need to
2216 # unittest.TestResult didn't have skipped until 2.7. We need to
2212 # polyfill it.
2217 # polyfill it.
2213 self.skipped = []
2218 self.skipped = []
2214
2219
2215 # We have a custom "ignored" result that isn't present in any Python
2220 # We have a custom "ignored" result that isn't present in any Python
2216 # unittest implementation. It is very similar to skipped. It may make
2221 # unittest implementation. It is very similar to skipped. It may make
2217 # sense to map it into skip some day.
2222 # sense to map it into skip some day.
2218 self.ignored = []
2223 self.ignored = []
2219
2224
2220 self.times = []
2225 self.times = []
2221 self._firststarttime = None
2226 self._firststarttime = None
2222 # Data stored for the benefit of generating xunit reports.
2227 # Data stored for the benefit of generating xunit reports.
2223 self.successes = []
2228 self.successes = []
2224 self.faildata = {}
2229 self.faildata = {}
2225
2230
2226 if options.color == 'auto':
2231 if options.color == 'auto':
2227 isatty = self.stream.isatty()
2232 isatty = self.stream.isatty()
2228 # For some reason, redirecting stdout on Windows disables the ANSI
2233 # For some reason, redirecting stdout on Windows disables the ANSI
2229 # color processing of stderr, which is what is used to print the
2234 # color processing of stderr, which is what is used to print the
2230 # output. Therefore, both must be tty on Windows to enable color.
2235 # output. Therefore, both must be tty on Windows to enable color.
2231 if WINDOWS:
2236 if WINDOWS:
2232 isatty = isatty and sys.stdout.isatty()
2237 isatty = isatty and sys.stdout.isatty()
2233 self.color = pygmentspresent and isatty
2238 self.color = pygmentspresent and isatty
2234 elif options.color == 'never':
2239 elif options.color == 'never':
2235 self.color = False
2240 self.color = False
2236 else: # 'always', for testing purposes
2241 else: # 'always', for testing purposes
2237 self.color = pygmentspresent
2242 self.color = pygmentspresent
2238
2243
2239 def onStart(self, test):
2244 def onStart(self, test):
2240 """Can be overriden by custom TestResult"""
2245 """Can be overriden by custom TestResult"""
2241
2246
2242 def onEnd(self):
2247 def onEnd(self):
2243 """Can be overriden by custom TestResult"""
2248 """Can be overriden by custom TestResult"""
2244
2249
2245 def addFailure(self, test, reason):
2250 def addFailure(self, test, reason):
2246 self.failures.append((test, reason))
2251 self.failures.append((test, reason))
2247
2252
2248 if self._options.first:
2253 if self._options.first:
2249 self.stop()
2254 self.stop()
2250 else:
2255 else:
2251 with iolock:
2256 with iolock:
2252 if reason == "timed out":
2257 if reason == "timed out":
2253 self.stream.write('t')
2258 self.stream.write('t')
2254 else:
2259 else:
2255 if not self._options.nodiff:
2260 if not self._options.nodiff:
2256 self.stream.write('\n')
2261 self.stream.write('\n')
2257 # Exclude the '\n' from highlighting to lex correctly
2262 # Exclude the '\n' from highlighting to lex correctly
2258 formatted = 'ERROR: %s output changed\n' % test
2263 formatted = 'ERROR: %s output changed\n' % test
2259 self.stream.write(highlightmsg(formatted, self.color))
2264 self.stream.write(highlightmsg(formatted, self.color))
2260 self.stream.write('!')
2265 self.stream.write('!')
2261
2266
2262 self.stream.flush()
2267 self.stream.flush()
2263
2268
2264 def addSuccess(self, test):
2269 def addSuccess(self, test):
2265 with iolock:
2270 with iolock:
2266 super(TestResult, self).addSuccess(test)
2271 super(TestResult, self).addSuccess(test)
2267 self.successes.append(test)
2272 self.successes.append(test)
2268
2273
2269 def addError(self, test, err):
2274 def addError(self, test, err):
2270 super(TestResult, self).addError(test, err)
2275 super(TestResult, self).addError(test, err)
2271 if self._options.first:
2276 if self._options.first:
2272 self.stop()
2277 self.stop()
2273
2278
2274 # Polyfill.
2279 # Polyfill.
2275 def addSkip(self, test, reason):
2280 def addSkip(self, test, reason):
2276 self.skipped.append((test, reason))
2281 self.skipped.append((test, reason))
2277 with iolock:
2282 with iolock:
2278 if self.showAll:
2283 if self.showAll:
2279 self.stream.writeln('skipped %s' % reason)
2284 self.stream.writeln('skipped %s' % reason)
2280 else:
2285 else:
2281 self.stream.write('s')
2286 self.stream.write('s')
2282 self.stream.flush()
2287 self.stream.flush()
2283
2288
2284 def addIgnore(self, test, reason):
2289 def addIgnore(self, test, reason):
2285 self.ignored.append((test, reason))
2290 self.ignored.append((test, reason))
2286 with iolock:
2291 with iolock:
2287 if self.showAll:
2292 if self.showAll:
2288 self.stream.writeln('ignored %s' % reason)
2293 self.stream.writeln('ignored %s' % reason)
2289 else:
2294 else:
2290 if reason not in ('not retesting', "doesn't match keyword"):
2295 if reason not in ('not retesting', "doesn't match keyword"):
2291 self.stream.write('i')
2296 self.stream.write('i')
2292 else:
2297 else:
2293 self.testsRun += 1
2298 self.testsRun += 1
2294 self.stream.flush()
2299 self.stream.flush()
2295
2300
2296 def addOutputMismatch(self, test, ret, got, expected):
2301 def addOutputMismatch(self, test, ret, got, expected):
2297 """Record a mismatch in test output for a particular test."""
2302 """Record a mismatch in test output for a particular test."""
2298 if self.shouldStop or firsterror:
2303 if self.shouldStop or firsterror:
2299 # don't print, some other test case already failed and
2304 # don't print, some other test case already failed and
2300 # printed, we're just stale and probably failed due to our
2305 # printed, we're just stale and probably failed due to our
2301 # temp dir getting cleaned up.
2306 # temp dir getting cleaned up.
2302 return
2307 return
2303
2308
2304 accepted = False
2309 accepted = False
2305 lines = []
2310 lines = []
2306
2311
2307 with iolock:
2312 with iolock:
2308 if self._options.nodiff:
2313 if self._options.nodiff:
2309 pass
2314 pass
2310 elif self._options.view:
2315 elif self._options.view:
2311 v = self._options.view
2316 v = self._options.view
2312 subprocess.call(
2317 subprocess.call(
2313 r'"%s" "%s" "%s"'
2318 r'"%s" "%s" "%s"'
2314 % (v, _bytes2sys(test.refpath), _bytes2sys(test.errpath)),
2319 % (v, _bytes2sys(test.refpath), _bytes2sys(test.errpath)),
2315 shell=True,
2320 shell=True,
2316 )
2321 )
2317 else:
2322 else:
2318 servefail, lines = getdiff(
2323 servefail, lines = getdiff(
2319 expected, got, test.refpath, test.errpath
2324 expected, got, test.refpath, test.errpath
2320 )
2325 )
2321 self.stream.write('\n')
2326 self.stream.write('\n')
2322 for line in lines:
2327 for line in lines:
2323 line = highlightdiff(line, self.color)
2328 line = highlightdiff(line, self.color)
2324 self.stream.flush()
2329 self.stream.flush()
2325 self.stream.buffer.write(line)
2330 self.stream.buffer.write(line)
2326 self.stream.buffer.flush()
2331 self.stream.buffer.flush()
2327
2332
2328 if servefail:
2333 if servefail:
2329 raise test.failureException(
2334 raise test.failureException(
2330 'server failed to start (HGPORT=%s)' % test._startport
2335 'server failed to start (HGPORT=%s)' % test._startport
2331 )
2336 )
2332
2337
2333 # handle interactive prompt without releasing iolock
2338 # handle interactive prompt without releasing iolock
2334 if self._options.interactive:
2339 if self._options.interactive:
2335 if test.readrefout() != expected:
2340 if test.readrefout() != expected:
2336 self.stream.write(
2341 self.stream.write(
2337 'Reference output has changed (run again to prompt '
2342 'Reference output has changed (run again to prompt '
2338 'changes)'
2343 'changes)'
2339 )
2344 )
2340 else:
2345 else:
2341 self.stream.write('Accept this change? [y/N] ')
2346 self.stream.write('Accept this change? [y/N] ')
2342 self.stream.flush()
2347 self.stream.flush()
2343 answer = sys.stdin.readline().strip()
2348 answer = sys.stdin.readline().strip()
2344 if answer.lower() in ('y', 'yes'):
2349 if answer.lower() in ('y', 'yes'):
2345 if test.path.endswith(b'.t'):
2350 if test.path.endswith(b'.t'):
2346 rename(test.errpath, test.path)
2351 rename(test.errpath, test.path)
2347 else:
2352 else:
2348 rename(test.errpath, b'%s.out' % test.path)
2353 rename(test.errpath, b'%s.out' % test.path)
2349 accepted = True
2354 accepted = True
2350 if not accepted:
2355 if not accepted:
2351 self.faildata[test.name] = b''.join(lines)
2356 self.faildata[test.name] = b''.join(lines)
2352
2357
2353 return accepted
2358 return accepted
2354
2359
2355 def startTest(self, test):
2360 def startTest(self, test):
2356 super(TestResult, self).startTest(test)
2361 super(TestResult, self).startTest(test)
2357
2362
2358 # os.times module computes the user time and system time spent by
2363 # os.times module computes the user time and system time spent by
2359 # child's processes along with real elapsed time taken by a process.
2364 # child's processes along with real elapsed time taken by a process.
2360 # This module has one limitation. It can only work for Linux user
2365 # This module has one limitation. It can only work for Linux user
2361 # and not for Windows. Hence why we fall back to another function
2366 # and not for Windows. Hence why we fall back to another function
2362 # for wall time calculations.
2367 # for wall time calculations.
2363 test.started_times = os.times()
2368 test.started_times = os.times()
2364 # TODO use a monotonic clock once support for Python 2.7 is dropped.
2369 # TODO use a monotonic clock once support for Python 2.7 is dropped.
2365 test.started_time = time.time()
2370 test.started_time = time.time()
2366 if self._firststarttime is None: # thread racy but irrelevant
2371 if self._firststarttime is None: # thread racy but irrelevant
2367 self._firststarttime = test.started_time
2372 self._firststarttime = test.started_time
2368
2373
2369 def stopTest(self, test, interrupted=False):
2374 def stopTest(self, test, interrupted=False):
2370 super(TestResult, self).stopTest(test)
2375 super(TestResult, self).stopTest(test)
2371
2376
2372 test.stopped_times = os.times()
2377 test.stopped_times = os.times()
2373 stopped_time = time.time()
2378 stopped_time = time.time()
2374
2379
2375 starttime = test.started_times
2380 starttime = test.started_times
2376 endtime = test.stopped_times
2381 endtime = test.stopped_times
2377 origin = self._firststarttime
2382 origin = self._firststarttime
2378 self.times.append(
2383 self.times.append(
2379 (
2384 (
2380 test.name,
2385 test.name,
2381 endtime[2] - starttime[2], # user space CPU time
2386 endtime[2] - starttime[2], # user space CPU time
2382 endtime[3] - starttime[3], # sys space CPU time
2387 endtime[3] - starttime[3], # sys space CPU time
2383 stopped_time - test.started_time, # real time
2388 stopped_time - test.started_time, # real time
2384 test.started_time - origin, # start date in run context
2389 test.started_time - origin, # start date in run context
2385 stopped_time - origin, # end date in run context
2390 stopped_time - origin, # end date in run context
2386 )
2391 )
2387 )
2392 )
2388
2393
2389 if interrupted:
2394 if interrupted:
2390 with iolock:
2395 with iolock:
2391 self.stream.writeln(
2396 self.stream.writeln(
2392 'INTERRUPTED: %s (after %d seconds)'
2397 'INTERRUPTED: %s (after %d seconds)'
2393 % (test.name, self.times[-1][3])
2398 % (test.name, self.times[-1][3])
2394 )
2399 )
2395
2400
2396
2401
2397 def getTestResult():
2402 def getTestResult():
2398 """
2403 """
2399 Returns the relevant test result
2404 Returns the relevant test result
2400 """
2405 """
2401 if "CUSTOM_TEST_RESULT" in os.environ:
2406 if "CUSTOM_TEST_RESULT" in os.environ:
2402 testresultmodule = __import__(os.environ["CUSTOM_TEST_RESULT"])
2407 testresultmodule = __import__(os.environ["CUSTOM_TEST_RESULT"])
2403 return testresultmodule.TestResult
2408 return testresultmodule.TestResult
2404 else:
2409 else:
2405 return TestResult
2410 return TestResult
2406
2411
2407
2412
2408 class TestSuite(unittest.TestSuite):
2413 class TestSuite(unittest.TestSuite):
2409 """Custom unittest TestSuite that knows how to execute Mercurial tests."""
2414 """Custom unittest TestSuite that knows how to execute Mercurial tests."""
2410
2415
2411 def __init__(
2416 def __init__(
2412 self,
2417 self,
2413 testdir,
2418 testdir,
2414 jobs=1,
2419 jobs=1,
2415 whitelist=None,
2420 whitelist=None,
2416 blacklist=None,
2421 blacklist=None,
2417 keywords=None,
2422 keywords=None,
2418 loop=False,
2423 loop=False,
2419 runs_per_test=1,
2424 runs_per_test=1,
2420 loadtest=None,
2425 loadtest=None,
2421 showchannels=False,
2426 showchannels=False,
2422 *args,
2427 *args,
2423 **kwargs
2428 **kwargs
2424 ):
2429 ):
2425 """Create a new instance that can run tests with a configuration.
2430 """Create a new instance that can run tests with a configuration.
2426
2431
2427 testdir specifies the directory where tests are executed from. This
2432 testdir specifies the directory where tests are executed from. This
2428 is typically the ``tests`` directory from Mercurial's source
2433 is typically the ``tests`` directory from Mercurial's source
2429 repository.
2434 repository.
2430
2435
2431 jobs specifies the number of jobs to run concurrently. Each test
2436 jobs specifies the number of jobs to run concurrently. Each test
2432 executes on its own thread. Tests actually spawn new processes, so
2437 executes on its own thread. Tests actually spawn new processes, so
2433 state mutation should not be an issue.
2438 state mutation should not be an issue.
2434
2439
2435 If there is only one job, it will use the main thread.
2440 If there is only one job, it will use the main thread.
2436
2441
2437 whitelist and blacklist denote tests that have been whitelisted and
2442 whitelist and blacklist denote tests that have been whitelisted and
2438 blacklisted, respectively. These arguments don't belong in TestSuite.
2443 blacklisted, respectively. These arguments don't belong in TestSuite.
2439 Instead, whitelist and blacklist should be handled by the thing that
2444 Instead, whitelist and blacklist should be handled by the thing that
2440 populates the TestSuite with tests. They are present to preserve
2445 populates the TestSuite with tests. They are present to preserve
2441 backwards compatible behavior which reports skipped tests as part
2446 backwards compatible behavior which reports skipped tests as part
2442 of the results.
2447 of the results.
2443
2448
2444 keywords denotes key words that will be used to filter which tests
2449 keywords denotes key words that will be used to filter which tests
2445 to execute. This arguably belongs outside of TestSuite.
2450 to execute. This arguably belongs outside of TestSuite.
2446
2451
2447 loop denotes whether to loop over tests forever.
2452 loop denotes whether to loop over tests forever.
2448 """
2453 """
2449 super(TestSuite, self).__init__(*args, **kwargs)
2454 super(TestSuite, self).__init__(*args, **kwargs)
2450
2455
2451 self._jobs = jobs
2456 self._jobs = jobs
2452 self._whitelist = whitelist
2457 self._whitelist = whitelist
2453 self._blacklist = blacklist
2458 self._blacklist = blacklist
2454 self._keywords = keywords
2459 self._keywords = keywords
2455 self._loop = loop
2460 self._loop = loop
2456 self._runs_per_test = runs_per_test
2461 self._runs_per_test = runs_per_test
2457 self._loadtest = loadtest
2462 self._loadtest = loadtest
2458 self._showchannels = showchannels
2463 self._showchannels = showchannels
2459
2464
2460 def run(self, result):
2465 def run(self, result):
2461 # We have a number of filters that need to be applied. We do this
2466 # We have a number of filters that need to be applied. We do this
2462 # here instead of inside Test because it makes the running logic for
2467 # here instead of inside Test because it makes the running logic for
2463 # Test simpler.
2468 # Test simpler.
2464 tests = []
2469 tests = []
2465 num_tests = [0]
2470 num_tests = [0]
2466 for test in self._tests:
2471 for test in self._tests:
2467
2472
2468 def get():
2473 def get():
2469 num_tests[0] += 1
2474 num_tests[0] += 1
2470 if getattr(test, 'should_reload', False):
2475 if getattr(test, 'should_reload', False):
2471 return self._loadtest(test, num_tests[0])
2476 return self._loadtest(test, num_tests[0])
2472 return test
2477 return test
2473
2478
2474 if not os.path.exists(test.path):
2479 if not os.path.exists(test.path):
2475 result.addSkip(test, "Doesn't exist")
2480 result.addSkip(test, "Doesn't exist")
2476 continue
2481 continue
2477
2482
2478 is_whitelisted = self._whitelist and (
2483 is_whitelisted = self._whitelist and (
2479 test.relpath in self._whitelist or test.bname in self._whitelist
2484 test.relpath in self._whitelist or test.bname in self._whitelist
2480 )
2485 )
2481 if not is_whitelisted:
2486 if not is_whitelisted:
2482 is_blacklisted = self._blacklist and (
2487 is_blacklisted = self._blacklist and (
2483 test.relpath in self._blacklist
2488 test.relpath in self._blacklist
2484 or test.bname in self._blacklist
2489 or test.bname in self._blacklist
2485 )
2490 )
2486 if is_blacklisted:
2491 if is_blacklisted:
2487 result.addSkip(test, 'blacklisted')
2492 result.addSkip(test, 'blacklisted')
2488 continue
2493 continue
2489 if self._keywords:
2494 if self._keywords:
2490 with open(test.path, 'rb') as f:
2495 with open(test.path, 'rb') as f:
2491 t = f.read().lower() + test.bname.lower()
2496 t = f.read().lower() + test.bname.lower()
2492 ignored = False
2497 ignored = False
2493 for k in self._keywords.lower().split():
2498 for k in self._keywords.lower().split():
2494 if k not in t:
2499 if k not in t:
2495 result.addIgnore(test, "doesn't match keyword")
2500 result.addIgnore(test, "doesn't match keyword")
2496 ignored = True
2501 ignored = True
2497 break
2502 break
2498
2503
2499 if ignored:
2504 if ignored:
2500 continue
2505 continue
2501 for _ in xrange(self._runs_per_test):
2506 for _ in xrange(self._runs_per_test):
2502 tests.append(get())
2507 tests.append(get())
2503
2508
2504 runtests = list(tests)
2509 runtests = list(tests)
2505 done = queue.Queue()
2510 done = queue.Queue()
2506 running = 0
2511 running = 0
2507
2512
2508 channels_lock = threading.Lock()
2513 channels_lock = threading.Lock()
2509 channels = [""] * self._jobs
2514 channels = [""] * self._jobs
2510
2515
2511 def job(test, result):
2516 def job(test, result):
2512 with channels_lock:
2517 with channels_lock:
2513 for n, v in enumerate(channels):
2518 for n, v in enumerate(channels):
2514 if not v:
2519 if not v:
2515 channel = n
2520 channel = n
2516 break
2521 break
2517 else:
2522 else:
2518 raise ValueError('Could not find output channel')
2523 raise ValueError('Could not find output channel')
2519 channels[channel] = "=" + test.name[5:].split(".")[0]
2524 channels[channel] = "=" + test.name[5:].split(".")[0]
2520
2525
2521 r = None
2526 r = None
2522 try:
2527 try:
2523 test(result)
2528 test(result)
2524 except KeyboardInterrupt:
2529 except KeyboardInterrupt:
2525 pass
2530 pass
2526 except: # re-raises
2531 except: # re-raises
2527 r = ('!', test, 'run-test raised an error, see traceback')
2532 r = ('!', test, 'run-test raised an error, see traceback')
2528 raise
2533 raise
2529 finally:
2534 finally:
2530 try:
2535 try:
2531 channels[channel] = ''
2536 channels[channel] = ''
2532 except IndexError:
2537 except IndexError:
2533 pass
2538 pass
2534 done.put(r)
2539 done.put(r)
2535
2540
2536 def stat():
2541 def stat():
2537 count = 0
2542 count = 0
2538 while channels:
2543 while channels:
2539 d = '\n%03s ' % count
2544 d = '\n%03s ' % count
2540 for n, v in enumerate(channels):
2545 for n, v in enumerate(channels):
2541 if v:
2546 if v:
2542 d += v[0]
2547 d += v[0]
2543 channels[n] = v[1:] or '.'
2548 channels[n] = v[1:] or '.'
2544 else:
2549 else:
2545 d += ' '
2550 d += ' '
2546 d += ' '
2551 d += ' '
2547 with iolock:
2552 with iolock:
2548 sys.stdout.write(d + ' ')
2553 sys.stdout.write(d + ' ')
2549 sys.stdout.flush()
2554 sys.stdout.flush()
2550 for x in xrange(10):
2555 for x in xrange(10):
2551 if channels:
2556 if channels:
2552 time.sleep(0.1)
2557 time.sleep(0.1)
2553 count += 1
2558 count += 1
2554
2559
2555 stoppedearly = False
2560 stoppedearly = False
2556
2561
2557 if self._showchannels:
2562 if self._showchannels:
2558 statthread = threading.Thread(target=stat, name="stat")
2563 statthread = threading.Thread(target=stat, name="stat")
2559 statthread.start()
2564 statthread.start()
2560
2565
2561 try:
2566 try:
2562 while tests or running:
2567 while tests or running:
2563 if not done.empty() or running == self._jobs or not tests:
2568 if not done.empty() or running == self._jobs or not tests:
2564 try:
2569 try:
2565 done.get(True, 1)
2570 done.get(True, 1)
2566 running -= 1
2571 running -= 1
2567 if result and result.shouldStop:
2572 if result and result.shouldStop:
2568 stoppedearly = True
2573 stoppedearly = True
2569 break
2574 break
2570 except queue.Empty:
2575 except queue.Empty:
2571 continue
2576 continue
2572 if tests and not running == self._jobs:
2577 if tests and not running == self._jobs:
2573 test = tests.pop(0)
2578 test = tests.pop(0)
2574 if self._loop:
2579 if self._loop:
2575 if getattr(test, 'should_reload', False):
2580 if getattr(test, 'should_reload', False):
2576 num_tests[0] += 1
2581 num_tests[0] += 1
2577 tests.append(self._loadtest(test, num_tests[0]))
2582 tests.append(self._loadtest(test, num_tests[0]))
2578 else:
2583 else:
2579 tests.append(test)
2584 tests.append(test)
2580 if self._jobs == 1:
2585 if self._jobs == 1:
2581 job(test, result)
2586 job(test, result)
2582 else:
2587 else:
2583 t = threading.Thread(
2588 t = threading.Thread(
2584 target=job, name=test.name, args=(test, result)
2589 target=job, name=test.name, args=(test, result)
2585 )
2590 )
2586 t.start()
2591 t.start()
2587 running += 1
2592 running += 1
2588
2593
2589 # If we stop early we still need to wait on started tests to
2594 # If we stop early we still need to wait on started tests to
2590 # finish. Otherwise, there is a race between the test completing
2595 # finish. Otherwise, there is a race between the test completing
2591 # and the test's cleanup code running. This could result in the
2596 # and the test's cleanup code running. This could result in the
2592 # test reporting incorrect.
2597 # test reporting incorrect.
2593 if stoppedearly:
2598 if stoppedearly:
2594 while running:
2599 while running:
2595 try:
2600 try:
2596 done.get(True, 1)
2601 done.get(True, 1)
2597 running -= 1
2602 running -= 1
2598 except queue.Empty:
2603 except queue.Empty:
2599 continue
2604 continue
2600 except KeyboardInterrupt:
2605 except KeyboardInterrupt:
2601 for test in runtests:
2606 for test in runtests:
2602 test.abort()
2607 test.abort()
2603
2608
2604 channels = []
2609 channels = []
2605
2610
2606 return result
2611 return result
2607
2612
2608
2613
2609 # Save the most recent 5 wall-clock runtimes of each test to a
2614 # Save the most recent 5 wall-clock runtimes of each test to a
2610 # human-readable text file named .testtimes. Tests are sorted
2615 # human-readable text file named .testtimes. Tests are sorted
2611 # alphabetically, while times for each test are listed from oldest to
2616 # alphabetically, while times for each test are listed from oldest to
2612 # newest.
2617 # newest.
2613
2618
2614
2619
2615 def loadtimes(outputdir):
2620 def loadtimes(outputdir):
2616 times = []
2621 times = []
2617 try:
2622 try:
2618 with open(os.path.join(outputdir, b'.testtimes')) as fp:
2623 with open(os.path.join(outputdir, b'.testtimes')) as fp:
2619 for line in fp:
2624 for line in fp:
2620 m = re.match('(.*?) ([0-9. ]+)', line)
2625 m = re.match('(.*?) ([0-9. ]+)', line)
2621 times.append(
2626 times.append(
2622 (m.group(1), [float(t) for t in m.group(2).split()])
2627 (m.group(1), [float(t) for t in m.group(2).split()])
2623 )
2628 )
2624 except IOError as err:
2629 except IOError as err:
2625 if err.errno != errno.ENOENT:
2630 if err.errno != errno.ENOENT:
2626 raise
2631 raise
2627 return times
2632 return times
2628
2633
2629
2634
2630 def savetimes(outputdir, result):
2635 def savetimes(outputdir, result):
2631 saved = dict(loadtimes(outputdir))
2636 saved = dict(loadtimes(outputdir))
2632 maxruns = 5
2637 maxruns = 5
2633 skipped = {str(t[0]) for t in result.skipped}
2638 skipped = {str(t[0]) for t in result.skipped}
2634 for tdata in result.times:
2639 for tdata in result.times:
2635 test, real = tdata[0], tdata[3]
2640 test, real = tdata[0], tdata[3]
2636 if test not in skipped:
2641 if test not in skipped:
2637 ts = saved.setdefault(test, [])
2642 ts = saved.setdefault(test, [])
2638 ts.append(real)
2643 ts.append(real)
2639 ts[:] = ts[-maxruns:]
2644 ts[:] = ts[-maxruns:]
2640
2645
2641 fd, tmpname = tempfile.mkstemp(
2646 fd, tmpname = tempfile.mkstemp(
2642 prefix=b'.testtimes', dir=outputdir, text=True
2647 prefix=b'.testtimes', dir=outputdir, text=True
2643 )
2648 )
2644 with os.fdopen(fd, 'w') as fp:
2649 with os.fdopen(fd, 'w') as fp:
2645 for name, ts in sorted(saved.items()):
2650 for name, ts in sorted(saved.items()):
2646 fp.write('%s %s\n' % (name, ' '.join(['%.3f' % (t,) for t in ts])))
2651 fp.write('%s %s\n' % (name, ' '.join(['%.3f' % (t,) for t in ts])))
2647 timepath = os.path.join(outputdir, b'.testtimes')
2652 timepath = os.path.join(outputdir, b'.testtimes')
2648 try:
2653 try:
2649 os.unlink(timepath)
2654 os.unlink(timepath)
2650 except OSError:
2655 except OSError:
2651 pass
2656 pass
2652 try:
2657 try:
2653 os.rename(tmpname, timepath)
2658 os.rename(tmpname, timepath)
2654 except OSError:
2659 except OSError:
2655 pass
2660 pass
2656
2661
2657
2662
2658 class TextTestRunner(unittest.TextTestRunner):
2663 class TextTestRunner(unittest.TextTestRunner):
2659 """Custom unittest test runner that uses appropriate settings."""
2664 """Custom unittest test runner that uses appropriate settings."""
2660
2665
2661 def __init__(self, runner, *args, **kwargs):
2666 def __init__(self, runner, *args, **kwargs):
2662 super(TextTestRunner, self).__init__(*args, **kwargs)
2667 super(TextTestRunner, self).__init__(*args, **kwargs)
2663
2668
2664 self._runner = runner
2669 self._runner = runner
2665
2670
2666 self._result = getTestResult()(
2671 self._result = getTestResult()(
2667 self._runner.options, self.stream, self.descriptions, self.verbosity
2672 self._runner.options, self.stream, self.descriptions, self.verbosity
2668 )
2673 )
2669
2674
2670 def listtests(self, test):
2675 def listtests(self, test):
2671 test = sorted(test, key=lambda t: t.name)
2676 test = sorted(test, key=lambda t: t.name)
2672
2677
2673 self._result.onStart(test)
2678 self._result.onStart(test)
2674
2679
2675 for t in test:
2680 for t in test:
2676 print(t.name)
2681 print(t.name)
2677 self._result.addSuccess(t)
2682 self._result.addSuccess(t)
2678
2683
2679 if self._runner.options.xunit:
2684 if self._runner.options.xunit:
2680 with open(self._runner.options.xunit, "wb") as xuf:
2685 with open(self._runner.options.xunit, "wb") as xuf:
2681 self._writexunit(self._result, xuf)
2686 self._writexunit(self._result, xuf)
2682
2687
2683 if self._runner.options.json:
2688 if self._runner.options.json:
2684 jsonpath = os.path.join(self._runner._outputdir, b'report.json')
2689 jsonpath = os.path.join(self._runner._outputdir, b'report.json')
2685 with open(jsonpath, 'w') as fp:
2690 with open(jsonpath, 'w') as fp:
2686 self._writejson(self._result, fp)
2691 self._writejson(self._result, fp)
2687
2692
2688 return self._result
2693 return self._result
2689
2694
2690 def run(self, test):
2695 def run(self, test):
2691 self._result.onStart(test)
2696 self._result.onStart(test)
2692 test(self._result)
2697 test(self._result)
2693
2698
2694 failed = len(self._result.failures)
2699 failed = len(self._result.failures)
2695 skipped = len(self._result.skipped)
2700 skipped = len(self._result.skipped)
2696 ignored = len(self._result.ignored)
2701 ignored = len(self._result.ignored)
2697
2702
2698 with iolock:
2703 with iolock:
2699 self.stream.writeln('')
2704 self.stream.writeln('')
2700
2705
2701 if not self._runner.options.noskips:
2706 if not self._runner.options.noskips:
2702 for test, msg in sorted(
2707 for test, msg in sorted(
2703 self._result.skipped, key=lambda s: s[0].name
2708 self._result.skipped, key=lambda s: s[0].name
2704 ):
2709 ):
2705 formatted = 'Skipped %s: %s\n' % (test.name, msg)
2710 formatted = 'Skipped %s: %s\n' % (test.name, msg)
2706 msg = highlightmsg(formatted, self._result.color)
2711 msg = highlightmsg(formatted, self._result.color)
2707 self.stream.write(msg)
2712 self.stream.write(msg)
2708 for test, msg in sorted(
2713 for test, msg in sorted(
2709 self._result.failures, key=lambda f: f[0].name
2714 self._result.failures, key=lambda f: f[0].name
2710 ):
2715 ):
2711 formatted = 'Failed %s: %s\n' % (test.name, msg)
2716 formatted = 'Failed %s: %s\n' % (test.name, msg)
2712 self.stream.write(highlightmsg(formatted, self._result.color))
2717 self.stream.write(highlightmsg(formatted, self._result.color))
2713 for test, msg in sorted(
2718 for test, msg in sorted(
2714 self._result.errors, key=lambda e: e[0].name
2719 self._result.errors, key=lambda e: e[0].name
2715 ):
2720 ):
2716 self.stream.writeln('Errored %s: %s' % (test.name, msg))
2721 self.stream.writeln('Errored %s: %s' % (test.name, msg))
2717
2722
2718 if self._runner.options.xunit:
2723 if self._runner.options.xunit:
2719 with open(self._runner.options.xunit, "wb") as xuf:
2724 with open(self._runner.options.xunit, "wb") as xuf:
2720 self._writexunit(self._result, xuf)
2725 self._writexunit(self._result, xuf)
2721
2726
2722 if self._runner.options.json:
2727 if self._runner.options.json:
2723 jsonpath = os.path.join(self._runner._outputdir, b'report.json')
2728 jsonpath = os.path.join(self._runner._outputdir, b'report.json')
2724 with open(jsonpath, 'w') as fp:
2729 with open(jsonpath, 'w') as fp:
2725 self._writejson(self._result, fp)
2730 self._writejson(self._result, fp)
2726
2731
2727 self._runner._checkhglib('Tested')
2732 self._runner._checkhglib('Tested')
2728
2733
2729 savetimes(self._runner._outputdir, self._result)
2734 savetimes(self._runner._outputdir, self._result)
2730
2735
2731 if failed and self._runner.options.known_good_rev:
2736 if failed and self._runner.options.known_good_rev:
2732 self._bisecttests(t for t, m in self._result.failures)
2737 self._bisecttests(t for t, m in self._result.failures)
2733 self.stream.writeln(
2738 self.stream.writeln(
2734 '# Ran %d tests, %d skipped, %d failed.'
2739 '# Ran %d tests, %d skipped, %d failed.'
2735 % (self._result.testsRun, skipped + ignored, failed)
2740 % (self._result.testsRun, skipped + ignored, failed)
2736 )
2741 )
2737 if failed:
2742 if failed:
2738 self.stream.writeln(
2743 self.stream.writeln(
2739 'python hash seed: %s' % os.environ['PYTHONHASHSEED']
2744 'python hash seed: %s' % os.environ['PYTHONHASHSEED']
2740 )
2745 )
2741 if self._runner.options.time:
2746 if self._runner.options.time:
2742 self.printtimes(self._result.times)
2747 self.printtimes(self._result.times)
2743
2748
2744 if self._runner.options.exceptions:
2749 if self._runner.options.exceptions:
2745 exceptions = aggregateexceptions(
2750 exceptions = aggregateexceptions(
2746 os.path.join(self._runner._outputdir, b'exceptions')
2751 os.path.join(self._runner._outputdir, b'exceptions')
2747 )
2752 )
2748
2753
2749 self.stream.writeln('Exceptions Report:')
2754 self.stream.writeln('Exceptions Report:')
2750 self.stream.writeln(
2755 self.stream.writeln(
2751 '%d total from %d frames'
2756 '%d total from %d frames'
2752 % (exceptions['total'], len(exceptions['exceptioncounts']))
2757 % (exceptions['total'], len(exceptions['exceptioncounts']))
2753 )
2758 )
2754 combined = exceptions['combined']
2759 combined = exceptions['combined']
2755 for key in sorted(combined, key=combined.get, reverse=True):
2760 for key in sorted(combined, key=combined.get, reverse=True):
2756 frame, line, exc = key
2761 frame, line, exc = key
2757 totalcount, testcount, leastcount, leasttest = combined[key]
2762 totalcount, testcount, leastcount, leasttest = combined[key]
2758
2763
2759 self.stream.writeln(
2764 self.stream.writeln(
2760 '%d (%d tests)\t%s: %s (%s - %d total)'
2765 '%d (%d tests)\t%s: %s (%s - %d total)'
2761 % (
2766 % (
2762 totalcount,
2767 totalcount,
2763 testcount,
2768 testcount,
2764 frame,
2769 frame,
2765 exc,
2770 exc,
2766 leasttest,
2771 leasttest,
2767 leastcount,
2772 leastcount,
2768 )
2773 )
2769 )
2774 )
2770
2775
2771 self.stream.flush()
2776 self.stream.flush()
2772
2777
2773 return self._result
2778 return self._result
2774
2779
2775 def _bisecttests(self, tests):
2780 def _bisecttests(self, tests):
2776 bisectcmd = ['hg', 'bisect']
2781 bisectcmd = ['hg', 'bisect']
2777 bisectrepo = self._runner.options.bisect_repo
2782 bisectrepo = self._runner.options.bisect_repo
2778 if bisectrepo:
2783 if bisectrepo:
2779 bisectcmd.extend(['-R', os.path.abspath(bisectrepo)])
2784 bisectcmd.extend(['-R', os.path.abspath(bisectrepo)])
2780
2785
2781 def pread(args):
2786 def pread(args):
2782 env = os.environ.copy()
2787 env = os.environ.copy()
2783 env['HGPLAIN'] = '1'
2788 env['HGPLAIN'] = '1'
2784 p = subprocess.Popen(
2789 p = subprocess.Popen(
2785 args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=env
2790 args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=env
2786 )
2791 )
2787 data = p.stdout.read()
2792 data = p.stdout.read()
2788 p.wait()
2793 p.wait()
2789 return data
2794 return data
2790
2795
2791 for test in tests:
2796 for test in tests:
2792 pread(bisectcmd + ['--reset']),
2797 pread(bisectcmd + ['--reset']),
2793 pread(bisectcmd + ['--bad', '.'])
2798 pread(bisectcmd + ['--bad', '.'])
2794 pread(bisectcmd + ['--good', self._runner.options.known_good_rev])
2799 pread(bisectcmd + ['--good', self._runner.options.known_good_rev])
2795 # TODO: we probably need to forward more options
2800 # TODO: we probably need to forward more options
2796 # that alter hg's behavior inside the tests.
2801 # that alter hg's behavior inside the tests.
2797 opts = ''
2802 opts = ''
2798 withhg = self._runner.options.with_hg
2803 withhg = self._runner.options.with_hg
2799 if withhg:
2804 if withhg:
2800 opts += ' --with-hg=%s ' % shellquote(_bytes2sys(withhg))
2805 opts += ' --with-hg=%s ' % shellquote(_bytes2sys(withhg))
2801 rtc = '%s %s %s %s' % (sysexecutable, sys.argv[0], opts, test)
2806 rtc = '%s %s %s %s' % (sysexecutable, sys.argv[0], opts, test)
2802 data = pread(bisectcmd + ['--command', rtc])
2807 data = pread(bisectcmd + ['--command', rtc])
2803 m = re.search(
2808 m = re.search(
2804 (
2809 (
2805 br'\nThe first (?P<goodbad>bad|good) revision '
2810 br'\nThe first (?P<goodbad>bad|good) revision '
2806 br'is:\nchangeset: +\d+:(?P<node>[a-f0-9]+)\n.*\n'
2811 br'is:\nchangeset: +\d+:(?P<node>[a-f0-9]+)\n.*\n'
2807 br'summary: +(?P<summary>[^\n]+)\n'
2812 br'summary: +(?P<summary>[^\n]+)\n'
2808 ),
2813 ),
2809 data,
2814 data,
2810 (re.MULTILINE | re.DOTALL),
2815 (re.MULTILINE | re.DOTALL),
2811 )
2816 )
2812 if m is None:
2817 if m is None:
2813 self.stream.writeln(
2818 self.stream.writeln(
2814 'Failed to identify failure point for %s' % test
2819 'Failed to identify failure point for %s' % test
2815 )
2820 )
2816 continue
2821 continue
2817 dat = m.groupdict()
2822 dat = m.groupdict()
2818 verb = 'broken' if dat['goodbad'] == b'bad' else 'fixed'
2823 verb = 'broken' if dat['goodbad'] == b'bad' else 'fixed'
2819 self.stream.writeln(
2824 self.stream.writeln(
2820 '%s %s by %s (%s)'
2825 '%s %s by %s (%s)'
2821 % (
2826 % (
2822 test,
2827 test,
2823 verb,
2828 verb,
2824 dat['node'].decode('ascii'),
2829 dat['node'].decode('ascii'),
2825 dat['summary'].decode('utf8', 'ignore'),
2830 dat['summary'].decode('utf8', 'ignore'),
2826 )
2831 )
2827 )
2832 )
2828
2833
2829 def printtimes(self, times):
2834 def printtimes(self, times):
2830 # iolock held by run
2835 # iolock held by run
2831 self.stream.writeln('# Producing time report')
2836 self.stream.writeln('# Producing time report')
2832 times.sort(key=lambda t: (t[3]))
2837 times.sort(key=lambda t: (t[3]))
2833 cols = '%7.3f %7.3f %7.3f %7.3f %7.3f %s'
2838 cols = '%7.3f %7.3f %7.3f %7.3f %7.3f %s'
2834 self.stream.writeln(
2839 self.stream.writeln(
2835 '%-7s %-7s %-7s %-7s %-7s %s'
2840 '%-7s %-7s %-7s %-7s %-7s %s'
2836 % ('start', 'end', 'cuser', 'csys', 'real', 'Test')
2841 % ('start', 'end', 'cuser', 'csys', 'real', 'Test')
2837 )
2842 )
2838 for tdata in times:
2843 for tdata in times:
2839 test = tdata[0]
2844 test = tdata[0]
2840 cuser, csys, real, start, end = tdata[1:6]
2845 cuser, csys, real, start, end = tdata[1:6]
2841 self.stream.writeln(cols % (start, end, cuser, csys, real, test))
2846 self.stream.writeln(cols % (start, end, cuser, csys, real, test))
2842
2847
2843 @staticmethod
2848 @staticmethod
2844 def _writexunit(result, outf):
2849 def _writexunit(result, outf):
2845 # See http://llg.cubic.org/docs/junit/ for a reference.
2850 # See http://llg.cubic.org/docs/junit/ for a reference.
2846 timesd = {t[0]: t[3] for t in result.times}
2851 timesd = {t[0]: t[3] for t in result.times}
2847 doc = minidom.Document()
2852 doc = minidom.Document()
2848 s = doc.createElement('testsuite')
2853 s = doc.createElement('testsuite')
2849 s.setAttribute('errors', "0") # TODO
2854 s.setAttribute('errors', "0") # TODO
2850 s.setAttribute('failures', str(len(result.failures)))
2855 s.setAttribute('failures', str(len(result.failures)))
2851 s.setAttribute('name', 'run-tests')
2856 s.setAttribute('name', 'run-tests')
2852 s.setAttribute(
2857 s.setAttribute(
2853 'skipped', str(len(result.skipped) + len(result.ignored))
2858 'skipped', str(len(result.skipped) + len(result.ignored))
2854 )
2859 )
2855 s.setAttribute('tests', str(result.testsRun))
2860 s.setAttribute('tests', str(result.testsRun))
2856 doc.appendChild(s)
2861 doc.appendChild(s)
2857 for tc in result.successes:
2862 for tc in result.successes:
2858 t = doc.createElement('testcase')
2863 t = doc.createElement('testcase')
2859 t.setAttribute('name', tc.name)
2864 t.setAttribute('name', tc.name)
2860 tctime = timesd.get(tc.name)
2865 tctime = timesd.get(tc.name)
2861 if tctime is not None:
2866 if tctime is not None:
2862 t.setAttribute('time', '%.3f' % tctime)
2867 t.setAttribute('time', '%.3f' % tctime)
2863 s.appendChild(t)
2868 s.appendChild(t)
2864 for tc, err in sorted(result.faildata.items()):
2869 for tc, err in sorted(result.faildata.items()):
2865 t = doc.createElement('testcase')
2870 t = doc.createElement('testcase')
2866 t.setAttribute('name', tc)
2871 t.setAttribute('name', tc)
2867 tctime = timesd.get(tc)
2872 tctime = timesd.get(tc)
2868 if tctime is not None:
2873 if tctime is not None:
2869 t.setAttribute('time', '%.3f' % tctime)
2874 t.setAttribute('time', '%.3f' % tctime)
2870 # createCDATASection expects a unicode or it will
2875 # createCDATASection expects a unicode or it will
2871 # convert using default conversion rules, which will
2876 # convert using default conversion rules, which will
2872 # fail if string isn't ASCII.
2877 # fail if string isn't ASCII.
2873 err = cdatasafe(err).decode('utf-8', 'replace')
2878 err = cdatasafe(err).decode('utf-8', 'replace')
2874 cd = doc.createCDATASection(err)
2879 cd = doc.createCDATASection(err)
2875 # Use 'failure' here instead of 'error' to match errors = 0,
2880 # Use 'failure' here instead of 'error' to match errors = 0,
2876 # failures = len(result.failures) in the testsuite element.
2881 # failures = len(result.failures) in the testsuite element.
2877 failelem = doc.createElement('failure')
2882 failelem = doc.createElement('failure')
2878 failelem.setAttribute('message', 'output changed')
2883 failelem.setAttribute('message', 'output changed')
2879 failelem.setAttribute('type', 'output-mismatch')
2884 failelem.setAttribute('type', 'output-mismatch')
2880 failelem.appendChild(cd)
2885 failelem.appendChild(cd)
2881 t.appendChild(failelem)
2886 t.appendChild(failelem)
2882 s.appendChild(t)
2887 s.appendChild(t)
2883 for tc, message in result.skipped:
2888 for tc, message in result.skipped:
2884 # According to the schema, 'skipped' has no attributes. So store
2889 # According to the schema, 'skipped' has no attributes. So store
2885 # the skip message as a text node instead.
2890 # the skip message as a text node instead.
2886 t = doc.createElement('testcase')
2891 t = doc.createElement('testcase')
2887 t.setAttribute('name', tc.name)
2892 t.setAttribute('name', tc.name)
2888 binmessage = message.encode('utf-8')
2893 binmessage = message.encode('utf-8')
2889 message = cdatasafe(binmessage).decode('utf-8', 'replace')
2894 message = cdatasafe(binmessage).decode('utf-8', 'replace')
2890 cd = doc.createCDATASection(message)
2895 cd = doc.createCDATASection(message)
2891 skipelem = doc.createElement('skipped')
2896 skipelem = doc.createElement('skipped')
2892 skipelem.appendChild(cd)
2897 skipelem.appendChild(cd)
2893 t.appendChild(skipelem)
2898 t.appendChild(skipelem)
2894 s.appendChild(t)
2899 s.appendChild(t)
2895 outf.write(doc.toprettyxml(indent=' ', encoding='utf-8'))
2900 outf.write(doc.toprettyxml(indent=' ', encoding='utf-8'))
2896
2901
2897 @staticmethod
2902 @staticmethod
2898 def _writejson(result, outf):
2903 def _writejson(result, outf):
2899 timesd = {}
2904 timesd = {}
2900 for tdata in result.times:
2905 for tdata in result.times:
2901 test = tdata[0]
2906 test = tdata[0]
2902 timesd[test] = tdata[1:]
2907 timesd[test] = tdata[1:]
2903
2908
2904 outcome = {}
2909 outcome = {}
2905 groups = [
2910 groups = [
2906 ('success', ((tc, None) for tc in result.successes)),
2911 ('success', ((tc, None) for tc in result.successes)),
2907 ('failure', result.failures),
2912 ('failure', result.failures),
2908 ('skip', result.skipped),
2913 ('skip', result.skipped),
2909 ]
2914 ]
2910 for res, testcases in groups:
2915 for res, testcases in groups:
2911 for tc, __ in testcases:
2916 for tc, __ in testcases:
2912 if tc.name in timesd:
2917 if tc.name in timesd:
2913 diff = result.faildata.get(tc.name, b'')
2918 diff = result.faildata.get(tc.name, b'')
2914 try:
2919 try:
2915 diff = diff.decode('unicode_escape')
2920 diff = diff.decode('unicode_escape')
2916 except UnicodeDecodeError as e:
2921 except UnicodeDecodeError as e:
2917 diff = '%r decoding diff, sorry' % e
2922 diff = '%r decoding diff, sorry' % e
2918 tres = {
2923 tres = {
2919 'result': res,
2924 'result': res,
2920 'time': ('%0.3f' % timesd[tc.name][2]),
2925 'time': ('%0.3f' % timesd[tc.name][2]),
2921 'cuser': ('%0.3f' % timesd[tc.name][0]),
2926 'cuser': ('%0.3f' % timesd[tc.name][0]),
2922 'csys': ('%0.3f' % timesd[tc.name][1]),
2927 'csys': ('%0.3f' % timesd[tc.name][1]),
2923 'start': ('%0.3f' % timesd[tc.name][3]),
2928 'start': ('%0.3f' % timesd[tc.name][3]),
2924 'end': ('%0.3f' % timesd[tc.name][4]),
2929 'end': ('%0.3f' % timesd[tc.name][4]),
2925 'diff': diff,
2930 'diff': diff,
2926 }
2931 }
2927 else:
2932 else:
2928 # blacklisted test
2933 # blacklisted test
2929 tres = {'result': res}
2934 tres = {'result': res}
2930
2935
2931 outcome[tc.name] = tres
2936 outcome[tc.name] = tres
2932 jsonout = json.dumps(
2937 jsonout = json.dumps(
2933 outcome, sort_keys=True, indent=4, separators=(',', ': ')
2938 outcome, sort_keys=True, indent=4, separators=(',', ': ')
2934 )
2939 )
2935 outf.writelines(("testreport =", jsonout))
2940 outf.writelines(("testreport =", jsonout))
2936
2941
2937
2942
2938 def sorttests(testdescs, previoustimes, shuffle=False):
2943 def sorttests(testdescs, previoustimes, shuffle=False):
2939 """Do an in-place sort of tests."""
2944 """Do an in-place sort of tests."""
2940 if shuffle:
2945 if shuffle:
2941 random.shuffle(testdescs)
2946 random.shuffle(testdescs)
2942 return
2947 return
2943
2948
2944 if previoustimes:
2949 if previoustimes:
2945
2950
2946 def sortkey(f):
2951 def sortkey(f):
2947 f = f['path']
2952 f = f['path']
2948 if f in previoustimes:
2953 if f in previoustimes:
2949 # Use most recent time as estimate
2954 # Use most recent time as estimate
2950 return -(previoustimes[f][-1])
2955 return -(previoustimes[f][-1])
2951 else:
2956 else:
2952 # Default to a rather arbitrary value of 1 second for new tests
2957 # Default to a rather arbitrary value of 1 second for new tests
2953 return -1.0
2958 return -1.0
2954
2959
2955 else:
2960 else:
2956 # keywords for slow tests
2961 # keywords for slow tests
2957 slow = {
2962 slow = {
2958 b'svn': 10,
2963 b'svn': 10,
2959 b'cvs': 10,
2964 b'cvs': 10,
2960 b'hghave': 10,
2965 b'hghave': 10,
2961 b'largefiles-update': 10,
2966 b'largefiles-update': 10,
2962 b'run-tests': 10,
2967 b'run-tests': 10,
2963 b'corruption': 10,
2968 b'corruption': 10,
2964 b'race': 10,
2969 b'race': 10,
2965 b'i18n': 10,
2970 b'i18n': 10,
2966 b'check': 100,
2971 b'check': 100,
2967 b'gendoc': 100,
2972 b'gendoc': 100,
2968 b'contrib-perf': 200,
2973 b'contrib-perf': 200,
2969 b'merge-combination': 100,
2974 b'merge-combination': 100,
2970 }
2975 }
2971 perf = {}
2976 perf = {}
2972
2977
2973 def sortkey(f):
2978 def sortkey(f):
2974 # run largest tests first, as they tend to take the longest
2979 # run largest tests first, as they tend to take the longest
2975 f = f['path']
2980 f = f['path']
2976 try:
2981 try:
2977 return perf[f]
2982 return perf[f]
2978 except KeyError:
2983 except KeyError:
2979 try:
2984 try:
2980 val = -os.stat(f).st_size
2985 val = -os.stat(f).st_size
2981 except OSError as e:
2986 except OSError as e:
2982 if e.errno != errno.ENOENT:
2987 if e.errno != errno.ENOENT:
2983 raise
2988 raise
2984 perf[f] = -1e9 # file does not exist, tell early
2989 perf[f] = -1e9 # file does not exist, tell early
2985 return -1e9
2990 return -1e9
2986 for kw, mul in slow.items():
2991 for kw, mul in slow.items():
2987 if kw in f:
2992 if kw in f:
2988 val *= mul
2993 val *= mul
2989 if f.endswith(b'.py'):
2994 if f.endswith(b'.py'):
2990 val /= 10.0
2995 val /= 10.0
2991 perf[f] = val / 1000.0
2996 perf[f] = val / 1000.0
2992 return perf[f]
2997 return perf[f]
2993
2998
2994 testdescs.sort(key=sortkey)
2999 testdescs.sort(key=sortkey)
2995
3000
2996
3001
2997 class TestRunner:
3002 class TestRunner:
2998 """Holds context for executing tests.
3003 """Holds context for executing tests.
2999
3004
3000 Tests rely on a lot of state. This object holds it for them.
3005 Tests rely on a lot of state. This object holds it for them.
3001 """
3006 """
3002
3007
3003 # Programs required to run tests.
3008 # Programs required to run tests.
3004 REQUIREDTOOLS = [
3009 REQUIREDTOOLS = [
3005 b'diff',
3010 b'diff',
3006 b'grep',
3011 b'grep',
3007 b'unzip',
3012 b'unzip',
3008 b'gunzip',
3013 b'gunzip',
3009 b'bunzip2',
3014 b'bunzip2',
3010 b'sed',
3015 b'sed',
3011 ]
3016 ]
3012
3017
3013 # Maps file extensions to test class.
3018 # Maps file extensions to test class.
3014 TESTTYPES = [
3019 TESTTYPES = [
3015 (b'.py', PythonTest),
3020 (b'.py', PythonTest),
3016 (b'.t', TTest),
3021 (b'.t', TTest),
3017 ]
3022 ]
3018
3023
3019 def __init__(self):
3024 def __init__(self):
3020 self.options = None
3025 self.options = None
3021 self._hgroot = None
3026 self._hgroot = None
3022 self._testdir = None
3027 self._testdir = None
3023 self._outputdir = None
3028 self._outputdir = None
3024 self._hgtmp = None
3029 self._hgtmp = None
3025 self._installdir = None
3030 self._installdir = None
3026 self._bindir = None
3031 self._bindir = None
3027 # a place for run-tests.py to generate executable it needs
3032 # a place for run-tests.py to generate executable it needs
3028 self._custom_bin_dir = None
3033 self._custom_bin_dir = None
3029 self._pythondir = None
3034 self._pythondir = None
3030 # True if we had to infer the pythondir from --with-hg
3035 # True if we had to infer the pythondir from --with-hg
3031 self._pythondir_inferred = False
3036 self._pythondir_inferred = False
3032 self._coveragefile = None
3037 self._coveragefile = None
3033 self._createdfiles = []
3038 self._createdfiles = []
3034 self._hgcommand = None
3039 self._hgcommand = None
3035 self._hgpath = None
3040 self._hgpath = None
3036 self._portoffset = 0
3041 self._portoffset = 0
3037 self._ports = {}
3042 self._ports = {}
3038
3043
3039 def run(self, args, parser=None):
3044 def run(self, args, parser=None):
3040 """Run the test suite."""
3045 """Run the test suite."""
3041 oldmask = os.umask(0o22)
3046 oldmask = os.umask(0o22)
3042 try:
3047 try:
3043 parser = parser or getparser()
3048 parser = parser or getparser()
3044 options = parseargs(args, parser)
3049 options = parseargs(args, parser)
3045 tests = [_sys2bytes(a) for a in options.tests]
3050 tests = [_sys2bytes(a) for a in options.tests]
3046 if options.test_list is not None:
3051 if options.test_list is not None:
3047 for listfile in options.test_list:
3052 for listfile in options.test_list:
3048 with open(listfile, 'rb') as f:
3053 with open(listfile, 'rb') as f:
3049 tests.extend(t for t in f.read().splitlines() if t)
3054 tests.extend(t for t in f.read().splitlines() if t)
3050 self.options = options
3055 self.options = options
3051
3056
3052 self._checktools()
3057 self._checktools()
3053 testdescs = self.findtests(tests)
3058 testdescs = self.findtests(tests)
3054 if options.profile_runner:
3059 if options.profile_runner:
3055 import statprof
3060 import statprof
3056
3061
3057 statprof.start()
3062 statprof.start()
3058 result = self._run(testdescs)
3063 result = self._run(testdescs)
3059 if options.profile_runner:
3064 if options.profile_runner:
3060 statprof.stop()
3065 statprof.stop()
3061 statprof.display()
3066 statprof.display()
3062 return result
3067 return result
3063
3068
3064 finally:
3069 finally:
3065 os.umask(oldmask)
3070 os.umask(oldmask)
3066
3071
3067 def _run(self, testdescs):
3072 def _run(self, testdescs):
3068 testdir = getcwdb()
3073 testdir = getcwdb()
3069 # assume all tests in same folder for now
3074 # assume all tests in same folder for now
3070 if testdescs:
3075 if testdescs:
3071 pathname = os.path.dirname(testdescs[0]['path'])
3076 pathname = os.path.dirname(testdescs[0]['path'])
3072 if pathname:
3077 if pathname:
3073 testdir = os.path.join(testdir, pathname)
3078 testdir = os.path.join(testdir, pathname)
3074 self._testdir = osenvironb[b'TESTDIR'] = testdir
3079 self._testdir = osenvironb[b'TESTDIR'] = testdir
3075 osenvironb[b'TESTDIR_FORWARD_SLASH'] = osenvironb[b'TESTDIR'].replace(
3080 osenvironb[b'TESTDIR_FORWARD_SLASH'] = osenvironb[b'TESTDIR'].replace(
3076 os.sep.encode('ascii'), b'/'
3081 os.sep.encode('ascii'), b'/'
3077 )
3082 )
3078
3083
3079 if self.options.outputdir:
3084 if self.options.outputdir:
3080 self._outputdir = canonpath(_sys2bytes(self.options.outputdir))
3085 self._outputdir = canonpath(_sys2bytes(self.options.outputdir))
3081 else:
3086 else:
3082 self._outputdir = getcwdb()
3087 self._outputdir = getcwdb()
3083 if testdescs and pathname:
3088 if testdescs and pathname:
3084 self._outputdir = os.path.join(self._outputdir, pathname)
3089 self._outputdir = os.path.join(self._outputdir, pathname)
3085 previoustimes = {}
3090 previoustimes = {}
3086 if self.options.order_by_runtime:
3091 if self.options.order_by_runtime:
3087 previoustimes = dict(loadtimes(self._outputdir))
3092 previoustimes = dict(loadtimes(self._outputdir))
3088 sorttests(testdescs, previoustimes, shuffle=self.options.random)
3093 sorttests(testdescs, previoustimes, shuffle=self.options.random)
3089
3094
3090 if 'PYTHONHASHSEED' not in os.environ:
3095 if 'PYTHONHASHSEED' not in os.environ:
3091 # use a random python hash seed all the time
3096 # use a random python hash seed all the time
3092 # we do the randomness ourself to know what seed is used
3097 # we do the randomness ourself to know what seed is used
3093 os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32))
3098 os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32))
3094
3099
3095 # Rayon (Rust crate for multi-threading) will use all logical CPU cores
3100 # Rayon (Rust crate for multi-threading) will use all logical CPU cores
3096 # by default, causing thrashing on high-cpu-count systems.
3101 # by default, causing thrashing on high-cpu-count systems.
3097 # Setting its limit to 3 during tests should still let us uncover
3102 # Setting its limit to 3 during tests should still let us uncover
3098 # multi-threading bugs while keeping the thrashing reasonable.
3103 # multi-threading bugs while keeping the thrashing reasonable.
3099 os.environ.setdefault("RAYON_NUM_THREADS", "3")
3104 os.environ.setdefault("RAYON_NUM_THREADS", "3")
3100
3105
3101 if self.options.tmpdir:
3106 if self.options.tmpdir:
3102 self.options.keep_tmpdir = True
3107 self.options.keep_tmpdir = True
3103 tmpdir = _sys2bytes(self.options.tmpdir)
3108 tmpdir = _sys2bytes(self.options.tmpdir)
3104 if os.path.exists(tmpdir):
3109 if os.path.exists(tmpdir):
3105 # Meaning of tmpdir has changed since 1.3: we used to create
3110 # Meaning of tmpdir has changed since 1.3: we used to create
3106 # HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if
3111 # HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if
3107 # tmpdir already exists.
3112 # tmpdir already exists.
3108 print("error: temp dir %r already exists" % tmpdir)
3113 print("error: temp dir %r already exists" % tmpdir)
3109 return 1
3114 return 1
3110
3115
3111 os.makedirs(tmpdir)
3116 os.makedirs(tmpdir)
3112 else:
3117 else:
3113 d = None
3118 d = None
3114 if WINDOWS:
3119 if WINDOWS:
3115 # without this, we get the default temp dir location, but
3120 # without this, we get the default temp dir location, but
3116 # in all lowercase, which causes troubles with paths (issue3490)
3121 # in all lowercase, which causes troubles with paths (issue3490)
3117 d = osenvironb.get(b'TMP', None)
3122 d = osenvironb.get(b'TMP', None)
3118 tmpdir = tempfile.mkdtemp(b'', b'hgtests.', d)
3123 tmpdir = tempfile.mkdtemp(b'', b'hgtests.', d)
3119
3124
3120 self._hgtmp = osenvironb[b'HGTMP'] = os.path.realpath(tmpdir)
3125 self._hgtmp = osenvironb[b'HGTMP'] = os.path.realpath(tmpdir)
3121
3126
3122 self._custom_bin_dir = os.path.join(self._hgtmp, b'custom-bin')
3127 self._custom_bin_dir = os.path.join(self._hgtmp, b'custom-bin')
3123 os.makedirs(self._custom_bin_dir)
3128 os.makedirs(self._custom_bin_dir)
3124
3129
3125 if self.options.with_hg:
3130 if self.options.with_hg:
3126 self._installdir = None
3131 self._installdir = None
3127 whg = self.options.with_hg
3132 whg = self.options.with_hg
3128 self._bindir = os.path.dirname(os.path.realpath(whg))
3133 self._bindir = os.path.dirname(os.path.realpath(whg))
3129 assert isinstance(self._bindir, bytes)
3134 assert isinstance(self._bindir, bytes)
3130 self._hgcommand = os.path.basename(whg)
3135 self._hgcommand = os.path.basename(whg)
3131
3136
3132 normbin = os.path.normpath(os.path.abspath(whg))
3137 normbin = os.path.normpath(os.path.abspath(whg))
3133 normbin = normbin.replace(_sys2bytes(os.sep), b'/')
3138 normbin = normbin.replace(_sys2bytes(os.sep), b'/')
3134
3139
3135 # Other Python scripts in the test harness need to
3140 # Other Python scripts in the test harness need to
3136 # `import mercurial`. If `hg` is a Python script, we assume
3141 # `import mercurial`. If `hg` is a Python script, we assume
3137 # the Mercurial modules are relative to its path and tell the tests
3142 # the Mercurial modules are relative to its path and tell the tests
3138 # to load Python modules from its directory.
3143 # to load Python modules from its directory.
3139 with open(whg, 'rb') as fh:
3144 with open(whg, 'rb') as fh:
3140 initial = fh.read(1024)
3145 initial = fh.read(1024)
3141
3146
3142 if re.match(b'#!.*python', initial):
3147 if re.match(b'#!.*python', initial):
3143 self._pythondir = self._bindir
3148 self._pythondir = self._bindir
3144 # If it looks like our in-repo Rust binary, use the source root.
3149 # If it looks like our in-repo Rust binary, use the source root.
3145 # This is a bit hacky. But rhg is still not supported outside the
3150 # This is a bit hacky. But rhg is still not supported outside the
3146 # source directory. So until it is, do the simple thing.
3151 # source directory. So until it is, do the simple thing.
3147 elif re.search(b'/rust/target/[^/]+/hg', normbin):
3152 elif re.search(b'/rust/target/[^/]+/hg', normbin):
3148 self._pythondir = os.path.dirname(self._testdir)
3153 self._pythondir = os.path.dirname(self._testdir)
3149 # Fall back to the legacy behavior.
3154 # Fall back to the legacy behavior.
3150 else:
3155 else:
3151 self._pythondir = self._bindir
3156 self._pythondir = self._bindir
3152 self._pythondir_inferred = True
3157 self._pythondir_inferred = True
3153
3158
3154 else:
3159 else:
3155 self._installdir = os.path.join(self._hgtmp, b"install")
3160 self._installdir = os.path.join(self._hgtmp, b"install")
3156 self._bindir = os.path.join(self._installdir, b"bin")
3161 self._bindir = os.path.join(self._installdir, b"bin")
3157 self._hgcommand = b'hg'
3162 self._hgcommand = b'hg'
3158 self._pythondir = os.path.join(self._installdir, b"lib", b"python")
3163 self._pythondir = os.path.join(self._installdir, b"lib", b"python")
3159
3164
3160 # Force the use of hg.exe instead of relying on MSYS to recognize hg is
3165 # Force the use of hg.exe instead of relying on MSYS to recognize hg is
3161 # a python script and feed it to python.exe. Legacy stdio is force
3166 # a python script and feed it to python.exe. Legacy stdio is force
3162 # enabled by hg.exe, and this is a more realistic way to launch hg
3167 # enabled by hg.exe, and this is a more realistic way to launch hg
3163 # anyway.
3168 # anyway.
3164 if WINDOWS and not self._hgcommand.endswith(b'.exe'):
3169 if WINDOWS and not self._hgcommand.endswith(b'.exe'):
3165 self._hgcommand += b'.exe'
3170 self._hgcommand += b'.exe'
3166
3171
3167 real_hg = os.path.join(self._bindir, self._hgcommand)
3172 real_hg = os.path.join(self._bindir, self._hgcommand)
3168 osenvironb[b'HGTEST_REAL_HG'] = real_hg
3173 osenvironb[b'HGTEST_REAL_HG'] = real_hg
3169 # set CHGHG, then replace "hg" command by "chg"
3174 # set CHGHG, then replace "hg" command by "chg"
3170 chgbindir = self._bindir
3175 chgbindir = self._bindir
3171 if self.options.chg or self.options.with_chg:
3176 if self.options.chg or self.options.with_chg:
3172 osenvironb[b'CHG_INSTALLED_AS_HG'] = b'1'
3177 osenvironb[b'CHG_INSTALLED_AS_HG'] = b'1'
3173 osenvironb[b'CHGHG'] = real_hg
3178 osenvironb[b'CHGHG'] = real_hg
3174 else:
3179 else:
3175 # drop flag for hghave
3180 # drop flag for hghave
3176 osenvironb.pop(b'CHG_INSTALLED_AS_HG', None)
3181 osenvironb.pop(b'CHG_INSTALLED_AS_HG', None)
3177 if self.options.chg:
3182 if self.options.chg:
3178 self._hgcommand = b'chg'
3183 self._hgcommand = b'chg'
3179 elif self.options.with_chg:
3184 elif self.options.with_chg:
3180 chgbindir = os.path.dirname(os.path.realpath(self.options.with_chg))
3185 chgbindir = os.path.dirname(os.path.realpath(self.options.with_chg))
3181 self._hgcommand = os.path.basename(self.options.with_chg)
3186 self._hgcommand = os.path.basename(self.options.with_chg)
3182
3187
3183 # configure fallback and replace "hg" command by "rhg"
3188 # configure fallback and replace "hg" command by "rhg"
3184 rhgbindir = self._bindir
3189 rhgbindir = self._bindir
3185 if self.options.rhg or self.options.with_rhg:
3190 if self.options.rhg or self.options.with_rhg:
3186 # Affects hghave.py
3191 # Affects hghave.py
3187 osenvironb[b'RHG_INSTALLED_AS_HG'] = b'1'
3192 osenvironb[b'RHG_INSTALLED_AS_HG'] = b'1'
3188 # Affects configuration. Alternatives would be setting configuration through
3193 # Affects configuration. Alternatives would be setting configuration through
3189 # `$HGRCPATH` but some tests override that, or changing `_hgcommand` to include
3194 # `$HGRCPATH` but some tests override that, or changing `_hgcommand` to include
3190 # `--config` but that disrupts tests that print command lines and check expected
3195 # `--config` but that disrupts tests that print command lines and check expected
3191 # output.
3196 # output.
3192 osenvironb[b'RHG_ON_UNSUPPORTED'] = b'fallback'
3197 osenvironb[b'RHG_ON_UNSUPPORTED'] = b'fallback'
3193 osenvironb[b'RHG_FALLBACK_EXECUTABLE'] = real_hg
3198 osenvironb[b'RHG_FALLBACK_EXECUTABLE'] = real_hg
3194 else:
3199 else:
3195 # drop flag for hghave
3200 # drop flag for hghave
3196 osenvironb.pop(b'RHG_INSTALLED_AS_HG', None)
3201 osenvironb.pop(b'RHG_INSTALLED_AS_HG', None)
3197 if self.options.rhg:
3202 if self.options.rhg:
3198 self._hgcommand = b'rhg'
3203 self._hgcommand = b'rhg'
3199 elif self.options.with_rhg:
3204 elif self.options.with_rhg:
3200 rhgbindir = os.path.dirname(os.path.realpath(self.options.with_rhg))
3205 rhgbindir = os.path.dirname(os.path.realpath(self.options.with_rhg))
3201 self._hgcommand = os.path.basename(self.options.with_rhg)
3206 self._hgcommand = os.path.basename(self.options.with_rhg)
3202
3207
3203 if self.options.pyoxidized:
3208 if self.options.pyoxidized:
3204 testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0])))
3209 testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0])))
3205 reporootdir = os.path.dirname(testdir)
3210 reporootdir = os.path.dirname(testdir)
3206 # XXX we should ideally install stuff instead of using the local build
3211 # XXX we should ideally install stuff instead of using the local build
3207 bin_path = (
3212 bin_path = (
3208 b'build/pyoxidizer/x86_64-pc-windows-msvc/release/app/hg.exe'
3213 b'build/pyoxidizer/x86_64-pc-windows-msvc/release/app/hg.exe'
3209 )
3214 )
3210 full_path = os.path.join(reporootdir, bin_path)
3215 full_path = os.path.join(reporootdir, bin_path)
3211 self._hgcommand = full_path
3216 self._hgcommand = full_path
3212 # Affects hghave.py
3217 # Affects hghave.py
3213 osenvironb[b'PYOXIDIZED_INSTALLED_AS_HG'] = b'1'
3218 osenvironb[b'PYOXIDIZED_INSTALLED_AS_HG'] = b'1'
3214 else:
3219 else:
3215 osenvironb.pop(b'PYOXIDIZED_INSTALLED_AS_HG', None)
3220 osenvironb.pop(b'PYOXIDIZED_INSTALLED_AS_HG', None)
3216
3221
3217 osenvironb[b"BINDIR"] = self._bindir
3222 osenvironb[b"BINDIR"] = self._bindir
3218 osenvironb[b"PYTHON"] = PYTHON
3223 osenvironb[b"PYTHON"] = PYTHON
3219
3224
3220 fileb = _sys2bytes(__file__)
3225 fileb = _sys2bytes(__file__)
3221 runtestdir = os.path.abspath(os.path.dirname(fileb))
3226 runtestdir = os.path.abspath(os.path.dirname(fileb))
3222 osenvironb[b'RUNTESTDIR'] = runtestdir
3227 osenvironb[b'RUNTESTDIR'] = runtestdir
3223 osenvironb[b'RUNTESTDIR_FORWARD_SLASH'] = runtestdir.replace(
3228 osenvironb[b'RUNTESTDIR_FORWARD_SLASH'] = runtestdir.replace(
3224 os.sep.encode('ascii'), b'/'
3229 os.sep.encode('ascii'), b'/'
3225 )
3230 )
3226 sepb = _sys2bytes(os.pathsep)
3231 sepb = _sys2bytes(os.pathsep)
3227 path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb)
3232 path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb)
3228 if os.path.islink(__file__):
3233 if os.path.islink(__file__):
3229 # test helper will likely be at the end of the symlink
3234 # test helper will likely be at the end of the symlink
3230 realfile = os.path.realpath(fileb)
3235 realfile = os.path.realpath(fileb)
3231 realdir = os.path.abspath(os.path.dirname(realfile))
3236 realdir = os.path.abspath(os.path.dirname(realfile))
3232 path.insert(2, realdir)
3237 path.insert(2, realdir)
3233 if chgbindir != self._bindir:
3238 if chgbindir != self._bindir:
3234 path.insert(1, chgbindir)
3239 path.insert(1, chgbindir)
3235 if rhgbindir != self._bindir:
3240 if rhgbindir != self._bindir:
3236 path.insert(1, rhgbindir)
3241 path.insert(1, rhgbindir)
3237 if self._testdir != runtestdir:
3242 if self._testdir != runtestdir:
3238 path = [self._testdir] + path
3243 path = [self._testdir] + path
3239 path = [self._custom_bin_dir] + path
3244 path = [self._custom_bin_dir] + path
3240 osenvironb[b"PATH"] = sepb.join(path)
3245 osenvironb[b"PATH"] = sepb.join(path)
3241
3246
3242 # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
3247 # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
3243 # can run .../tests/run-tests.py test-foo where test-foo
3248 # can run .../tests/run-tests.py test-foo where test-foo
3244 # adds an extension to HGRC. Also include run-test.py directory to
3249 # adds an extension to HGRC. Also include run-test.py directory to
3245 # import modules like heredoctest.
3250 # import modules like heredoctest.
3246 pypath = [self._pythondir, self._testdir, runtestdir]
3251 pypath = [self._pythondir, self._testdir, runtestdir]
3247 # We have to augment PYTHONPATH, rather than simply replacing
3252 # We have to augment PYTHONPATH, rather than simply replacing
3248 # it, in case external libraries are only available via current
3253 # it, in case external libraries are only available via current
3249 # PYTHONPATH. (In particular, the Subversion bindings on OS X
3254 # PYTHONPATH. (In particular, the Subversion bindings on OS X
3250 # are in /opt/subversion.)
3255 # are in /opt/subversion.)
3251 oldpypath = osenvironb.get(IMPL_PATH)
3256 oldpypath = osenvironb.get(IMPL_PATH)
3252 if oldpypath:
3257 if oldpypath:
3253 pypath.append(oldpypath)
3258 pypath.append(oldpypath)
3254 osenvironb[IMPL_PATH] = sepb.join(pypath)
3259 osenvironb[IMPL_PATH] = sepb.join(pypath)
3255
3260
3256 if self.options.pure:
3261 if self.options.pure:
3257 os.environ["HGTEST_RUN_TESTS_PURE"] = "--pure"
3262 os.environ["HGTEST_RUN_TESTS_PURE"] = "--pure"
3258 os.environ["HGMODULEPOLICY"] = "py"
3263 os.environ["HGMODULEPOLICY"] = "py"
3259 if self.options.rust:
3264 if self.options.rust:
3260 os.environ["HGMODULEPOLICY"] = "rust+c"
3265 os.environ["HGMODULEPOLICY"] = "rust+c"
3261 if self.options.no_rust:
3266 if self.options.no_rust:
3262 current_policy = os.environ.get("HGMODULEPOLICY", "")
3267 current_policy = os.environ.get("HGMODULEPOLICY", "")
3263 if current_policy.startswith("rust+"):
3268 if current_policy.startswith("rust+"):
3264 os.environ["HGMODULEPOLICY"] = current_policy[len("rust+") :]
3269 os.environ["HGMODULEPOLICY"] = current_policy[len("rust+") :]
3265 os.environ.pop("HGWITHRUSTEXT", None)
3270 os.environ.pop("HGWITHRUSTEXT", None)
3266
3271
3267 if self.options.allow_slow_tests:
3272 if self.options.allow_slow_tests:
3268 os.environ["HGTEST_SLOW"] = "slow"
3273 os.environ["HGTEST_SLOW"] = "slow"
3269 elif 'HGTEST_SLOW' in os.environ:
3274 elif 'HGTEST_SLOW' in os.environ:
3270 del os.environ['HGTEST_SLOW']
3275 del os.environ['HGTEST_SLOW']
3271
3276
3272 self._coveragefile = os.path.join(self._testdir, b'.coverage')
3277 self._coveragefile = os.path.join(self._testdir, b'.coverage')
3273
3278
3274 if self.options.exceptions:
3279 if self.options.exceptions:
3275 exceptionsdir = os.path.join(self._outputdir, b'exceptions')
3280 exceptionsdir = os.path.join(self._outputdir, b'exceptions')
3276 try:
3281 try:
3277 os.makedirs(exceptionsdir)
3282 os.makedirs(exceptionsdir)
3278 except OSError as e:
3283 except OSError as e:
3279 if e.errno != errno.EEXIST:
3284 if e.errno != errno.EEXIST:
3280 raise
3285 raise
3281
3286
3282 # Remove all existing exception reports.
3287 # Remove all existing exception reports.
3283 for f in os.listdir(exceptionsdir):
3288 for f in os.listdir(exceptionsdir):
3284 os.unlink(os.path.join(exceptionsdir, f))
3289 os.unlink(os.path.join(exceptionsdir, f))
3285
3290
3286 osenvironb[b'HGEXCEPTIONSDIR'] = exceptionsdir
3291 osenvironb[b'HGEXCEPTIONSDIR'] = exceptionsdir
3287 logexceptions = os.path.join(self._testdir, b'logexceptions.py')
3292 logexceptions = os.path.join(self._testdir, b'logexceptions.py')
3288 self.options.extra_config_opt.append(
3293 self.options.extra_config_opt.append(
3289 'extensions.logexceptions=%s' % logexceptions.decode('utf-8')
3294 'extensions.logexceptions=%s' % logexceptions.decode('utf-8')
3290 )
3295 )
3291
3296
3292 vlog("# Using TESTDIR", _bytes2sys(self._testdir))
3297 vlog("# Using TESTDIR", _bytes2sys(self._testdir))
3293 vlog("# Using RUNTESTDIR", _bytes2sys(osenvironb[b'RUNTESTDIR']))
3298 vlog("# Using RUNTESTDIR", _bytes2sys(osenvironb[b'RUNTESTDIR']))
3294 vlog("# Using HGTMP", _bytes2sys(self._hgtmp))
3299 vlog("# Using HGTMP", _bytes2sys(self._hgtmp))
3295 vlog("# Using PATH", os.environ["PATH"])
3300 vlog("# Using PATH", os.environ["PATH"])
3296 vlog(
3301 vlog(
3297 "# Using",
3302 "# Using",
3298 _bytes2sys(IMPL_PATH),
3303 _bytes2sys(IMPL_PATH),
3299 _bytes2sys(osenvironb[IMPL_PATH]),
3304 _bytes2sys(osenvironb[IMPL_PATH]),
3300 )
3305 )
3301 vlog("# Writing to directory", _bytes2sys(self._outputdir))
3306 vlog("# Writing to directory", _bytes2sys(self._outputdir))
3302
3307
3303 try:
3308 try:
3304 return self._runtests(testdescs) or 0
3309 return self._runtests(testdescs) or 0
3305 finally:
3310 finally:
3306 time.sleep(0.1)
3311 time.sleep(0.1)
3307 self._cleanup()
3312 self._cleanup()
3308
3313
3309 def findtests(self, args):
3314 def findtests(self, args):
3310 """Finds possible test files from arguments.
3315 """Finds possible test files from arguments.
3311
3316
3312 If you wish to inject custom tests into the test harness, this would
3317 If you wish to inject custom tests into the test harness, this would
3313 be a good function to monkeypatch or override in a derived class.
3318 be a good function to monkeypatch or override in a derived class.
3314 """
3319 """
3315 if not args:
3320 if not args:
3316 if self.options.changed:
3321 if self.options.changed:
3317 proc = Popen4(
3322 proc = Popen4(
3318 b'hg st --rev "%s" -man0 .'
3323 b'hg st --rev "%s" -man0 .'
3319 % _sys2bytes(self.options.changed),
3324 % _sys2bytes(self.options.changed),
3320 None,
3325 None,
3321 0,
3326 0,
3322 )
3327 )
3323 stdout, stderr = proc.communicate()
3328 stdout, stderr = proc.communicate()
3324 args = stdout.strip(b'\0').split(b'\0')
3329 args = stdout.strip(b'\0').split(b'\0')
3325 else:
3330 else:
3326 args = os.listdir(b'.')
3331 args = os.listdir(b'.')
3327
3332
3328 expanded_args = []
3333 expanded_args = []
3329 for arg in args:
3334 for arg in args:
3330 if os.path.isdir(arg):
3335 if os.path.isdir(arg):
3331 if not arg.endswith(b'/'):
3336 if not arg.endswith(b'/'):
3332 arg += b'/'
3337 arg += b'/'
3333 expanded_args.extend([arg + a for a in os.listdir(arg)])
3338 expanded_args.extend([arg + a for a in os.listdir(arg)])
3334 else:
3339 else:
3335 expanded_args.append(arg)
3340 expanded_args.append(arg)
3336 args = expanded_args
3341 args = expanded_args
3337
3342
3338 testcasepattern = re.compile(br'([\w-]+\.t|py)(?:#([a-zA-Z0-9_\-.#]+))')
3343 testcasepattern = re.compile(br'([\w-]+\.t|py)(?:#([a-zA-Z0-9_\-.#]+))')
3339 tests = []
3344 tests = []
3340 for t in args:
3345 for t in args:
3341 case = []
3346 case = []
3342
3347
3343 if not (
3348 if not (
3344 os.path.basename(t).startswith(b'test-')
3349 os.path.basename(t).startswith(b'test-')
3345 and (t.endswith(b'.py') or t.endswith(b'.t'))
3350 and (t.endswith(b'.py') or t.endswith(b'.t'))
3346 ):
3351 ):
3347
3352
3348 m = testcasepattern.match(os.path.basename(t))
3353 m = testcasepattern.match(os.path.basename(t))
3349 if m is not None:
3354 if m is not None:
3350 t_basename, casestr = m.groups()
3355 t_basename, casestr = m.groups()
3351 t = os.path.join(os.path.dirname(t), t_basename)
3356 t = os.path.join(os.path.dirname(t), t_basename)
3352 if casestr:
3357 if casestr:
3353 case = casestr.split(b'#')
3358 case = casestr.split(b'#')
3354 else:
3359 else:
3355 continue
3360 continue
3356
3361
3357 if t.endswith(b'.t'):
3362 if t.endswith(b'.t'):
3358 # .t file may contain multiple test cases
3363 # .t file may contain multiple test cases
3359 casedimensions = parsettestcases(t)
3364 casedimensions = parsettestcases(t)
3360 if casedimensions:
3365 if casedimensions:
3361 cases = []
3366 cases = []
3362
3367
3363 def addcases(case, casedimensions):
3368 def addcases(case, casedimensions):
3364 if not casedimensions:
3369 if not casedimensions:
3365 cases.append(case)
3370 cases.append(case)
3366 else:
3371 else:
3367 for c in casedimensions[0]:
3372 for c in casedimensions[0]:
3368 addcases(case + [c], casedimensions[1:])
3373 addcases(case + [c], casedimensions[1:])
3369
3374
3370 addcases([], casedimensions)
3375 addcases([], casedimensions)
3371 if case and case in cases:
3376 if case and case in cases:
3372 cases = [case]
3377 cases = [case]
3373 elif case:
3378 elif case:
3374 # Ignore invalid cases
3379 # Ignore invalid cases
3375 cases = []
3380 cases = []
3376 else:
3381 else:
3377 pass
3382 pass
3378 tests += [{'path': t, 'case': c} for c in sorted(cases)]
3383 tests += [{'path': t, 'case': c} for c in sorted(cases)]
3379 else:
3384 else:
3380 tests.append({'path': t})
3385 tests.append({'path': t})
3381 else:
3386 else:
3382 tests.append({'path': t})
3387 tests.append({'path': t})
3383
3388
3384 if self.options.retest:
3389 if self.options.retest:
3385 retest_args = []
3390 retest_args = []
3386 for test in tests:
3391 for test in tests:
3387 errpath = self._geterrpath(test)
3392 errpath = self._geterrpath(test)
3388 if os.path.exists(errpath):
3393 if os.path.exists(errpath):
3389 retest_args.append(test)
3394 retest_args.append(test)
3390 tests = retest_args
3395 tests = retest_args
3391 return tests
3396 return tests
3392
3397
3393 def _runtests(self, testdescs):
3398 def _runtests(self, testdescs):
3394 def _reloadtest(test, i):
3399 def _reloadtest(test, i):
3395 # convert a test back to its description dict
3400 # convert a test back to its description dict
3396 desc = {'path': test.path}
3401 desc = {'path': test.path}
3397 case = getattr(test, '_case', [])
3402 case = getattr(test, '_case', [])
3398 if case:
3403 if case:
3399 desc['case'] = case
3404 desc['case'] = case
3400 return self._gettest(desc, i)
3405 return self._gettest(desc, i)
3401
3406
3402 try:
3407 try:
3403 if self.options.restart:
3408 if self.options.restart:
3404 orig = list(testdescs)
3409 orig = list(testdescs)
3405 while testdescs:
3410 while testdescs:
3406 desc = testdescs[0]
3411 desc = testdescs[0]
3407 errpath = self._geterrpath(desc)
3412 errpath = self._geterrpath(desc)
3408 if os.path.exists(errpath):
3413 if os.path.exists(errpath):
3409 break
3414 break
3410 testdescs.pop(0)
3415 testdescs.pop(0)
3411 if not testdescs:
3416 if not testdescs:
3412 print("running all tests")
3417 print("running all tests")
3413 testdescs = orig
3418 testdescs = orig
3414
3419
3415 tests = [self._gettest(d, i) for i, d in enumerate(testdescs)]
3420 tests = [self._gettest(d, i) for i, d in enumerate(testdescs)]
3416 num_tests = len(tests) * self.options.runs_per_test
3421 num_tests = len(tests) * self.options.runs_per_test
3417
3422
3418 jobs = min(num_tests, self.options.jobs)
3423 jobs = min(num_tests, self.options.jobs)
3419
3424
3420 failed = False
3425 failed = False
3421 kws = self.options.keywords
3426 kws = self.options.keywords
3422 if kws is not None:
3427 if kws is not None:
3423 kws = kws.encode('utf-8')
3428 kws = kws.encode('utf-8')
3424
3429
3425 suite = TestSuite(
3430 suite = TestSuite(
3426 self._testdir,
3431 self._testdir,
3427 jobs=jobs,
3432 jobs=jobs,
3428 whitelist=self.options.whitelisted,
3433 whitelist=self.options.whitelisted,
3429 blacklist=self.options.blacklist,
3434 blacklist=self.options.blacklist,
3430 keywords=kws,
3435 keywords=kws,
3431 loop=self.options.loop,
3436 loop=self.options.loop,
3432 runs_per_test=self.options.runs_per_test,
3437 runs_per_test=self.options.runs_per_test,
3433 showchannels=self.options.showchannels,
3438 showchannels=self.options.showchannels,
3434 tests=tests,
3439 tests=tests,
3435 loadtest=_reloadtest,
3440 loadtest=_reloadtest,
3436 )
3441 )
3437 verbosity = 1
3442 verbosity = 1
3438 if self.options.list_tests:
3443 if self.options.list_tests:
3439 verbosity = 0
3444 verbosity = 0
3440 elif self.options.verbose:
3445 elif self.options.verbose:
3441 verbosity = 2
3446 verbosity = 2
3442 runner = TextTestRunner(self, verbosity=verbosity)
3447 runner = TextTestRunner(self, verbosity=verbosity)
3443
3448
3444 if self.options.list_tests:
3449 if self.options.list_tests:
3445 result = runner.listtests(suite)
3450 result = runner.listtests(suite)
3446 else:
3451 else:
3447 self._usecorrectpython()
3452 self._usecorrectpython()
3448 if self._installdir:
3453 if self._installdir:
3449 self._installhg()
3454 self._installhg()
3450 self._checkhglib("Testing")
3455 self._checkhglib("Testing")
3451 if self.options.chg:
3456 if self.options.chg:
3452 assert self._installdir
3457 assert self._installdir
3453 self._installchg()
3458 self._installchg()
3454 if self.options.rhg:
3459 if self.options.rhg:
3455 assert self._installdir
3460 assert self._installdir
3456 self._installrhg()
3461 self._installrhg()
3457 elif self.options.pyoxidized:
3462 elif self.options.pyoxidized:
3458 self._build_pyoxidized()
3463 self._build_pyoxidized()
3459 self._use_correct_mercurial()
3464 self._use_correct_mercurial()
3460
3465
3461 log(
3466 log(
3462 'running %d tests using %d parallel processes'
3467 'running %d tests using %d parallel processes'
3463 % (num_tests, jobs)
3468 % (num_tests, jobs)
3464 )
3469 )
3465
3470
3466 result = runner.run(suite)
3471 result = runner.run(suite)
3467
3472
3468 if result.failures or result.errors:
3473 if result.failures or result.errors:
3469 failed = True
3474 failed = True
3470
3475
3471 result.onEnd()
3476 result.onEnd()
3472
3477
3473 if self.options.anycoverage:
3478 if self.options.anycoverage:
3474 self._outputcoverage()
3479 self._outputcoverage()
3475 except KeyboardInterrupt:
3480 except KeyboardInterrupt:
3476 failed = True
3481 failed = True
3477 print("\ninterrupted!")
3482 print("\ninterrupted!")
3478
3483
3479 if failed:
3484 if failed:
3480 return 1
3485 return 1
3481
3486
3482 def _geterrpath(self, test):
3487 def _geterrpath(self, test):
3483 # test['path'] is a relative path
3488 # test['path'] is a relative path
3484 if 'case' in test:
3489 if 'case' in test:
3485 # for multiple dimensions test cases
3490 # for multiple dimensions test cases
3486 casestr = b'#'.join(test['case'])
3491 casestr = b'#'.join(test['case'])
3487 errpath = b'%s#%s.err' % (test['path'], casestr)
3492 errpath = b'%s#%s.err' % (test['path'], casestr)
3488 else:
3493 else:
3489 errpath = b'%s.err' % test['path']
3494 errpath = b'%s.err' % test['path']
3490 if self.options.outputdir:
3495 if self.options.outputdir:
3491 self._outputdir = canonpath(_sys2bytes(self.options.outputdir))
3496 self._outputdir = canonpath(_sys2bytes(self.options.outputdir))
3492 errpath = os.path.join(self._outputdir, errpath)
3497 errpath = os.path.join(self._outputdir, errpath)
3493 return errpath
3498 return errpath
3494
3499
3495 def _getport(self, count):
3500 def _getport(self, count):
3496 port = self._ports.get(count) # do we have a cached entry?
3501 port = self._ports.get(count) # do we have a cached entry?
3497 if port is None:
3502 if port is None:
3498 portneeded = 3
3503 portneeded = 3
3499 # above 100 tries we just give up and let test reports failure
3504 # above 100 tries we just give up and let test reports failure
3500 for tries in xrange(100):
3505 for tries in xrange(100):
3501 allfree = True
3506 allfree = True
3502 port = self.options.port + self._portoffset
3507 port = self.options.port + self._portoffset
3503 for idx in xrange(portneeded):
3508 for idx in xrange(portneeded):
3504 if not checkportisavailable(port + idx):
3509 if not checkportisavailable(port + idx):
3505 allfree = False
3510 allfree = False
3506 break
3511 break
3507 self._portoffset += portneeded
3512 self._portoffset += portneeded
3508 if allfree:
3513 if allfree:
3509 break
3514 break
3510 self._ports[count] = port
3515 self._ports[count] = port
3511 return port
3516 return port
3512
3517
3513 def _gettest(self, testdesc, count):
3518 def _gettest(self, testdesc, count):
3514 """Obtain a Test by looking at its filename.
3519 """Obtain a Test by looking at its filename.
3515
3520
3516 Returns a Test instance. The Test may not be runnable if it doesn't
3521 Returns a Test instance. The Test may not be runnable if it doesn't
3517 map to a known type.
3522 map to a known type.
3518 """
3523 """
3519 path = testdesc['path']
3524 path = testdesc['path']
3520 lctest = path.lower()
3525 lctest = path.lower()
3521 testcls = Test
3526 testcls = Test
3522
3527
3523 for ext, cls in self.TESTTYPES:
3528 for ext, cls in self.TESTTYPES:
3524 if lctest.endswith(ext):
3529 if lctest.endswith(ext):
3525 testcls = cls
3530 testcls = cls
3526 break
3531 break
3527
3532
3528 refpath = os.path.join(getcwdb(), path)
3533 refpath = os.path.join(getcwdb(), path)
3529 tmpdir = os.path.join(self._hgtmp, b'child%d' % count)
3534 tmpdir = os.path.join(self._hgtmp, b'child%d' % count)
3530
3535
3531 # extra keyword parameters. 'case' is used by .t tests
3536 # extra keyword parameters. 'case' is used by .t tests
3532 kwds = {k: testdesc[k] for k in ['case'] if k in testdesc}
3537 kwds = {k: testdesc[k] for k in ['case'] if k in testdesc}
3533
3538
3534 t = testcls(
3539 t = testcls(
3535 refpath,
3540 refpath,
3536 self._outputdir,
3541 self._outputdir,
3537 tmpdir,
3542 tmpdir,
3538 keeptmpdir=self.options.keep_tmpdir,
3543 keeptmpdir=self.options.keep_tmpdir,
3539 debug=self.options.debug,
3544 debug=self.options.debug,
3540 first=self.options.first,
3545 first=self.options.first,
3541 timeout=self.options.timeout,
3546 timeout=self.options.timeout,
3542 startport=self._getport(count),
3547 startport=self._getport(count),
3543 extraconfigopts=self.options.extra_config_opt,
3548 extraconfigopts=self.options.extra_config_opt,
3544 shell=self.options.shell,
3549 shell=self.options.shell,
3545 hgcommand=self._hgcommand,
3550 hgcommand=self._hgcommand,
3546 usechg=bool(self.options.with_chg or self.options.chg),
3551 usechg=bool(self.options.with_chg or self.options.chg),
3547 chgdebug=self.options.chg_debug,
3552 chgdebug=self.options.chg_debug,
3548 useipv6=useipv6,
3553 useipv6=useipv6,
3549 **kwds
3554 **kwds
3550 )
3555 )
3551 t.should_reload = True
3556 t.should_reload = True
3552 return t
3557 return t
3553
3558
3554 def _cleanup(self):
3559 def _cleanup(self):
3555 """Clean up state from this test invocation."""
3560 """Clean up state from this test invocation."""
3556 if self.options.keep_tmpdir:
3561 if self.options.keep_tmpdir:
3557 return
3562 return
3558
3563
3559 vlog("# Cleaning up HGTMP", _bytes2sys(self._hgtmp))
3564 vlog("# Cleaning up HGTMP", _bytes2sys(self._hgtmp))
3560 shutil.rmtree(self._hgtmp, True)
3565 shutil.rmtree(self._hgtmp, True)
3561 for f in self._createdfiles:
3566 for f in self._createdfiles:
3562 try:
3567 try:
3563 os.remove(f)
3568 os.remove(f)
3564 except OSError:
3569 except OSError:
3565 pass
3570 pass
3566
3571
3567 def _usecorrectpython(self):
3572 def _usecorrectpython(self):
3568 """Configure the environment to use the appropriate Python in tests."""
3573 """Configure the environment to use the appropriate Python in tests."""
3569 # Tests must use the same interpreter as us or bad things will happen.
3574 # Tests must use the same interpreter as us or bad things will happen.
3570 if WINDOWS:
3575 if WINDOWS:
3571 pyexe_names = [b'python', b'python3', b'python.exe']
3576 pyexe_names = [b'python', b'python3', b'python.exe']
3572 else:
3577 else:
3573 pyexe_names = [b'python', b'python3']
3578 pyexe_names = [b'python', b'python3']
3574
3579
3575 # os.symlink() is a thing with py3 on Windows, but it requires
3580 # os.symlink() is a thing with py3 on Windows, but it requires
3576 # Administrator rights.
3581 # Administrator rights.
3577 if not WINDOWS and getattr(os, 'symlink', None):
3582 if not WINDOWS and getattr(os, 'symlink', None):
3578 msg = "# Making python executable in test path a symlink to '%s'"
3583 msg = "# Making python executable in test path a symlink to '%s'"
3579 msg %= sysexecutable
3584 msg %= sysexecutable
3580 vlog(msg)
3585 vlog(msg)
3581 for pyexename in pyexe_names:
3586 for pyexename in pyexe_names:
3582 mypython = os.path.join(self._custom_bin_dir, pyexename)
3587 mypython = os.path.join(self._custom_bin_dir, pyexename)
3583 try:
3588 try:
3584 if os.readlink(mypython) == sysexecutable:
3589 if os.readlink(mypython) == sysexecutable:
3585 continue
3590 continue
3586 os.unlink(mypython)
3591 os.unlink(mypython)
3587 except OSError as err:
3592 except OSError as err:
3588 if err.errno != errno.ENOENT:
3593 if err.errno != errno.ENOENT:
3589 raise
3594 raise
3590 if self._findprogram(pyexename) != sysexecutable:
3595 if self._findprogram(pyexename) != sysexecutable:
3591 try:
3596 try:
3592 os.symlink(sysexecutable, mypython)
3597 os.symlink(sysexecutable, mypython)
3593 self._createdfiles.append(mypython)
3598 self._createdfiles.append(mypython)
3594 except OSError as err:
3599 except OSError as err:
3595 # child processes may race, which is harmless
3600 # child processes may race, which is harmless
3596 if err.errno != errno.EEXIST:
3601 if err.errno != errno.EEXIST:
3597 raise
3602 raise
3598 elif WINDOWS and not os.getenv('MSYSTEM'):
3603 elif WINDOWS and not os.getenv('MSYSTEM'):
3599 raise AssertionError('cannot run test on Windows without MSYSTEM')
3604 raise AssertionError('cannot run test on Windows without MSYSTEM')
3600 else:
3605 else:
3601 # Generate explicit file instead of symlink
3606 # Generate explicit file instead of symlink
3602 #
3607 #
3603 # This is especially important as Windows doesn't have
3608 # This is especially important as Windows doesn't have
3604 # `python3.exe`, and MSYS cannot understand the reparse point with
3609 # `python3.exe`, and MSYS cannot understand the reparse point with
3605 # that name provided by Microsoft. Create a simple script on PATH
3610 # that name provided by Microsoft. Create a simple script on PATH
3606 # with that name that delegates to the py3 launcher so the shebang
3611 # with that name that delegates to the py3 launcher so the shebang
3607 # lines work.
3612 # lines work.
3608 esc_executable = _sys2bytes(shellquote(sysexecutable))
3613 esc_executable = _sys2bytes(shellquote(sysexecutable))
3609 for pyexename in pyexe_names:
3614 for pyexename in pyexe_names:
3610 stub_exec_path = os.path.join(self._custom_bin_dir, pyexename)
3615 stub_exec_path = os.path.join(self._custom_bin_dir, pyexename)
3611 with open(stub_exec_path, 'wb') as f:
3616 with open(stub_exec_path, 'wb') as f:
3612 f.write(b'#!/bin/sh\n')
3617 f.write(b'#!/bin/sh\n')
3613 f.write(b'%s "$@"\n' % esc_executable)
3618 f.write(b'%s "$@"\n' % esc_executable)
3614
3619
3615 if WINDOWS:
3620 if WINDOWS:
3616 # adjust the path to make sur the main python finds it own dll
3621 # adjust the path to make sur the main python finds it own dll
3617 path = os.environ['PATH'].split(os.pathsep)
3622 path = os.environ['PATH'].split(os.pathsep)
3618 main_exec_dir = os.path.dirname(sysexecutable)
3623 main_exec_dir = os.path.dirname(sysexecutable)
3619 extra_paths = [_bytes2sys(self._custom_bin_dir), main_exec_dir]
3624 extra_paths = [_bytes2sys(self._custom_bin_dir), main_exec_dir]
3620
3625
3621 # Binaries installed by pip into the user area like pylint.exe may
3626 # Binaries installed by pip into the user area like pylint.exe may
3622 # not be in PATH by default.
3627 # not be in PATH by default.
3623 appdata = os.environ.get('APPDATA')
3628 appdata = os.environ.get('APPDATA')
3624 vi = sys.version_info
3629 vi = sys.version_info
3625 if appdata is not None:
3630 if appdata is not None:
3626 python_dir = 'Python%d%d' % (vi[0], vi[1])
3631 python_dir = 'Python%d%d' % (vi[0], vi[1])
3627 scripts_path = [appdata, 'Python', python_dir, 'Scripts']
3632 scripts_path = [appdata, 'Python', python_dir, 'Scripts']
3628 scripts_dir = os.path.join(*scripts_path)
3633 scripts_dir = os.path.join(*scripts_path)
3629 extra_paths.append(scripts_dir)
3634 extra_paths.append(scripts_dir)
3630
3635
3631 os.environ['PATH'] = os.pathsep.join(extra_paths + path)
3636 os.environ['PATH'] = os.pathsep.join(extra_paths + path)
3632
3637
3633 def _use_correct_mercurial(self):
3638 def _use_correct_mercurial(self):
3634 target_exec = os.path.join(self._custom_bin_dir, b'hg')
3639 target_exec = os.path.join(self._custom_bin_dir, b'hg')
3635 if self._hgcommand != b'hg':
3640 if self._hgcommand != b'hg':
3636 # shutil.which only accept bytes from 3.8
3641 # shutil.which only accept bytes from 3.8
3637 real_exec = which(self._hgcommand)
3642 real_exec = which(self._hgcommand)
3638 if real_exec is None:
3643 if real_exec is None:
3639 raise ValueError('could not find exec path for "%s"', real_exec)
3644 raise ValueError('could not find exec path for "%s"', real_exec)
3640 if real_exec == target_exec:
3645 if real_exec == target_exec:
3641 # do not overwrite something with itself
3646 # do not overwrite something with itself
3642 return
3647 return
3643 if WINDOWS:
3648 if WINDOWS:
3644 with open(target_exec, 'wb') as f:
3649 with open(target_exec, 'wb') as f:
3645 f.write(b'#!/bin/sh\n')
3650 f.write(b'#!/bin/sh\n')
3646 escaped_exec = shellquote(_bytes2sys(real_exec))
3651 escaped_exec = shellquote(_bytes2sys(real_exec))
3647 f.write(b'%s "$@"\n' % _sys2bytes(escaped_exec))
3652 f.write(b'%s "$@"\n' % _sys2bytes(escaped_exec))
3648 else:
3653 else:
3649 os.symlink(real_exec, target_exec)
3654 os.symlink(real_exec, target_exec)
3650 self._createdfiles.append(target_exec)
3655 self._createdfiles.append(target_exec)
3651
3656
3652 def _installhg(self):
3657 def _installhg(self):
3653 """Install hg into the test environment.
3658 """Install hg into the test environment.
3654
3659
3655 This will also configure hg with the appropriate testing settings.
3660 This will also configure hg with the appropriate testing settings.
3656 """
3661 """
3657 vlog("# Performing temporary installation of HG")
3662 vlog("# Performing temporary installation of HG")
3658 installerrs = os.path.join(self._hgtmp, b"install.err")
3663 installerrs = os.path.join(self._hgtmp, b"install.err")
3659 compiler = ''
3664 compiler = ''
3660 if self.options.compiler:
3665 if self.options.compiler:
3661 compiler = '--compiler ' + self.options.compiler
3666 compiler = '--compiler ' + self.options.compiler
3662 setup_opts = b""
3667 setup_opts = b""
3663 if self.options.pure:
3668 if self.options.pure:
3664 setup_opts = b"--pure"
3669 setup_opts = b"--pure"
3665 elif self.options.rust:
3670 elif self.options.rust:
3666 setup_opts = b"--rust"
3671 setup_opts = b"--rust"
3667 elif self.options.no_rust:
3672 elif self.options.no_rust:
3668 setup_opts = b"--no-rust"
3673 setup_opts = b"--no-rust"
3669
3674
3670 # Run installer in hg root
3675 # Run installer in hg root
3671 compiler = _sys2bytes(compiler)
3676 compiler = _sys2bytes(compiler)
3672 script = _sys2bytes(os.path.realpath(sys.argv[0]))
3677 script = _sys2bytes(os.path.realpath(sys.argv[0]))
3673 exe = _sys2bytes(sysexecutable)
3678 exe = _sys2bytes(sysexecutable)
3674 hgroot = os.path.dirname(os.path.dirname(script))
3679 hgroot = os.path.dirname(os.path.dirname(script))
3675 self._hgroot = hgroot
3680 self._hgroot = hgroot
3676 os.chdir(hgroot)
3681 os.chdir(hgroot)
3677 nohome = b'--home=""'
3682 nohome = b'--home=""'
3678 if WINDOWS:
3683 if WINDOWS:
3679 # The --home="" trick works only on OS where os.sep == '/'
3684 # The --home="" trick works only on OS where os.sep == '/'
3680 # because of a distutils convert_path() fast-path. Avoid it at
3685 # because of a distutils convert_path() fast-path. Avoid it at
3681 # least on Windows for now, deal with .pydistutils.cfg bugs
3686 # least on Windows for now, deal with .pydistutils.cfg bugs
3682 # when they happen.
3687 # when they happen.
3683 nohome = b''
3688 nohome = b''
3684 cmd = (
3689 cmd = (
3685 b'"%(exe)s" setup.py %(setup_opts)s clean --all'
3690 b'"%(exe)s" setup.py %(setup_opts)s clean --all'
3686 b' build %(compiler)s --build-base="%(base)s"'
3691 b' build %(compiler)s --build-base="%(base)s"'
3687 b' install --force --prefix="%(prefix)s"'
3692 b' install --force --prefix="%(prefix)s"'
3688 b' --install-lib="%(libdir)s"'
3693 b' --install-lib="%(libdir)s"'
3689 b' --install-scripts="%(bindir)s" %(nohome)s >%(logfile)s 2>&1'
3694 b' --install-scripts="%(bindir)s" %(nohome)s >%(logfile)s 2>&1'
3690 % {
3695 % {
3691 b'exe': exe,
3696 b'exe': exe,
3692 b'setup_opts': setup_opts,
3697 b'setup_opts': setup_opts,
3693 b'compiler': compiler,
3698 b'compiler': compiler,
3694 b'base': os.path.join(self._hgtmp, b"build"),
3699 b'base': os.path.join(self._hgtmp, b"build"),
3695 b'prefix': self._installdir,
3700 b'prefix': self._installdir,
3696 b'libdir': self._pythondir,
3701 b'libdir': self._pythondir,
3697 b'bindir': self._bindir,
3702 b'bindir': self._bindir,
3698 b'nohome': nohome,
3703 b'nohome': nohome,
3699 b'logfile': installerrs,
3704 b'logfile': installerrs,
3700 }
3705 }
3701 )
3706 )
3702
3707
3703 # setuptools requires install directories to exist.
3708 # setuptools requires install directories to exist.
3704 def makedirs(p):
3709 def makedirs(p):
3705 try:
3710 try:
3706 os.makedirs(p)
3711 os.makedirs(p)
3707 except OSError as e:
3712 except OSError as e:
3708 if e.errno != errno.EEXIST:
3713 if e.errno != errno.EEXIST:
3709 raise
3714 raise
3710
3715
3711 makedirs(self._pythondir)
3716 makedirs(self._pythondir)
3712 makedirs(self._bindir)
3717 makedirs(self._bindir)
3713
3718
3714 vlog("# Running", cmd.decode("utf-8"))
3719 vlog("# Running", cmd.decode("utf-8"))
3715 if subprocess.call(_bytes2sys(cmd), shell=True) == 0:
3720 if subprocess.call(_bytes2sys(cmd), shell=True) == 0:
3716 if not self.options.verbose:
3721 if not self.options.verbose:
3717 try:
3722 try:
3718 os.remove(installerrs)
3723 os.remove(installerrs)
3719 except OSError as e:
3724 except OSError as e:
3720 if e.errno != errno.ENOENT:
3725 if e.errno != errno.ENOENT:
3721 raise
3726 raise
3722 else:
3727 else:
3723 with open(installerrs, 'rb') as f:
3728 with open(installerrs, 'rb') as f:
3724 for line in f:
3729 for line in f:
3725 sys.stdout.buffer.write(line)
3730 sys.stdout.buffer.write(line)
3726 sys.exit(1)
3731 sys.exit(1)
3727 os.chdir(self._testdir)
3732 os.chdir(self._testdir)
3728
3733
3729 hgbat = os.path.join(self._bindir, b'hg.bat')
3734 hgbat = os.path.join(self._bindir, b'hg.bat')
3730 if os.path.isfile(hgbat):
3735 if os.path.isfile(hgbat):
3731 # hg.bat expects to be put in bin/scripts while run-tests.py
3736 # hg.bat expects to be put in bin/scripts while run-tests.py
3732 # installation layout put it in bin/ directly. Fix it
3737 # installation layout put it in bin/ directly. Fix it
3733 with open(hgbat, 'rb') as f:
3738 with open(hgbat, 'rb') as f:
3734 data = f.read()
3739 data = f.read()
3735 if br'"%~dp0..\python" "%~dp0hg" %*' in data:
3740 if br'"%~dp0..\python" "%~dp0hg" %*' in data:
3736 data = data.replace(
3741 data = data.replace(
3737 br'"%~dp0..\python" "%~dp0hg" %*',
3742 br'"%~dp0..\python" "%~dp0hg" %*',
3738 b'"%~dp0python" "%~dp0hg" %*',
3743 b'"%~dp0python" "%~dp0hg" %*',
3739 )
3744 )
3740 with open(hgbat, 'wb') as f:
3745 with open(hgbat, 'wb') as f:
3741 f.write(data)
3746 f.write(data)
3742 else:
3747 else:
3743 print('WARNING: cannot fix hg.bat reference to python.exe')
3748 print('WARNING: cannot fix hg.bat reference to python.exe')
3744
3749
3745 if self.options.anycoverage:
3750 if self.options.anycoverage:
3746 custom = os.path.join(
3751 custom = os.path.join(
3747 osenvironb[b'RUNTESTDIR'], b'sitecustomize.py'
3752 osenvironb[b'RUNTESTDIR'], b'sitecustomize.py'
3748 )
3753 )
3749 target = os.path.join(self._pythondir, b'sitecustomize.py')
3754 target = os.path.join(self._pythondir, b'sitecustomize.py')
3750 vlog('# Installing coverage trigger to %s' % target)
3755 vlog('# Installing coverage trigger to %s' % target)
3751 shutil.copyfile(custom, target)
3756 shutil.copyfile(custom, target)
3752 rc = os.path.join(self._testdir, b'.coveragerc')
3757 rc = os.path.join(self._testdir, b'.coveragerc')
3753 vlog('# Installing coverage rc to %s' % rc)
3758 vlog('# Installing coverage rc to %s' % rc)
3754 osenvironb[b'COVERAGE_PROCESS_START'] = rc
3759 osenvironb[b'COVERAGE_PROCESS_START'] = rc
3755 covdir = os.path.join(self._installdir, b'..', b'coverage')
3760 covdir = os.path.join(self._installdir, b'..', b'coverage')
3756 try:
3761 try:
3757 os.mkdir(covdir)
3762 os.mkdir(covdir)
3758 except OSError as e:
3763 except OSError as e:
3759 if e.errno != errno.EEXIST:
3764 if e.errno != errno.EEXIST:
3760 raise
3765 raise
3761
3766
3762 osenvironb[b'COVERAGE_DIR'] = covdir
3767 osenvironb[b'COVERAGE_DIR'] = covdir
3763
3768
3764 def _checkhglib(self, verb):
3769 def _checkhglib(self, verb):
3765 """Ensure that the 'mercurial' package imported by python is
3770 """Ensure that the 'mercurial' package imported by python is
3766 the one we expect it to be. If not, print a warning to stderr."""
3771 the one we expect it to be. If not, print a warning to stderr."""
3767 if self._pythondir_inferred:
3772 if self._pythondir_inferred:
3768 # The pythondir has been inferred from --with-hg flag.
3773 # The pythondir has been inferred from --with-hg flag.
3769 # We cannot expect anything sensible here.
3774 # We cannot expect anything sensible here.
3770 return
3775 return
3771 expecthg = os.path.join(self._pythondir, b'mercurial')
3776 expecthg = os.path.join(self._pythondir, b'mercurial')
3772 actualhg = self._gethgpath()
3777 actualhg = self._gethgpath()
3773 if os.path.abspath(actualhg) != os.path.abspath(expecthg):
3778 if os.path.abspath(actualhg) != os.path.abspath(expecthg):
3774 sys.stderr.write(
3779 sys.stderr.write(
3775 'warning: %s with unexpected mercurial lib: %s\n'
3780 'warning: %s with unexpected mercurial lib: %s\n'
3776 ' (expected %s)\n' % (verb, actualhg, expecthg)
3781 ' (expected %s)\n' % (verb, actualhg, expecthg)
3777 )
3782 )
3778
3783
3779 def _gethgpath(self):
3784 def _gethgpath(self):
3780 """Return the path to the mercurial package that is actually found by
3785 """Return the path to the mercurial package that is actually found by
3781 the current Python interpreter."""
3786 the current Python interpreter."""
3782 if self._hgpath is not None:
3787 if self._hgpath is not None:
3783 return self._hgpath
3788 return self._hgpath
3784
3789
3785 cmd = b'"%s" -c "import mercurial; print (mercurial.__path__[0])"'
3790 cmd = b'"%s" -c "import mercurial; print (mercurial.__path__[0])"'
3786 cmd = _bytes2sys(cmd % PYTHON)
3791 cmd = _bytes2sys(cmd % PYTHON)
3787
3792
3788 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
3793 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
3789 out, err = p.communicate()
3794 out, err = p.communicate()
3790
3795
3791 self._hgpath = out.strip()
3796 self._hgpath = out.strip()
3792
3797
3793 return self._hgpath
3798 return self._hgpath
3794
3799
3795 def _installchg(self):
3800 def _installchg(self):
3796 """Install chg into the test environment"""
3801 """Install chg into the test environment"""
3797 vlog('# Performing temporary installation of CHG')
3802 vlog('# Performing temporary installation of CHG')
3798 assert os.path.dirname(self._bindir) == self._installdir
3803 assert os.path.dirname(self._bindir) == self._installdir
3799 assert self._hgroot, 'must be called after _installhg()'
3804 assert self._hgroot, 'must be called after _installhg()'
3800 cmd = b'"%(make)s" clean install PREFIX="%(prefix)s"' % {
3805 cmd = b'"%(make)s" clean install PREFIX="%(prefix)s"' % {
3801 b'make': b'make', # TODO: switch by option or environment?
3806 b'make': b'make', # TODO: switch by option or environment?
3802 b'prefix': self._installdir,
3807 b'prefix': self._installdir,
3803 }
3808 }
3804 cwd = os.path.join(self._hgroot, b'contrib', b'chg')
3809 cwd = os.path.join(self._hgroot, b'contrib', b'chg')
3805 vlog("# Running", cmd)
3810 vlog("# Running", cmd)
3806 proc = subprocess.Popen(
3811 proc = subprocess.Popen(
3807 cmd,
3812 cmd,
3808 shell=True,
3813 shell=True,
3809 cwd=cwd,
3814 cwd=cwd,
3810 stdin=subprocess.PIPE,
3815 stdin=subprocess.PIPE,
3811 stdout=subprocess.PIPE,
3816 stdout=subprocess.PIPE,
3812 stderr=subprocess.STDOUT,
3817 stderr=subprocess.STDOUT,
3813 )
3818 )
3814 out, _err = proc.communicate()
3819 out, _err = proc.communicate()
3815 if proc.returncode != 0:
3820 if proc.returncode != 0:
3816 sys.stdout.buffer.write(out)
3821 sys.stdout.buffer.write(out)
3817 sys.exit(1)
3822 sys.exit(1)
3818
3823
3819 def _installrhg(self):
3824 def _installrhg(self):
3820 """Install rhg into the test environment"""
3825 """Install rhg into the test environment"""
3821 vlog('# Performing temporary installation of rhg')
3826 vlog('# Performing temporary installation of rhg')
3822 assert os.path.dirname(self._bindir) == self._installdir
3827 assert os.path.dirname(self._bindir) == self._installdir
3823 assert self._hgroot, 'must be called after _installhg()'
3828 assert self._hgroot, 'must be called after _installhg()'
3824 cmd = b'"%(make)s" install-rhg PREFIX="%(prefix)s"' % {
3829 cmd = b'"%(make)s" install-rhg PREFIX="%(prefix)s"' % {
3825 b'make': b'make', # TODO: switch by option or environment?
3830 b'make': b'make', # TODO: switch by option or environment?
3826 b'prefix': self._installdir,
3831 b'prefix': self._installdir,
3827 }
3832 }
3828 cwd = self._hgroot
3833 cwd = self._hgroot
3829 vlog("# Running", cmd)
3834 vlog("# Running", cmd)
3830 proc = subprocess.Popen(
3835 proc = subprocess.Popen(
3831 cmd,
3836 cmd,
3832 shell=True,
3837 shell=True,
3833 cwd=cwd,
3838 cwd=cwd,
3834 stdin=subprocess.PIPE,
3839 stdin=subprocess.PIPE,
3835 stdout=subprocess.PIPE,
3840 stdout=subprocess.PIPE,
3836 stderr=subprocess.STDOUT,
3841 stderr=subprocess.STDOUT,
3837 )
3842 )
3838 out, _err = proc.communicate()
3843 out, _err = proc.communicate()
3839 if proc.returncode != 0:
3844 if proc.returncode != 0:
3840 sys.stdout.buffer.write(out)
3845 sys.stdout.buffer.write(out)
3841 sys.exit(1)
3846 sys.exit(1)
3842
3847
3843 def _build_pyoxidized(self):
3848 def _build_pyoxidized(self):
3844 """build a pyoxidized version of mercurial into the test environment
3849 """build a pyoxidized version of mercurial into the test environment
3845
3850
3846 Ideally this function would be `install_pyoxidier` and would both build
3851 Ideally this function would be `install_pyoxidier` and would both build
3847 and install pyoxidier. However we are starting small to get pyoxidizer
3852 and install pyoxidier. However we are starting small to get pyoxidizer
3848 build binary to testing quickly.
3853 build binary to testing quickly.
3849 """
3854 """
3850 vlog('# build a pyoxidized version of Mercurial')
3855 vlog('# build a pyoxidized version of Mercurial')
3851 assert os.path.dirname(self._bindir) == self._installdir
3856 assert os.path.dirname(self._bindir) == self._installdir
3852 assert self._hgroot, 'must be called after _installhg()'
3857 assert self._hgroot, 'must be called after _installhg()'
3853 cmd = b'"%(make)s" pyoxidizer-windows-tests' % {
3858 cmd = b'"%(make)s" pyoxidizer-windows-tests' % {
3854 b'make': b'make',
3859 b'make': b'make',
3855 }
3860 }
3856 cwd = self._hgroot
3861 cwd = self._hgroot
3857 vlog("# Running", cmd)
3862 vlog("# Running", cmd)
3858 proc = subprocess.Popen(
3863 proc = subprocess.Popen(
3859 _bytes2sys(cmd),
3864 _bytes2sys(cmd),
3860 shell=True,
3865 shell=True,
3861 cwd=_bytes2sys(cwd),
3866 cwd=_bytes2sys(cwd),
3862 stdin=subprocess.PIPE,
3867 stdin=subprocess.PIPE,
3863 stdout=subprocess.PIPE,
3868 stdout=subprocess.PIPE,
3864 stderr=subprocess.STDOUT,
3869 stderr=subprocess.STDOUT,
3865 )
3870 )
3866 out, _err = proc.communicate()
3871 out, _err = proc.communicate()
3867 if proc.returncode != 0:
3872 if proc.returncode != 0:
3868 sys.stdout.buffer.write(out)
3873 sys.stdout.buffer.write(out)
3869 sys.exit(1)
3874 sys.exit(1)
3870
3875
3871 def _outputcoverage(self):
3876 def _outputcoverage(self):
3872 """Produce code coverage output."""
3877 """Produce code coverage output."""
3873 import coverage
3878 import coverage
3874
3879
3875 coverage = coverage.coverage
3880 coverage = coverage.coverage
3876
3881
3877 vlog('# Producing coverage report')
3882 vlog('# Producing coverage report')
3878 # chdir is the easiest way to get short, relative paths in the
3883 # chdir is the easiest way to get short, relative paths in the
3879 # output.
3884 # output.
3880 os.chdir(self._hgroot)
3885 os.chdir(self._hgroot)
3881 covdir = os.path.join(_bytes2sys(self._installdir), '..', 'coverage')
3886 covdir = os.path.join(_bytes2sys(self._installdir), '..', 'coverage')
3882 cov = coverage(data_file=os.path.join(covdir, 'cov'))
3887 cov = coverage(data_file=os.path.join(covdir, 'cov'))
3883
3888
3884 # Map install directory paths back to source directory.
3889 # Map install directory paths back to source directory.
3885 cov.config.paths['srcdir'] = ['.', _bytes2sys(self._pythondir)]
3890 cov.config.paths['srcdir'] = ['.', _bytes2sys(self._pythondir)]
3886
3891
3887 cov.combine()
3892 cov.combine()
3888
3893
3889 omit = [
3894 omit = [
3890 _bytes2sys(os.path.join(x, b'*'))
3895 _bytes2sys(os.path.join(x, b'*'))
3891 for x in [self._bindir, self._testdir]
3896 for x in [self._bindir, self._testdir]
3892 ]
3897 ]
3893 cov.report(ignore_errors=True, omit=omit)
3898 cov.report(ignore_errors=True, omit=omit)
3894
3899
3895 if self.options.htmlcov:
3900 if self.options.htmlcov:
3896 htmldir = os.path.join(_bytes2sys(self._outputdir), 'htmlcov')
3901 htmldir = os.path.join(_bytes2sys(self._outputdir), 'htmlcov')
3897 cov.html_report(directory=htmldir, omit=omit)
3902 cov.html_report(directory=htmldir, omit=omit)
3898 if self.options.annotate:
3903 if self.options.annotate:
3899 adir = os.path.join(_bytes2sys(self._outputdir), 'annotated')
3904 adir = os.path.join(_bytes2sys(self._outputdir), 'annotated')
3900 if not os.path.isdir(adir):
3905 if not os.path.isdir(adir):
3901 os.mkdir(adir)
3906 os.mkdir(adir)
3902 cov.annotate(directory=adir, omit=omit)
3907 cov.annotate(directory=adir, omit=omit)
3903
3908
3904 def _findprogram(self, program):
3909 def _findprogram(self, program):
3905 """Search PATH for a executable program"""
3910 """Search PATH for a executable program"""
3906 dpb = _sys2bytes(os.defpath)
3911 dpb = _sys2bytes(os.defpath)
3907 sepb = _sys2bytes(os.pathsep)
3912 sepb = _sys2bytes(os.pathsep)
3908 for p in osenvironb.get(b'PATH', dpb).split(sepb):
3913 for p in osenvironb.get(b'PATH', dpb).split(sepb):
3909 name = os.path.join(p, program)
3914 name = os.path.join(p, program)
3910 if WINDOWS or os.access(name, os.X_OK):
3915 if WINDOWS or os.access(name, os.X_OK):
3911 return _bytes2sys(name)
3916 return _bytes2sys(name)
3912 return None
3917 return None
3913
3918
3914 def _checktools(self):
3919 def _checktools(self):
3915 """Ensure tools required to run tests are present."""
3920 """Ensure tools required to run tests are present."""
3916 for p in self.REQUIREDTOOLS:
3921 for p in self.REQUIREDTOOLS:
3917 if WINDOWS and not p.endswith(b'.exe'):
3922 if WINDOWS and not p.endswith(b'.exe'):
3918 p += b'.exe'
3923 p += b'.exe'
3919 found = self._findprogram(p)
3924 found = self._findprogram(p)
3920 p = p.decode("utf-8")
3925 p = p.decode("utf-8")
3921 if found:
3926 if found:
3922 vlog("# Found prerequisite", p, "at", found)
3927 vlog("# Found prerequisite", p, "at", found)
3923 else:
3928 else:
3924 print("WARNING: Did not find prerequisite tool: %s " % p)
3929 print("WARNING: Did not find prerequisite tool: %s " % p)
3925
3930
3926
3931
3927 def aggregateexceptions(path):
3932 def aggregateexceptions(path):
3928 exceptioncounts = collections.Counter()
3933 exceptioncounts = collections.Counter()
3929 testsbyfailure = collections.defaultdict(set)
3934 testsbyfailure = collections.defaultdict(set)
3930 failuresbytest = collections.defaultdict(set)
3935 failuresbytest = collections.defaultdict(set)
3931
3936
3932 for f in os.listdir(path):
3937 for f in os.listdir(path):
3933 with open(os.path.join(path, f), 'rb') as fh:
3938 with open(os.path.join(path, f), 'rb') as fh:
3934 data = fh.read().split(b'\0')
3939 data = fh.read().split(b'\0')
3935 if len(data) != 5:
3940 if len(data) != 5:
3936 continue
3941 continue
3937
3942
3938 exc, mainframe, hgframe, hgline, testname = data
3943 exc, mainframe, hgframe, hgline, testname = data
3939 exc = exc.decode('utf-8')
3944 exc = exc.decode('utf-8')
3940 mainframe = mainframe.decode('utf-8')
3945 mainframe = mainframe.decode('utf-8')
3941 hgframe = hgframe.decode('utf-8')
3946 hgframe = hgframe.decode('utf-8')
3942 hgline = hgline.decode('utf-8')
3947 hgline = hgline.decode('utf-8')
3943 testname = testname.decode('utf-8')
3948 testname = testname.decode('utf-8')
3944
3949
3945 key = (hgframe, hgline, exc)
3950 key = (hgframe, hgline, exc)
3946 exceptioncounts[key] += 1
3951 exceptioncounts[key] += 1
3947 testsbyfailure[key].add(testname)
3952 testsbyfailure[key].add(testname)
3948 failuresbytest[testname].add(key)
3953 failuresbytest[testname].add(key)
3949
3954
3950 # Find test having fewest failures for each failure.
3955 # Find test having fewest failures for each failure.
3951 leastfailing = {}
3956 leastfailing = {}
3952 for key, tests in testsbyfailure.items():
3957 for key, tests in testsbyfailure.items():
3953 fewesttest = None
3958 fewesttest = None
3954 fewestcount = 99999999
3959 fewestcount = 99999999
3955 for test in sorted(tests):
3960 for test in sorted(tests):
3956 if len(failuresbytest[test]) < fewestcount:
3961 if len(failuresbytest[test]) < fewestcount:
3957 fewesttest = test
3962 fewesttest = test
3958 fewestcount = len(failuresbytest[test])
3963 fewestcount = len(failuresbytest[test])
3959
3964
3960 leastfailing[key] = (fewestcount, fewesttest)
3965 leastfailing[key] = (fewestcount, fewesttest)
3961
3966
3962 # Create a combined counter so we can sort by total occurrences and
3967 # Create a combined counter so we can sort by total occurrences and
3963 # impacted tests.
3968 # impacted tests.
3964 combined = {}
3969 combined = {}
3965 for key in exceptioncounts:
3970 for key in exceptioncounts:
3966 combined[key] = (
3971 combined[key] = (
3967 exceptioncounts[key],
3972 exceptioncounts[key],
3968 len(testsbyfailure[key]),
3973 len(testsbyfailure[key]),
3969 leastfailing[key][0],
3974 leastfailing[key][0],
3970 leastfailing[key][1],
3975 leastfailing[key][1],
3971 )
3976 )
3972
3977
3973 return {
3978 return {
3974 'exceptioncounts': exceptioncounts,
3979 'exceptioncounts': exceptioncounts,
3975 'total': sum(exceptioncounts.values()),
3980 'total': sum(exceptioncounts.values()),
3976 'combined': combined,
3981 'combined': combined,
3977 'leastfailing': leastfailing,
3982 'leastfailing': leastfailing,
3978 'byfailure': testsbyfailure,
3983 'byfailure': testsbyfailure,
3979 'bytest': failuresbytest,
3984 'bytest': failuresbytest,
3980 }
3985 }
3981
3986
3982
3987
3983 if __name__ == '__main__':
3988 if __name__ == '__main__':
3984 if WINDOWS and not os.getenv('MSYSTEM'):
3989 if WINDOWS and not os.getenv('MSYSTEM'):
3985 print('cannot run test on Windows without MSYSTEM', file=sys.stderr)
3990 print('cannot run test on Windows without MSYSTEM', file=sys.stderr)
3986 print(
3991 print(
3987 '(if you need to do so contact the mercurial devs: '
3992 '(if you need to do so contact the mercurial devs: '
3988 'mercurial@mercurial-scm.org)',
3993 'mercurial@mercurial-scm.org)',
3989 file=sys.stderr,
3994 file=sys.stderr,
3990 )
3995 )
3991 sys.exit(255)
3996 sys.exit(255)
3992
3997
3993 runner = TestRunner()
3998 runner = TestRunner()
3994
3999
3995 try:
4000 try:
3996 import msvcrt
4001 import msvcrt
3997
4002
3998 msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
4003 msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
3999 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4004 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4000 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
4005 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
4001 except ImportError:
4006 except ImportError:
4002 pass
4007 pass
4003
4008
4004 sys.exit(runner.run(sys.argv[1:]))
4009 sys.exit(runner.run(sys.argv[1:]))
@@ -1,43 +1,79 b''
1 Make a narrow clone then archive it
1 Make a narrow clone then archive it
2 $ . "$TESTDIR/narrow-library.sh"
2 $ . "$TESTDIR/narrow-library.sh"
3
3
4 $ hg init master
4 $ hg init master
5 $ cd master
5 $ cd master
6
6
7 $ for x in `$TESTDIR/seq.py 3`; do
7 $ for x in `$TESTDIR/seq.py 3`; do
8 > echo $x > "f$x"
8 > echo $x > "f$x"
9 > hg add "f$x"
9 > hg add "f$x"
10 > hg commit -m "Add $x"
10 > hg commit -m "Add $x"
11 > done
11 > done
12 $ cat >> .hg/hgrc << EOF
12 $ cat >> .hg/hgrc << EOF
13 > [narrowacl]
13 > [narrowacl]
14 > default.includes=f1 f2
14 > default.includes=f1 f2
15 > EOF
15 > EOF
16 $ hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid
16 $ hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid
17 $ cat hg.pid >> "$DAEMON_PIDS"
17 $ cat hg.pid >> "$DAEMON_PIDS"
18
18
19 $ cd ..
19 $ cd ..
20 $ hg clone http://localhost:$HGPORT1 narrowclone1
20 $ hg clone http://localhost:$HGPORT1 narrowclone1
21 requesting all changes
21 requesting all changes
22 adding changesets
22 adding changesets
23 adding manifests
23 adding manifests
24 adding file changes
24 adding file changes
25 added 3 changesets with 2 changes to 2 files
25 added 3 changesets with 2 changes to 2 files
26 new changesets * (glob)
26 new changesets * (glob)
27 updating to branch default
27 updating to branch default
28 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
29
29
30 The clone directory should only contain f1 and f2
30 The clone directory should only contain f1 and f2
31 $ ls -A -1 narrowclone1 | sort
31 $ ls -A -1 narrowclone1 | sort
32 .hg
32 .hg
33 f1
33 f1
34 f2
34 f2
35
35
36 Requirements should contain narrowhg
36 Requirements should contain narrowhg
37 $ hg debugrequires -R narrowclone1 | grep narrowhg
37 $ hg debugrequires -R narrowclone1 | grep narrowhg
38 narrowhg-experimental
38 narrowhg-experimental
39
39
40 NarrowHG should track f1 and f2
40 NarrowHG should track f1 and f2
41 $ hg -R narrowclone1 tracked
41 $ hg -R narrowclone1 tracked
42 I path:f1
42 I path:f1
43 I path:f2
43 I path:f2
44
45 Narrow should not be able to widen to include f3
46 $ hg -R narrowclone1 tracked --addinclude f3
47 comparing with http://localhost:$HGPORT1/
48 searching for changes
49 abort: The following includes are not accessible for test: ['path:f3']
50 [255]
51 $ ls -A -1 narrowclone1 | sort
52 .hg
53 f1
54 f2
55 $ hg -R narrowclone1 tracked
56 I path:f1
57 I path:f2
58
59 Narrow should allow widen to include f2
60 $ hg -R narrowclone1 tracked --removeinclude f2 > /dev/null
61 $ hg -R narrowclone1 tracked
62 I path:f1
63 $ ls -A -1 narrowclone1 | sort
64 .hg
65 f1
66 $ hg -R narrowclone1 tracked --addinclude f2
67 comparing with http://localhost:$HGPORT1/
68 searching for changes
69 adding changesets
70 adding manifests
71 adding file changes
72 added 0 changesets with 1 changes to 1 files
73 $ hg -R narrowclone1 tracked
74 I path:f1
75 I path:f2
76 $ ls -A -1 narrowclone1 | sort
77 .hg
78 f1
79 f2
General Comments 0
You need to be logged in to leave comments. Login now