[autotest] test failure send email via a different gmail account

Test failures notification emails sometimes causing quota issues
when a huge amount of notifications are sent out around the same time.

Move it to a different gmail account to gurantee that more
critical emails like inventory emails can be sent out on time.

Also, add support for a "creds" dir.

TEST=send email using the new gmail account:
- with gmail_api_credentials_test_failure and creds dir set.
  confirm using new credentials.
- without gmail_api_credentials_test_failure and creds dir set.
  confirm using the default credentials.
BUG=chromium:541824;chromium:567882

Change-Id: I191e14303cdead164147d188ac495da6f7c18ba6
Reviewed-on: https://chromium-review.googlesource.com/316680
Commit-Ready: Fang Deng <fdeng@chromium.org>
Tested-by: Fang Deng <fdeng@chromium.org>
Reviewed-by: Fang Deng <fdeng@chromium.org>
diff --git a/global_config.ini b/global_config.ini
index 41eb0e2..e4ebaa3 100644
--- a/global_config.ini
+++ b/global_config.ini
@@ -151,6 +151,10 @@
 # AFE server connected to the master DB.
 global_afe_hostname: cautotest
 
+# Credential directory where all credentials files should go. If not specified,
+# will look for credentils in autotest root dir.
+creds_dir:
+
 [SCHEDULER]
 die_on_orphans: False
 enable_scheduler: True
@@ -329,7 +333,8 @@
 chromium_build_url: http://build.chromium.org/p/chromiumos/
 sheriffs: USE SHADOW SHERIFFS
 lab_sheriffs: USE SHADOW SHERIFFS
-gmail_api_credentials: USE SHADOW GMAIL_API_CREDENTIALS
+gmail_api_credentials:
+gmail_api_credentials_test_failure:
 
 
 [POOL_INSTANCE_SHARDING]
diff --git a/server/cros/dynamic_suite/reporting.py b/server/cros/dynamic_suite/reporting.py
index b8298a8..9a88ff3 100644
--- a/server/cros/dynamic_suite/reporting.py
+++ b/server/cros/dynamic_suite/reporting.py
@@ -38,6 +38,8 @@
 
 CHROMIUM_EMAIL_ADDRESS = global_config.global_config.get_config_value(
         BUG_CONFIG_SECTION, 'chromium_email_address', default='')
+EMAIL_CREDS_FILE = global_config.global_config.get_config_value(
+        'NOTIFICATIONS', 'gmail_api_credentials_test_failure', default=None)
 
 
 class Bug(object):
@@ -912,8 +914,9 @@
         to_set.add(bug_template.get('owner'))
     recipients = ', '.join(to_set)
     try:
-        gmail_lib.send_email(recipients, bug.title(), bug.summary(),
-                             retry=False)
+        gmail_lib.send_email(
+            recipients, bug.title(), bug.summary(), retry=False,
+            creds_path=site_utils.get_creds_abspath(EMAIL_CREDS_FILE))
     except Exception:
         autotest_stats.Counter(EMAIL_COUNT_KEY % 'fail').increment()
         raise
diff --git a/server/site_utils.py b/server/site_utils.py
index 1ebff49..6d44467 100644
--- a/server/site_utils.py
+++ b/server/site_utils.py
@@ -691,3 +691,24 @@
         return (machine['hostname'], machine['host_attributes'])
     else:
         return (machine, {})
+
+
+def get_creds_abspath(creds_file):
+    """Returns the abspath of the credentials file.
+
+    If creds_file is already an absolute path, just return it.
+    Otherwise, assume it is located in the creds directory
+    specified in global_config and return the absolute path.
+
+    @param: creds_path, a path to the credentials.
+    @return: An absolute path to the credentials file.
+    """
+    if not creds_file:
+        return None
+    if os.path.isabs(creds_file):
+        return creds_file
+    creds_dir = global_config.global_config.get_config_value(
+            'SERVER', 'creds_dir', default='')
+    if not creds_dir or not os.path.exists(creds_dir):
+        creds_dir = common.autotest_dir
+    return os.path.join(creds_dir, creds_file)
diff --git a/site_utils/gmail_lib.py b/site_utils/gmail_lib.py
index 3cb0f89..4d3d459 100755
--- a/site_utils/gmail_lib.py
+++ b/site_utils/gmail_lib.py
@@ -27,6 +27,7 @@
 import common
 from autotest_lib.client.common_lib import global_config
 from autotest_lib.client.common_lib.cros.graphite import autotest_stats
+from autotest_lib.server import utils as server_utils
 from chromite.lib import retry_util
 
 try:
@@ -39,8 +40,8 @@
 
 
 EMAIL_COUNT_KEY = 'emails.%s'
-DEFAULT_GMAIL_CREDS_PATH = global_config.global_config.get_config_value(
-        'NOTIFICATIONS', 'gmail_api_credentials', default='')
+DEFAULT_CREDS_FILE = global_config.global_config.get_config_value(
+        'NOTIFICATIONS', 'gmail_api_credentials', default=None)
 RETRY_DELAY = 5
 RETRY_BACKOFF_FACTOR = 1.5
 MAX_RETRY = 10
@@ -117,26 +118,19 @@
                 raise
 
 
-def get_default_creds_abspath():
-    """Returns the abspath of the gmail api credentials file.
-
-    @return: A path to the oauth2 credentials file.
-    """
-    auth_creds = DEFAULT_GMAIL_CREDS_PATH
-    return (auth_creds if os.path.isabs(auth_creds) else
-            os.path.join(common.autotest_dir, auth_creds))
-
-
-def send_email(to, subject, message_text, retry=True):
+def send_email(to, subject, message_text, retry=True, creds_path=None):
     """Send email.
 
     @param to: The recipients, separated by comma.
     @param subject: Subject of the email.
     @param message_text: Text to send.
     @param retry: If retry on retriable failures as defined in RETRIABLE_MSGS.
+    @param creds_path: The credential path for gmail account, if None,
+                       will use DEFAULT_CREDS_FILE.
     """
-    auth_creds = get_default_creds_abspath()
-    if not os.path.isfile(auth_creds):
+    auth_creds = server_utils.get_creds_abspath(
+        creds_path or DEFAULT_CREDS_FILE)
+    if not auth_creds or not os.path.isfile(auth_creds):
         logging.error('Failed to send email to %s: Credential file does not'
                       'exist: %s. If this is a prod server, puppet should'
                       'install it. If you need to be able to send email, '