1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium 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 bug hunter."""
import logging
from optparse import Values
import smtplib
import sys
import unittest
from bug_hunter import BugHunter
from bug_hunter import BugHunterUtils
try:
import atom.data
import gdata.data
import gdata.projecthosting.client
except ImportError:
logging.error('gdata-client needs to be installed. Please install\n'
'and try again (http://code.google.com/p/gdata-python-client/)')
sys.exit(1)
class MockClient(object):
"""A mock class for gdata.projecthosting.client.ProjectHostingClient.
Mocking the very simple method invocations for get_issues() and
get_comments().
"""
def _CreateIssues(self, n_issues):
feed = gdata.projecthosting.data.IssuesFeed()
for i in xrange(n_issues):
feed.entry.append(gdata.projecthosting.data.IssueEntry(
title=atom.data.Title(text='title'),
content=atom.data.Content(text='http://www.content.com'),
id=atom.data.Id(text='/' + str(i)),
status=gdata.projecthosting.data.Status(text='Unconfirmed'),
state=gdata.projecthosting.data.State(text='open'),
label=[gdata.projecthosting.data.Label('label1')],
author=[atom.data.Author(name=atom.data.Name(text='author'))]))
return feed
def get_issues(self, project_name, query):
"""Get issues using mock object without calling the issue tracker API.
Based on query argument, this returns the dummy issues. The number of
dummy issues are specified in query.text_query.
Args:
project_name: A string for project name in the issue tracker.
query: A query object for querying the issue tracker.
Returns:
A IssuesFeed object that contains a simple test issue.
"""
n_issues = 1
if query.text_query.isdigit():
n_issues = int(query.text_query)
return self._CreateIssues(n_issues)
def get_comments(self, project_name, issue_id):
"""Get comments using mock object without calling the issue tracker API.
Args:
project_name: A string for project name in the issue tracker.
issue_id: Issue_id string.
Returns:
A CommentsFeed object that contains a simple test comment.
"""
feed = gdata.projecthosting.data.CommentsFeed()
feed.entry = [gdata.projecthosting.data.CommentEntry(
id=atom.data.Id(text='/0'),
content=atom.data.Content(text='http://www.comments.com'),
updated=atom.data.Updated(text='Updated'),
author=[atom.data.Author(name=atom.data.Name(text='cauthor'))])]
return feed
class BugHunterUnitTest(unittest.TestCase):
"""Unit tests for the Bug Hunter class."""
def setUp(self):
self._old_client = gdata.projecthosting.client.ProjectHostingClient
gdata.projecthosting.client.ProjectHostingClient = MockClient
def tearDown(self):
gdata.projecthosting.client.ProjectHostingClient = self._old_client
def _GetDefaultOption(self, set_10_days_ago, query='steps'):
ops = Values()
ops.query = query
if set_10_days_ago:
ops.interval_value = 10
ops.interval_unit = 'days'
else:
ops.interval_value = None
ops.email_entries = ['comments']
ops.project_name = 'chromium'
ops.query_title = 'query title'
ops.max_comments = None
return ops
def _GetIssue(self, n_issues):
issues = []
for i in xrange(n_issues):
issues.append({'issue_id': str(i), 'title': 'title', 'author': 'author',
'status': 'status', 'state': 'state',
'content': 'content', 'comments': [],
'labels': [], 'urls': []})
return issues
def testSetUpEmailSubjectMsg(self):
bh = BugHunter(self._GetDefaultOption(False))
subject, content = bh._SetUpEmailSubjectMsg(self._GetIssue(1))
self.assertEquals(subject,
'BugHunter found 1 query title bug!')
self.assertEquals(content,
('<a href="http://code.google.com/p/chromium/issues/'
'list?can=2&colspec=ID+Pri+Mstone+ReleaseBlock+Area+'
'Feature+Status+Owner+Summary&cells=tiles&sort=-id&'
'q=steps">Used Query</a>: steps<br><br>The number of '
'issues : 1<br><ul><li><a href="http://crbug.com/0">0 '
'title</a> [] </li></ul>'))
def testSetUpEmailSubjectMsgMultipleIssues(self):
bh = BugHunter(self._GetDefaultOption(False))
subject, content = bh._SetUpEmailSubjectMsg(self._GetIssue(2))
self.assertEquals(subject,
'BugHunter found 2 query title bugs!')
def testSetUpEmailSubjectMsgWith10DaysAgoAndAssertSubject(self):
bh = BugHunter(self._GetDefaultOption(True))
subject, _ = bh._SetUpEmailSubjectMsg(self._GetIssue(1))
self.assertEquals(subject,
('BugHunter found 1 query title bug in the past 10 '
'days!'))
def testGetIssuesWithMockClient(self):
bh = BugHunter(self._GetDefaultOption(False,
query=('dummy')))
expected_issues = [{'issue_id': '0', 'title': 'title', 'author': 'author',
'status': 'Unconfirmed', 'state': 'open',
'content': 'http://www.content.com',
'comments': '', 'labels': ['label1'],
'urls': ['http://www.content.com']}]
self.assertEquals(expected_issues, bh.GetIssues())
class MockSmtp(object):
"""A mock class for SMTP."""
def __init__(self, server):
pass
def sendmail(self, sender_email_address, receivers_email_addresses,
msg):
# TODO(imasaki): Do something here.
return True
def quit(self):
pass
class BugHunterUtilsTest(unittest.TestCase):
"""Unit tests for the Bug Hunter utility."""
def testStripHTML(self):
self.assertEquals(BugHunterUtils.StripHTML('<p>X</p>'), 'X')
def testStripHTMLEmpty(self):
self.assertEquals(BugHunterUtils.StripHTML(''), '')
def testSendEmail(self):
smtplib.SMTP = MockSmtp
self.assertEqual(BugHunterUtils.SendEmail('message', 'sender_email_address',
'receivers_email_addresses',
'subject'),
True)
|