blob: b0ec48b17d7d3ff8473772858d630667a4105457 [file] [log] [blame]
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for the gdata_lib module."""
from __future__ import print_function
import getpass
import mox
import re
import atom.service
import gdata.projecthosting.client as gd_ph_client
import gdata.spreadsheet.service
from chromite.lib import cros_test_lib
from chromite.lib import gdata_lib
from chromite.lib import osutils
# pylint: disable=W0212,E1101
class GdataLibTest(cros_test_lib.OutputTestCase):
"""Tests for methods that escape/unescape strings for speadsheets."""
def testPrepColNameForSS(self):
tests = {
'foo': 'foo',
'Foo': 'foo',
'FOO': 'foo',
'foo bar': 'foobar',
'Foo Bar': 'foobar',
'F O O B A R': 'foobar',
'Foo/Bar': 'foobar',
'Foo Bar/Dude': 'foobardude',
'foo/bar': 'foobar',
}
for col in tests:
expected = tests[col]
self.assertEquals(expected, gdata_lib.PrepColNameForSS(col))
self.assertEquals(expected, gdata_lib.PrepColNameForSS(expected))
def testPrepValForSS(self):
tests = {
None: None,
'': '',
'foo': 'foo',
'foo123': 'foo123',
'123': "'123",
'1.2': "'1.2",
}
for val in tests:
expected = tests[val]
self.assertEquals(expected, gdata_lib.PrepValForSS(val))
def testPrepRowForSS(self):
vals = {
None: None,
'': '',
'foo': 'foo',
'foo123': 'foo123',
'123': "'123",
'1.2': "'1.2",
}
# Create before and after rows (rowIn, rowOut).
rowIn = {}
rowOut = {}
col = 'a' # Column names not important.
for valIn in vals:
valOut = vals[valIn]
rowIn[col] = valIn
rowOut[col] = valOut
col = chr(ord(col) + 1) # Change column name.
self.assertEquals(rowOut, gdata_lib.PrepRowForSS(rowIn))
def testScrubValFromSS(self):
tests = {
None: None,
'foo': 'foo',
'123': '123',
"'123": '123',
}
for val in tests:
expected = tests[val]
self.assertEquals(expected, gdata_lib.ScrubValFromSS(val))
class CredsTest(cros_test_lib.MockOutputTestCase):
"""Tests related to user credentials."""
USER = 'somedude@chromium.org'
PASSWORD = 'worldsbestpassword'
DOCS_TOKEN = 'SomeDocsAuthToken'
TRACKER_TOKEN = 'SomeTrackerAuthToken'
@osutils.TempFileDecorator
def testStoreLoadCreds(self):
# This is the replay script for the test.
creds = gdata_lib.Creds()
# This is the test verification.
with self.OutputCapturer():
creds.SetCreds(self.USER, self.PASSWORD)
self.assertEquals(self.USER, creds.user)
self.assertEquals(self.PASSWORD, creds.password)
self.assertTrue(creds.creds_dirty)
creds.StoreCreds(self.tempfile)
self.assertEquals(self.USER, creds.user)
self.assertEquals(self.PASSWORD, creds.password)
self.assertFalse(creds.creds_dirty)
# Clear user/password before loading from just-created file.
creds.user = None
creds.password = None
self.assertEquals(None, creds.user)
self.assertEquals(None, creds.password)
creds.LoadCreds(self.tempfile)
self.assertEquals(self.USER, creds.user)
self.assertEquals(self.PASSWORD, creds.password)
self.assertFalse(creds.creds_dirty)
@osutils.TempFileDecorator
def testStoreLoadToken(self):
# This is the replay script for the test.
creds = gdata_lib.Creds()
creds.user = self.USER
# This is the test verification.
with self.OutputCapturer():
creds.SetDocsAuthToken(self.DOCS_TOKEN)
self.assertEquals(self.DOCS_TOKEN, creds.docs_auth_token)
self.assertTrue(creds.token_dirty)
creds.SetTrackerAuthToken(self.TRACKER_TOKEN)
self.assertEquals(self.TRACKER_TOKEN, creds.tracker_auth_token)
self.assertTrue(creds.token_dirty)
creds.StoreAuthToken(self.tempfile)
self.assertEquals(self.DOCS_TOKEN, creds.docs_auth_token)
self.assertEquals(self.TRACKER_TOKEN, creds.tracker_auth_token)
self.assertFalse(creds.token_dirty)
# Clear auth_tokens before loading from just-created file.
creds.docs_auth_token = None
creds.tracker_auth_token = None
creds.user = None
creds.LoadAuthToken(self.tempfile)
self.assertEquals(self.DOCS_TOKEN, creds.docs_auth_token)
self.assertEquals(self.TRACKER_TOKEN, creds.tracker_auth_token)
self.assertFalse(creds.token_dirty)
self.assertEquals(self.USER, creds.user)
def testSetCreds(self):
# This is the replay script for the test.
creds = gdata_lib.Creds()
# This is the test verification.
creds.SetCreds(self.USER, password=self.PASSWORD)
self.assertEquals(self.USER, creds.user)
self.assertEquals(self.PASSWORD, creds.password)
self.assertTrue(creds.creds_dirty)
def testSetCredsNoPassword(self):
# Add test-specific mocks/stubs
self.PatchObject(getpass, 'getpass', return_value=self.PASSWORD)
# This is the replay script for the test.
creds = gdata_lib.Creds()
# This is the test verification.
creds.SetCreds(self.USER)
self.assertEquals(self.USER, creds.user)
self.assertEquals(self.PASSWORD, creds.password)
self.assertTrue(creds.creds_dirty)
def testSetDocsToken(self):
# This is the replay script for the test.
creds = gdata_lib.Creds()
# This is the test verification.
creds.SetDocsAuthToken(self.DOCS_TOKEN)
self.assertEquals(self.DOCS_TOKEN, creds.docs_auth_token)
self.assertTrue(creds.token_dirty)
def testSetTrackerToken(self):
# This is the replay script for the test.
creds = gdata_lib.Creds()
# This is the test verification.
creds.SetTrackerAuthToken(self.TRACKER_TOKEN)
self.assertEquals(self.TRACKER_TOKEN, creds.tracker_auth_token)
self.assertTrue(creds.token_dirty)
class SpreadsheetRowTest(cros_test_lib.OutputTestCase):
"""Tests related to spreadsheet row interaction."""
SS_ROW_OBJ = 'SSRowObj'
SS_ROW_NUM = 5
def testEmpty(self):
row = gdata_lib.SpreadsheetRow(self.SS_ROW_OBJ, self.SS_ROW_NUM)
self.assertEquals(0, len(row))
self.assertEquals(self.SS_ROW_OBJ, row.ss_row_obj)
self.assertEquals(self.SS_ROW_NUM, row.ss_row_num)
self.assertRaises(TypeError, row, '__setitem__', 'abc', 'xyz')
self.assertEquals(0, len(row))
self.assertFalse('abc' in row)
def testInit(self):
starting_vals = {'abc': 'xyz', 'foo': 'bar'}
row = gdata_lib.SpreadsheetRow(self.SS_ROW_OBJ, self.SS_ROW_NUM,
starting_vals)
self.assertEquals(len(starting_vals), len(row))
self.assertEquals(starting_vals, row)
self.assertEquals(row['abc'], 'xyz')
self.assertTrue('abc' in row)
self.assertEquals(row['foo'], 'bar')
self.assertTrue('foo' in row)
self.assertEquals(self.SS_ROW_OBJ, row.ss_row_obj)
self.assertEquals(self.SS_ROW_NUM, row.ss_row_num)
self.assertRaises(TypeError, row, '__delitem__', 'abc')
self.assertEquals(len(starting_vals), len(row))
self.assertTrue('abc' in row)
class SpreadsheetCommTest(cros_test_lib.MoxOutputTestCase):
"""Test Speadsheet communication."""
SS_KEY = 'TheSSKey'
WS_NAME = 'TheWSName'
WS_KEY = 'TheWSKey'
USER = 'dude'
PASSWORD = 'shhh'
TOKEN = 'authtoken'
COLUMNS = ('greeting', 'name', 'title')
ROWS = (
{'greeting': 'Hi', 'name': 'George', 'title': 'Mr.'},
{'greeting': 'Howdy', 'name': 'Billy Bob', 'title': 'Mr.'},
{'greeting': 'Yo', 'name': 'Adriane', 'title': 'Ms.'},
)
def MockScomm(self, connect=True):
"""Return a mocked SpreadsheetComm"""
mocked_scomm = self.mox.CreateMock(gdata_lib.SpreadsheetComm)
mocked_scomm._columns = None
mocked_scomm._rows = None
if connect:
mocked_gdclient = self.mox.CreateMock(gdata_lib.RetrySpreadsheetsService)
mocked_scomm.gd_client = mocked_gdclient
mocked_scomm.ss_key = self.SS_KEY
mocked_scomm.ws_name = self.WS_NAME
mocked_scomm.ws_key = self.WS_KEY
else:
mocked_scomm.gd_client = None
mocked_scomm.ss_key = None
mocked_scomm.ws_name = None
mocked_scomm.ws_key = None
return mocked_scomm
def NewScomm(self, gd_client=None, connect=True):
"""Return a non-mocked SpreadsheetComm."""
scomm = gdata_lib.SpreadsheetComm()
scomm.gd_client = gd_client
if connect:
scomm.ss_key = self.SS_KEY
scomm.ws_name = self.WS_NAME
scomm.ws_key = self.WS_KEY
else:
scomm.ss_key = None
scomm.ws_name = None
scomm.ws_key = None
return scomm
def GenerateCreds(self, skip_user=False, skip_token=False):
creds = gdata_lib.Creds()
if not skip_user:
creds.user = self.USER
creds.password = self.PASSWORD
if not skip_token:
creds.docs_auth_token = self.TOKEN
return creds
def testConnect(self):
mocked_scomm = self.MockScomm(connect=False)
creds = self.GenerateCreds()
# This is the replay script for the test.
mocked_scomm._Login(creds, 'chromiumos')
mocked_scomm.SetCurrentWorksheet(self.WS_NAME, ss_key=self.SS_KEY)
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm.Connect(mocked_scomm, creds,
self.SS_KEY, self.WS_NAME)
self.mox.VerifyAll()
def testColumns(self):
"""Test the .columns property. Testing a property gets ugly."""
self.mox.StubOutWithMock(gdata.spreadsheet.service, 'CellQuery')
mocked_gdclient = self.mox.CreateMock(gdata_lib.RetrySpreadsheetsService)
scomm = self.NewScomm(gd_client=mocked_gdclient, connect=True)
query = {'max-row': '1'}
# Simulate a Cells feed from spreadsheet for the column row.
cols = [c[0].upper() + c[1:] for c in self.COLUMNS]
entry = [cros_test_lib.EasyAttr(
content=cros_test_lib.EasyAttr(text=c)) for c in cols]
feed = cros_test_lib.EasyAttr(entry=entry)
# This is the replay script for the test.
gdata.spreadsheet.service.CellQuery().AndReturn(query)
mocked_gdclient.GetCellsFeed(
self.SS_KEY, self.WS_KEY, query=query).AndReturn(feed)
self.mox.ReplayAll()
# This is the test verification.
result = scomm.columns
del scomm # Force deletion now before VerifyAll.
self.mox.VerifyAll()
expected_result = self.COLUMNS
self.assertEquals(expected_result, result)
def testRows(self):
"""Test the .rows property. Testing a property gets ugly."""
mocked_gdclient = self.mox.CreateMock(gdata_lib.RetrySpreadsheetsService)
scomm = self.NewScomm(gd_client=mocked_gdclient, connect=True)
# Simulate a List feed from spreadsheet for all rows.
rows = [
{'col_name': 'Joe', 'col_age': '12', 'col_zip': '12345'},
{'col_name': 'Bob', 'col_age': '15', 'col_zip': '54321'},
]
entry = []
for row in rows:
custom = dict((k, cros_test_lib.EasyAttr(text=v))
for (k, v) in row.iteritems())
entry.append(cros_test_lib.EasyAttr(custom=custom))
feed = cros_test_lib.EasyAttr(entry=entry)
# This is the replay script for the test.
mocked_gdclient.GetListFeed(self.SS_KEY, self.WS_KEY).AndReturn(feed)
self.mox.ReplayAll()
# This is the test verification.
result = scomm.rows
del scomm # Force deletion now before VerifyAll.
self.mox.VerifyAll()
self.assertEquals(tuple(rows), result)
# Result tuple should have spreadsheet row num as attribute on each row.
self.assertEquals(2, result[0].ss_row_num)
self.assertEquals(3, result[1].ss_row_num)
# Result tuple should have spreadsheet row obj as attribute on each row.
self.assertEquals(entry[0], result[0].ss_row_obj)
self.assertEquals(entry[1], result[1].ss_row_obj)
def testSetCurrentWorksheetStart(self):
mocked_scomm = self.MockScomm(connect=True)
# Undo worksheet settings.
mocked_scomm.ss_key = None
mocked_scomm.ws_name = None
mocked_scomm.ws_key = None
# This is the replay script for the test.
mocked_scomm._ClearCache()
mocked_scomm._GetWorksheetKey(
self.SS_KEY, self.WS_NAME).AndReturn(self.WS_KEY)
mocked_scomm._ClearCache()
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm.SetCurrentWorksheet(mocked_scomm, self.WS_NAME,
ss_key=self.SS_KEY)
self.mox.VerifyAll()
self.assertEquals(self.SS_KEY, mocked_scomm.ss_key)
self.assertEquals(self.WS_KEY, mocked_scomm.ws_key)
self.assertEquals(self.WS_NAME, mocked_scomm.ws_name)
def testSetCurrentWorksheetRestart(self):
mocked_scomm = self.MockScomm(connect=True)
other_ws_name = 'OtherWSName'
other_ws_key = 'OtherWSKey'
# This is the replay script for the test.
mocked_scomm._GetWorksheetKey(
self.SS_KEY, other_ws_name).AndReturn(other_ws_key)
mocked_scomm._ClearCache()
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm.SetCurrentWorksheet(mocked_scomm, other_ws_name)
self.mox.VerifyAll()
self.assertEquals(self.SS_KEY, mocked_scomm.ss_key)
self.assertEquals(other_ws_key, mocked_scomm.ws_key)
self.assertEquals(other_ws_name, mocked_scomm.ws_name)
def testClearCache(self):
rows = 'SomeRows'
cols = 'SomeColumns'
scomm = self.NewScomm()
scomm._rows = rows
scomm._columns = cols
scomm._ClearCache(keep_columns=True)
self.assertTrue(scomm._rows is None)
self.assertEquals(cols, scomm._columns)
scomm._rows = rows
scomm._columns = cols
scomm._ClearCache(keep_columns=False)
self.assertTrue(scomm._rows is None)
self.assertTrue(scomm._columns is None)
scomm._rows = rows
scomm._columns = cols
scomm._ClearCache()
self.assertTrue(scomm._rows is None)
self.assertTrue(scomm._columns is None)
def testLoginWithUserPassword(self):
mocked_scomm = self.MockScomm(connect=False)
creds = self.GenerateCreds(skip_token=True)
self.mox.StubOutClassWithMocks(gdata_lib, 'RetrySpreadsheetsService')
source = 'SomeSource'
# This is the replay script for the test.
mocked_gdclient = gdata_lib.RetrySpreadsheetsService()
mocked_gdclient.ProgrammaticLogin()
mocked_gdclient.GetClientLoginToken().AndReturn(self.TOKEN)
self.mox.ReplayAll()
# This is the test verification.
with self.OutputCapturer():
gdata_lib.SpreadsheetComm._Login(mocked_scomm, creds, source)
self.mox.VerifyAll()
self.assertEquals(self.USER, mocked_gdclient.email)
self.assertEquals(self.PASSWORD, mocked_gdclient.password)
self.assertEquals(self.TOKEN, creds.docs_auth_token)
self.assertEquals(source, mocked_gdclient.source)
self.assertEquals(mocked_gdclient, mocked_scomm.gd_client)
def testLoginWithToken(self):
mocked_scomm = self.MockScomm(connect=False)
creds = self.GenerateCreds(skip_user=True)
self.mox.StubOutClassWithMocks(gdata_lib, 'RetrySpreadsheetsService')
source = 'SomeSource'
# This is the replay script for the test.
mocked_gdclient = gdata_lib.RetrySpreadsheetsService()
mocked_gdclient.SetClientLoginToken(creds.docs_auth_token)
self.mox.ReplayAll()
# This is the test verification.
with self.OutputCapturer():
gdata_lib.SpreadsheetComm._Login(mocked_scomm, creds, source)
self.mox.VerifyAll()
self.assertFalse(hasattr(mocked_gdclient, 'email'))
self.assertFalse(hasattr(mocked_gdclient, 'password'))
self.assertEquals(source, mocked_gdclient.source)
self.assertEquals(mocked_gdclient, mocked_scomm.gd_client)
def testGetWorksheetKey(self):
mocked_scomm = self.MockScomm()
entrylist = [
cros_test_lib.EasyAttr(
title=cros_test_lib.EasyAttr(text='Foo'), id='NotImportant'),
cros_test_lib.EasyAttr(
title=cros_test_lib.EasyAttr(text=self.WS_NAME),
id=cros_test_lib.EasyAttr(text='/some/path/%s' % self.WS_KEY)),
cros_test_lib.EasyAttr(
title=cros_test_lib.EasyAttr(text='Bar'), id='NotImportant'),
]
feed = cros_test_lib.EasyAttr(entry=entrylist)
# This is the replay script for the test.
mocked_scomm.gd_client.GetWorksheetsFeed(self.SS_KEY).AndReturn(feed)
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm._GetWorksheetKey(mocked_scomm,
self.SS_KEY, self.WS_NAME)
self.mox.VerifyAll()
def testGetColumns(self):
mocked_scomm = self.MockScomm()
mocked_scomm.columns = 'SomeColumns'
# Replay script
self.mox.ReplayAll()
# This is the test verification.
result = gdata_lib.SpreadsheetComm.GetColumns(mocked_scomm)
self.mox.VerifyAll()
self.assertEquals('SomeColumns', result)
def testGetColumnIndex(self):
# Note that spreadsheet column indices start at 1.
mocked_scomm = self.MockScomm()
mocked_scomm.columns = ['these', 'are', 'column', 'names']
# This is the replay script for the test.
self.mox.ReplayAll()
# This is the test verification.
result = gdata_lib.SpreadsheetComm.GetColumnIndex(mocked_scomm, 'are')
self.mox.VerifyAll()
self.assertEquals(2, result)
def testGetRows(self):
mocked_scomm = self.MockScomm()
rows = []
for row_ix, row_dict in enumerate(self.ROWS):
rows.append(gdata_lib.SpreadsheetRow('SSRowObj%d' % (row_ix + 2),
(row_ix + 2), row_dict))
mocked_scomm.rows = tuple(rows)
# This is the replay script for the test.
self.mox.ReplayAll()
# This is the test verification.
result = gdata_lib.SpreadsheetComm.GetRows(mocked_scomm)
self.mox.VerifyAll()
self.assertEquals(self.ROWS, result)
for row_ix in xrange(len(self.ROWS)):
self.assertEquals(row_ix + 2, result[row_ix].ss_row_num)
self.assertEquals('SSRowObj%d' % (row_ix + 2), result[row_ix].ss_row_obj)
def testGetRowCacheByCol(self):
mocked_scomm = self.MockScomm()
# This is the replay script for the test.
mocked_scomm.GetRows().AndReturn(self.ROWS)
self.mox.ReplayAll()
# This is the test verification.
result = gdata_lib.SpreadsheetComm.GetRowCacheByCol(mocked_scomm, 'name')
self.mox.VerifyAll()
# Result is a dict of rows by the 'name' column.
for row in self.ROWS:
name = row['name']
self.assertEquals(row, result[name])
def testGetRowCacheByColDuplicates(self):
mocked_scomm = self.MockScomm()
# Create new row list with duplicates by name column.
rows = []
for row in self.ROWS:
new_row = dict(row)
new_row['greeting'] = row['greeting'] + ' there'
rows.append(new_row)
rows.extend(self.ROWS)
# This is the replay script for the test.
mocked_scomm.GetRows().AndReturn(tuple(rows))
self.mox.ReplayAll()
# This is the test verification.
result = gdata_lib.SpreadsheetComm.GetRowCacheByCol(mocked_scomm, 'name')
self.mox.VerifyAll()
# Result is a dict of rows by the 'name' column. In this
# test each result should be a list of the rows with the same
# value in the 'name' column.
num_rows = len(rows)
for ix in xrange(num_rows / 2):
row1 = rows[ix]
row2 = rows[ix + (num_rows / 2)]
name = row1['name']
self.assertEquals(name, row2['name'])
expected_rows = [row1, row2]
self.assertEquals(expected_rows, result[name])
def testInsertRow(self):
mocked_scomm = self.MockScomm()
row = 'TheRow'
# Replay script
mocked_scomm.gd_client.InsertRow(row, mocked_scomm.ss_key,
mocked_scomm.ws_key)
mocked_scomm._ClearCache(keep_columns=True)
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm.InsertRow(mocked_scomm, row)
self.mox.VerifyAll()
def testUpdateRowCellByCell(self):
mocked_scomm = self.MockScomm()
rowIx = 5
row = {'a': 123, 'b': 234, 'c': 345}
colIndices = {'a': 1, 'b': None, 'c': 4}
# Replay script
for colName in row:
colIx = colIndices[colName]
mocked_scomm.GetColumnIndex(colName).AndReturn(colIx)
if colIx is not None:
mocked_scomm.ReplaceCellValue(rowIx, colIx, row[colName])
mocked_scomm._ClearCache(keep_columns=True)
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm.UpdateRowCellByCell(mocked_scomm, rowIx, row)
self.mox.VerifyAll()
def testDeleteRow(self):
mocked_scomm = self.MockScomm()
ss_row = 'TheRow'
# Replay script
mocked_scomm.gd_client.DeleteRow(ss_row)
mocked_scomm._ClearCache(keep_columns=True)
self.mox.ReplayAll()
# This is the test verification.
gdata_lib.SpreadsheetComm.DeleteRow(mocked_scomm, ss_row)
self.mox.VerifyAll()
def testReplaceCellValue(self):
mocked_scomm = self.MockScomm()
rowIx = 14
colIx = 4
val = 'TheValue'
# Replay script
mocked_scomm.gd_client.UpdateCell(rowIx, colIx, val,
mocked_scomm.ss_key, mocked_scomm.ws_key)
mocked_scomm._ClearCache(keep_columns=True)
self.mox.ReplayAll()
# Verify
gdata_lib.SpreadsheetComm.ReplaceCellValue(mocked_scomm, rowIx, colIx, val)
self.mox.VerifyAll()
def testClearCellValue(self):
mocked_scomm = self.MockScomm()
rowIx = 14
colIx = 4
# Replay script
mocked_scomm.ReplaceCellValue(rowIx, colIx, None)
self.mox.ReplayAll()
# Verify
gdata_lib.SpreadsheetComm.ClearCellValue(mocked_scomm, rowIx, colIx)
self.mox.VerifyAll()
class IssueCommentTest(cros_test_lib.TestCase):
"""Test creating comments."""
def testInit(self):
title = 'Greetings, Earthlings'
text = 'I come in peace.'
ic = gdata_lib.IssueComment(title, text)
self.assertEquals(title, ic.title)
self.assertEquals(text, ic.text)
def createTrackerIssue(tid, labels, owner, status, content, title):
tissue = cros_test_lib.EasyAttr()
tissue.id = cros_test_lib.EasyAttr(
text='http://www/some/path/%d' % tid)
tissue.label = [cros_test_lib.EasyAttr(text=l) for l in labels]
tissue.owner = cros_test_lib.EasyAttr(
username=cros_test_lib.EasyAttr(text=owner))
tissue.status = cros_test_lib.EasyAttr(text=status)
tissue.content = cros_test_lib.EasyAttr(text=content)
tissue.title = cros_test_lib.EasyAttr(text=title)
return tissue
class IssueTest(cros_test_lib.MoxTestCase):
"""Test creating a bug."""
def testInitOverride(self):
owner = 'somedude@chromium.org'
status = 'Assigned'
issue = gdata_lib.Issue(owner=owner, status=status)
self.assertEquals(owner, issue.owner)
self.assertEquals(status, issue.status)
def testInitInvalidOverride(self):
self.assertRaises(ValueError, gdata_lib.Issue,
foobar='NotARealAttr')
def testInitFromTracker(self):
# Need to create a dummy Tracker Issue object.
tissue_id = 123
tissue_labels = ['Iteration-10', 'Effort-2']
tissue_owner = 'thedude@chromium.org'
tissue_status = 'Available'
tissue_content = 'The summary message'
tissue_title = 'The Big Title'
tissue = createTrackerIssue(tid=tissue_id, labels=tissue_labels,
owner=tissue_owner, status=tissue_status,
content=tissue_content, title=tissue_title)
mocked_issue = self.mox.CreateMock(gdata_lib.Issue)
# Replay script
mocked_issue.GetTrackerIssueComments(tissue_id, 'TheProject').AndReturn([])
self.mox.ReplayAll()
# Verify
gdata_lib.Issue.InitFromTracker(mocked_issue, tissue, 'TheProject')
self.mox.VerifyAll()
self.assertEquals(tissue_id, mocked_issue.id)
self.assertEquals(tissue_labels, mocked_issue.labels)
self.assertEquals(tissue_owner, mocked_issue.owner)
self.assertEquals(tissue_status, mocked_issue.status)
self.assertEquals(tissue_content, mocked_issue.summary)
self.assertEquals(tissue_title, mocked_issue.title)
self.assertEquals([], mocked_issue.comments)
class TrackerCommTest(cros_test_lib.MoxOutputTestCase):
"""Test bug tracker communication."""
def testConnectEmail(self):
source = 'TheSource'
token = 'TheToken'
creds = gdata_lib.Creds()
creds.user = 'dude'
creds.password = 'shhh'
creds.tracker_auth_token = None
self.mox.StubOutClassWithMocks(gd_ph_client, 'ProjectHostingClient')
mocked_tcomm = self.mox.CreateMock(gdata_lib.TrackerComm)
def set_token(*_args, **_kwargs):
mocked_itclient.auth_token = cros_test_lib.EasyAttr(token_string=token)
# Replay script
mocked_itclient = gd_ph_client.ProjectHostingClient()
mocked_itclient.ClientLogin(
creds.user, creds.password, source=source, service='code',
account_type='GOOGLE').WithSideEffects(set_token)
self.mox.ReplayAll()
# Verify
with self.OutputCapturer():
gdata_lib.TrackerComm.Connect(mocked_tcomm, creds, 'TheProject',
source=source)
self.mox.VerifyAll()
self.assertEquals(mocked_tcomm.it_client, mocked_itclient)
def testConnectToken(self):
source = 'TheSource'
token = 'TheToken'
creds = gdata_lib.Creds()
creds.user = 'dude'
creds.password = 'shhh'
creds.tracker_auth_token = token
mocked_tcomm = self.mox.CreateMock(gdata_lib.TrackerComm)
self.mox.StubOutClassWithMocks(gd_ph_client, 'ProjectHostingClient')
self.mox.StubOutClassWithMocks(gdata.gauth, 'ClientLoginToken')
# Replay script
mocked_itclient = gd_ph_client.ProjectHostingClient()
mocked_token = gdata.gauth.ClientLoginToken(token)
self.mox.ReplayAll()
# Verify
with self.OutputCapturer():
gdata_lib.TrackerComm.Connect(mocked_tcomm, creds, 'TheProject',
source=source)
self.mox.VerifyAll()
self.assertEquals(mocked_tcomm.it_client, mocked_itclient)
self.assertEquals(mocked_itclient.auth_token, mocked_token)
def testGetTrackerIssueById(self):
mocked_itclient = self.mox.CreateMock(gd_ph_client.ProjectHostingClient)
tcomm = gdata_lib.TrackerComm()
tcomm.it_client = mocked_itclient
tcomm.project_name = 'TheProject'
self.mox.StubOutClassWithMocks(gd_ph_client, 'Query')
self.mox.StubOutClassWithMocks(gdata_lib, 'Issue')
self.mox.StubOutWithMock(gdata_lib.Issue, 'InitFromTracker')
issue_id = 12345
feed = cros_test_lib.EasyAttr(entry=['hi', 'there'])
# Replay script
mocked_query = gd_ph_client.Query(issue_id=str(issue_id))
mocked_itclient.get_issues(
'TheProject', query=mocked_query).AndReturn(feed)
mocked_issue = gdata_lib.Issue()
mocked_issue.InitFromTracker(feed.entry[0], 'TheProject')
self.mox.ReplayAll()
# Verify
issue = tcomm.GetTrackerIssueById(issue_id)
self.mox.VerifyAll()
self.assertEquals(mocked_issue, issue)
def testGetTrackerIssuesByText(self):
author = 'TheAuthor'
project = 'TheProject'
text = "find me"
# Set up the fake tracker issue.
tissue_id = 1
tissue_labels = ['auto-filed']
tissue_owner = 'someone@chromium.org'
tissue_status = 'Available'
tissue_content = 'find me in body'
tissue_title = 'find me in title'
tissue = createTrackerIssue(tid=tissue_id, labels=tissue_labels,
owner=tissue_owner, status=tissue_status,
content=tissue_content, title=tissue_title)
issue = gdata_lib.Issue(id=tissue_id, labels=tissue_labels,
owner=tissue_owner, status=tissue_status,
title=tissue_title, summary=tissue_content)
# This will get called as part of Issue.InitFromTracker.
self.mox.StubOutWithMock(gdata_lib.Issue, 'GetTrackerIssueComments')
mocked_itclient = self.mox.CreateMock(gd_ph_client.ProjectHostingClient)
tcomm = gdata_lib.TrackerComm()
tcomm.author = author
tcomm.it_client = mocked_itclient
tcomm.project_name = project
# We expect a Query instance to be passed into get_issues.
# pylint: disable=E1120
self.mox.StubOutClassWithMocks(gd_ph_client, 'Query')
mocked_query = gd_ph_client.Query(text_query='%s is:open' % text)
feed = cros_test_lib.EasyAttr(entry=[tissue])
mocked_itclient.get_issues(project, query=mocked_query).AndReturn(feed)
gdata_lib.Issue.GetTrackerIssueComments(1, project).AndReturn([])
self.mox.ReplayAll()
issues = tcomm.GetTrackerIssuesByText(text)
self.assertEquals(issues, [issue])
def testCreateTrackerIssue(self):
author = 'TheAuthor'
mocked_itclient = self.mox.CreateMock(gd_ph_client.ProjectHostingClient)
mocked_tcomm = self.mox.CreateMock(gdata_lib.TrackerComm)
mocked_tcomm.author = author
mocked_tcomm.it_client = mocked_itclient
mocked_tcomm.project_name = 'TheProject'
issue = cros_test_lib.EasyAttr(title='TheTitle',
summary='TheSummary',
status='TheStatus',
owner='TheOwner',
labels='TheLabels',
ccs=[])
# Replay script
issue_id = cros_test_lib.EasyAttr(
id=cros_test_lib.EasyAttr(text='foo/bar/123'))
mocked_itclient.add_issue(
project_name='TheProject',
title=issue.title,
content=issue.summary,
author=author,
status=issue.status,
owner=issue.owner,
labels=issue.labels,
ccs=issue.ccs).AndReturn(issue_id)
self.mox.ReplayAll()
# Verify
result = gdata_lib.TrackerComm.CreateTrackerIssue(mocked_tcomm, issue)
self.mox.VerifyAll()
self.assertEquals(123, result)
def testAppendTrackerIssueById(self):
author = 'TheAuthor'
project_name = 'TheProject'
mocked_itclient = self.mox.CreateMock(gd_ph_client.ProjectHostingClient)
mocked_tcomm = self.mox.CreateMock(gdata_lib.TrackerComm)
mocked_tcomm.author = author
mocked_tcomm.it_client = mocked_itclient
mocked_tcomm.project_name = project_name
issue_id = 54321
comment = 'TheComment'
# Replay script
mocked_itclient.update_issue(project_name=project_name,
issue_id=issue_id,
author=author,
comment=comment,
owner=None)
self.mox.ReplayAll()
# Verify
result = gdata_lib.TrackerComm.AppendTrackerIssueById(mocked_tcomm,
issue_id, comment)
self.mox.VerifyAll()
self.assertEquals(issue_id, result)
class RetrySpreadsheetsServiceTest(cros_test_lib.MoxOutputTestCase):
"""Test Spreadsheet server retry helper."""
def testRequest(self):
"""Test that calling request method invokes _RetryRequest wrapper."""
# pylint: disable=W0212
self.mox.StubOutWithMock(gdata_lib.RetrySpreadsheetsService,
'_RetryRequest')
# Use a real RetrySpreadsheetsService object rather than a mocked
# one, because the .request method only exists if __init__ is run.
# Also split up __new__ and __init__ in order to grab the original
# rss.request method (inherited from base class at that point).
rss = gdata_lib.RetrySpreadsheetsService.__new__(
gdata_lib.RetrySpreadsheetsService)
orig_request = rss.request
rss.__init__()
args = ('GET', 'http://foo.bar')
# This is the replay script for the test.
gdata_lib.RetrySpreadsheetsService._RetryRequest(
orig_request, *args).AndReturn('wrapped')
self.mox.ReplayAll()
# This is the test verification.
retval = rss.request(*args)
self.mox.VerifyAll()
self.assertEquals('wrapped', retval)
def _TestHttpClientRetryRequest(self, statuses):
"""Test retry logic in http_client request during ProgrammaticLogin.
|statuses| is list of http codes to simulate, where 200 means success.
"""
expect_success = statuses[-1] == 200
self.mox.StubOutWithMock(atom.http.ProxiedHttpClient, 'request')
rss = gdata_lib.RetrySpreadsheetsService()
args = ('POST', 'https://www.google.com/accounts/ClientLogin')
def _read():
return 'Some response text'
# This is the replay script for the test.
# Simulate the return codes in statuses.
for status in statuses:
retstatus = cros_test_lib.EasyAttr(status=status, read=_read)
atom.http.ProxiedHttpClient.request(
*args, data=mox.IgnoreArg(),
headers=mox.IgnoreArg()).AndReturn(retstatus)
self.mox.ReplayAll()
# This is the test verification.
with self.OutputCapturer():
if expect_success:
rss.ProgrammaticLogin()
else:
self.assertRaises(gdata.service.Error, rss.ProgrammaticLogin)
self.mox.VerifyAll()
if not expect_success:
# Retries did not help, request still failed.
regexp = re.compile(r'^Giving up on HTTP request')
self.AssertOutputContainsWarning(regexp=regexp)
elif len(statuses) > 1:
# Warning expected if retries were needed.
self.AssertOutputContainsWarning()
else:
# First try worked, expect no warnings.
self.AssertOutputContainsWarning(invert=True)
def testHttpClientRetryRequest(self):
self._TestHttpClientRetryRequest([200])
def testHttpClientRetryRequest403(self):
self._TestHttpClientRetryRequest([403, 200])
def testHttpClientRetryRequest403x2(self):
self._TestHttpClientRetryRequest([403, 403, 200])
def testHttpClientRetryRequest403x3(self):
self._TestHttpClientRetryRequest([403, 403, 403, 200])
def testHttpClientRetryRequest403x4(self):
self._TestHttpClientRetryRequest([403, 403, 403, 403, 200])
def testHttpClientRetryRequest403x5(self):
# This one should exhaust the retries.
self._TestHttpClientRetryRequest([403, 403, 403, 403, 403])
def _TestRetryRequest(self, statuses):
"""Test retry logic for request method.
|statuses| is list of http codes to simulate, where 200 means success.
"""
expect_success = statuses[-1] == 200
expected_status_index = len(statuses) - 1 if expect_success else 0
mocked_ss = self.mox.CreateMock(gdata_lib.RetrySpreadsheetsService)
args = ('GET', 'http://foo.bar')
# This is the replay script for the test.
for ix, status in enumerate(statuses):
# Add index of status to track which status the request function is
# returning. It is expected to return the last return status if
# successful (retries or not), but first return status if failed.
retval = cros_test_lib.EasyAttr(status=status, index=ix)
mocked_ss.request(*args).AndReturn(retval)
self.mox.ReplayAll()
# This is the test verification.
with self.OutputCapturer():
# pylint: disable=W0212
rval = gdata_lib.RetrySpreadsheetsService._RetryRequest(mocked_ss,
mocked_ss.request,
*args)
self.mox.VerifyAll()
self.assertEquals(statuses[expected_status_index], rval.status)
self.assertEquals(expected_status_index, rval.index)
if not expect_success:
# Retries did not help, request still failed.
regexp = re.compile(r'^Giving up on HTTP request')
self.AssertOutputContainsWarning(regexp=regexp)
elif expected_status_index > 0:
# Warning expected if retries were needed.
self.AssertOutputContainsWarning()
else:
# First try worked, expect no warnings.
self.AssertOutputContainsWarning(invert=True)
def testRetryRequest(self):
self._TestRetryRequest([200])
def testRetryRequest403(self):
self._TestRetryRequest([403, 200])
def testRetryRequest403x2(self):
self._TestRetryRequest([403, 403, 200])
def testRetryRequest403x3(self):
self._TestRetryRequest([403, 403, 403, 200])
def testRetryRequest403x4(self):
self._TestRetryRequest([403, 403, 403, 403, 200])
def testRetryRequest403x5(self):
# This one should exhaust the retries.
self._TestRetryRequest([403, 403, 403, 403, 403])