Example #1
0
 def test_add(self):
     entry_path = os.path.join(self.temp_dir, "entry")
     data = b"test\n"
     with mkfile(entry_path, mode="wb") as entry:
         entry.write(data)
     checksum_file = ChecksumFile(self.config, self.temp_dir, "MD5SUMS",
                                  hashlib.md5)
     checksum_file.add("entry")
     self.assertEqual({"entry": hashlib.md5(data).hexdigest()},
                      checksum_file.entries)
Example #2
0
 def test_add_updated_mtime(self):
     # Adding an existing file with an mtime newer than that of the
     # checksums file causes its checksum to be updated.
     path = os.path.join(self.temp_dir, "entry")
     with mkfile(path) as entry:
         pass
     checksum_file = ChecksumFile(self.config,
                                  self.temp_dir,
                                  "MD5SUMS",
                                  hashlib.md5,
                                  sign=False)
     checksum_file.add("entry")
     checksum_file.write()
     self.rewind_mtime(checksum_file.path)
     with mkfile(path) as entry:
         print("mtime", end="", file=entry)
     checksum_file.add("entry")
     self.assertEqual(
         hashlib.md5(b"mtime").hexdigest(), checksum_file.entries["entry"])
 def test_select_proxy(self):
     self.assertIsNone(_select_proxy(self.config, "any-caller"))
     with mkfile(self.config_path) as f:
         print("test1\thttp://foo.example.org:3128/", file=f)
         print("test2\thttp://bar.example.org:3128/", file=f)
     self.assertEqual("http://foo.example.org:3128/",
                      _select_proxy(self.config, "test1"))
     self.assertEqual("http://bar.example.org:3128/",
                      _select_proxy(self.config, "test2"))
     self.assertIsNone(_select_proxy(self.config, "other-caller"))
Example #4
0
 def test_check_manifest_unknown_file(self):
     config = Config(read=False)
     config.root = self.use_temp_dir()
     manifest = os.path.join(self.temp_dir, "www", "simple", ".manifest")
     with mkfile(manifest) as f:
         print(
             "ubuntu\tprecise\t/precise/ubuntu-12.04.2-desktop-i386.iso\t"
             "726970368",
             file=f)
     self.assertRaises(UnknownManifestFile, check_manifest, config)
Example #5
0
 def test_remove(self):
     entry_path = os.path.join(self.temp_dir, "entry")
     data = "test\n"
     with mkfile(entry_path) as entry:
         print(data, end="", file=entry)
     self.create_checksum_files(["entry"])
     checksum_files = self.cls(self.config, self.temp_dir)
     checksum_files.read()
     checksum_files.remove("entry")
     self.assertChecksumsEqual({}, checksum_files)
Example #6
0
 def test_context_manager(self):
     for name in "1", "2":
         entry_path = os.path.join(self.temp_dir, name)
         with mkfile(entry_path) as entry:
             print(name, end="", file=entry)
     md5sums_path = os.path.join(self.temp_dir, "MD5SUMS")
     with mkfile(md5sums_path) as md5sums:
         subprocess.call(["md5sum", "-b", "1", "2"],
                         stdout=md5sums,
                         cwd=self.temp_dir)
     with ChecksumFile(self.config,
                       self.temp_dir,
                       "MD5SUMS",
                       hashlib.md5,
                       sign=False) as checksum_file:
         self.assertCountEqual(["1", "2"], checksum_file.entries)
         checksum_file.remove("1")
     with open(md5sums_path) as md5sums:
         self.assertEqual("%s *2\n" % hashlib.md5(b"2").hexdigest(),
                          md5sums.read())
Example #7
0
 def test_merge(self):
     old_dir = os.path.join(self.temp_dir, "old")
     os.mkdir(old_dir)
     entry_path = os.path.join(self.temp_dir, "entry")
     with mkfile(entry_path) as entry:
         print("data", end="", file=entry)
     shutil.copy(entry_path, os.path.join(old_dir, "entry"))
     self.create_checksum_files(["entry"], directory=old_dir)
     checksum_files = self.cls(self.config, self.temp_dir)
     checksum_files.merge([old_dir], "entry", ["entry"])
     self.assertChecksumsEqual({"entry": b"data"}, checksum_files)
