# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import mozunit
from mozpack.copier import FileCopier, FileRegistry from mozpack.manifests import InstallManifest, UnreadableInstallManifest from mozpack.test.test_files import TestWithTmpDir
class TestInstallManifest(TestWithTmpDir): def test_construct(self):
m = InstallManifest()
self.assertEqual(len(m), 0)
def test_malformed(self):
f = self.tmppath("manifest")
open(f, "wt").write("junk\n") with self.assertRaises(UnreadableInstallManifest):
InstallManifest(f)
self.assertEqual(len(m), 8)
self.assertIn("s_dest", m)
self.assertIn("c_dest", m)
self.assertIn("p_dest", m)
self.assertIn("e_dest", m)
self.assertIn("o_dest", m)
self.assertIn("content", m)
with self.assertRaises(ValueError):
m.add_link("s_other", "s_dest")
with self.assertRaises(ValueError):
m.add_copy("c_other", "c_dest")
with self.assertRaises(ValueError):
m.add_preprocess("p_other", "p_dest", "p_other.pp")
with self.assertRaises(ValueError):
m.add_required_exists("e_dest")
with self.assertRaises(ValueError):
m.add_optional_exists("o_dest")
with self.assertRaises(ValueError):
m.add_pattern_link("ps_base", "ps/*", "ps_dest")
with self.assertRaises(ValueError):
m.add_pattern_copy("pc_base", "pc/**", "pc_dest")
with self.assertRaises(ValueError):
m.add_content("content", "content")
with open(self.tmppath("dest/s_dest"), "rt") as fh:
self.assertEqual(fh.read(), "symlink!")
with open(self.tmppath("dest/c_dest"), "rt") as fh:
self.assertEqual(fh.read(), "copy!")
with open(self.tmppath("dest/p_dest"), "rt") as fh:
self.assertEqual(fh.read(), "preprocess!")
self.assertEqual(
result.updated_files,
set(
self.tmppath(p) for p in ("dest/s_dest", "dest/c_dest", "dest/p_dest", "dest/content")
),
)
self.assertEqual(
result.existing_files,
set([self.tmppath("dest/e_dest"), self.tmppath("dest/o_dest")]),
)
self.assertEqual(result.removed_files, {to_delete})
self.assertEqual(result.removed_directories, set())
def test_preprocessor(self):
manifest = self.tmppath("m")
deps = self.tmppath("m.pp")
dest = self.tmppath("dest")
include = self.tmppath("p_incl")
with open(include, "wt") as fh:
fh.write("#define INCL\n")
time = os.path.getmtime(include) - 3
os.utime(include, (time, time))
with open(self.tmppath("p_source"), "wt") as fh:
fh.write("#ifdef FOO\n#if BAZ == QUX\nPASS1\n#endif\n#endif\n")
fh.write("#ifdef DEPTEST\nPASS2\n#endif\n")
fh.write("#include p_incl\n#ifdef INCLTEST\nPASS3\n#endif\n")
time = os.path.getmtime(self.tmppath("p_source")) - 3
os.utime(self.tmppath("p_source"), (time, time))
# Create and write a manifest with the preprocessed file, then apply it. # This should write out our preprocessed file.
m = InstallManifest()
m.add_preprocess(
self.tmppath("p_source"), "p_dest", deps, "#", {"FOO": "BAR", "BAZ": "QUX"}
)
m.write(path=manifest)
m = InstallManifest(path=manifest)
c = FileCopier()
m.populate_registry(c)
c.copy(dest)
with open(self.tmppath("dest/p_dest"), "rt") as fh:
self.assertEqual(fh.read(), "PASS1\n")
# Create a second manifest with the preprocessed file, then apply it. # Since this manifest does not exist on the disk, there should not be a # dependency on it, and the preprocessed file should not be modified.
m2 = InstallManifest()
m2.add_preprocess(
self.tmppath("p_source"), "p_dest", deps, "#", {"DEPTEST": True}
)
c = FileCopier()
m2.populate_registry(c)
result = c.copy(dest)
self.assertFalse(self.tmppath("dest/p_dest") in result.updated_files)
self.assertTrue(self.tmppath("dest/p_dest") in result.existing_files)
# Write out the second manifest, then load it back in from the disk. # This should add the dependency on the manifest file, so our # preprocessed file should be regenerated with the new defines. # We also set the mtime on the destination file back, so it will be # older than the manifest file.
m2.write(path=manifest)
time = os.path.getmtime(manifest) - 1
os.utime(self.tmppath("dest/p_dest"), (time, time))
m2 = InstallManifest(path=manifest)
c = FileCopier()
m2.populate_registry(c)
self.assertTrue(c.copy(dest))
with open(self.tmppath("dest/p_dest"), "rt") as fh:
self.assertEqual(fh.read(), "PASS2\n")
# Set the time on the manifest back, so it won't be picked up as # modified in the next test
time = os.path.getmtime(manifest) - 1
os.utime(manifest, (time, time))
# Update the contents of a file included by the source file. This should # cause the destination to be regenerated. with open(include, "wt") as fh:
fh.write("#define INCLTEST\n")
time = os.path.getmtime(include) - 1
os.utime(self.tmppath("dest/p_dest"), (time, time))
c = FileCopier()
m2.populate_registry(c)
self.assertTrue(c.copy(dest))
with open(self.tmppath("dest/p_dest"), "rt") as fh:
self.assertEqual(fh.read(), "PASS2\nPASS3\n")
with open(source, "wt") as fh:
fh.write("#define SRC\nSOURCE\n")
time = os.path.getmtime(source) - 3
os.utime(source, (time, time))
with open(include, "wt") as fh:
fh.write("INCLUDE\n")
time = os.path.getmtime(source) - 3
os.utime(include, (time, time))
# Create and write a manifest with the preprocessed file.
m = InstallManifest()
m.add_preprocess(source, "p_dest", deps, "#", {"FOO": "BAR", "BAZ": "QUX"})
m.write(path=manifest)
time = os.path.getmtime(source) - 5
os.utime(manifest, (time, time))
# Now read the manifest back in, and apply it. This should write out # our preprocessed file.
m = InstallManifest(path=manifest)
c = FileCopier()
m.populate_registry(c)
self.assertTrue(c.copy(dest))
with open(destfile, "rt") as fh:
self.assertEqual(fh.read(), "SOURCE\n")
# Next, modify the source to #INCLUDE another file. with open(source, "wt") as fh:
fh.write("SOURCE\n#include p_incl\n")
time = os.path.getmtime(source) - 1
os.utime(destfile, (time, time))
# Apply the manifest, and confirm that it also reads the newly included # file.
m = InstallManifest(path=manifest)
c = FileCopier()
m.populate_registry(c)
c.copy(dest)
with open(destfile, "rt") as fh:
self.assertEqual(fh.read(), "SOURCE\nINCLUDE\n")
# Set the time on the source file back, so it won't be picked up as # modified in the next test.
time = os.path.getmtime(source) - 1
os.utime(source, (time, time))
# Now, modify the include file (but not the original source). with open(include, "wt") as fh:
fh.write("INCLUDE MODIFIED\n")
time = os.path.getmtime(include) - 1
os.utime(destfile, (time, time))
# Apply the manifest, and confirm that the change to the include file # is detected. That should cause the preprocessor to run again.
m = InstallManifest(path=manifest)
c = FileCopier()
m.populate_registry(c)
c.copy(dest)
with open(destfile, "rt") as fh:
self.assertEqual(fh.read(), "SOURCE\nINCLUDE MODIFIED\n")
# ORing an InstallManifest should copy file dependencies
m = InstallManifest()
m |= InstallManifest(path=manifest)
c = FileCopier()
m.populate_registry(c)
e = c._files["p_dest"]
self.assertEqual(e.extra_depends, [manifest])
d = FileCopier()
q.populate_registry(d)
self.assertEqual(d.paths(), ["target/dest/foo/file1", "target/dest/foo/file2"])
# Some of the values in an InstallManifest include destination # information that is present in the keys. Verify that we can # round-trip serialization.
r = InstallManifest()
r.add_entries_from(m)
r.add_entries_from(m, base="target")
self.assertEqual(len(r), 2)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.