summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/test/action
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozbuild/mozbuild/test/action')
-rw-r--r--python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_basic.xml10
-rw-r--r--python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_multiple_templates.xml30
-rw-r--r--python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_xul.xml14
-rw-r--r--python/mozbuild/mozbuild/test/action/data/invalid/region.properties12
-rw-r--r--python/mozbuild/mozbuild/test/action/data/node/node-test-script.js11
-rw-r--r--python/mozbuild/mozbuild/test/action/test_buildlist.py96
-rw-r--r--python/mozbuild/mozbuild/test/action/test_html_fragment_preprocessor.py196
-rw-r--r--python/mozbuild/mozbuild/test/action/test_langpack_manifest.py269
-rw-r--r--python/mozbuild/mozbuild/test/action/test_node.py80
-rw-r--r--python/mozbuild/mozbuild/test/action/test_process_install_manifest.py65
10 files changed, 783 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_basic.xml b/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_basic.xml
new file mode 100644
index 0000000000..251b4a3069
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_basic.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<template xmlns="http://www.w3.org/1999/xhtml">
+ <div class="main">
+ <p>Hello World</p>
+ </div>
+</template>
diff --git a/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_multiple_templates.xml b/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_multiple_templates.xml
new file mode 100644
index 0000000000..2e249aec63
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_multiple_templates.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<template xmlns="http://www.w3.org/1999/xhtml">
+ <template doctype="true">
+ <![CDATA[
+ <!DOCTYPE bindings [
+ <!ENTITY % exampleDTD SYSTEM "chrome://global/locale/example.dtd">
+ %exampleDTD;
+ ]>
+ ]]>
+ </template>
+ <template name="alpha">
+ <div class="main">
+ <p>Hello World</p>
+ </div>
+ </template>
+ <template name="beta">
+ <div class="body">
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </div>
+ </template>
+ <template name="charlie">
+ <div class="footer">
+ <p>Goodbye</p>
+ </div>
+ </template>
+</template>
diff --git a/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_xul.xml b/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_xul.xml
new file mode 100644
index 0000000000..5e0ea0b34a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/data/html_fragment_preprocesor/example_xul.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<template xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml">
+ <html:link href="chrome://global/skin/example.css" rel="stylesheet"/>
+ <hbox id="label-box" part="label-box" flex="1" role="none">
+ <image part="icon" role="none"/>
+ <label id="label" part="label" crop="end" flex="1" role="none"/>
+ <label id="highlightable-label" part="label" crop="end" flex="1" role="none"/>
+ </hbox>
+ <html:slot/>
+</template>
diff --git a/python/mozbuild/mozbuild/test/action/data/invalid/region.properties b/python/mozbuild/mozbuild/test/action/data/invalid/region.properties
new file mode 100644
index 0000000000..d4d8109b69
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/data/invalid/region.properties
@@ -0,0 +1,12 @@
+# A region.properties file with invalid unicode byte sequences. The
+# sequences were cribbed from Markus Kuhn's "UTF-8 decoder capability
+# and stress test", available at
+# http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
+
+# 3.5 Impossible bytes |
+# |
+# The following two bytes cannot appear in a correct UTF-8 string |
+# |
+# 3.5.1 fe = "ţ" |
+# 3.5.2 ff = "˙" |
+# 3.5.3 fe fe ff ff = "ţţ˙˙" |
diff --git a/python/mozbuild/mozbuild/test/action/data/node/node-test-script.js b/python/mozbuild/mozbuild/test/action/data/node/node-test-script.js
new file mode 100644
index 0000000000..f6dbfcc594
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/data/node/node-test-script.js
@@ -0,0 +1,11 @@
+#! /usr/bin/env node
+"use strict";
+
+/* eslint-disable no-console */
+
+let args = process.argv.slice(2);
+
+for (let arg of args) {
+ console.log(`dep:${arg}`);
+}
+
diff --git a/python/mozbuild/mozbuild/test/action/test_buildlist.py b/python/mozbuild/mozbuild/test/action/test_buildlist.py
new file mode 100644
index 0000000000..9a1d2738ed
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/test_buildlist.py
@@ -0,0 +1,96 @@
+# 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 os.path
+import unittest
+from shutil import rmtree
+from tempfile import mkdtemp
+
+import mozunit
+
+from mozbuild.action.buildlist import addEntriesToListFile
+
+
+class TestBuildList(unittest.TestCase):
+ """
+ Unit tests for buildlist.py
+ """
+
+ def setUp(self):
+ self.tmpdir = mkdtemp()
+
+ def tearDown(self):
+ rmtree(self.tmpdir)
+
+ # utility methods for tests
+ def touch(self, file, dir=None):
+ if dir is None:
+ dir = self.tmpdir
+ f = os.path.join(dir, file)
+ open(f, "w").close()
+ return f
+
+ def assertFileContains(self, filename, l):
+ """Assert that the lines in the file |filename| are equal
+ to the contents of the list |l|, in order."""
+ l = l[:]
+ f = open(filename, "r")
+ lines = [line.rstrip() for line in f.readlines()]
+ f.close()
+ for line in lines:
+ self.assertTrue(
+ len(l) > 0,
+ "ran out of expected lines! (expected '{0}', got '{1}')".format(
+ l, lines
+ ),
+ )
+ self.assertEqual(line, l.pop(0))
+ self.assertTrue(
+ len(l) == 0,
+ "not enough lines in file! (expected '{0}'," " got '{1}'".format(l, lines),
+ )
+
+ def test_basic(self):
+ "Test that addEntriesToListFile works when file doesn't exist."
+ testfile = os.path.join(self.tmpdir, "test.list")
+ l = ["a", "b", "c"]
+ addEntriesToListFile(testfile, l)
+ self.assertFileContains(testfile, l)
+ # ensure that attempting to add the same entries again doesn't change it
+ addEntriesToListFile(testfile, l)
+ self.assertFileContains(testfile, l)
+
+ def test_append(self):
+ "Test adding new entries."
+ testfile = os.path.join(self.tmpdir, "test.list")
+ l = ["a", "b", "c"]
+ addEntriesToListFile(testfile, l)
+ self.assertFileContains(testfile, l)
+ l2 = ["x", "y", "z"]
+ addEntriesToListFile(testfile, l2)
+ l.extend(l2)
+ self.assertFileContains(testfile, l)
+
+ def test_append_some(self):
+ "Test adding new entries mixed with existing entries."
+ testfile = os.path.join(self.tmpdir, "test.list")
+ l = ["a", "b", "c"]
+ addEntriesToListFile(testfile, l)
+ self.assertFileContains(testfile, l)
+ addEntriesToListFile(testfile, ["a", "x", "c", "z"])
+ self.assertFileContains(testfile, ["a", "b", "c", "x", "z"])
+
+ def test_add_multiple(self):
+ """Test that attempting to add the same entry multiple times results in
+ only one entry being added."""
+ testfile = os.path.join(self.tmpdir, "test.list")
+ addEntriesToListFile(testfile, ["a", "b", "a", "a", "b"])
+ self.assertFileContains(testfile, ["a", "b"])
+ addEntriesToListFile(testfile, ["c", "a", "c", "b", "c"])
+ self.assertFileContains(testfile, ["a", "b", "c"])
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/python/mozbuild/mozbuild/test/action/test_html_fragment_preprocessor.py b/python/mozbuild/mozbuild/test/action/test_html_fragment_preprocessor.py
new file mode 100644
index 0000000000..3cce1c5f94
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/test_html_fragment_preprocessor.py
@@ -0,0 +1,196 @@
+import os
+import unittest
+import xml.etree.ElementTree as ET
+
+import mozpack.path as mozpath
+import mozunit
+
+from mozbuild.action.html_fragment_preprocesor import (
+ fill_html_fragments_map,
+ generate,
+ get_fragment_key,
+ get_html_fragments_from_file,
+)
+
+test_data_path = mozpath.abspath(mozpath.dirname(__file__))
+test_data_path = mozpath.join(test_data_path, "data", "html_fragment_preprocesor")
+
+
+def data(name):
+ return os.path.join(test_data_path, name)
+
+
+TEST_PATH = "/some/path/somewhere/example.xml".replace("/", os.sep)
+EXAMPLE_BASIC = data("example_basic.xml")
+EXAMPLE_TEMPLATES = data("example_multiple_templates.xml")
+EXAMPLE_XUL = data("example_xul.xml")
+DUMMY_FILE = data("dummy.js")
+
+
+class TestNode(unittest.TestCase):
+ """
+ Tests for html_fragment_preprocesor.py.
+ """
+
+ maxDiff = None
+
+ def assertXMLEqual(self, a, b, message):
+ aRoot = ET.fromstring(a)
+ bRoot = ET.fromstring(b)
+ self.assertXMLNodesEqual(aRoot, bRoot, message)
+
+ def assertXMLNodesEqual(self, a, b, message, xpath=""):
+ xpath += "/" + a.tag
+ messageWithPath = message + " at " + xpath
+ self.assertEqual(a.tag, b.tag, messageWithPath + " tag name")
+ self.assertEqual(a.text, b.text, messageWithPath + " text")
+ self.assertEqual(
+ a.attrib.keys(), b.attrib.keys(), messageWithPath + " attribute names"
+ )
+ for aKey, aValue in a.attrib.items():
+ self.assertEqual(
+ aValue,
+ b.attrib[aKey],
+ messageWithPath + "[@" + aKey + "] attribute value",
+ )
+ for aChild, bChild in zip(a, b):
+ self.assertXMLNodesEqual(aChild, bChild, message, xpath)
+
+ def test_get_fragment_key_path(self):
+ key = get_fragment_key("/some/path/somewhere/example.xml")
+ self.assertEqual(key, "example")
+
+ def test_get_fragment_key_with_named_template(self):
+ key = get_fragment_key(TEST_PATH, "some-template")
+ self.assertEqual(key, "example/some-template")
+
+ def test_get_html_fragments_from_template_no_doctype_no_name(self):
+ key = "example"
+ fragment_map = {}
+ template = ET.Element("template")
+ p1 = ET.SubElement(template, "p")
+ p1.text = "Hello World"
+ p2 = ET.SubElement(template, "p")
+ p2.text = "Goodbye"
+ fill_html_fragments_map(fragment_map, TEST_PATH, template)
+ self.assertEqual(fragment_map[key], "<p>Hello World</p><p>Goodbye</p>")
+
+ def test_get_html_fragments_from_named_template_with_html_element(self):
+ key = "example/some-template"
+ fragment_map = {}
+ template = ET.Element("template")
+ template.attrib["name"] = "some-template"
+ p = ET.SubElement(template, "p")
+ p.text = "Hello World"
+ fill_html_fragments_map(fragment_map, TEST_PATH, template)
+ self.assertEqual(fragment_map[key], "<p>Hello World</p>")
+
+ def test_get_html_fragments_from_template_with_doctype(self):
+ key = "example"
+ doctype = "doctype definition goes here"
+ fragment_map = {}
+ template = ET.Element("template")
+ p = ET.SubElement(template, "p")
+ p.text = "Hello World"
+ fill_html_fragments_map(fragment_map, TEST_PATH, template, doctype)
+ self.assertEqual(
+ fragment_map[key], "doctype definition goes here\n<p>Hello World</p>"
+ )
+
+ def test_get_html_fragments_from_file_basic(self):
+ key = "example_basic"
+ fragment_map = {}
+ get_html_fragments_from_file(fragment_map, EXAMPLE_BASIC)
+ self.assertEqual(
+ fragment_map[key],
+ '<div xmlns="http://www.w3.org/1999/xhtml" class="main">'
+ + " <p>Hello World</p> </div>",
+ )
+
+ def test_get_html_fragments_from_file_multiple_templates(self):
+ key1 = "example_multiple_templates/alpha"
+ key2 = "example_multiple_templates/beta"
+ key3 = "example_multiple_templates/charlie"
+ fragment_map = {}
+ get_html_fragments_from_file(fragment_map, EXAMPLE_TEMPLATES)
+ self.assertIn("<p>Hello World</p>", fragment_map[key1], "Has HTML content")
+ self.assertIn(
+ '<!ENTITY % exampleDTD SYSTEM "chrome://global/locale/example.dtd">',
+ fragment_map[key1],
+ "Has doctype",
+ )
+ self.assertIn("<p>Lorem ipsum", fragment_map[key2], "Has HTML content")
+ self.assertIn(
+ '<!ENTITY % exampleDTD SYSTEM "chrome://global/locale/example.dtd">',
+ fragment_map[key2],
+ "Has doctype",
+ )
+ self.assertIn("<p>Goodbye</p>", fragment_map[key3], "Has HTML content")
+ self.assertIn(
+ '<!ENTITY % exampleDTD SYSTEM "chrome://global/locale/example.dtd">',
+ fragment_map[key3],
+ "Has doctype",
+ )
+
+ def test_get_html_fragments_from_file_with_xul(self):
+ key = "example_xul"
+ fragment_map = {}
+ get_html_fragments_from_file(fragment_map, EXAMPLE_XUL)
+ xml = "<root>" + fragment_map[key] + "</root>"
+ self.assertXMLEqual(
+ xml,
+ "<root>"
+ + '<html:link xmlns:html="http://www.w3.org/1999/xhtml" '
+ + 'href="chrome://global/skin/example.css" rel="stylesheet">'
+ + "</html:link> "
+ + '<hbox xmlns="http://www.mozilla.org/keymaster/'
+ + 'gatekeeper/there.is.only.xul" flex="1" id="label-box" '
+ + 'part="label-box" role="none"> '
+ + '<image part="icon" role="none"></image> '
+ + '<label crop="end" flex="1" id="label" part="label" '
+ + 'role="none"></label> '
+ + '<label crop="end" flex="1" id="highlightable-label" '
+ + 'part="label" role="none"></label> '
+ + "</hbox> "
+ + '<html:slot xmlns:html="http://www.w3.org/1999/xhtml">'
+ + "</html:slot></root>",
+ "XML values must match",
+ )
+
+ def test_generate(self):
+ with open(DUMMY_FILE, "w") as file:
+ deps = generate(
+ file,
+ EXAMPLE_BASIC,
+ EXAMPLE_TEMPLATES,
+ EXAMPLE_XUL,
+ )
+ with open(DUMMY_FILE, "r") as file:
+ contents = file.read()
+ self.assertIn(
+ "<!ENTITY % exampleDTD SYSTEM",
+ contents,
+ "Has doctype",
+ )
+ self.assertIn("<p>Lorem ipsum", contents, "Has HTML content")
+ self.assertIn('"example_basic"', contents, "Has basic fragment key")
+ self.assertIn(
+ '"example_multiple_templates/alpha"',
+ contents,
+ "Has multiple templates fragment key",
+ )
+ self.assertIn('"example_xul"', contents, "Has XUL fragment key")
+ self.assertIn(
+ "const getHTMLFragment =",
+ contents,
+ "Has fragment loader method declaration",
+ )
+ os.remove(DUMMY_FILE)
+ self.assertEqual(len(deps), 3, "deps are correct")
+ self.assertIn(EXAMPLE_BASIC, deps, "deps are correct")
+ self.assertIn(EXAMPLE_TEMPLATES, deps, "deps are correct")
+ self.assertIn(EXAMPLE_XUL, deps, "deps are correct")
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/python/mozbuild/mozbuild/test/action/test_langpack_manifest.py b/python/mozbuild/mozbuild/test/action/test_langpack_manifest.py
new file mode 100644
index 0000000000..29e8642fc7
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/test_langpack_manifest.py
@@ -0,0 +1,269 @@
+# -*- coding: utf-8 -*-
+
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+import json
+import os
+import shutil
+import tempfile
+import unittest
+
+import mozunit
+
+from mozbuild.action import langpack_manifest
+
+
+class TestGenerateManifest(unittest.TestCase):
+ """
+ Unit tests for langpack_manifest.py.
+ """
+
+ def test_parse_flat_ftl(self):
+ src = """
+langpack-creator = bar {"bar"}
+langpack-contributors = { "" }
+"""
+ tmp = tempfile.NamedTemporaryFile(mode="wt", suffix=".ftl", delete=False)
+ try:
+ tmp.write(src)
+ tmp.close()
+ ftl = langpack_manifest.parse_flat_ftl(tmp.name)
+ self.assertEqual(ftl["langpack-creator"], "bar bar")
+ self.assertEqual(ftl["langpack-contributors"], "")
+ finally:
+ os.remove(tmp.name)
+
+ def test_parse_flat_ftl_missing(self):
+ ftl = langpack_manifest.parse_flat_ftl("./does-not-exist.ftl")
+ self.assertEqual(len(ftl), 0)
+
+ def test_manifest(self):
+ ctx = {
+ "langpack-creator": "Suomennosprojekti",
+ "langpack-contributors": "Joe Smith, Mary White",
+ }
+ os.environ["MOZ_BUILD_DATE"] = "20210928100000"
+ manifest = langpack_manifest.create_webmanifest(
+ "fi",
+ "57.0.1",
+ "57.0",
+ "57.0.*",
+ "Firefox",
+ "/var/vcs/l10n-central",
+ "langpack-fi@firefox.mozilla.og",
+ ctx,
+ {},
+ )
+
+ data = json.loads(manifest)
+ self.assertEqual(data["name"], "Language: Suomi (Finnish)")
+ self.assertEqual(
+ data["description"], "Firefox Language Pack for Suomi (fi) – Finnish"
+ )
+ self.assertEqual(
+ data["author"], "Suomennosprojekti (contributors: Joe Smith, Mary White)"
+ )
+ self.assertEqual(data["version"], "57.0.20210928.100000")
+
+ def test_manifest_truncated_name(self):
+ ctx = {
+ "langpack-creator": "Mozilla.org / SoftcatalĂ ",
+ "langpack-contributors": "Joe Smith, Mary White",
+ }
+ os.environ["MOZ_BUILD_DATE"] = "20210928100000"
+ manifest = langpack_manifest.create_webmanifest(
+ "ca-valencia",
+ "57.0.1",
+ "57.0",
+ "57.0.*",
+ "Firefox",
+ "/var/vcs/l10n-central",
+ "langpack-ca-valencia@firefox.mozilla.og",
+ ctx,
+ {},
+ )
+
+ data = json.loads(manifest)
+ self.assertEqual(data["name"], "Language: CatalĂ  (ValenciĂ )")
+ self.assertEqual(
+ data["description"],
+ "Firefox Language Pack for Català (Valencià) (ca-valencia) – Catalan, Valencian",
+ )
+
+ def test_manifest_name_untranslated(self):
+ ctx = {
+ "langpack-creator": "Mozilla.org",
+ "langpack-contributors": "Joe Smith, Mary White",
+ }
+ os.environ["MOZ_BUILD_DATE"] = "20210928100000"
+ manifest = langpack_manifest.create_webmanifest(
+ "en-US",
+ "57.0.1",
+ "57.0",
+ "57.0.*",
+ "Firefox",
+ "/var/vcs/l10n-central",
+ "langpack-ca-valencia@firefox.mozilla.og",
+ ctx,
+ {},
+ )
+
+ data = json.loads(manifest)
+ self.assertEqual(data["name"], "Language: English (US)")
+ self.assertEqual(
+ data["description"],
+ "Firefox Language Pack for English (US) (en-US)",
+ )
+
+ def test_manifest_without_contributors(self):
+ ctx = {
+ "langpack-creator": "Suomennosprojekti",
+ "langpack-contributors": "",
+ }
+ manifest = langpack_manifest.create_webmanifest(
+ "fi",
+ "57.0.1",
+ "57.0",
+ "57.0.*",
+ "Firefox",
+ "/var/vcs/l10n-central",
+ "langpack-fi@firefox.mozilla.og",
+ ctx,
+ {},
+ )
+
+ data = json.loads(manifest)
+ self.assertEqual(data["name"], "Language: Suomi (Finnish)")
+ self.assertEqual(
+ data["description"], "Firefox Language Pack for Suomi (fi) – Finnish"
+ )
+ self.assertEqual(data["author"], "Suomennosprojekti")
+
+ def test_manifest_truncation(self):
+ locale = (
+ "Long locale code that will be truncated and will cause both "
+ "the name and the description to exceed the maximum number of "
+ "characters allowed in manifest.json"
+ )
+ title, description = langpack_manifest.get_title_and_description(
+ "Firefox", locale
+ )
+
+ self.assertEqual(len(title), 45)
+ self.assertEqual(len(description), 132)
+
+ def test_get_version_maybe_buildid(self):
+ for (app_version, buildid, expected_version) in [
+ ("109", "", "109"),
+ ("109.0", "", "109.0"),
+ ("109.0.0", "", "109.0.0"),
+ ("109", "20210928", "109"), # buildid should be 14 chars
+ ("109", "20210928123456", "109.20210928.123456"),
+ ("109.0", "20210928123456", "109.0.20210928.123456"),
+ ("109.0.0", "20210928123456", "109.0.20210928.123456"),
+ ("109", "20230215023456", "109.20230215.23456"),
+ ("109.0", "20230215023456", "109.0.20230215.23456"),
+ ("109.0.0", "20230215023456", "109.0.20230215.23456"),
+ ("109", "20230215003456", "109.20230215.3456"),
+ ("109", "20230215000456", "109.20230215.456"),
+ ("109", "20230215000056", "109.20230215.56"),
+ ("109", "20230215000006", "109.20230215.6"),
+ ("109", "20230215000000", "109.20230215.0"),
+ ("109.1.2.3", "20230201000000", "109.1.20230201.0"),
+ ("109.0a1", "", "109.0"),
+ ("109a0.0b0", "", "109.0"),
+ ("109.0.0b1", "", "109.0.0"),
+ ("109.0.b1", "", "109.0.0"),
+ ("109..1", "", "109.0.1"),
+ ]:
+ os.environ["MOZ_BUILD_DATE"] = buildid
+ version = langpack_manifest.get_version_maybe_buildid(app_version)
+ self.assertEqual(version, expected_version)
+
+ def test_main(self):
+ # We set this env variable so that the manifest.json version string
+ # uses a "buildid", see: `get_version_maybe_buildid()` for more
+ # information.
+ os.environ["MOZ_BUILD_DATE"] = "20210928100000"
+
+ TEST_CASES = [
+ {
+ "app_version": "112.0.1",
+ "max_app_version": "112.*",
+ "expected_version": "112.0.20210928.100000",
+ "expected_min_version": "112.0",
+ "expected_max_version": "112.*",
+ },
+ {
+ "app_version": "112.1.0",
+ "max_app_version": "112.*",
+ "expected_version": "112.1.20210928.100000",
+ # We expect the second part to be "0" even if the app version
+ # has a minor part equal to "1".
+ "expected_min_version": "112.0",
+ "expected_max_version": "112.*",
+ },
+ {
+ "app_version": "114.0a1",
+ "max_app_version": "114.*",
+ "expected_version": "114.0.20210928.100000",
+ # We expect the min version to be equal to the app version
+ # because we don't change alpha versions.
+ "expected_min_version": "114.0a1",
+ "expected_max_version": "114.*",
+ },
+ ]
+
+ tmpdir = tempfile.mkdtemp()
+ try:
+ # These files are required by the `main()` function.
+ for file in ["chrome.manifest", "empty-metadata.ftl"]:
+ langpack_manifest.write_file(os.path.join(tmpdir, file), "")
+
+ for tc in TEST_CASES:
+ extension_id = "some@extension-id"
+ locale = "fr"
+
+ args = [
+ "--input",
+ tmpdir,
+ # This file has been created right above.
+ "--metadata",
+ "empty-metadata.ftl",
+ "--app-name",
+ "Firefox",
+ "--l10n-basedir",
+ "/var/vcs/l10n-central",
+ "--locales",
+ locale,
+ "--langpack-eid",
+ extension_id,
+ "--app-version",
+ tc["app_version"],
+ "--max-app-ver",
+ tc["max_app_version"],
+ ]
+ langpack_manifest.main(args)
+
+ with open(os.path.join(tmpdir, "manifest.json")) as manifest_file:
+ manifest = json.load(manifest_file)
+ self.assertEqual(manifest["version"], tc["expected_version"])
+ self.assertEqual(manifest["langpack_id"], locale)
+ self.assertEqual(
+ manifest["browser_specific_settings"],
+ {
+ "gecko": {
+ "id": extension_id,
+ "strict_min_version": tc["expected_min_version"],
+ "strict_max_version": tc["expected_max_version"],
+ }
+ },
+ )
+ finally:
+ shutil.rmtree(tmpdir, ignore_errors=True)
+ del os.environ["MOZ_BUILD_DATE"]
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/python/mozbuild/mozbuild/test/action/test_node.py b/python/mozbuild/mozbuild/test/action/test_node.py
new file mode 100644
index 0000000000..f1ab5afd17
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/test_node.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+import os
+import unittest
+
+import buildconfig
+import mozpack.path as mozpath
+import mozunit
+
+from mozbuild.action.node import SCRIPT_ALLOWLIST, generate
+from mozbuild.nodeutil import find_node_executable
+
+test_data_path = mozpath.abspath(mozpath.dirname(__file__))
+test_data_path = mozpath.join(test_data_path, "data", "node")
+
+
+def data(name):
+ return os.path.join(test_data_path, name)
+
+
+TEST_SCRIPT = data("node-test-script.js")
+NONEXISTENT_TEST_SCRIPT = data("non-existent-test-script.js")
+
+
+class TestNode(unittest.TestCase):
+ """
+ Tests for node.py.
+ """
+
+ def setUp(self):
+ if not buildconfig.substs.get("NODEJS"):
+ buildconfig.substs["NODEJS"] = find_node_executable()[0]
+ SCRIPT_ALLOWLIST.append(TEST_SCRIPT)
+
+ def tearDown(self):
+ try:
+ SCRIPT_ALLOWLIST.remove(TEST_SCRIPT)
+ except Exception:
+ pass
+
+ def test_generate_no_returned_deps(self):
+ deps = generate("dummy_argument", TEST_SCRIPT)
+
+ self.assertSetEqual(deps, set([]))
+
+ def test_generate_returns_passed_deps(self):
+ deps = generate("dummy_argument", TEST_SCRIPT, "a", "b")
+
+ self.assertSetEqual(deps, set(["a", "b"]))
+
+ def test_called_process_error_handled(self):
+ SCRIPT_ALLOWLIST.append(NONEXISTENT_TEST_SCRIPT)
+
+ with self.assertRaises(SystemExit) as cm:
+ generate("dummy_arg", NONEXISTENT_TEST_SCRIPT)
+
+ self.assertEqual(cm.exception.code, 1)
+ SCRIPT_ALLOWLIST.remove(NONEXISTENT_TEST_SCRIPT)
+
+ def test_nodejs_not_set(self):
+ buildconfig.substs["NODEJS"] = None
+
+ with self.assertRaises(SystemExit) as cm:
+ generate("dummy_arg", TEST_SCRIPT)
+
+ self.assertEqual(cm.exception.code, 1)
+
+ def test_generate_missing_allowlist_entry_exit_code(self):
+ SCRIPT_ALLOWLIST.remove(TEST_SCRIPT)
+ with self.assertRaises(SystemExit) as cm:
+ generate("dummy_arg", TEST_SCRIPT)
+
+ self.assertEqual(cm.exception.code, 1)
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/python/mozbuild/mozbuild/test/action/test_process_install_manifest.py b/python/mozbuild/mozbuild/test/action/test_process_install_manifest.py
new file mode 100644
index 0000000000..3aea4bca73
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/action/test_process_install_manifest.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+import os
+
+import mozunit
+from mozpack.manifests import InstallManifest
+from mozpack.test.test_files import TestWithTmpDir
+
+import mozbuild.action.process_install_manifest as process_install_manifest
+
+
+class TestGenerateManifest(TestWithTmpDir):
+ """
+ Unit tests for process_install_manifest.py.
+ """
+
+ def test_process_manifest(self):
+ source = self.tmppath("source")
+ os.mkdir(source)
+ os.mkdir("%s/base" % source)
+ os.mkdir("%s/base/foo" % source)
+ os.mkdir("%s/base2" % source)
+
+ with open("%s/base/foo/file1" % source, "a"):
+ pass
+
+ with open("%s/base/foo/file2" % source, "a"):
+ pass
+
+ with open("%s/base2/file3" % source, "a"):
+ pass
+
+ m = InstallManifest()
+ m.add_pattern_link("%s/base" % source, "**", "")
+ m.add_link("%s/base2/file3" % source, "foo/file3")
+
+ p = self.tmppath("m")
+ m.write(path=p)
+
+ dest = self.tmppath("dest")
+ track = self.tmppath("track")
+
+ for i in range(2):
+ process_install_manifest.process_manifest(dest, [p], track)
+
+ self.assertTrue(os.path.exists(self.tmppath("dest/foo/file1")))
+ self.assertTrue(os.path.exists(self.tmppath("dest/foo/file2")))
+ self.assertTrue(os.path.exists(self.tmppath("dest/foo/file3")))
+
+ m = InstallManifest()
+ m.write(path=p)
+
+ for i in range(2):
+ process_install_manifest.process_manifest(dest, [p], track)
+
+ self.assertFalse(os.path.exists(self.tmppath("dest/foo/file1")))
+ self.assertFalse(os.path.exists(self.tmppath("dest/foo/file2")))
+ self.assertFalse(os.path.exists(self.tmppath("dest/foo/file3")))
+
+
+if __name__ == "__main__":
+ mozunit.main()