Example #8
0
 def test_arches_override(self):
     # If ARCHES is set in the environment, it overrides
     # etc/default-arches.
     os.environ["CDIMAGE_ROOT"] = self.use_temp_dir()
     os.environ["ARCHES"] = "amd64"
     os.environ.pop("CPUARCHES", None)
     etc_dir = os.path.join(self.temp_dir, "etc")
     with mkfile(os.path.join(etc_dir, "config")) as f:
         print(dedent("""\
             #! /bin/sh
             PROJECT=ubuntu
             DIST=raring
             """),
               file=f)
     with mkfile(os.path.join(etc_dir, "default-arches")) as f:
         print("*\tdaily-live\traring\tamd64 amd64+mac i386", file=f)
     config = Config(IMAGE_TYPE="daily-live")
     self.assertEqual("daily-live", config["IMAGE_TYPE"])
     self.assertEqual("amd64", config["ARCHES"])
     self.assertEqual("amd64", config["CPUARCHES"])
Example #9
0
 def check_manifest_pass(self):
     config = Config(read=False)
     config.root = self.use_temp_dir()
     manifest = os.path.join(self.temp_dir, "www", "simple", ".manifest")
     with mkfile(manifest) as f:
         print(
             "ubuntu\tprecise\t/precise/ubuntu-12.04.2-desktop-i386.iso\t"
             "726970368",
             file=f)
     touch(
         os.path.join(self.temp_dir, "www", "simple", "precise",
                      "ubuntu-12.04.2-desktop-i386.iso"))
Example #10
0
 def test_merge_ignores_stale_checksums(self):
     old_dir = os.path.join(self.temp_dir, "old")
     with mkfile(os.path.join(old_dir, "MD5SUMS")) as old_md5sums:
         print("checksum *entry", file=old_md5sums)
     entry_path = os.path.join(self.temp_dir, "entry")
     touch(entry_path)
     next_minute = time.time() + 60
     os.utime(entry_path, (next_minute, next_minute))
     checksum_file = ChecksumFile(self.config, self.temp_dir, "MD5SUMS",
                                  hashlib.md5)
     checksum_file.merge([old_dir], "entry", ["entry"])
     self.assertEqual({}, checksum_file.entries)
Example #11
0
 def test_read_shell(self):
     os.environ["CDIMAGE_ROOT"] = self.use_temp_dir()
     with mkfile(os.path.join(self.temp_dir, "etc", "config")) as f:
         print(dedent("""\
             #! /bin/sh
             PROJECT=ubuntu
             CAPPROJECT=Ubuntu
             """),
               file=f)
     config = Config()
     self.assertEqual("ubuntu", config["PROJECT"])
     self.assertEqual("Ubuntu", config["CAPPROJECT"])
     self.assertNotIn("DEBUG", config)
Example #12
0
 def send_mail_to_file(self, path, subject, generator, recipients, body,
                       dry_run=False):
     with mkfile(path) as f:
         print("To: %s" % ", ".join(recipients), file=f)
         print("Subject: %s" % subject, file=f)
         print("X-Generated-By: %s" % generator, file=f)
         print("", file=f)
         if isinstance(body, text_file_type):
             for line in body:
                 print(line.rstrip("\n"), file=f)
         else:
             for line in body.splitlines():
                 print(line, file=f)
Example #13
0
 def test_add_existing(self):
     # Attempting to add an existing file that is not newer than the
     # checksums file has no effect.  (Use .remove() first to overwrite
     # an existing checksum.)
     entry_path = os.path.join(self.temp_dir, "entry")
     data = "test\n"
     with mkfile(entry_path) as entry:
         entry.write(data)
     checksum_file = ChecksumFile(self.config, self.temp_dir, "MD5SUMS",
                                  hashlib.md5)
     checksum_file.entries["entry"] = ""
     checksum_file.add("entry")
     self.assertEqual("", checksum_file.entries["entry"])
Example #14
0
 def test_context_manager(self):
     for name in "1", "2":
         entry_path = os.path.join(self.temp_dir, name)
         with mkfile(entry_path) as entry:
             print(name, end="", file=entry)
     self.create_checksum_files(["1", "2"])
     with self.cls(self.config, self.temp_dir,
                   sign=False) as checksum_files:
         self.assertChecksumsEqual({"1": b"1", "2": b"2"}, checksum_files)
         checksum_files.remove("1")
     with open(os.path.join(self.temp_dir, "MD5SUMS-metalink")) as md5sums:
         self.assertEqual("%s *2\n" % hashlib.md5(b"2").hexdigest(),
                          md5sums.read())
