)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"e5f0bd590822313fc694265f1dbd235025e822d2","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"In addition to the container sync stat. report, keeping per container"},{"line_number":10,"context_line":"statistics allows administrator with more control over bytes"},{"line_number":11,"context_line":"transfered over a specific time per user account"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: Ia8abcdaf53e466e8d60a957c76e32c2b2c5dc3fa"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bae84128_18891227","line":11,"updated":"2016-02-21 08:30:16.000000000","message":"I think it is important to point spell out that:\n1. The per container stats are crucial for billing purposes.\n2. They give the operator a \u0027progress bar\u0027 equivalent on the container\u0027s replication status","commit_id":"440abe8367889b1b331ba1a91768bde22bba871a"}],"doc/source/overview_container_sync.rst":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"0b11298c3c7de44e71d422348717f0dbe184373e","unresolved":false,"context_lines":[{"line_number":128,"context_line":"-----------------------------"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"Container Sync INFO level logs contains activity metrics and accounting"},{"line_number":131,"context_line":"information foe insightful tracking."},{"line_number":132,"context_line":"Currently two different statistics are collected:"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"About once an hour or so, accumulated statistics of all operations performed"}],"source_content_type":"text/x-rst","patch_set":13,"id":"1a122d0e_e8e4640e","line":131,"updated":"2016-04-18 06:34:33.000000000","message":"nit: foe -\u003e for","commit_id":"c96d5c671db9c96f65067d93c0a307cf4b7d91b4"}],"swift/container/sync.py":[{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"e5f0bd590822313fc694265f1dbd235025e822d2","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        self.container_failures \u003d 0"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"        #: Per container stats. These are collected per container."},{"line_number":210,"context_line":"        #: We rely on green threads safety for the arithmetics here."},{"line_number":211,"context_line":"        #: puts - the number of puts that were done for the container"},{"line_number":212,"context_line":"        #: deletes - the number of deletes that were fot the container"},{"line_number":213,"context_line":"        #: bytes - the total number of bytes transferred per the container"}],"source_content_type":"text/x-python","patch_set":1,"id":"bae84128_5810ba01","line":210,"range":{"start_line":210,"start_character":8,"end_line":210,"end_character":68},"updated":"2016-02-21 08:30:16.000000000","message":"There are no green threads yet (performance patch 2), so lets delete this line","commit_id":"440abe8367889b1b331ba1a91768bde22bba871a"},{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"e5f0bd590822313fc694265f1dbd235025e822d2","unresolved":false,"context_lines":[{"line_number":428,"context_line":"                    broker.set_x_container_sync_points(None, sync_point2)"},{"line_number":429,"context_line":"                if next_sync_point:"},{"line_number":430,"context_line":"                    broker.set_x_container_sync_points(None, next_sync_point)"},{"line_number":431,"context_line":"                else:"},{"line_number":432,"context_line":"                    next_sync_point \u003d sync_point2"},{"line_number":433,"context_line":"                sync_stage_time \u003d time()"},{"line_number":434,"context_line":"                while sync_stage_time \u003c stop_at:"}],"source_content_type":"text/x-python","patch_set":1,"id":"bae84128_f82f0e3c","line":431,"updated":"2016-02-21 08:30:16.000000000","message":"nit: I believe this else is redundant, although adds to code readability.","commit_id":"440abe8367889b1b331ba1a91768bde22bba871a"},{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"e5f0bd590822313fc694265f1dbd235025e822d2","unresolved":false,"context_lines":[{"line_number":454,"context_line":"                self.container_syncs +\u003d 1"},{"line_number":455,"context_line":"                self.logger.increment(\u0027syncs\u0027)"},{"line_number":456,"context_line":"                if sync_stage_time \u003e stop_at:"},{"line_number":457,"context_line":"                    sync_stage_time \u003d stop_at"},{"line_number":458,"context_line":"                self.container_report(start_at, sync_stage_time, path,"},{"line_number":459,"context_line":"                                      sync_point1, next_sync_point,"},{"line_number":460,"context_line":"                                      info, broker.get_max_row())"}],"source_content_type":"text/x-python","patch_set":1,"id":"bae84128_78e3fe05","line":457,"updated":"2016-02-21 08:30:16.000000000","message":"IMO, we want to report the real time when we have stopped.","commit_id":"440abe8367889b1b331ba1a91768bde22bba871a"},{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"e5f0bd590822313fc694265f1dbd235025e822d2","unresolved":false,"context_lines":[{"line_number":508,"context_line":"                except ClientException as err:"},{"line_number":509,"context_line":"                    if err.http_status !\u003d HTTP_NOT_FOUND:"},{"line_number":510,"context_line":"                        raise"},{"line_number":511,"context_line":"                self.container_deletes +\u003d 1"},{"line_number":512,"context_line":"                self.logger.increment(\u0027deletes\u0027)"},{"line_number":513,"context_line":"                self.logger.timing_since(\u0027deletes.timing\u0027, start_time)"},{"line_number":514,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"bae84128_d8f20ad2","line":511,"updated":"2016-02-21 08:30:16.000000000","message":"Shouldn\u0027t we increase the per container stats delete here?","commit_id":"440abe8367889b1b331ba1a91768bde22bba871a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":319,"context_line":"        self.container_stats[\u0027deletes\u0027] +\u003d 1"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _add_container_stats_bytes(self, bytes_count):"},{"line_number":322,"context_line":"        self.container_stats[\u0027bytes\u0027] +\u003d bytes_count"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"    def container_report(self, start, end, path,"},{"line_number":325,"context_line":"                         sync_point1, sync_point2, info,"}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_6e30349f","line":322,"updated":"2016-03-14 18:33:39.000000000","message":"the methods above seem unnecessary. Consider using:\n\n  container_stats \u003d collections.defaultdict(int)\n\nthen you can write inline:\n\n  container_stats[\u0027deletes\u0027] +\u003d 1\n\nand simply use container_stats.clear() to reset the dict when needed.","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"9d8066ede2e2a1849c9e355a733d61dcff14499f","unresolved":false,"context_lines":[{"line_number":321,"context_line":"    def _add_container_stats_bytes(self, bytes_count):"},{"line_number":322,"context_line":"        self.container_stats[\u0027bytes\u0027] +\u003d bytes_count"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"    def container_report(self, start, end, path,"},{"line_number":325,"context_line":"                         sync_point1, sync_point2, info,"},{"line_number":326,"context_line":"                         max_row):"},{"line_number":327,"context_line":"        self.logger.info(_(\u0027Container %(container)s sync report \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"5aef4532_535fe80d","line":324,"updated":"2016-03-08 20:12:32.000000000","message":"At some point we would like to have posts here.\nI wonder if we want to put a place holder saying N/A so that when it is available we do not break the parsing of this log line","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":321,"context_line":"    def _add_container_stats_bytes(self, bytes_count):"},{"line_number":322,"context_line":"        self.container_stats[\u0027bytes\u0027] +\u003d bytes_count"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"    def container_report(self, start, end, path,"},{"line_number":325,"context_line":"                         sync_point1, sync_point2, info,"},{"line_number":326,"context_line":"                         max_row):"},{"line_number":327,"context_line":"        self.logger.info(_(\u0027Container %(container)s sync report \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_931327b8","line":324,"in_reply_to":"5aef4532_535fe80d","updated":"2016-03-14 18:33:39.000000000","message":"+1","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":341,"context_line":"                          \u0027bytes\u0027: self.container_stats[\u0027bytes\u0027],"},{"line_number":342,"context_line":"                          \u0027point1\u0027: sync_point1,"},{"line_number":343,"context_line":"                          \u0027point2\u0027: sync_point2,"},{"line_number":344,"context_line":"                          \u0027total\u0027: max_row})"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def container_sync(self, path):"},{"line_number":347,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_4e6458e3","line":344,"updated":"2016-03-14 18:33:39.000000000","message":"The path arg is not being reported - either use it or remove it :)","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":351,"context_line":""},{"line_number":352,"context_line":"        :param path: the path to a container db"},{"line_number":353,"context_line":"        \"\"\""},{"line_number":354,"context_line":"        broker \u003d None"},{"line_number":355,"context_line":"        try:"},{"line_number":356,"context_line":"            broker \u003d ContainerBroker(path)"},{"line_number":357,"context_line":"            # The path we pass to the ContainerBroker is a real path of"}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_4eca986e","line":354,"updated":"2016-03-14 18:33:39.000000000","message":"you could declare container_stats \u003d defaultdict(int) here i.e. use a local variable scoped only to this method and pass it to container_sync_row.\n\n- its just an idea, it might prove easier to maintain IF the container sync daemon is ever made multi-threaded (did I hear that mentioned at hackathon?), but what you have is fine at the moment.","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"9d8066ede2e2a1849c9e355a733d61dcff14499f","unresolved":false,"context_lines":[{"line_number":453,"context_line":"                self.container_syncs +\u003d 1"},{"line_number":454,"context_line":"                self.logger.increment(\u0027syncs\u0027)"},{"line_number":455,"context_line":"                if sync_stage_time \u003e stop_at:"},{"line_number":456,"context_line":"                    sync_stage_time \u003d stop_at"},{"line_number":457,"context_line":"                self.container_report(start_at, sync_stage_time, path,"},{"line_number":458,"context_line":"                                      sync_point1, next_sync_point,"},{"line_number":459,"context_line":"                                      info, broker.get_max_row())"}],"source_content_type":"text/x-python","patch_set":5,"id":"5aef4532_e8139f64","line":456,"updated":"2016-03-08 20:12:32.000000000","message":"Not sure why we do not use sync_stage_time as is. Afterall, this is the real time where we are doing the report.\nTo be more specific, I think lines 455, 456 should be deleted","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":860,"name":"Donagh McCabe","email":"donagh.mccabe@gmail.com","username":"donagh-mccabe"},"change_message_id":"a19c2b8f8a3f5aa612a227394c479050fedffa3f","unresolved":false,"context_lines":[{"line_number":310,"context_line":""},{"line_number":311,"context_line":"    def container_report(self, start, end, sync_point1, sync_point2, info,"},{"line_number":312,"context_line":"                         max_row):"},{"line_number":313,"context_line":"        self.logger.info(_(\u0027Container %(container)s sync report \u0027"},{"line_number":314,"context_line":"                           \u0027for time window: %(start)s-%(end)s: \u0027"},{"line_number":315,"context_line":"                           \u0027%(puts)s puts, \u0027"},{"line_number":316,"context_line":"                           \u0027%(posts)s posts, \u0027"},{"line_number":317,"context_line":"                           \u0027%(deletes)s deletes, \u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa0719c6_30353cda","line":314,"range":{"start_line":313,"start_character":28,"end_line":314,"end_character":44},"updated":"2016-03-21 15:18:01.000000000","message":"With this layout of the message, we get something such as:\n\n    Mar 21 01:07:31 padawan-ccp-c1-m1-mgmt container-sync: Container AUTH_d788406d14744f37abd78bb6e040793c/mydocument sync report for time window: ...\n\nIf I\u0027m searching log files, it\u0027s easier to grep for something fixed, so it would be nicer if this read something such as\n\n    Mar 21 01:07:31 padawan-ccp-c1-m1-mgmt container-sync: Container sync report: container: AUTH_d788406d14744f37abd78bb6e040793c/mydocument for time window: ...\n\ni.e., put the words \"Container sync report\" together (without the name in the middle of the string). That way, I can watch the logs with something such as:\n\n    tail -f /var/log/swift/swift.log | grep \"Container sync report\"\n\nor, if I need a specific container:\n\n    tail -f /var/log/swift/swift.log | grep \"Container sync report\" |grep mydocuments\n\nAlso, since the purpose of this to help manage or monitor the sync progress, we should design the message to be easier to consume by a program. A radical suggestion might be to use json e.g.,:\n\n    Mar 21 01:07:31 padawan-ccp-c1-m1-mgmt container-sync: Container sync report: {\"container\": \"AUTH_d788406d14744f37abd78bb6e040793c/mydocument\", \"puts\": 0,....}\n\n(an advantage of this is that you could add a \"posts\" item without disturbing anyone)\n\nOr, if that\u0027s too much, at least be consistent in how you present the data, so instead of:\n\n    .... 8 deletes 1999 bytes sync_point1: blah ...\n\nit should be:\n\n    ... bytes: 1999 sync_point1: blah ...","commit_id":"9246781db4a9baba7901d8a5ce9a24e97ae12449"},{"author":{"_account_id":860,"name":"Donagh McCabe","email":"donagh.mccabe@gmail.com","username":"donagh-mccabe"},"change_message_id":"a19c2b8f8a3f5aa612a227394c479050fedffa3f","unresolved":false,"context_lines":[{"line_number":324,"context_line":"                          \u0027start\u0027: start,"},{"line_number":325,"context_line":"                          \u0027end\u0027: end,"},{"line_number":326,"context_line":"                          \u0027puts\u0027: self.container_stats[\u0027puts\u0027],"},{"line_number":327,"context_line":"                          \u0027posts\u0027: \"N/A\","},{"line_number":328,"context_line":"                          \u0027deletes\u0027: self.container_stats[\u0027deletes\u0027],"},{"line_number":329,"context_line":"                          \u0027bytes\u0027: self.container_stats[\u0027bytes\u0027],"},{"line_number":330,"context_line":"                          \u0027point1\u0027: sync_point1,"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa0719c6_30bffcfc","line":327,"range":{"start_line":327,"start_character":35,"end_line":327,"end_character":40},"updated":"2016-03-21 15:18:01.000000000","message":"If not using my json suggestion, the \"posts\" should not be \"N/A\" ... it should be 0 (zero)","commit_id":"9246781db4a9baba7901d8a5ce9a24e97ae12449"},{"author":{"_account_id":860,"name":"Donagh McCabe","email":"donagh.mccabe@gmail.com","username":"donagh-mccabe"},"change_message_id":"c79eb0eade8afe055d891096ee57b66a89b0c8cd","unresolved":false,"context_lines":[{"line_number":428,"context_line":"                    sync_stage_time \u003d time()"},{"line_number":429,"context_line":"                self.container_syncs +\u003d 1"},{"line_number":430,"context_line":"                self.logger.increment(\u0027syncs\u0027)"},{"line_number":431,"context_line":"                if sync_stage_time \u003e stop_at:"},{"line_number":432,"context_line":"                    sync_stage_time \u003d stop_at"},{"line_number":433,"context_line":"                self.container_report(start_at, sync_stage_time,"},{"line_number":434,"context_line":"                                      sync_point1, next_sync_point,"},{"line_number":435,"context_line":"                                      info, broker.get_max_row())"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa0719c6_6a3a6e9a","line":432,"range":{"start_line":431,"start_character":16,"end_line":432,"end_character":45},"updated":"2016-03-24 13:04:51.000000000","message":"In draft 5, eron suggested that lines 430,431 should be deleted. I\u0027m afraid I\u0027ve not spent enough time to understand why. However, it would help other reviewers if you explained why you thought it correct to keep the lines (i.e., you could click \"reply\" for Eron\u0027s comment in draft 5, or click reply here (draft 7)","commit_id":"7d3e65213ca2ec3f8283b80290c38621d9116844"},{"author":{"_account_id":860,"name":"Donagh McCabe","email":"donagh.mccabe@gmail.com","username":"donagh-mccabe"},"change_message_id":"b0d6be683401b27ccc88f8dcb97dc9b1e1fa8d1a","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                    broker.set_x_container_sync_points(None, sync_point2)"},{"line_number":399,"context_line":"                if next_sync_point:"},{"line_number":400,"context_line":"                    broker.set_x_container_sync_points(None, next_sync_point)"},{"line_number":401,"context_line":"                else:"},{"line_number":402,"context_line":"                    next_sync_point \u003d sync_point2"},{"line_number":403,"context_line":"                sync_stage_time \u003d time()"},{"line_number":404,"context_line":"                while sync_stage_time \u003c stop_at:"},{"line_number":405,"context_line":"                    rows \u003d broker.get_items_since(sync_point1, 1)"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba0121b8_e9d5de1b","line":402,"range":{"start_line":401,"start_character":16,"end_line":402,"end_character":49},"updated":"2016-04-01 12:02:43.000000000","message":"I don\u0027t think you use next_sync_point in the code below (since you now use info[\u0027x_container_sync_point2\u0027]","commit_id":"bf98ff2de80b0ff18cc213fb5672afe2efa8fc51"},{"author":{"_account_id":860,"name":"Donagh McCabe","email":"donagh.mccabe@gmail.com","username":"donagh-mccabe"},"change_message_id":"719ec8d4536d8f28c7c24a055b32fbe7735df571","unresolved":false,"context_lines":[{"line_number":294,"context_line":""},{"line_number":295,"context_line":"    def container_report(self, start, end, sync_point1, sync_point2, info,"},{"line_number":296,"context_line":"                         max_row):"},{"line_number":297,"context_line":"        self.logger.info(_(\u0027Container sync report: %(container)s,\u0027"},{"line_number":298,"context_line":"                           \u0027time window start: %(start)s, \u0027"},{"line_number":299,"context_line":"                           \u0027time window end: %(end)s, \u0027"},{"line_number":300,"context_line":"                           \u0027puts: %(puts)s, \u0027"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a18252c_688ab51c","line":297,"range":{"start_line":297,"start_character":60,"end_line":297,"end_character":66},"updated":"2016-04-14 11:31:17.000000000","message":"Missing space after comma, so get...\n\n    container-sync: Container sync report: AUTH_db78da6197664da489c82d3be8eb637e/src,time window start: 1460631865.95, time window end: ...\n\n...making it hard to find/read\n\nActually, given that we expect this to be processed by a program, could we drop the \",\" between fields -- it would be easier to parse (in my opinion)","commit_id":"d6a26cbd44d73975a887590b871a2c0d4860f6af"}],"test/unit/container/test_sync.py":[{"author":{"_account_id":11317,"name":"Eran Rom","email":"eran@itsonlyme.name","username":"eranr"},"change_message_id":"e5f0bd590822313fc694265f1dbd235025e822d2","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        self.sync_point1 \u003d -1"},{"line_number":58,"context_line":"        self.sync_point2 \u003d -1"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def get_max_row(self):"},{"line_number":61,"context_line":"        return 1"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    def get_info(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"bae84128_589a7a64","line":60,"updated":"2016-02-21 08:30:16.000000000","message":"Should we reflect here the real number of rows in the faked container db?","commit_id":"440abe8367889b1b331ba1a91768bde22bba871a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":793,"context_line":"            cs.container_sync(\u0027isa.db\u0027)"},{"line_number":794,"context_line":"            # Succeeds because no rows match"},{"line_number":795,"context_line":"            log_line \u003d cs.logger.get_lines_for_level(\u0027info\u0027)[0]"},{"line_number":796,"context_line":"            self.assertTrue(\u00273 puts\u0027 in log_line)"},{"line_number":797,"context_line":"            self.assertTrue(\u00272 deletes\u0027 in log_line)"},{"line_number":798,"context_line":"            self.assertTrue(\u00271100 bytes\u0027 in log_line)"},{"line_number":799,"context_line":"            self.assertTrue(\u0027sync_point1: 5\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_491f325f","line":796,"updated":"2016-03-14 18:33:39.000000000","message":"use self.assertIn(\u00273 puts\u0027, log_line) ... but see comment below about splitting the log_line","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":796,"context_line":"            self.assertTrue(\u00273 puts\u0027 in log_line)"},{"line_number":797,"context_line":"            self.assertTrue(\u00272 deletes\u0027 in log_line)"},{"line_number":798,"context_line":"            self.assertTrue(\u00271100 bytes\u0027 in log_line)"},{"line_number":799,"context_line":"            self.assertTrue(\u0027sync_point1: 5\u0027)"},{"line_number":800,"context_line":"            self.assertTrue(\u0027sync_point2: 5\u0027)"},{"line_number":801,"context_line":""},{"line_number":802,"context_line":"    def test_container_sync_row_delete(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_89277ab5","line":799,"updated":"2016-03-14 18:33:39.000000000","message":"that is always True - think you have missed \u0027in log_line\u0027","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4365053fe72c8cc6bdae7acb372ef4a68f0cd5fe","unresolved":false,"context_lines":[{"line_number":797,"context_line":"            self.assertTrue(\u00272 deletes\u0027 in log_line)"},{"line_number":798,"context_line":"            self.assertTrue(\u00271100 bytes\u0027 in log_line)"},{"line_number":799,"context_line":"            self.assertTrue(\u0027sync_point1: 5\u0027)"},{"line_number":800,"context_line":"            self.assertTrue(\u0027sync_point2: 5\u0027)"},{"line_number":801,"context_line":""},{"line_number":802,"context_line":"    def test_container_sync_row_delete(self):"},{"line_number":803,"context_line":"        self._test_container_sync_row_delete(None, None)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3afc51ec_a95b562d","line":800,"updated":"2016-03-14 18:33:39.000000000","message":"The asertions could be a little more rigorous, for example by splitting the log_line:\n\n  lines \u003d log_line.split(\u0027,\u0027)\n\nand then pop\u0027ping items from lines before asserting their value. That way the ordering of the log line is tested. e.g.\n\n  self.assertTrue(\u0027sync_point2: 5\u0027, lines.pop())","commit_id":"eb216d3ae2f036ef3013c3c4080941044dcd5792"}]}
