)]}'
{"oslo_middleware/stats.py":[{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"2bda10fc8642f5e88e3d77e7c1d5c2ad1ea572eb","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import re"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import logging"},{"line_number":18,"context_line":"from statsd import StatsClient"},{"line_number":19,"context_line":"import webob.dec"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7a77a97e_be5556c7","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":14},"updated":"2016-11-22 14:03:40.000000000","message":"group with re","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"c6d0a2da865e71ecd2d1206245d473370c535e87","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import re"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import logging"},{"line_number":18,"context_line":"from statsd import StatsClient"},{"line_number":19,"context_line":"import webob.dec"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5a74a57a_301b471d","line":17,"range":{"start_line":17,"start_character":0,"end_line":17,"end_character":14},"in_reply_to":"7a77a97e_be5556c7","updated":"2016-11-23 23:19:29.000000000","message":"Done","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"2bda10fc8642f5e88e3d77e7c1d5c2ad1ea572eb","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        timer.\u003cappname\u003e.\u003cMETHOD\u003e.\u003cpath\u003e.\u003cfrom\u003e.\u003curl\u003e"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    Note that URLs with versions in them (pretty much all of Openstack) are"},{"line_number":42,"context_line":"    always processed to remove the dot, so for example v2.0 becomes v02,"},{"line_number":43,"context_line":"    and v1.1 becomes v11, since a dot \u0027.\u0027 has special meaning in Graphite."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    The original StatsD is written in nodejs. If you want a Python"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a77a97e_deb93217","line":42,"range":{"start_line":42,"start_character":68,"end_line":42,"end_character":71},"updated":"2016-11-22 14:03:40.000000000","message":"v20... is it better to just replace \u0027.\u0027 with \u0027_\u0027?","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"c6d0a2da865e71ecd2d1206245d473370c535e87","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        timer.\u003cappname\u003e.\u003cMETHOD\u003e.\u003cpath\u003e.\u003cfrom\u003e.\u003curl\u003e"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    Note that URLs with versions in them (pretty much all of Openstack) are"},{"line_number":42,"context_line":"    always processed to remove the dot, so for example v2.0 becomes v02,"},{"line_number":43,"context_line":"    and v1.1 becomes v11, since a dot \u0027.\u0027 has special meaning in Graphite."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    The original StatsD is written in nodejs. If you want a Python"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a74a57a_90097b98","line":42,"range":{"start_line":42,"start_character":68,"end_line":42,"end_character":71},"in_reply_to":"7a77a97e_deb93217","updated":"2016-11-23 23:19:29.000000000","message":"Yes! Good spot.","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"2bda10fc8642f5e88e3d77e7c1d5c2ad1ea572eb","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        self.application \u003d application"},{"line_number":66,"context_line":"        self.stat_name \u003d conf.get(\u0027name\u0027)"},{"line_number":67,"context_line":"        if self.stat_name is None:"},{"line_number":68,"context_line":"            raise TypeError(\u0027name must be specified\u0027)"},{"line_number":69,"context_line":"        self.stats_host \u003d conf.get(\u0027stats_host\u0027)"},{"line_number":70,"context_line":"        if self.stats_host is None:"},{"line_number":71,"context_line":"            raise TypeError(\u0027stats_host must be specified\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a77a97e_3e35c645","line":68,"range":{"start_line":68,"start_character":18,"end_line":68,"end_character":27},"updated":"2016-11-22 14:03:40.000000000","message":"TypeError seems like wrong error to raise considering it\u0027s description. NameError maybe? or a custom error?\n\nhttps://docs.python.org/3/library/exceptions.html#TypeError","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"c6d0a2da865e71ecd2d1206245d473370c535e87","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        self.application \u003d application"},{"line_number":66,"context_line":"        self.stat_name \u003d conf.get(\u0027name\u0027)"},{"line_number":67,"context_line":"        if self.stat_name is None:"},{"line_number":68,"context_line":"            raise TypeError(\u0027name must be specified\u0027)"},{"line_number":69,"context_line":"        self.stats_host \u003d conf.get(\u0027stats_host\u0027)"},{"line_number":70,"context_line":"        if self.stats_host is None:"},{"line_number":71,"context_line":"            raise TypeError(\u0027stats_host must be specified\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a74a57a_53328df2","line":68,"range":{"start_line":68,"start_character":18,"end_line":68,"end_character":27},"in_reply_to":"7a77a97e_3e35c645","updated":"2016-11-23 23:19:29.000000000","message":"Done","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":15,"context_line":"import logging"},{"line_number":16,"context_line":"import re"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from statsd import StatsClient"},{"line_number":19,"context_line":"import webob.dec"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from oslo_middleware import base"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_4de5a335","line":18,"updated":"2017-01-02 20:16:26.000000000","message":"The reason we usually import a module instead of a class is to make it possible to mock the thing being used. If you change this to \"import statsd\" then below you don\u0027t need _get_stats_client().","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"94f1e07fe2ef5327df59bb7889a8eb2d8b1b1035","unresolved":false,"context_lines":[{"line_number":15,"context_line":"import logging"},{"line_number":16,"context_line":"import re"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from statsd import StatsClient"},{"line_number":19,"context_line":"import webob.dec"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from oslo_middleware import base"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_b3dd8c44","line":18,"in_reply_to":"ba5201f7_4de5a335","updated":"2017-01-03 01:54:56.000000000","message":"Done","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":23,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":24,"context_line":"VERSION_REGEX \u003d re.compile(\"/(v[0-9]{1}\\.[0-9]{1})\")"},{"line_number":25,"context_line":"UUID_REGEX \u003d re.compile("},{"line_number":26,"context_line":"    \u0027.*(\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}).*\u0027)"},{"line_number":27,"context_line":"# UUIDs without the - char, used in some places in Nova URLs."},{"line_number":28,"context_line":"SHORT_UUID_REGEX \u003d re.compile(\u0027.*(\\.[0-9a-fA-F]{32}).*\u0027)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_8deeab20","line":26,"updated":"2017-01-02 20:16:26.000000000","message":"You could add the case-insensitive flag to this, just in case.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"94f1e07fe2ef5327df59bb7889a8eb2d8b1b1035","unresolved":false,"context_lines":[{"line_number":23,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":24,"context_line":"VERSION_REGEX \u003d re.compile(\"/(v[0-9]{1}\\.[0-9]{1})\")"},{"line_number":25,"context_line":"UUID_REGEX \u003d re.compile("},{"line_number":26,"context_line":"    \u0027.*(\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}).*\u0027)"},{"line_number":27,"context_line":"# UUIDs without the - char, used in some places in Nova URLs."},{"line_number":28,"context_line":"SHORT_UUID_REGEX \u003d re.compile(\u0027.*(\\.[0-9a-fA-F]{32}).*\u0027)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_53ef00e8","line":26,"in_reply_to":"ba5201f7_8deeab20","updated":"2017-01-03 01:54:56.000000000","message":"Done","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class StatsMiddleware(base.ConfigurableMiddleware):"},{"line_number":32,"context_line":"    \"\"\"Send stats to statsd based on API requests."},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    Examines the URL path and request method, and sends a stat count and timer"},{"line_number":35,"context_line":"    to a statsd host based on the path/method."}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_ad7c4f73","line":32,"updated":"2017-01-02 20:16:26.000000000","message":"I\u0027ve rechecked to verify, but I believe this class docstring will end up in the documentation. If not, we\u0027ll need to make that change too. In the mean time, I have a few markup suggestions inline.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    to a statsd host based on the path/method."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    If your statsd is configured to send stats to Graphite, you\u0027ll end up with"},{"line_number":38,"context_line":"    stat names of the form:"},{"line_number":39,"context_line":"        timer.\u003cappname\u003e.\u003cMETHOD\u003e.\u003cpath\u003e.\u003cfrom\u003e.\u003curl\u003e"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    Note that URLs with versions in them (pretty much all of Openstack)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_ed965793","line":38,"updated":"2017-01-02 20:16:26.000000000","message":"End the line with a double colon to start a literal block, then add a blank line between 38 and 39 to offset that literal block containing the format string.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"94f1e07fe2ef5327df59bb7889a8eb2d8b1b1035","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    to a statsd host based on the path/method."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    If your statsd is configured to send stats to Graphite, you\u0027ll end up with"},{"line_number":38,"context_line":"    stat names of the form:"},{"line_number":39,"context_line":"        timer.\u003cappname\u003e.\u003cMETHOD\u003e.\u003cpath\u003e.\u003cfrom\u003e.\u003curl\u003e"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    Note that URLs with versions in them (pretty much all of Openstack)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_b3b4acf2","line":38,"in_reply_to":"ba5201f7_ed965793","updated":"2017-01-03 01:54:56.000000000","message":"Done","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    (and much nicer IMO)."},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    The Paste config must contain some parameters. Configure a filter like"},{"line_number":51,"context_line":"    this:"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    [filter:stats]"},{"line_number":54,"context_line":"    paste.filter_factory \u003d oslo_middleware.stats:StatsMiddleware.factory"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_2d913f9a","line":51,"updated":"2017-01-02 20:16:26.000000000","message":"End this line with a double colon, as described above. Then indent all of lines 53-61 a couple of spaces to indicate that they are the literal block.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"94f1e07fe2ef5327df59bb7889a8eb2d8b1b1035","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    (and much nicer IMO)."},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    The Paste config must contain some parameters. Configure a filter like"},{"line_number":51,"context_line":"    this:"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    [filter:stats]"},{"line_number":54,"context_line":"    paste.filter_factory \u003d oslo_middleware.stats:StatsMiddleware.factory"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_73a164a9","line":51,"in_reply_to":"ba5201f7_2d913f9a","updated":"2017-01-03 01:54:56.000000000","message":"Done","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _get_stats_client(self, host):"},{"line_number":78,"context_line":"        # Mocking point for tests."},{"line_number":79,"context_line":"        return StatsClient(host)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    @staticmethod"},{"line_number":82,"context_line":"    def strip_short_uuid(path):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_8dd5cb44","line":79,"updated":"2017-01-02 20:16:26.000000000","message":"See comment above about import.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"94f1e07fe2ef5327df59bb7889a8eb2d8b1b1035","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _get_stats_client(self, host):"},{"line_number":78,"context_line":"        # Mocking point for tests."},{"line_number":79,"context_line":"        return StatsClient(host)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    @staticmethod"},{"line_number":82,"context_line":"    def strip_short_uuid(path):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_93a6c8bf","line":79,"in_reply_to":"ba5201f7_8dd5cb44","updated":"2017-01-03 01:54:56.000000000","message":"Done","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"}],"oslo_middleware/tests/test_stats.py":[{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"ae289236a7027fde66ade4954a59df6d1babeef3","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_random_method(self):"},{"line_number":78,"context_line":"        choices \u003d [\u0027GET\u0027, \u0027PUT\u0027, \u0027POST\u0027, \u0027HEAD\u0027]"},{"line_number":79,"context_line":"        return random.choice(choices)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def perform_request(self, app, path, method):"},{"line_number":82,"context_line":"        req \u003d webob.Request.blank(path, method\u003dmethod)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_ad41af0d","line":79,"updated":"2017-01-02 20:16:26.000000000","message":"Don\u0027t introduce non-deterministic behavior into the test suite. If you want to test with a variety of methods without writing the tests out explicitly, use testscenarios to build them dynamically. If the method name doesn\u0027t matter, just hard-code it.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"c1bb2804c55ea95974ea72695f167ff7c2ae3269","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_random_method(self):"},{"line_number":78,"context_line":"        choices \u003d [\u0027GET\u0027, \u0027PUT\u0027, \u0027POST\u0027, \u0027HEAD\u0027]"},{"line_number":79,"context_line":"        return random.choice(choices)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def perform_request(self, app, path, method):"},{"line_number":82,"context_line":"        req \u003d webob.Request.blank(path, method\u003dmethod)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_1780e145","line":79,"in_reply_to":"ba5201f7_9d6327dc","updated":"2017-01-03 23:14:16.000000000","message":"Thank you for your ongoing review Doug.\n\nHowever, I could not disagree any more with your assessment here. The whole point of random inputs is to find bugs so if you\u0027re getting a 1% failure rate then you have bugs to fix. This is *nothing* to do with poor testing and *everything* to do with poor code under test.\n\nIn this instance the value is pass-through. Therefore the best test practice is to randomise it and check that the same value appears on the other side.  The test intent shows that the value is irrelevant, only that the data passes.\n\nPeople who know plenty about testing have even written frameworks that work on this principle: See http://hypothesis.works/ and https://jml.io/2016/06/evolving-toward-property-based-testing-with-hypothesis.html\n\nFor a quiet life, I will downgrade my test capability, but I do so under protest.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"94f1e07fe2ef5327df59bb7889a8eb2d8b1b1035","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_random_method(self):"},{"line_number":78,"context_line":"        choices \u003d [\u0027GET\u0027, \u0027PUT\u0027, \u0027POST\u0027, \u0027HEAD\u0027]"},{"line_number":79,"context_line":"        return random.choice(choices)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def perform_request(self, app, path, method):"},{"line_number":82,"context_line":"        req \u003d webob.Request.blank(path, method\u003dmethod)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_d3b5b0cd","line":79,"in_reply_to":"ba5201f7_ad41af0d","updated":"2017-01-03 01:54:56.000000000","message":"One of the pieces of craftmanship around writing tests is that of conveying test intent.\n\nI\u0027ve been writing Python tests for 10 years and one of the guiding principles I\u0027ve learned is to randomise input that\u0027s irrelevant to the function of the code under test.  In the cases here, the method is irrelevant other than that it is included in the stats name generated. I could, in fact, use an entirely random string that is not a valid http method as the code doesn\u0027t care at all about the method name, it\u0027s simply copied to the stats name in the right part, which is exactly what\u0027s getting tested.\n\nUsing testscenarios here would be entirely wrong, based on this principle.\n\nThis code is logically no different to the use of uuid.uuid4() that is used here and other places throughout Openstack as test input where the input doesn\u0027t matter.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"2cbf0e34f5b7ae34c20401e6653ee3ae3e24e853","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_random_method(self):"},{"line_number":78,"context_line":"        choices \u003d [\u0027GET\u0027, \u0027PUT\u0027, \u0027POST\u0027, \u0027HEAD\u0027]"},{"line_number":79,"context_line":"        return random.choice(choices)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def perform_request(self, app, path, method):"},{"line_number":82,"context_line":"        req \u003d webob.Request.blank(path, method\u003dmethod)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5201f7_9d6327dc","line":79,"in_reply_to":"ba5201f7_d3b5b0cd","updated":"2017-01-03 14:22:36.000000000","message":"We run hundreds of test jobs *daily*. There\u0027s enough non-deterministic behavior introduced by the environment running the tests that we see weird failures all the time. At the rate those jobs run, even a 1% failure rate adds up quickly, and slows down the community. We therefore do not write tests with random inputs where we can avoid it.\n\nWe live with random UUID values all over the place because we need uniqueness and that code is well tested to provide values the conform to the spec. If the method name here is truly not important, then the randomness does not provide a useful input to the test and sets a bad example of practices for writing tests in our environment. While it may not have any impact on these tests, it is not always easy to reason about these sorts of things and some other developer may come along and copy the concept in other tests where it does matter.","commit_id":"f1bf0b1b46c6fe56ff90f8e660e87471da927348"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"90870cc728ab993edb0acdc3571531a0cc23838e","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def test_strips_dots_from_version(self):"},{"line_number":43,"context_line":"        num1 \u003d random.randint(0, 9)"},{"line_number":44,"context_line":"        num2 \u003d random.randint(0, 9)"},{"line_number":45,"context_line":"        path \u003d \"/v{}.{}/foo.bar/bar.foo\".format(num1, num2)"},{"line_number":46,"context_line":"        stat \u003d stats.StatsMiddleware.strip_dot_from_version(path)"},{"line_number":47,"context_line":"        self.assertEqual("}],"source_content_type":"text/x-python","patch_set":5,"id":"ba5201f7_1dcbb7a6","line":44,"updated":"2017-01-03 14:23:30.000000000","message":"Remove the use of random.","commit_id":"23a670134f90a182c0675e8ab66d040e60e4d6d3"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"90870cc728ab993edb0acdc3571531a0cc23838e","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def get_random_method(self):"},{"line_number":78,"context_line":"        choices \u003d [\u0027GET\u0027, \u0027PUT\u0027, \u0027POST\u0027, \u0027HEAD\u0027]"},{"line_number":79,"context_line":"        return random.choice(choices)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def perform_request(self, app, path, method):"},{"line_number":82,"context_line":"        req \u003d webob.Request.blank(path, method\u003dmethod)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba5201f7_9de88712","line":79,"updated":"2017-01-03 14:23:30.000000000","message":"Remove the use of random.","commit_id":"23a670134f90a182c0675e8ab66d040e60e4d6d3"}],"requirements.txt":[{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"dfe72687b85d15fc89929db47c2f7c5efb20c766","unresolved":false,"context_lines":[{"line_number":12,"context_line":"stevedore\u003e\u003d1.16.0 # Apache-2.0"},{"line_number":13,"context_line":"WebOb\u003e\u003d1.2.3 # MIT"},{"line_number":14,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":15,"context_line":"statsd\u003e\u003d3.2.1 # MIT"}],"source_content_type":"text/plain","patch_set":2,"id":"7a77a97e_044b7bb1","line":15,"updated":"2016-11-21 23:30:06.000000000","message":"should be in test-requirements because it\u0027s only relevant to one middleware.","commit_id":"816e763fe68c521489443e9a3f791645db616910"},{"author":{"_account_id":15750,"name":"Julian Edwards","email":"bigjools@gmail.com","username":"bigjools"},"change_message_id":"c6d0a2da865e71ecd2d1206245d473370c535e87","unresolved":false,"context_lines":[{"line_number":12,"context_line":"stevedore\u003e\u003d1.16.0 # Apache-2.0"},{"line_number":13,"context_line":"WebOb\u003e\u003d1.2.3 # MIT"},{"line_number":14,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":15,"context_line":"statsd\u003e\u003d3.2.1 # MIT"}],"source_content_type":"text/plain","patch_set":2,"id":"5a74a57a_b33be1ea","line":15,"in_reply_to":"7a77a97e_044b7bb1","updated":"2016-11-23 23:19:29.000000000","message":"Really? None of the other filters follow this. I thought test-requirements was only used by tox.","commit_id":"816e763fe68c521489443e9a3f791645db616910"}]}