Example #15
0
 def test_merge_all(self):
     old_dir = os.path.join(self.temp_dir, "old")
     old_iso_i386_path = os.path.join(old_dir, "foo-i386.iso")
     with mkfile(old_iso_i386_path) as old_iso_i386:
         print("foo-i386.iso", end="", file=old_iso_i386)
     old_metalink_i386_path = os.path.join(old_dir, "foo-i386.metalink")
     with mkfile(old_metalink_i386_path) as old_metalink_i386:
         print("foo-i386.metalink", end="", file=old_metalink_i386)
     self.create_checksum_files(["foo-i386.metalink"], directory=old_dir)
     metalink_amd64_path = os.path.join(self.temp_dir, "foo-amd64.metalink")
     with mkfile(metalink_amd64_path) as metalink_amd64:
         print("foo-amd64.metalink", end="", file=metalink_amd64)
     touch(os.path.join(self.temp_dir, "foo-amd64.list"))
     shutil.copy(old_metalink_i386_path,
                 os.path.join(self.temp_dir, "foo-i386.metalink"))
     checksum_files = self.cls(self.config, self.temp_dir)
     checksum_files.merge_all([old_dir])
     self.assertChecksumsEqual(
         {
             "foo-amd64.metalink": b"foo-amd64.metalink",
             "foo-i386.metalink": b"foo-i386.metalink",
         }, checksum_files)
 def test_read_shell_config(self):
     os.environ["ONE"] = "one"
     config_path = os.path.join(self.temp_dir, "config")
     with mkfile(config_path) as config:
         print(dedent("""\
             ONE="$ONE two three"
             TWO=two
             THREE=three"""),
               file=config)
     config_dict = dict(
         osextras.read_shell_config(config_path, ["ONE", "TWO"]))
     self.assertEqual("one two three", config_dict["ONE"])
     self.assertEqual("two", config_dict["TWO"])
     self.assertNotIn("three", config_dict)
Example #17
0
 def test_read(self):
     with mkfile(os.path.join(self.temp_dir, "MD5SUMS")) as md5sums:
         print(dedent("""\
             checksum  one-path
             checksum *another-path
             """),
               file=md5sums)
     checksum_file = ChecksumFile(self.config, self.temp_dir, "MD5SUMS",
                                  hashlib.md5)
     checksum_file.read()
     self.assertEqual({
         "one-path": "checksum",
         "another-path": "checksum"
     }, checksum_file.entries)
Example #18
0
 def test_write(self):
     checksum_files = self.cls(self.config, self.temp_dir, sign=False)
     for name in "1", "2":
         entry_path = os.path.join(self.temp_dir, name)
         with mkfile(entry_path) as entry:
             print(name, end="", file=entry)
         checksum_files.add(name)
     checksum_files.write()
     for cf in checksum_files.checksum_files:
         self.assertEqual(
             0,
             subprocess.call([
                 self.files_and_commands[cf.name], "-c", "--status", cf.name
             ],
                             cwd=self.temp_dir))
