Refactor derive_sdk to be more testable
Refactor the code into a reusable library that is used from the
derive_sdk binary as well as a newly added cc_test.
The code now accepts an argument for which dir to scan for mounted
modules.
Add a simple test for the current system image R SDK version for now.
Bug: 173188089
Test: atest derive_sdk_test
Change-Id: If7442d515d55b35174d396cc579ee2c9865da2b5
diff --git a/derive_sdk/Android.bp b/derive_sdk/Android.bp
index 3e030e8..dc4e352 100644
--- a/derive_sdk/Android.bp
+++ b/derive_sdk/Android.bp
@@ -14,10 +14,6 @@
cc_defaults {
name: "derive_sdk-defaults",
- srcs: [
- "derive_sdk.cpp",
- "sdk.proto",
- ],
proto: {
type: "lite",
static: true,
@@ -29,26 +25,56 @@
static_libs: [
"libbase",
"libmodules-utils-build",
+ "libprotobuf-cpp-lite",
],
}
+cc_library {
+ name: "libderive_sdk",
+ srcs: [
+ "derive_sdk.cpp",
+ "sdk.proto",
+ ],
+ defaults: ["derive_sdk-defaults"],
+ apex_available: ["com.android.sdkext"],
+}
+
+cc_defaults {
+ name: "derive_sdk_binary-defaults",
+ defaults: ["derive_sdk-defaults"],
+ srcs: ["main.cpp"],
+ static_libs: ["libderive_sdk"],
+
+}
cc_binary {
name: "derive_sdk",
- defaults: [ "derive_sdk-defaults" ],
- apex_available: [ "com.android.sdkext" ],
+ defaults: ["derive_sdk_binary-defaults"],
+ apex_available: ["com.android.sdkext"],
}
// Work around testing using a 64-bit test suite on 32-bit test device by
// using a prefer32 version of derive_sdk in testing.
cc_binary {
name: "derive_sdk_prefer32",
- defaults: [ "derive_sdk-defaults" ],
+ defaults: ["derive_sdk_binary-defaults"],
compile_multilib: "prefer32",
stem: "derive_sdk",
- apex_available: [ "test_com.android.sdkext" ],
+ apex_available: ["test_com.android.sdkext"],
installable: false,
}
+cc_test {
+ name: "derive_sdk_test",
+ defaults: ["derive_sdk-defaults"],
+ srcs: [
+ "derive_sdk_test.cpp",
+ "sdk.proto",
+ ],
+ require_root: true,
+ static_libs: ["libderive_sdk"],
+ test_suites: ["device-tests"],
+}
+
prebuilt_etc {
name: "derive_sdk.rc",
src: "derive_sdk.rc",
diff --git a/derive_sdk/derive_sdk.cpp b/derive_sdk/derive_sdk.cpp
index 1b85c90..fb5f1f5 100644
--- a/derive_sdk/derive_sdk.cpp
+++ b/derive_sdk/derive_sdk.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "derive_sdk"
+#include "derive_sdk.h"
+
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -31,11 +33,15 @@
using com::android::sdkext::proto::SdkVersion;
-int main(int, char**) {
- std::unique_ptr<DIR, decltype(&closedir)> apex(opendir("/apex"), closedir);
+namespace android {
+namespace derivesdk {
+
+bool SetSdkLevels(const std::string& mountpath) {
+ std::unique_ptr<DIR, decltype(&closedir)> apex(opendir(mountpath.c_str()),
+ closedir);
if (!apex) {
- LOG(ERROR) << "Could not read /apex";
- return EXIT_FAILURE;
+ LOG(ERROR) << "Could not read " + mountpath;
+ return false;
}
struct dirent* de;
std::vector<std::string> paths;
@@ -45,7 +51,7 @@
// Skip <name>@<ver> dirs, as they are bind-mounted to <name>
continue;
}
- std::string path = "/apex/" + name + "/etc/sdkinfo.binarypb";
+ std::string path = mountpath + "/" + name + "/etc/sdkinfo.binarypb";
struct stat statbuf;
if (stat(path.c_str(), &statbuf) == 0) {
paths.push_back(path);
@@ -72,15 +78,18 @@
if (!android::base::SetProperty("build.version.extensions.r", prop_value)) {
LOG(ERROR) << "failed to set r sdk_info prop";
- return EXIT_FAILURE;
+ return false;
}
if (android::modules::sdklevel::IsAtLeastS()) {
if (!android::base::SetProperty("build.version.extensions.s", prop_value)) {
LOG(ERROR) << "failed to set s sdk_info prop";
- return EXIT_FAILURE;
+ return false;
}
}
LOG(INFO) << "Extension version is " << prop_value;
- return EXIT_SUCCESS;
+ return true;
}
+
+} // namespace derivesdk
+} // namespace android
diff --git a/derive_sdk/derive_sdk.h b/derive_sdk/derive_sdk.h
new file mode 100644
index 0000000..2d64b7c
--- /dev/null
+++ b/derive_sdk/derive_sdk.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace android {
+namespace derivesdk {
+
+bool SetSdkLevels(const std::string& mountpath);
+
+} // namespace derivesdk
+} // namespace android
diff --git a/derive_sdk/derive_sdk_test.cpp b/derive_sdk/derive_sdk_test.cpp
new file mode 100644
index 0000000..5dbfdb7
--- /dev/null
+++ b/derive_sdk/derive_sdk_test.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "derive_sdk.h"
+
+#include <android-base/properties.h>
+#include <gtest/gtest.h>
+
+#include <cstdlib>
+
+class DeriveSdkTest : public ::testing::Test {
+ protected:
+ void TearDown() override { android::derivesdk::SetSdkLevels("/apex"); }
+};
+
+int R() {
+ return android::base::GetIntProperty("build.version.extensions.r", -1);
+}
+
+TEST_F(DeriveSdkTest, CurrentSystemImageValue) { EXPECT_EQ(R(), 0); }
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/derive_sdk/main.cpp b/derive_sdk/main.cpp
new file mode 100644
index 0000000..d7b0e7a
--- /dev/null
+++ b/derive_sdk/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+
+#include "derive_sdk.h"
+
+int main(int, char**) {
+ if (!android::derivesdk::SetSdkLevels("/apex")) {
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}