[dev-util] Add stage_debug,symbolicate_dump endpoints to dev server
Add an endpoint to the dev server that will synchronously download
and stage the debug symbols for a given build.
Add an endpoint to the dev server that will symbolicate a minidump.
BUG=chromium-os:29850,chromium-os:30399
TEST=unit
TEST=run dev server, use curl to make it download some artifacts; ensure
TEST=debug.tgz is _not_ downloaded immediately, but that the rest of the build is staged.
TEST=run dev server, use curl to make it download debug_symbols; check to
TEST=see that debug symbols are staged in static/archive
TEST=once symbols are staged, run the dev server in your
TEST=chroot and use curl with a minidump file like this:
TEST= curl -F minidump=@/home/cmasone/chromeos/phooey/powerd.20120424.141235.1005.dmp http://localhost:8080/symbolicate_dump
Change-Id: Ie460526396d2b9999137142c723b87793bc23aaa
Reviewed-on: https://gerrit.chromium.org/gerrit/21696
Reviewed-by: Chris Sosa <sosa@chromium.org>
Commit-Ready: Chris Masone <cmasone@chromium.org>
Tested-by: Chris Masone <cmasone@chromium.org>
diff --git a/downloader_unittest.py b/downloader_unittest.py
index 693689a..a470f84 100755
--- a/downloader_unittest.py
+++ b/downloader_unittest.py
@@ -12,7 +12,7 @@
import tempfile
import unittest
-import artifact_download
+import downloadable_artifact
import devserver
import devserver_util
import downloader
@@ -26,7 +26,7 @@
}
-class DownloaderTest(mox.MoxTestBase):
+class DownloaderTestBase(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
@@ -42,10 +42,10 @@
def _CommonDownloaderSetup(self):
"""Common code to downloader tests.
- Sets up artifacts and sets up expectations for synchronous artifacts to
- be downloaded first.
+ Mocks out key devserver_util module methods, creates mock artifacts
+ and sets appropriate expectations.
- Returns the artifacts to use in the test.
+ @return iterable of artifact objects with appropriate expectations.
"""
board = 'x86-mario-release'
self.mox.StubOutWithMock(devserver_util, 'AcquireLock')
@@ -53,32 +53,78 @@
self.mox.StubOutWithMock(devserver_util, 'ReleaseLock')
self.mox.StubOutWithMock(tempfile, 'mkdtemp')
- artifacts = []
+ devserver_util.AcquireLock(
+ static_dir=self._work_dir,
+ tag=self._ClassUnderTest().GenerateLockTag(board, self.build)
+ ).AndReturn(self._work_dir)
+ tempfile.mkdtemp(suffix=mox.IgnoreArg()).AndReturn(self._work_dir)
+ return self._GenerateArtifacts()
+
+ def _CreateArtifactDownloader(self, artifacts):
+ """Create and return a Downloader of the appropriate type.
+
+ The returned downloader will expect to download and stage the
+ DownloadableArtifacts listed in [artifacts].
+
+ @param artifacts: iterable of DownloadableArtifacts.
+ @return instance of downloader.Downloader or subclass.
+ """
+ raise NotImplementedError()
+
+ def _ClassUnderTest(self):
+ """Return class object of the type being tested.
+
+ @return downloader.Downloader class object, or subclass.
+ """
+ raise NotImplementedError()
+
+ def _GenerateArtifacts(self):
+ """Instantiate artifact mocks and set expectations on them.
+
+ @return iterable of artifact objects with appropriate expectations.
+ """
+ raise NotImplementedError()
+
+
+class DownloaderTest(DownloaderTestBase):
+ """Unit tests for downloader.Downloader.
+
+ setUp() and tearDown() inherited from DownloaderTestBase.
+ """
+
+ def _CreateArtifactDownloader(self, artifacts):
+ d = downloader.Downloader(self._work_dir)
+ self.mox.StubOutWithMock(d, 'GatherArtifactDownloads')
+ d.GatherArtifactDownloads(
+ self._work_dir, self.archive_url_prefix, self.build,
+ self._work_dir).AndReturn(artifacts)
+ return d
+
+ def _ClassUnderTest(self):
+ return downloader.Downloader
+
+ def _GenerateArtifacts(self):
+ """Instantiate artifact mocks and set expectations on them.
+
+ Sets up artifacts and sets up expectations for synchronous artifacts to
+ be downloaded first.
+
+ @return iterable of artifact objects with appropriate expectations.
+ """
+ artifacts = []
for index in range(5):
- artifact = self.mox.CreateMock(artifact_download.DownloadableArtifact)
+ artifact = self.mox.CreateMock(downloadable_artifact.DownloadableArtifact)
# Make every other artifact synchronous.
if index % 2 == 0:
artifact.Synchronous = lambda: True
+ artifact.Download()
+ artifact.Stage()
else:
artifact.Synchronous = lambda: False
artifacts.append(artifact)
- devserver_util.AcquireLock(
- static_dir=self._work_dir,
- tag='/'.join([board, self.build])).AndReturn(self._work_dir)
-
- tempfile.mkdtemp(suffix=mox.IgnoreArg()).AndReturn(self._work_dir)
- devserver_util.GatherArtifactDownloads(
- self._work_dir, self.archive_url_prefix, self.build,
- self._work_dir).AndReturn(artifacts)
-
- for index, artifact in enumerate(artifacts):
- if index % 2 == 0:
- artifact.Download()
- artifact.Stage()
-
return artifacts
def testDownloaderSerially(self):
@@ -91,9 +137,10 @@
artifact.Download()
artifact.Stage()
+ d = self._CreateArtifactDownloader(artifacts)
self.mox.ReplayAll()
- self.assertEqual(downloader.Downloader(self._work_dir).Download(
- self.archive_url_prefix, background=False), 'Success')
+ self.assertEqual(d.Download(self.archive_url_prefix, background=False),
+ 'Success')
self.mox.VerifyAll()
def testDownloaderInBackground(self):
@@ -106,8 +153,8 @@
artifact.Download()
artifact.Stage()
+ d = self._CreateArtifactDownloader(artifacts)
self.mox.ReplayAll()
- d = downloader.Downloader(self._work_dir)
d.Download(self.archive_url_prefix, background=True)
self.assertEqual(d.GetStatusOfBackgroundDownloads(), 'Success')
self.mox.VerifyAll()
@@ -115,6 +162,10 @@
def testInteractionWithDevserver(self):
"""Tests interaction between the downloader and devserver methods."""
artifacts = self._CommonDownloaderSetup()
+ devserver_util.GatherArtifactDownloads(
+ self._work_dir, self.archive_url_prefix, self.build,
+ self._work_dir).AndReturn(artifacts)
+
class FakeUpdater():
static_dir = self._work_dir
@@ -147,5 +198,45 @@
self._work_dir))
+class SymbolDownloaderTest(DownloaderTestBase):
+ """Unit tests for downloader.SymbolDownloader.
+
+ setUp() and tearDown() inherited from DownloaderTestBase.
+ """
+
+ def _CreateArtifactDownloader(self, artifacts):
+ d = downloader.SymbolDownloader(self._work_dir)
+ self.mox.StubOutWithMock(d, 'GatherArtifactDownloads')
+ d.GatherArtifactDownloads(
+ self._work_dir, self.archive_url_prefix, '',
+ self._work_dir).AndReturn(artifacts)
+ return d
+
+ def _ClassUnderTest(self):
+ return downloader.SymbolDownloader
+
+ def _GenerateArtifacts(self):
+ """Instantiate artifact mocks and set expectations on them.
+
+ Sets up a DebugTarball and sets up expectation that it will be
+ downloaded and staged.
+
+ @return iterable of one artifact object with appropriate expectations.
+ """
+ artifact = self.mox.CreateMock(downloadable_artifact.DownloadableArtifact)
+ artifact.Synchronous = lambda: True
+ artifact.Download()
+ artifact.Stage()
+ return [artifact]
+
+ def testDownloaderSerially(self):
+ """Runs through the symbol downloader workflow."""
+ d = self._CreateArtifactDownloader(self._CommonDownloaderSetup())
+
+ self.mox.ReplayAll()
+ self.assertEqual(d.Download(self.archive_url_prefix), 'Success')
+ self.mox.VerifyAll()
+
+
if __name__ == '__main__':
unittest.main()