Example #19
0
    def test_update_tasks_sends_mail(self, mock_send_mail):
        original_call = subprocess.call

        def call_side_effect(command, *args, **kwargs):
            if (len(command) >= 4 and command[:2] == ["diff", "-u"] and
                    "stdout" in kwargs):
                old = os.path.basename(command[2])
                new = os.path.basename(command[3])
                original_call(
                    ["printf", "%s\\n", "--- %s" % old], *args, **kwargs)
                original_call(
                    ["printf", "%s\\n", "+++ %s" % new], *args, **kwargs)
                return 1
            else:
                return original_call(command, *args, **kwargs)

        self.write_ubuntu_structure()
        self.config["PROJECT"] = "ubuntu"
        self.config["CAPPROJECT"] = "Ubuntu"
        self.config["DIST"] = "raring"
        self.config["IMAGE_TYPE"] = "daily-live"
        output_dir = os.path.join(
            self.temp_dir, "scratch", "ubuntu", "raring", "daily-live",
            "tasks")
        touch(os.path.join(output_dir, "required"))
        touch(os.path.join(output_dir, "minimal"))
        touch(os.path.join(output_dir, "standard"))
        touch(os.path.join("%s-previous" % output_dir, "minimal"))
        touch(os.path.join("%s-previous" % output_dir, "standard"))
        task_mail_path = os.path.join(self.temp_dir, "etc", "task-mail")
        with mkfile(task_mail_path) as task_mail:
            print("*****@*****.**", file=task_mail)
        mock_send_mail.side_effect = partial(
            self.send_mail_to_file, os.path.join(self.temp_dir, "mail"))
        output = GerminateOutput(self.config, self.temp_dir)
        with mock.patch("subprocess.call", side_effect=call_side_effect):
            output.update_tasks("20130319")
        with open(os.path.join(self.temp_dir, "mail")) as mail:
            self.assertEqual(dedent("""\
                To: [email protected]
                Subject: Task changes for Ubuntu daily-live/raring on 20130319
                X-Generated-By: update-tasks

                --- minimal
                +++ minimal
                --- standard
                +++ standard
                """), mail.read())
Example #20
0
 def test_send_mail_from_file(self, mock_popen):
     path = os.path.join(self.temp_dir, "body")
     with mkfile(path) as body:
         print("Body", file=body)
         print("Text", file=body)
     with open(path) as body:
         send_mail("Test subject", "test_notify", ["*****@*****.**"], body)
         expected_command = [
             "mail",
             "-s",
             "Test subject",
             "-a",
             "X-Generated-By: test_notify",
             "*****@*****.**",
         ]
         mock_popen.assert_called_once_with(expected_command, stdin=body)
Example #21
0
 def test_get_mirrors(self):
     config = Config(read=False)
     config.root = self.use_temp_dir()
     production_path = os.path.join(self.temp_dir, "production",
                                    "trigger-mirrors")
     os.makedirs(os.path.dirname(production_path))
     with mkfile(production_path) as production:
         print("sync x.example.org", file=production)
         print("async other.example.org", file=production)
         print("sync y.example.org z.example.org", file=production)
     self.assertEqual(["x.example.org", "y.example.org", "z.example.org"],
                      _get_mirrors(config))
     self.configure_triggers()
     self.assertEqual(["foo", "bar"], _get_mirrors(self.config))
     self.config["UBUNTU_DEFAULTS_LOCALE"] = "zh_CN"
     self.assertEqual(["strix.canonical.com"], _get_mirrors(self.config))
Example #22
0
 def test_common_initrd_packages(self):
     self.write_ubuntu_structure()
     manifest_path = os.path.join(
         self.temp_dir, "ftp", "dists", "raring", "main", "installer-i386",
         "current", "images", "MANIFEST.udebs")
     with mkfile(manifest_path) as manifest:
         print(dedent("""\
             cdrom/initrd.gz
             \tanna 1.45ubuntu1 i386
             \tcdrom-detect 1.43ubuntu1 all
             netboot/netboot.tar.gz
             \tanna 1.45ubuntu1 i386
             \tnet-retriever 1.32ubuntu1 i386"""), file=manifest)
     self.config["DIST"] = "raring"
     output = GerminateOutput(self.config, self.temp_dir)
     self.assertEqual(set(["anna"]), output.common_initrd_packages("i386"))
Example #23
0
 def test_get_mirrors_async(self):
     config = Config(read=False)
     config.root = self.use_temp_dir()
     production_path = os.path.join(self.temp_dir, "production",
                                    "trigger-mirrors")
     with mkfile(production_path) as production:
         print("sync x.example.org", file=production)
         print("async a.example.org b.example.org", file=production)
         print("sync y.example.org z.example.org", file=production)
         print("async c.example.org", file=production)
     self.assertEqual(["a.example.org", "b.example.org", "c.example.org"],
                      _get_mirrors_async(config))
     self.configure_triggers()
     self.assertEqual(["foo-async", "bar-async"],
                      _get_mirrors_async(self.config))
     self.config["UBUNTU_DEFAULTS_LOCALE"] = "zh_CN"
     self.assertEqual([], _get_mirrors_async(self.config))
