Skip to content
This repository was archived by the owner on Mar 20, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 858d7bc

Browse files
author
Erwin Jansen
committedMay 15, 2023
Add additional tests and fix code issues
This adds a series of tests to validate that we can actually pull images from our public repository. Cleans up the tests to exclusively use pytest, and fixes a series of py3 issues. Test: All pytests are green Bug: 280634466
1 parent e41b04d commit 858d7bc

21 files changed

+552
-377
lines changed
 

‎.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
__pycache__/
33
*.py[cod]
44
*$py.class
5+
bld/
56

67
# C extensions
78
*.so
@@ -98,7 +99,7 @@ celerybeat-schedule
9899

99100
# Environments
100101
.env
101-
.venv
102+
.venv/
102103
env/
103104
venv/
104105
ENV/

‎aemu-container.code-workspace

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
}
99
],
1010
"settings": {
11-
"python.formatting.provider": "black"
11+
"python.formatting.provider": "none",
12+
"[python]": {
13+
"editor.defaultFormatter": "ms-python.black-formatter"
14+
}
1215
}
1316
}

‎emu/android_release_zip.py

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
import os
1717
import shutil
1818
import zipfile
19+
from typing import Dict, Set, Union
1920

2021
from tqdm import tqdm
2122

2223
from emu.utils import api_codename
2324

2425

26+
class NotAZipfile(Exception):
27+
pass
28+
29+
2530
class AndroidReleaseZip(object):
2631
"""Provides information of released android products.
2732
@@ -30,74 +35,84 @@ class AndroidReleaseZip(object):
3035
about the contents of the zip.
3136
"""
3237

33-
def __init__(self, file_name):
34-
self.file_name = file_name
38+
def __init__(self, file_name: str):
39+
self.file_name: str = file_name
3540
if not zipfile.is_zipfile(file_name):
36-
raise Exception("{} is not a zipfile!".format(file_name))
41+
raise NotAZipfile(f"{file_name} is not a zipfile!")
42+
3743
with zipfile.ZipFile(file_name, "r") as zip_file:
38-
self.props = collections.defaultdict(set)
39-
files = [x for x in zip_file.infolist() if "source.properties" in x.filename or "build.prop" in x.filename]
44+
self.props: Dict[str, Set[str]] = collections.defaultdict(set)
45+
files = [
46+
x
47+
for x in zip_file.infolist()
48+
if "source.properties" in x.filename or "build.prop" in x.filename
49+
]
4050
for file in files:
4151
for key, value in self._unpack_properties(zip_file, file).items():
4252
self.props[key] = value
4353

44-
def _unpack_properties(self, zip_file, zip_info):
54+
def _unpack_properties(
55+
self, zip_file: zipfile.ZipFile, zip_info: zipfile.ZipInfo
56+
) -> Dict[str, str]:
4557
prop = zip_file.read(zip_info).decode("utf-8").splitlines()
4658
res = dict([a.split("=") for a in prop if "=" in a])
4759
return res
4860

49-
def __str__(self):
50-
return "{}-{}".format(self.description(), self.revision())
61+
def __str__(self) -> str:
62+
return f"{self.description()}-{self.revision()}"
5163

52-
def description(self):
64+
def description(self) -> Union[str, None]:
5365
"""Descripton of this release."""
5466
return self.props.get("Pkg.Desc")
5567

56-
def revision(self):
68+
def revision(self) -> Union[str, None]:
5769
"""The revision of this release."""
5870
return self.props.get("Pkg.Revision")
5971

60-
def build_id(self):
72+
def build_id(self) -> str:
6173
"""The Pkg.BuildId or revision if build id is not available."""
6274
if "Pkg.BuildId" in self.props:
6375
return self.props.get("Pkg.BuildId")
6476
return self.revision()
6577

66-
def is_system_image(self):
78+
def is_system_image(self) -> bool:
6779
"""True if this zip file contains a system image."""
68-
return "System Image" in self.description() or "Android SDK Platform" in self.description()
80+
return (
81+
"System Image" in self.description()
82+
or "Android SDK Platform" in self.description()
83+
)
6984

70-
def is_emulator(self):
85+
def is_emulator(self) -> bool:
7186
"""True if this zip file contains the android emulator."""
7287
return "Android Emulator" in self.description()
7388

74-
def copy(self, destination):
89+
def copy(self, destination: str) -> str:
7590
"""Copy the zipfile to the given destination.
7691
7792
If the destination is the same as this zipfile the current path
7893
will be returned a no copy is made.
7994
8095
Args:
81-
destination ({string}): The destination to copy this zip to.
96+
destination (str): The destination to copy this zip to.
8297
8398
Returns:
84-
{string}: The path where this zip file was copied to
99+
str: The path where this zip file was copied to.
85100
"""
86101
try:
87102
return shutil.copy2(self.file_name, destination)
88103
except shutil.SameFileError:
89104
logging.warning("Will not copy to itself, ignoring..")
90105
return self.file_name
91106

92-
def extract(self, destination):
107+
def extract(self, destination: str) -> None:
93108
"""Extract this release zip to the given destination
94109
95110
Args:
96-
destination ({string}): The destination to extract the zipfile to.
111+
destination (str): The destination to extract the zipfile to.
97112
"""
98113

