Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | #!/usr/bin/env python |
michael@0 | 2 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | # License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 4 | # You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 5 | |
michael@0 | 6 | """ |
michael@0 | 7 | Imports a test suite from a remote repository. Takes one argument, a file in |
michael@0 | 8 | the format described in README. |
michael@0 | 9 | Note: removes both source and destination directory before starting. Do not |
michael@0 | 10 | use with outstanding changes in either directory. |
michael@0 | 11 | """ |
michael@0 | 12 | |
michael@0 | 13 | from __future__ import print_function, unicode_literals |
michael@0 | 14 | |
michael@0 | 15 | import os |
michael@0 | 16 | import shutil |
michael@0 | 17 | import subprocess |
michael@0 | 18 | import sys |
michael@0 | 19 | |
michael@0 | 20 | import parseManifest |
michael@0 | 21 | import writeBuildFiles |
michael@0 | 22 | |
michael@0 | 23 | def readManifests(iden, dirs): |
michael@0 | 24 | def parseManifestFile(iden, path): |
michael@0 | 25 | pathstr = "hg-%s/%s/MANIFEST" % (iden, path) |
michael@0 | 26 | subdirs, mochitests, reftests, _, supportfiles = parseManifest.parseManifestFile(pathstr) |
michael@0 | 27 | return subdirs, mochitests, reftests, supportfiles |
michael@0 | 28 | |
michael@0 | 29 | data = [] |
michael@0 | 30 | for path in dirs: |
michael@0 | 31 | subdirs, mochitests, reftests, supportfiles = parseManifestFile(iden, path) |
michael@0 | 32 | data.append({ |
michael@0 | 33 | "path": path, |
michael@0 | 34 | "mochitests": mochitests, |
michael@0 | 35 | "reftests": reftests, |
michael@0 | 36 | "supportfiles": supportfiles, |
michael@0 | 37 | }) |
michael@0 | 38 | data.extend(readManifests(iden, ["%s/%s" % (path, d) for d in subdirs])) |
michael@0 | 39 | return data |
michael@0 | 40 | |
michael@0 | 41 | |
michael@0 | 42 | def getData(confFile): |
michael@0 | 43 | """This function parses a file of the form |
michael@0 | 44 | (hg or git)|URL of remote repository|identifier for the local directory |
michael@0 | 45 | First directory of tests |
michael@0 | 46 | ... |
michael@0 | 47 | Last directory of tests""" |
michael@0 | 48 | vcs = "" |
michael@0 | 49 | url = "" |
michael@0 | 50 | iden = "" |
michael@0 | 51 | directories = [] |
michael@0 | 52 | try: |
michael@0 | 53 | with open(confFile, 'r') as fp: |
michael@0 | 54 | first = True |
michael@0 | 55 | for line in fp: |
michael@0 | 56 | if first: |
michael@0 | 57 | vcs, url, iden = line.strip().split("|") |
michael@0 | 58 | first = False |
michael@0 | 59 | else: |
michael@0 | 60 | directories.append(line.strip()) |
michael@0 | 61 | finally: |
michael@0 | 62 | return vcs, url, iden, directories |
michael@0 | 63 | |
michael@0 | 64 | |
michael@0 | 65 | def makePathInternal(a, b): |
michael@0 | 66 | if not b: |
michael@0 | 67 | # Empty directory, i.e., the repository root. |
michael@0 | 68 | return a |
michael@0 | 69 | return "%s/%s" % (a, b) |
michael@0 | 70 | |
michael@0 | 71 | |
michael@0 | 72 | def makeSourcePath(a, b): |
michael@0 | 73 | """Make a path in the source (upstream) directory.""" |
michael@0 | 74 | return makePathInternal("hg-%s" % a, b) |
michael@0 | 75 | |
michael@0 | 76 | |
michael@0 | 77 | def makeDestPath(a, b): |
michael@0 | 78 | """Make a path in the destination (mozilla-central) directory, shortening as |
michael@0 | 79 | appropriate.""" |
michael@0 | 80 | def shorten(path): |
michael@0 | 81 | path = path.replace('dom-tree-accessors', 'dta') |
michael@0 | 82 | path = path.replace('document.getElementsByName', 'doc.gEBN') |
michael@0 | 83 | path = path.replace('requirements-for-implementations', 'implreq') |
michael@0 | 84 | path = path.replace('other-elements-attributes-and-apis', 'oeaaa') |
michael@0 | 85 | return path |
michael@0 | 86 | |
michael@0 | 87 | return shorten(makePathInternal(a, b)) |
michael@0 | 88 | |
michael@0 | 89 | |
michael@0 | 90 | def extractReftestFiles(reftests): |
michael@0 | 91 | """Returns the set of files referenced in the reftests argument""" |
michael@0 | 92 | files = set() |
michael@0 | 93 | for line in reftests: |
michael@0 | 94 | files.update([line[1], line[2]]) |
michael@0 | 95 | return files |
michael@0 | 96 | |
michael@0 | 97 | |
michael@0 | 98 | def copy(dest, directories): |
michael@0 | 99 | """Copy mochitests and support files from the external HG directory to their |
michael@0 | 100 | place in mozilla-central. |
michael@0 | 101 | """ |
michael@0 | 102 | print("Copying tests...") |
michael@0 | 103 | for d in directories: |
michael@0 | 104 | sourcedir = makeSourcePath(dest, d["path"]) |
michael@0 | 105 | destdir = makeDestPath(dest, d["path"]) |
michael@0 | 106 | os.makedirs(destdir) |
michael@0 | 107 | |
michael@0 | 108 | reftestfiles = extractReftestFiles(d["reftests"]) |
michael@0 | 109 | |
michael@0 | 110 | for mochitest in d["mochitests"]: |
michael@0 | 111 | shutil.copy("%s/%s" % (sourcedir, mochitest), "%s/test_%s" % (destdir, mochitest)) |
michael@0 | 112 | for reftest in sorted(reftestfiles): |
michael@0 | 113 | shutil.copy("%s/%s" % (sourcedir, reftest), "%s/%s" % (destdir, reftest)) |
michael@0 | 114 | for support in d["supportfiles"]: |
michael@0 | 115 | shutil.copy("%s/%s" % (sourcedir, support), "%s/%s" % (destdir, support)) |
michael@0 | 116 | |
michael@0 | 117 | def printBuildFiles(dest, directories): |
michael@0 | 118 | """Create a mochitest.ini that all the contains tests we import. |
michael@0 | 119 | """ |
michael@0 | 120 | print("Creating manifest...") |
michael@0 | 121 | all_mochitests = set() |
michael@0 | 122 | all_support = set() |
michael@0 | 123 | |
michael@0 | 124 | for d in directories: |
michael@0 | 125 | path = makeDestPath(dest, d["path"]) |
michael@0 | 126 | |
michael@0 | 127 | all_mochitests |= set('%s/test_%s' % (d['path'], mochitest) |
michael@0 | 128 | for mochitest in d['mochitests']) |
michael@0 | 129 | all_support |= set('%s/%s' % (d['path'], p) for p in d['supportfiles']) |
michael@0 | 130 | |
michael@0 | 131 | if d["reftests"]: |
michael@0 | 132 | with open(path + "/reftest.list", "w") as fh: |
michael@0 | 133 | result = writeBuildFiles.substReftestList("importTestsuite.py", |
michael@0 | 134 | d["reftests"]) |
michael@0 | 135 | fh.write(result) |
michael@0 | 136 | |
michael@0 | 137 | manifest_path = dest + '/mochitest.ini' |
michael@0 | 138 | with open(manifest_path, 'w') as fh: |
michael@0 | 139 | result = writeBuildFiles.substManifest('importTestsuite.py', |
michael@0 | 140 | all_mochitests, all_support) |
michael@0 | 141 | fh.write(result) |
michael@0 | 142 | subprocess.check_call(["hg", "add", manifest_path]) |
michael@0 | 143 | |
michael@0 | 144 | def hgadd(dest, directories): |
michael@0 | 145 | """Inform hg of the files in |directories|.""" |
michael@0 | 146 | print("hg addremoving...") |
michael@0 | 147 | for d in directories: |
michael@0 | 148 | subprocess.check_call(["hg", "addremove", makeDestPath(dest, d)]) |
michael@0 | 149 | |
michael@0 | 150 | def removeAndCloneRepo(vcs, url, dest): |
michael@0 | 151 | """Replaces the repo at dest by a fresh clone from url using vcs""" |
michael@0 | 152 | assert vcs in ('hg', 'git') |
michael@0 | 153 | |
michael@0 | 154 | print("Removing %s..." % dest) |
michael@0 | 155 | subprocess.check_call(["rm", "-rf", dest]) |
michael@0 | 156 | |
michael@0 | 157 | print("Cloning %s to %s with %s..." % (url, dest, vcs)) |
michael@0 | 158 | subprocess.check_call([vcs, "clone", url, dest]) |
michael@0 | 159 | |
michael@0 | 160 | def importRepo(confFile): |
michael@0 | 161 | try: |
michael@0 | 162 | vcs, url, iden, directories = getData(confFile) |
michael@0 | 163 | dest = iden |
michael@0 | 164 | hgdest = "hg-%s" % iden |
michael@0 | 165 | |
michael@0 | 166 | print("Removing %s..." % dest) |
michael@0 | 167 | subprocess.check_call(["rm", "-rf", dest]) |
michael@0 | 168 | |
michael@0 | 169 | removeAndCloneRepo(vcs, url, hgdest) |
michael@0 | 170 | |
michael@0 | 171 | data = readManifests(iden, directories) |
michael@0 | 172 | print("Going to import %s..." % [d["path"] for d in data]) |
michael@0 | 173 | |
michael@0 | 174 | copy(dest, data) |
michael@0 | 175 | printBuildFiles(dest, data) |
michael@0 | 176 | hgadd(dest, directories) |
michael@0 | 177 | print("Removing %s again..." % hgdest) |
michael@0 | 178 | subprocess.check_call(["rm", "-rf", hgdest]) |
michael@0 | 179 | except subprocess.CalledProcessError as e: |
michael@0 | 180 | print(e.returncode) |
michael@0 | 181 | finally: |
michael@0 | 182 | print("Done") |
michael@0 | 183 | |
michael@0 | 184 | if __name__ == "__main__": |
michael@0 | 185 | if len(sys.argv) != 2: |
michael@0 | 186 | print("Need one argument.") |
michael@0 | 187 | else: |
michael@0 | 188 | importRepo(sys.argv[1]) |
michael@0 | 189 |