blob: a470f842bf65e43a5f25e4f7f22fe55f8117f2a3 [file] [log] [blame]
Chris Sosa47a7d4e2012-03-28 11:26:55 -07001#!/usr/bin/python
2#
3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Unit tests for devserver_util module."""
8
9import mox
10import os
11import shutil
12import tempfile
13import unittest
14
Chris Masone816e38c2012-05-02 12:22:36 -070015import downloadable_artifact
Chris Sosa47a7d4e2012-03-28 11:26:55 -070016import devserver
17import devserver_util
18import downloader
19
20
21# Fake Dev Server Layout:
22TEST_LAYOUT = {
23 'test-board-1': ['R17-1413.0.0-a1-b1346', 'R17-18.0.0-a1-b1346'],
24 'test-board-2': ['R16-2241.0.0-a0-b2', 'R17-2.0.0-a1-b1346'],
25 'test-board-3': []
26}
27
28
Chris Masone816e38c2012-05-02 12:22:36 -070029class DownloaderTestBase(mox.MoxTestBase):
Chris Sosa47a7d4e2012-03-28 11:26:55 -070030
31 def setUp(self):
32 mox.MoxTestBase.setUp(self)
33 self._work_dir = tempfile.mkdtemp('downloader-test')
34 self.build = 'R17-1413.0.0-a1-b1346'
35 self.archive_url_prefix = (
36 'gs://chromeos-image-archive/x86-mario-release/' + self.build)
37
38 def tearDown(self):
39 if os.path.exists(self._work_dir):
40 shutil.rmtree(self._work_dir)
41
42 def _CommonDownloaderSetup(self):
43 """Common code to downloader tests.
44
Chris Masone816e38c2012-05-02 12:22:36 -070045 Mocks out key devserver_util module methods, creates mock artifacts
46 and sets appropriate expectations.
Chris Sosa47a7d4e2012-03-28 11:26:55 -070047
Chris Masone816e38c2012-05-02 12:22:36 -070048 @return iterable of artifact objects with appropriate expectations.
Chris Sosa47a7d4e2012-03-28 11:26:55 -070049 """
50 board = 'x86-mario-release'
51 self.mox.StubOutWithMock(devserver_util, 'AcquireLock')
52 self.mox.StubOutWithMock(devserver_util, 'GatherArtifactDownloads')
53 self.mox.StubOutWithMock(devserver_util, 'ReleaseLock')
54 self.mox.StubOutWithMock(tempfile, 'mkdtemp')
55
Chris Masone816e38c2012-05-02 12:22:36 -070056 devserver_util.AcquireLock(
57 static_dir=self._work_dir,
58 tag=self._ClassUnderTest().GenerateLockTag(board, self.build)
59 ).AndReturn(self._work_dir)
Chris Sosa47a7d4e2012-03-28 11:26:55 -070060
Chris Masone816e38c2012-05-02 12:22:36 -070061 tempfile.mkdtemp(suffix=mox.IgnoreArg()).AndReturn(self._work_dir)
62 return self._GenerateArtifacts()
63
64 def _CreateArtifactDownloader(self, artifacts):
65 """Create and return a Downloader of the appropriate type.
66
67 The returned downloader will expect to download and stage the
68 DownloadableArtifacts listed in [artifacts].
69
70 @param artifacts: iterable of DownloadableArtifacts.
71 @return instance of downloader.Downloader or subclass.
72 """
73 raise NotImplementedError()
74
75 def _ClassUnderTest(self):
76 """Return class object of the type being tested.
77
78 @return downloader.Downloader class object, or subclass.
79 """
80 raise NotImplementedError()
81
82 def _GenerateArtifacts(self):
83 """Instantiate artifact mocks and set expectations on them.
84
85 @return iterable of artifact objects with appropriate expectations.
86 """
87 raise NotImplementedError()
88
89
90class DownloaderTest(DownloaderTestBase):
91 """Unit tests for downloader.Downloader.
92
93 setUp() and tearDown() inherited from DownloaderTestBase.
94 """
95
96 def _CreateArtifactDownloader(self, artifacts):
97 d = downloader.Downloader(self._work_dir)
98 self.mox.StubOutWithMock(d, 'GatherArtifactDownloads')
99 d.GatherArtifactDownloads(
100 self._work_dir, self.archive_url_prefix, self.build,
101 self._work_dir).AndReturn(artifacts)
102 return d
103
104 def _ClassUnderTest(self):
105 return downloader.Downloader
106
107 def _GenerateArtifacts(self):
108 """Instantiate artifact mocks and set expectations on them.
109
110 Sets up artifacts and sets up expectations for synchronous artifacts to
111 be downloaded first.
112
113 @return iterable of artifact objects with appropriate expectations.
114 """
115 artifacts = []
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700116 for index in range(5):
Chris Masone816e38c2012-05-02 12:22:36 -0700117 artifact = self.mox.CreateMock(downloadable_artifact.DownloadableArtifact)
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700118 # Make every other artifact synchronous.
119 if index % 2 == 0:
120 artifact.Synchronous = lambda: True
Chris Masone816e38c2012-05-02 12:22:36 -0700121 artifact.Download()
122 artifact.Stage()
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700123 else:
124 artifact.Synchronous = lambda: False
125
126 artifacts.append(artifact)
127
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700128 return artifacts
129
130 def testDownloaderSerially(self):
131 """Runs through the standard downloader workflow with no backgrounding."""
132 artifacts = self._CommonDownloaderSetup()
133
134 # Downloads non-synchronous artifacts second.
135 for index, artifact in enumerate(artifacts):
136 if index % 2 != 0:
137 artifact.Download()
138 artifact.Stage()
139
Chris Masone816e38c2012-05-02 12:22:36 -0700140 d = self._CreateArtifactDownloader(artifacts)
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700141 self.mox.ReplayAll()
Chris Masone816e38c2012-05-02 12:22:36 -0700142 self.assertEqual(d.Download(self.archive_url_prefix, background=False),
143 'Success')
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700144 self.mox.VerifyAll()
145
146 def testDownloaderInBackground(self):
147 """Runs through the standard downloader workflow with backgrounding."""
148 artifacts = self._CommonDownloaderSetup()
149
150 # Downloads non-synchronous artifacts second.
151 for index, artifact in enumerate(artifacts):
152 if index % 2 != 0:
153 artifact.Download()
154 artifact.Stage()
155
Chris Masone816e38c2012-05-02 12:22:36 -0700156 d = self._CreateArtifactDownloader(artifacts)
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700157 self.mox.ReplayAll()
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700158 d.Download(self.archive_url_prefix, background=True)
159 self.assertEqual(d.GetStatusOfBackgroundDownloads(), 'Success')
160 self.mox.VerifyAll()
161
162 def testInteractionWithDevserver(self):
Chris Sosa9164ca32012-03-28 11:04:50 -0700163 """Tests interaction between the downloader and devserver methods."""
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700164 artifacts = self._CommonDownloaderSetup()
Chris Masone816e38c2012-05-02 12:22:36 -0700165 devserver_util.GatherArtifactDownloads(
166 self._work_dir, self.archive_url_prefix, self.build,
167 self._work_dir).AndReturn(artifacts)
168
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700169 class FakeUpdater():
170 static_dir = self._work_dir
171
172 devserver.updater = FakeUpdater()
173
174 # Downloads non-synchronous artifacts second.
175 for index, artifact in enumerate(artifacts):
176 if index % 2 != 0:
177 artifact.Download()
178 artifact.Stage()
179
180 self.mox.ReplayAll()
181 dev = devserver.DevServerRoot()
182 status = dev.download(archive_url=self.archive_url_prefix)
183 self.assertTrue(status, 'Success')
184 status = dev.wait_for_status(archive_url=self.archive_url_prefix)
185 self.assertTrue(status, 'Success')
186 self.mox.VerifyAll()
187
Chris Sosa9164ca32012-03-28 11:04:50 -0700188 def testBuildStaged(self):
189 """Test whether we can correctly check if a build is previously staged."""
190 archive_url = 'x86-awesome-release/R99-1234.0-r1'
191 archive_url_non_staged = 'x86-awesome-release/R99-1234.0-r2'
192 # Create the directory to reflect staging.
193 os.makedirs(os.path.join(self._work_dir, archive_url))
194
195 self.assertTrue(downloader.Downloader.BuildStaged(archive_url,
196 self._work_dir))
197 self.assertFalse(downloader.Downloader.BuildStaged(archive_url_non_staged,
198 self._work_dir))
199
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700200
Chris Masone816e38c2012-05-02 12:22:36 -0700201class SymbolDownloaderTest(DownloaderTestBase):
202 """Unit tests for downloader.SymbolDownloader.
203
204 setUp() and tearDown() inherited from DownloaderTestBase.
205 """
206
207 def _CreateArtifactDownloader(self, artifacts):
208 d = downloader.SymbolDownloader(self._work_dir)
209 self.mox.StubOutWithMock(d, 'GatherArtifactDownloads')
210 d.GatherArtifactDownloads(
211 self._work_dir, self.archive_url_prefix, '',
212 self._work_dir).AndReturn(artifacts)
213 return d
214
215 def _ClassUnderTest(self):
216 return downloader.SymbolDownloader
217
218 def _GenerateArtifacts(self):
219 """Instantiate artifact mocks and set expectations on them.
220
221 Sets up a DebugTarball and sets up expectation that it will be
222 downloaded and staged.
223
224 @return iterable of one artifact object with appropriate expectations.
225 """
226 artifact = self.mox.CreateMock(downloadable_artifact.DownloadableArtifact)
227 artifact.Synchronous = lambda: True
228 artifact.Download()
229 artifact.Stage()
230 return [artifact]
231
232 def testDownloaderSerially(self):
233 """Runs through the symbol downloader workflow."""
234 d = self._CreateArtifactDownloader(self._CommonDownloaderSetup())
235
236 self.mox.ReplayAll()
237 self.assertEqual(d.Download(self.archive_url_prefix), 'Success')
238 self.mox.VerifyAll()
239
240
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700241if __name__ == '__main__':
242 unittest.main()