99114
zip_file = zipfile.ZipFile(self.file_name)
100-
print("Extracting: {} -> {}".format(self.file_name, destination))
115+
print(f"Extracting: {self.file_name} -> {destination}")
101116
for info in tqdm(iterable=zip_file.infolist(), total=len(zip_file.infolist())):
102117
filename = zip_file.extract(info, path=destination)
103118
mode = info.external_attr >> 16
@@ -108,61 +123,71 @@ def extract(self, destination):
108123
class SystemImageReleaseZip(AndroidReleaseZip):
109124
"""An Android Release Zipfile containing an emulator system image."""
110125

111-
ABI_CPU_MAP = {"armeabi-v7a": "arm", "arm64-v8a": "arm64", "x86_64": "x86_64", "x86": "x86"}
112-
SHORT_MAP = {"armeabi-v7a": "a32", "arm64-v8a": "a64", "x86_64": "x64", "x86": "x86"}
113-
SHORT_TAG = {
126+
ABI_CPU_MAP: Dict[str, str] = {
127+
"armeabi-v7a": "arm",
128+
"arm64-v8a": "arm64",
129+
"x86_64": "x86_64",
130+
"x86": "x86",
131+
}
132+
SHORT_MAP: Dict[str, str] = {
133+
"armeabi-v7a": "a32",
134+
"arm64-v8a": "a64",
135+
"x86_64": "x64",
136+
"x86": "x86",
137+
}
138+
SHORT_TAG: Dict[str, str] = {
114139
"android": "aosp",
115140
"google_apis": "google",
116141
"google_apis_playstore": "playstore",
117142
"google_ndk_playstore": "ndk_playstore",
118143
"android-tv": "tv",
119144
}
120145

121-
def __init__(self, file_name):
146+
def __init__(self, file_name: str):
122147
super().__init__(file_name)
123148
if not self.is_system_image():
124-
raise Exception("{} is not a zip file with a system image".format(file_name))
149+
raise NotAZipfile(f"{file_name} is not a zip file with a system image")
125150

126151
self.props["qemu.cpu"] = self.qemu_cpu()
127152
self.props["qemu.tag"] = self.tag()
128153
self.props["qemu.short_tag"] = self.short_tag()
129154
self.props["qemu.short_abi"] = self.short_abi()
130155

131-
def api(self):
156+
def api(self) -> str:
132157
"""The api level, if any."""
133158
return self.props.get("AndroidVersion.ApiLevel", "")
134159

135-
def codename(self):
160+
def codename(self) -> str:
136161
"""First letter of the desert, if any."""
137162
if "AndroidVersion.CodeName" in self.props:
138163
return self.props["AndroidVersion.CodeName"]
139164
return api_codename(self.api())
140165

141-
def abi(self):
166+
def abi(self) -> str:
142167
"""The abi if any."""
143168
return self.props.get("SystemImage.Abi", "")
144169

145-
def short_abi(self):
170+
def short_abi(self) -> str:
146171
"""Shortened version of the ABI string."""
147172
if self.abi() not in self.SHORT_MAP:
148173
logging.error("%s not in short map", self)
149174
return self.SHORT_MAP[self.abi()]
150175

151-
def qemu_cpu(self):
176+
def qemu_cpu(self) -> str:
152177
"""Returns the cpu architecture, derived from the abi."""
153178
return self.ABI_CPU_MAP.get(self.abi(), "None")
154179

155-
def gpu(self):
180+
def gpu(self) -> str:
156181
"""Returns whether or not the system has gpu support."""
157182
return self.props.get("SystemImage.GpuSupport")
158183

159-
def tag(self):
184+
def tag(self) -> str:
160185
"""The tag associated with this release."""
161186
tag = self.props.get("SystemImage.TagId", "")
162187
if tag == "default" or tag.strip() == "":
163188
tag = "android"
164189
return tag
165190

166-
def short_tag(self):
191+
def short_tag(self) -> str:
167192
"""A shorthand tag."""
168193
return self.SHORT_TAG[self.tag()]

‎emu/cloud_build.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,25 @@ def cloud_build(args):
9999
emulators.add(emulator_container.props["emu_build_id"])
100100
steps.append(create_build_step(emulator_container, args.dest))
101101
images.append(emulator_container.full_name())
102-
images.append(emulator_container.latest_name())
103102
emulator_images.append(emulator_container.full_name())
104-
emulator_images.append(emulator_container.latest_name())
105103

106104
cloudbuild = {"steps": steps, "images": images, "timeout": "21600s"}
107105
logging.info("Writing cloud yaml [%s] in %s", yaml, args.dest)
108-
with open(os.path.join(args.dest, "cloudbuild.yaml"), "w") as ymlfile:
106+
with open(os.path.join(args.dest, "cloudbuild.yaml"), "w", encoding="utf-8") as ymlfile:
109107
yaml.dump(cloudbuild, ymlfile)
110108

111109
writer = TemplateWriter(args.dest)
112110
writer.write_template(
113111
"cloudbuild.README.MD",
114-
{"emu_version": ", ".join(emulators), "emu_images": "\n".join(["* {}".format(x) for x in emulator_images])},
112+
{"emu_version": ", ".join(emulators),
113+
"emu_images": "\n".join([f"* {x}" for x in emulator_images])},
115114
rename_as="README.MD",
116115
)
117116
writer.write_template(
118117
"registry.README.MD",
119118
{
120119
"emu_version": ", ".join(emulators),
121-
"emu_images": "\n".join(["* {}".format(x) for x in images]),
120+
"emu_images": "\n".join([f"* {x}" for x in images]),
122121
"first_image": next(iter(images), None),
123122
},
124123
rename_as="REGISTRY.MD",

0 commit comments

Comments
 (0)
This repository has been archived.