Example #24
0
    def test_task_headers(self):
        self.write_ubuntu_structure()
        seedtext_path = os.path.join(self.temp_dir, "i386", "desktop.seedtext")
        with mkfile(seedtext_path) as seedtext:
            print(dedent("""\
                Task-Per-Derivative: 1
                Task-Key: ubuntu-desktop
                Task-Seeds: desktop-common

                = Seed text starts here ="""), file=seedtext)
        output = GerminateOutput(self.config, self.temp_dir)
        expected = {
            "per-derivative": "1",
            "key": "ubuntu-desktop",
            "seeds": "desktop-common",
        }
        self.assertEqual(expected, output.task_headers("i386", "desktop"))
        self.assertEqual({}, output.task_headers("i386", "missing"))
Example #25
0
 def write_seed_output(self, arch, seed, packages):
     """Write a simplified Germinate output file, enough for testing."""
     with mkfile(os.path.join(self.temp_dir, arch, seed)) as f:
         why = "Ubuntu.Trusty %s seed" % seed
         pkg_len = max(len("Package"), max(map(len, packages)))
         src_len = max(len("Source"), max(map(len, packages)))
         why_len = len(why)
         print("%-*s | %-*s | %-*s |" %
               (pkg_len, "Package", src_len, "Source", why_len, "Why"),
               file=f)
         print(("-" * pkg_len) + "-+-" + ("-" * src_len) + "-+-" +
               ("-" * why_len) + "-+",
               file=f)
         for pkg in packages:
             print("%-*s | %-*s | %-*s |" %
                   (pkg_len, pkg, src_len, pkg, why_len, why),
                   file=f)
         print(("-" * (pkg_len + src_len + why_len + 6)) + "-+", file=f)
         print("%*s |" % (pkg_len + src_len + why_len + 6, ""), file=f)
Example #26
0
 def test_add_updated_ctime(self):
     # Adding an existing file with a ctime newer than that of the
     # checksums file causes its checksum to be updated.
     path = os.path.join(self.temp_dir, "entry")
     with mkfile(path) as entry:
         print("ctime", end="", file=entry)
     checksum_file = ChecksumFile(self.config,
                                  self.temp_dir,
                                  "MD5SUMS",
                                  hashlib.md5,
                                  sign=False)
     checksum_file.entries["entry"] = ""
     checksum_file.changed = True
     checksum_file.write()
     # We can simulate a ctime change by rewinding the mtime of both
     # entry and the checksums file.
     self.rewind_mtime(checksum_file.path)
     self.rewind_mtime(path)
     checksum_file.add("entry")
     self.assertEqual(
         hashlib.md5(b"ctime").hexdigest(), checksum_file.entries["entry"])
Example #27
0
 def test_send_mail_dry_run_from_file(self):
     path = os.path.join(self.temp_dir, "body")
     with mkfile(path) as body:
         print("Body", file=body)
         print("Text", file=body)
     self.capture_logging()
     with open(path) as body:
         send_mail("Test subject",
                   "test_notify", ["*****@*****.**"],
                   body,
                   dry_run=True)
     self.assertLogEqual([
         "Would send mail to: [email protected]",
         "",
         "Subject: Test subject",
         "X-Generated-By: test_notify",
         "",
         "Body",
         "Text",
         "",
     ])
Example #28
0
 def test_write(self):
     checksum_file = ChecksumFile(self.config,
                                  self.temp_dir,
                                  "MD5SUMS",
                                  hashlib.md5,
                                  sign=False)
     for name in "1", "2":
         entry_path = os.path.join(self.temp_dir, name)
         with mkfile(entry_path) as entry:
             print(name, end="", file=entry)
         checksum_file.add(name)
     checksum_file.write()
     with open(checksum_file.path) as md5sums:
         expected = dedent("""\
             %s *1
             %s *2
             """) % (hashlib.md5(b"1").hexdigest(),
                     hashlib.md5(b"2").hexdigest())
         self.assertEqual(expected, md5sums.read())
     self.assertEqual(
         0,
         subprocess.call(["md5sum", "-c", "--status", "MD5SUMS"],
                         cwd=self.temp_dir))
Example #29
0
 def write_structure(self, seed_inherit):
     with mkfile(os.path.join(self.temp_dir, "STRUCTURE")) as structure:
         for seed, inherit in seed_inherit:
             print("%s: %s" % (seed, " ".join(inherit)), file=structure)
