Merge "Sync with upstream OpenBSD stdio."
diff --git a/tools/bionicbb/gerrit.py b/tools/bionicbb/gerrit.py
index a3d5887..76e42b4 100644
--- a/tools/bionicbb/gerrit.py
+++ b/tools/bionicbb/gerrit.py
@@ -24,6 +24,11 @@
         super(GerritError, self).__init__('Error {}: {}'.format(code, url))
 
 
+def get_commit(change_id, revision):
+    return json.loads(
+        call('/changes/{}/revisions/{}/commit'.format(change_id, revision)))
+
+
 def call(endpoint, method='GET'):
     if method != 'GET':
         raise NotImplementedError('Currently only HTTP GET is supported.')
diff --git a/tools/bionicbb/gmail_listener.py b/tools/bionicbb/gmail_listener.py
index 8718484..6a8b9e6 100644
--- a/tools/bionicbb/gmail_listener.py
+++ b/tools/bionicbb/gmail_listener.py
@@ -51,6 +51,16 @@
     return headers
 
 
+def should_skip_message(info):
+    if info['MessageType'] in ('newchange', 'newpatchset', 'comment'):
+        commit = gerrit.get_commit(info['Change-Id'], info['PatchSet'])
+        committer = commit['committer']['email']
+        return not committer.endswith('@google.com')
+    else:
+        raise ValueError('should_skip_message() is only valid for new '
+                         'changes, patch sets, and commits.')
+
+
 def build_service():
     from apiclient.discovery import build
     from oauth2client.client import flow_from_clientsecrets
@@ -200,6 +210,8 @@
 
 
 def handle_change(gerrit_info, _, dry_run):
+    if should_skip_message(gerrit_info):
+        return True
     return build_project(gerrit_info, dry_run)
 handle_newchange = handle_change
 handle_newpatchset = handle_change
@@ -230,6 +242,10 @@
     if 'Verified+1' in body:
         drop_rejection(gerrit_info, dry_run)
 
+    # TODO(danalbert): Needs to be based on the account that made the comment.
+    if should_skip_message(gerrit_info):
+        return True
+
     command_map = {
         'clean': lambda: clean_project(gerrit_info, dry_run),
         'retry': lambda: build_project(gerrit_info, dry_run),
diff --git a/tools/bionicbb/test_gmail_listener.py b/tools/bionicbb/test_gmail_listener.py
new file mode 100644
index 0000000..6545cdc
--- /dev/null
+++ b/tools/bionicbb/test_gmail_listener.py
@@ -0,0 +1,64 @@
+import gmail_listener
+import mock
+import unittest
+
+
+class TestShouldSkipMessage(unittest.TestCase):
+    def test_accepts_googlers(self):
+        for message_type in ('newchange', 'newpatchset', 'comment'):
+            with mock.patch('gerrit.get_commit') as mock_commit:
+                mock_commit.return_value = {
+                    'committer': {'email': 'googler@google.com'}
+                }
+
+                self.assertFalse(gmail_listener.should_skip_message({
+                    'MessageType': message_type,
+                    'Change-Id': '',
+                    'PatchSet': '',
+                }))
+
+    def test_rejects_non_googlers(self):
+        for message_type in ('newchange', 'newpatchset', 'comment'):
+            with mock.patch('gerrit.get_commit') as mock_commit:
+                mock_commit.return_value = {
+                    'committer': {'email': 'fakegoogler@google.com.fake.com'}
+                }
+
+                self.assertTrue(gmail_listener.should_skip_message({
+                    'MessageType': message_type,
+                    'Change-Id': '',
+                    'PatchSet': '',
+                }))
+
+            with mock.patch('gerrit.get_commit') as mock_commit:
+                mock_commit.return_value = {
+                    'committer': {'email': 'johndoe@example.com'}
+                }
+
+                self.assertTrue(gmail_listener.should_skip_message({
+                    'MessageType': message_type,
+                    'Change-Id': '',
+                    'PatchSet': '',
+                }))
+
+    def test_calls_gerrit_get_commit(self):  # pylint: disable=no-self-use
+        for message_type in ('newchange', 'newpatchset', 'comment'):
+            with mock.patch('gerrit.get_commit') as mock_commit:
+                gmail_listener.should_skip_message({
+                    'MessageType': message_type,
+                    'Change-Id': 'foo',
+                    'PatchSet': 'bar',
+                })
+            mock_commit.assert_called_once_with('foo', 'bar')
+
+            with mock.patch('gerrit.get_commit') as mock_commit:
+                gmail_listener.should_skip_message({
+                    'MessageType': message_type,
+                    'Change-Id': 'baz',
+                    'PatchSet': 'qux',
+                })
+            mock_commit.assert_called_once_with('baz', 'qux')
+
+
+if __name__ == '__main__':
+    unittest.main()