michael@0: #!/usr/bin/env python michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: # file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: import os, tempfile, unittest, shutil, struct, platform, subprocess, multiprocessing.dummy michael@0: import mock michael@0: from mock import patch michael@0: import symbolstore michael@0: michael@0: # Some simple functions to mock out files that the platform-specific dumpers will accept. michael@0: # dump_syms itself will not be run (we mock that call out), but we can't override michael@0: # the ShouldProcessFile method since we actually want to test that. michael@0: def write_elf(filename): michael@0: open(filename, "wb").write(struct.pack("<7B45x", 0x7f, ord("E"), ord("L"), ord("F"), 1, 1, 1)) michael@0: michael@0: def write_macho(filename): michael@0: open(filename, "wb").write(struct.pack(" michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: """) michael@0: # Use a source file from each of the three projects michael@0: file1 = os.path.join(self.test_dir, "projects", "one", "src1.c") michael@0: file2 = os.path.join(self.test_dir, "projects", "another", "src2.c") michael@0: file3 = os.path.join(self.test_dir, "something_else", "src3.c") michael@0: d = symbolstore.Dumper("dump_syms", "symbol_path", michael@0: repo_manifest=manifest) michael@0: self.assertEqual("git:example.com/bar/projects/one:src1.c:abcd1234", michael@0: symbolstore.GetVCSFilename(file1, d.srcdirs)[0]) michael@0: self.assertEqual("git:example.com/foo/projects/two:src2.c:ffffffff", michael@0: symbolstore.GetVCSFilename(file2, d.srcdirs)[0]) michael@0: self.assertEqual("git:example.com/bar/something_else:src3.c:00000000", michael@0: symbolstore.GetVCSFilename(file3, d.srcdirs)[0]) michael@0: michael@0: if platform.system() in ("Windows", "Microsoft"): michael@0: class TestSourceServer(HelperMixin, unittest.TestCase): michael@0: @patch("subprocess.call") michael@0: @patch("subprocess.Popen") michael@0: def test_HGSERVER(self, mock_Popen, mock_call): michael@0: """ michael@0: Test that HGSERVER gets set correctly in the source server index. michael@0: """ michael@0: symbolpath = os.path.join(self.test_dir, "symbols") michael@0: os.makedirs(symbolpath) michael@0: srcdir = os.path.join(self.test_dir, "srcdir") michael@0: os.makedirs(os.path.join(srcdir, ".hg")) michael@0: sourcefile = os.path.join(srcdir, "foo.c") michael@0: test_files = add_extension(["foo"]) michael@0: self.add_test_files(test_files) michael@0: # srcsrv needs PDBSTR_PATH set michael@0: os.environ["PDBSTR_PATH"] = "pdbstr" michael@0: # mock calls to `dump_syms`, `hg parent` and michael@0: # `hg showconfig paths.default` michael@0: mock_Popen.return_value.stdout = iter([ michael@0: "MODULE os x86 %s %s" % ("X" * 33, test_files[0]), michael@0: "FILE 0 %s" % sourcefile, michael@0: "PUBLIC xyz 123" michael@0: ]) michael@0: mock_communicate = mock_Popen.return_value.communicate michael@0: mock_communicate.side_effect = [("abcd1234", ""), michael@0: ("http://example.com/repo", ""), michael@0: ] michael@0: # And mock the call to pdbstr to capture the srcsrv stream data. michael@0: global srcsrv_stream michael@0: srcsrv_stream = None michael@0: def mock_pdbstr(args, cwd="", **kwargs): michael@0: for arg in args: michael@0: if arg.startswith("-i:"): michael@0: global srcsrv_stream michael@0: srcsrv_stream = open(os.path.join(cwd, arg[3:]), 'r').read() michael@0: return 0 michael@0: mock_call.side_effect = mock_pdbstr michael@0: d = symbolstore.GetPlatformSpecificDumper(dump_syms="dump_syms", michael@0: symbol_path=symbolpath, michael@0: srcdirs=[srcdir], michael@0: vcsinfo=True, michael@0: srcsrv=True, michael@0: copy_debug=True) michael@0: # stub out CopyDebug michael@0: d.CopyDebug = lambda *args: True michael@0: d.Process(self.test_dir) michael@0: d.Finish(stop_pool=False) michael@0: self.assertNotEqual(srcsrv_stream, None) michael@0: hgserver = [x.rstrip() for x in srcsrv_stream.splitlines() if x.startswith("HGSERVER=")] michael@0: self.assertEqual(len(hgserver), 1) michael@0: self.assertEqual(hgserver[0].split("=")[1], "http://example.com/repo") michael@0: michael@0: if __name__ == '__main__': michael@0: # use the multiprocessing.dummy module to use threading wrappers so michael@0: # that our mocking/module-patching works michael@0: symbolstore.Dumper.GlobalInit(module=multiprocessing.dummy) michael@0: michael@0: unittest.main() michael@0: michael@0: symbolstore.Dumper.pool.close() michael@0: symbolstore.Dumper.pool.join()