Example #30
0
 def test_write_tasks_project(self):
     self.write_ubuntu_structure()
     for arch in "amd64", "i386":
         seed_dir = os.path.join(self.temp_dir, arch)
         self.write_seed_output(arch, "required", ["base-files-%s" % arch])
         self.write_seed_output(arch, "minimal", ["adduser-%s" % arch])
         self.write_seed_output(arch, "desktop", ["xterm", "firefox"])
         self.write_seed_output(arch, "live", ["xterm"])
         with mkfile(os.path.join(
                 seed_dir, "minimal.seedtext")) as seedtext:
             print("Task-Seeds: required", file=seedtext)
         with mkfile(os.path.join(
                 seed_dir, "desktop.seedtext")) as seedtext:
             print("Task-Per-Derivative: 1", file=seedtext)
         with mkfile(os.path.join(seed_dir, "live.seedtext")) as seedtext:
             print("Task-Per-Derivative: 1", file=seedtext)
     self.config["DIST"] = "raring"
     self.config["ARCHES"] = "amd64 i386"
     self.config["IMAGE_TYPE"] = "daily-live"
     self.config["CDIMAGE_LIVE"] = "1"
     output = GerminateOutput(self.config, self.temp_dir)
     output.write_tasks_project("ubuntu")
     output_dir = os.path.join(
         self.temp_dir, "scratch", "ubuntu", "raring", "daily-live",
         "tasks")
     self.assertCountEqual([
         "required", "minimal", "desktop", "live",
         "override.amd64", "override.i386",
         "important.amd64", "important.i386",
         "MASTER",
     ], os.listdir(output_dir))
     with open(os.path.join(output_dir, "required")) as f:
         self.assertEqual(
             dedent("""\
                 #ifdef ARCH_amd64
                 base-files-amd64
                 #endif /* ARCH_amd64 */
                 #ifdef ARCH_i386
                 base-files-i386
                 #endif /* ARCH_i386 */
                 """),
             f.read())
     with open(os.path.join(output_dir, "minimal")) as f:
         self.assertEqual(
             dedent("""\
                 #ifdef ARCH_amd64
                 adduser-amd64
                 #endif /* ARCH_amd64 */
                 #ifdef ARCH_i386
                 adduser-i386
                 #endif /* ARCH_i386 */
                 """),
             f.read())
     with open(os.path.join(output_dir, "desktop")) as f:
         self.assertEqual(
             dedent("""\
                 #ifdef ARCH_amd64
                 firefox
                 xterm
                 #endif /* ARCH_amd64 */
                 #ifdef ARCH_i386
                 firefox
                 xterm
                 #endif /* ARCH_i386 */
                 """),
             f.read())
     with open(os.path.join(output_dir, "live")) as f:
         self.assertEqual(
             dedent("""\
                 #ifdef ARCH_amd64
                 xterm
                 #endif /* ARCH_amd64 */
                 #ifdef ARCH_i386
                 xterm
                 #endif /* ARCH_i386 */
                 """),
             f.read())
     with open(os.path.join(output_dir, "override.amd64")) as f:
         self.assertEqual(
             dedent("""\
                 adduser-amd64  Task  minimal
                 base-files-amd64  Task  minimal
                 firefox  Task  ubuntu-desktop
                 xterm  Task  ubuntu-desktop, ubuntu-live
                 """),
             f.read())
     with open(os.path.join(output_dir, "override.i386")) as f:
         self.assertEqual(
             dedent("""\
                 adduser-i386  Task  minimal
                 base-files-i386  Task  minimal
                 firefox  Task  ubuntu-desktop
                 xterm  Task  ubuntu-desktop, ubuntu-live
                 """),
             f.read())
     with open(os.path.join(output_dir, "important.amd64")) as f:
         self.assertEqual("adduser-amd64\nbase-files-amd64\n", f.read())
     with open(os.path.join(output_dir, "important.i386")) as f:
         self.assertEqual("adduser-i386\nbase-files-i386\n", f.read())
     with open(os.path.join(output_dir, "MASTER")) as f:
         self.assertEqual("#include <ubuntu/raring/ship-live>\n", f.read())