Skip to content

Commit f077e54

Browse files
committed
Request higher SafeLevel builds when requesting Android build by branch
In cvd fetch, when requesting a build by branch and target, prefer requesting higher SafeLevel builds (PLATINUM, SAFE_2, SAFE_1) when possible before falling back to any complete successful build (SAFE_0 / unspecified). If users want a specific build id, that is already possible to request through command line arguments. When a user requests a branch by name, they probably do not care as much how recent the build is. In the case of our presubmit, this will hopefully reduce flakes that come from the device side. The main failure mode here is if a build target / branch combination has previously reported a higher safe level and no longer does, it will get stuck on the older build from the higher safe level indefinitely. Assisted-by: Jetski:Gemini Next Bug: b/518049553
1 parent 091b65f commit f077e54

3 files changed

Lines changed: 74 additions & 21 deletions

File tree

base/cvd/cuttlefish/host/libs/web/android_build_api.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -276,25 +276,29 @@ Result<std::vector<std::string>> AndroidBuildApi::Headers() {
276276

277277
Result<std::optional<std::string>> AndroidBuildApi::LatestBuildId(
278278
const std::string& branch, const std::string& target) {
279-
const std::string url =
280-
android_build_url_->GetLatestBuildIdUrl(branch, target);
281-
auto response =
282-
CF_EXPECT(HttpGetToJson(http_client_, url, CF_EXPECT(Headers())));
283-
284-
const Json::Value json = CF_EXPECTF(GetResponseJson(response),
285-
"Error fetching last known good build "
286-
"id for:\nbranch \"{}\", target \"{}\"",
287-
branch, target);
288-
if (!json.isMember("builds")) {
289-
return std::nullopt;
279+
for (const SafeLevel safe_level : kAllSafeLevels) {
280+
VLOG(0) << "Attempting to download build at safe level '" << safe_level
281+
<< "' for branch '" << branch << "' and target '" << target << "'";
282+
const std::string url =
283+
android_build_url_->GetLatestBuildIdUrl(branch, target, safe_level);
284+
const std::vector<std::string> headers = CF_EXPECT(Headers());
285+
const HttpResponse<Json::Value> response =
286+
CF_EXPECT(HttpGetToJson(http_client_, url, headers));
287+
288+
const Json::Value json = CF_EXPECTF(
289+
GetResponseJson(response),
290+
"Error fetching last known good build id for:\nbranch '{}', target "
291+
"'{}', safe_level '{}'",
292+
branch, target, safe_level);
293+
if (json.empty()) {
294+
continue;
295+
}
296+
Json::Value builds = CF_EXPECT(GetValue<Json::Value>(json, {"builds"}));
297+
CF_EXPECT(builds.isArray());
298+
CF_EXPECT_EQ(builds.size(), 1);
299+
return CF_EXPECT(GetValue<std::string>(builds[0], {"buildId"}));
290300
}
291-
292-
CF_EXPECTF(json["builds"].isArray() && json["builds"].size() == 1,
293-
"Expected to find a single latest build for branch \"{}\" and "
294-
"target \"{}\" in the response array, "
295-
"but found {}",
296-
branch, target, json["builds"].size());
297-
return CF_EXPECT(GetValue<std::string>(json["builds"][0], { "buildId" }));
301+
return std::nullopt;
298302
}
299303

300304
Result<std::unordered_set<std::string>> AndroidBuildApi::Artifacts(

base/cvd/cuttlefish/host/libs/web/android_build_url.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "cuttlefish/host/libs/web/android_build_url.h"
1717

18+
#include <ostream>
1819
#include <sstream>
1920
#include <string>
2021
#include <string_view>
@@ -109,19 +110,40 @@ std::string BuildNameRegexp(
109110

110111
} // namespace
111112

113+
std::string_view format_as(SafeLevel level) {
114+
switch (level) {
115+
case SafeLevel::kPlatinum:
116+
return "PLATINUM";
117+
case SafeLevel::kSafe2:
118+
return "SAFE_2";
119+
case SafeLevel::kSafe1:
120+
return "SAFE_1";
121+
case SafeLevel::kSafe0:
122+
return "SAFE_0";
123+
case SafeLevel::kSafeLevelUnspecified:
124+
return "";
125+
}
126+
}
127+
128+
std::ostream& operator<<(std::ostream& os, SafeLevel level) {
129+
return os << format_as(level);
130+
}
131+
112132
AndroidBuildUrl::AndroidBuildUrl(std::string api_base_url, std::string api_key,
113133
std::string project_id)
114134
: api_base_url_(std::move(api_base_url)),
115135
api_key_(std::move(api_key)),
116136
project_id_(std::move(project_id)) {}
117137

118138
std::string AndroidBuildUrl::GetLatestBuildIdUrl(std::string_view branch,
119-
std::string_view target) {
139+
std::string_view target,
140+
SafeLevel safe_level) {
120141
UrlBuilder builder = UrlBuilder::GetLatestBuildIdBaseUrl(api_base_url_);
121142
builder.AddQueryParameter("buildAttemptStatus", "complete");
122143
builder.AddQueryParameter("buildType", "submitted");
123144
builder.AddQueryParameter("pageSize", "1");
124145
builder.AddQueryParameter("successful", "true");
146+
builder.AddQueryParameter("safeLevel", format_as(safe_level));
125147
builder.AddQueryParameter("branches", branch);
126148
builder.AddQueryParameter("targets", target);
127149
builder.AddApiKeyAndProjectId(api_key_, project_id_);

base/cvd/cuttlefish/host/libs/web/android_build_url.h

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,38 @@
1515

1616
#pragma once
1717

18+
#include <ostream>
1819
#include <string>
1920
#include <string_view>
2021
#include <vector>
2122

2223
namespace cuttlefish {
2324

25+
enum class SafeLevel {
26+
kSafeLevelUnspecified = 0,
27+
kSafe0,
28+
kSafe1,
29+
kSafe2,
30+
kPlatinum,
31+
};
32+
33+
std::string_view format_as(SafeLevel level);
34+
35+
template <typename Sink>
36+
void AbslStringify(Sink& sink, SafeLevel level) {
37+
sink.Append(format_as(level));
38+
}
39+
40+
std::ostream& operator<<(std::ostream& os, SafeLevel level);
41+
42+
inline constexpr SafeLevel kAllSafeLevels[] = {
43+
SafeLevel::kPlatinum,
44+
SafeLevel::kSafe2,
45+
SafeLevel::kSafe1,
46+
SafeLevel::kSafe0,
47+
SafeLevel::kSafeLevelUnspecified,
48+
};
49+
2450
inline constexpr char kAndroidBuildServiceUrl[] =
2551
"https://androidbuild-pa.googleapis.com/v4";
2652

@@ -29,8 +55,9 @@ class AndroidBuildUrl {
2955
AndroidBuildUrl(std::string api_base_url, std::string api_key,
3056
std::string project_id);
3157

32-
std::string GetLatestBuildIdUrl(std::string_view branch,
33-
std::string_view target);
58+
std::string GetLatestBuildIdUrl(
59+
std::string_view branch, std::string_view target,
60+
SafeLevel safe_level = SafeLevel::kSafeLevelUnspecified);
3461
std::string GetBuildUrl(std::string_view id, std::string_view target);
3562
std::string GetArtifactUrl(std::string_view id, std::string_view target,
3663
const std::vector<std::string>& artifact_filenames,

0 commit comments

Comments
 (0)