blob: b09797522a63967242366becf0a40d873e6e52bf [file] [log] [blame]
import importlib
import os
import unittest
import zipfile
# Import module using importlib because package name contains a dash.
jps_build = importlib.import_module("tools.adt.idea.jps-build.jps_build")
def get_path(name):
return os.path.join(os.getenv("TEST_TMPDIR"), name)
def create_zip(name, contents):
path = get_path(name)
tmp = 0
with zipfile.ZipFile(path, "w") as zip:
for e, v in contents.items():
if isinstance(v, str):
info = zipfile.ZipInfo(e)
if e.endswith(".sh"):
info.external_attr = 0o777 << 16
zip.writestr(info, v)
else:
tmp_path = create_zip("%s.%d.zip" % (name, tmp), v)
zip.write(tmp_path, e)
os.remove(tmp_path)
return path
def create_file(name, content):
path = get_path(name)
with open(path, "w") as f:
f.write(content)
return path
def read_file(path, mode = "r"):
with open(path, mode) as f:
return f.read()
def read_entry(zip, entry):
with zipfile.ZipFile(zip, "r") as z:
return z.read(entry).decode("utf-8")
def create_idea_sources():
return create_zip("idea_sources.zip", {
"tools/idea/platform/jps-bootstrap/jps-bootstrap.sh": FAKE_JPS_BOOTSTRAP_SH,
})
def write_file(path, content):
with open(path, "w") as f:
f.write(content)
def list_files(path):
if path.endswith(".zip"):
with zipfile.ZipFile(path, "r") as zip:
return sorted([n for n in zip.namelist() if not n.endswith("/")])
else:
return sorted(jps_build.files_in_dir(path))
FAKE_JPS_BOOTSTRAP_SH = """#!/bin/sh
# Fake download files
mkdir -p $HOME/.down
touch $HOME/.down/down.jar
mkdir -p build/download
touch build/download/down.jar
touch build/download/down.exe
chmod a+x build/download/down.exe
mkdir -p out/jps-bootstrap
touch out/jps-bootstrap/boot.jar
mkdir -p unexpected_download
touch unexpected_download/what.txt
# Only "download if file is not there"
mkdir -p out/studio/artifacts
if [ -f conditional.jar ]; then
echo "Not Downloaded" > out/studio/artifacts/download.log
else
touch conditional.jar
echo "Downloaded" > out/studio/artifacts/download.log
fi
# Fake build and write outputs
mkdir -p out/studio/classes/module
touch out/studio/classes/module/a.class
mkdir -p out/studio/artifacts/debugger-tests
echo "{out}/some/out/dir" > out/studio/artifacts/debugger-tests/classpath.txt
"""
class JpsBuildTest(unittest.TestCase):
def test_build_output(self):
idea = create_idea_sources()
out_classpath = get_path("classpath.txt")
out_zip = get_path("out.zip")
jps_build.main([
"--sources",
idea,
"--out_file",
out_zip,
"--command",
"platform/jps-bootstrap/jps-bootstrap.sh",
"--working_directory",
"tools/idea",
"--output_dir",
"tools/idea/out/studio/",
"--output_dir",
"tools/idea/build/jps-bootstrap-work/",
], {}, get_path("."))
self.assertEqual([
"tools/idea/out/studio/artifacts/debugger-tests/classpath.txt",
"tools/idea/out/studio/artifacts/download.log",
"tools/idea/out/studio/classes/module/a.class",
], list_files(out_zip))
def test_custom_command(self):
idea = create_zip("idea_sources.zip", {
"dir/bin.sh": FAKE_JPS_BOOTSTRAP_SH,
})
out_classpath = get_path("classpath.txt")
out_zip = get_path("out.zip")
jps_build.main([
"--sources",
idea,
"--out_file",
out_zip,
"--command",
"bin.sh",
"--working_directory",
"dir",
"--output_dir",
"dir/out/studio/",
"--output_dir",
"dir/build/jps-bootstrap-work/",
], {}, get_path("."))
self.assertEqual([
"dir/out/studio/artifacts/debugger-tests/classpath.txt",
"dir/out/studio/artifacts/download.log",
"dir/out/studio/classes/module/a.class",
], list_files(out_zip))
def test_error(self):
idea = create_zip("idea_sources.zip", {
"dir/bin.sh": "#!/bin/sh\nexit 1",
})
ret = jps_build.main([
"--sources",
idea,
"--command",
"bin.sh",
"--working_directory",
"dir",
], {}, get_path("."))
self.assertEqual(1, ret)
def test_download_cache(self):
idea = create_idea_sources()
run_workspace = get_path("run_workspace")
jps_build.main([
"--sources",
idea,
"--download_cache",
"cache.zip",
"--command",
"platform/jps-bootstrap/jps-bootstrap.sh",
"--working_directory",
"tools/idea",
"--output_dir",
"tools/idea/out/studio/",
"--output_dir",
"tools/idea/build/jps-bootstrap-work/",
], {"BUILD_WORKSPACE_DIRECTORY": run_workspace}, get_path("."))
self.assertEqual([
"home/.down/down.jar",
"tools/idea/build/download/down.exe",
"tools/idea/build/download/down.jar",
"tools/idea/conditional.jar",
"tools/idea/out/jps-bootstrap/boot.jar",
"tools/idea/unexpected_download/what.txt",
], list_files(os.path.join(run_workspace, "cache.zip")))
def test_ignore(self):
idea = create_idea_sources()
run_workspace = get_path("run_workspace")
out_zip = get_path("out.zip")
jps_build.main([
"--sources",
idea,
"--out_file",
out_zip,
"--download_cache",
"cache.zip",
"--command",
"platform/jps-bootstrap/jps-bootstrap.sh",
"--working_directory",
"tools/idea",
"--output_dir",
"tools/idea/out/studio/",
"--output_dir",
"tools/idea/build/jps-bootstrap-work/",
"--ignore_dir",
"tools/idea/build/download",
"--ignore_dir",
"tools/idea/out/jps-bootstrap",
], {"BUILD_WORKSPACE_DIRECTORY": run_workspace}, get_path("."))
self.assertEqual([
"home/.down/down.jar",
"tools/idea/conditional.jar",
"tools/idea/unexpected_download/what.txt",
], list_files(os.path.join(run_workspace, "cache.zip")))
self.assertEqual([
"tools/idea/out/studio/artifacts/debugger-tests/classpath.txt",
"tools/idea/out/studio/artifacts/download.log",
"tools/idea/out/studio/classes/module/a.class",
], list_files(out_zip))
def test_dev_flow(self):
# Test that it "downloads" into a directory, and then builds from it.
idea = create_idea_sources()
run_workspace = get_path("run_workspace")
os.makedirs(os.path.join(run_workspace, "cache"))
write_file(os.path.join(run_workspace, "cache/keep.me"), "hi")
first_out_zip = get_path("first_out.zip")
jps_build.main([
"--sources",
idea,
"--download_cache",
"cache",
"--out_file",
first_out_zip,
"--command",
"platform/jps-bootstrap/jps-bootstrap.sh",
"--working_directory",
"tools/idea",
"--output_dir",
"tools/idea/out/studio/",
"--output_dir",
"tools/idea/build/jps-bootstrap-work/",
], {"BUILD_WORKSPACE_DIRECTORY": run_workspace}, get_path("."))
self.assertEqual([
"./keep.me",
"home/.down/down.jar",
"tools/idea/build/download/down.exe",
"tools/idea/build/download/down.jar",
"tools/idea/conditional.jar",
"tools/idea/out/jps-bootstrap/boot.jar",
"tools/idea/unexpected_download/what.txt",
], list_files(os.path.join(run_workspace, "cache")))
self.assertTrue(os.access(os.path.join(run_workspace, "cache/tools/idea/build/download/down.exe"), os.X_OK))
self.assertEqual("Downloaded\n", read_entry(first_out_zip, "tools/idea/out/studio/artifacts/download.log"))
cache = os.path.join(run_workspace, "cache")
files = ["%s=%s\n" % (f, os.path.join(cache, f)) for f in list_files(cache)]
cache_lst = get_path("cache.lst")
write_file(cache_lst, "".join(files))
# Add the downloaded cache as a source
out_zip = get_path("out.zip")
jps_build.main([
"--sources",
idea,
"--sources",
cache_lst,
"--download_cache",
"cache",
"--out_file",
out_zip,
"--command",
"platform/jps-bootstrap/jps-bootstrap.sh",
"--working_directory",
"tools/idea",
"--output_dir",
"tools/idea/out/studio/",
"--output_dir",
"tools/idea/build/jps-bootstrap-work/",
], {}, run_workspace)
self.assertEqual([
"tools/idea/out/studio/artifacts/debugger-tests/classpath.txt",
"tools/idea/out/studio/artifacts/download.log",
"tools/idea/out/studio/classes/module/a.class",
], list_files(out_zip))
#not cache, read output
self.assertEqual("Not Downloaded\n", read_entry(out_zip, "tools/idea/out/studio/artifacts/download.log"))
if __name__ == "__main__":
unittest.main()