1*33f37583SAndroid Build Coastguard Worker /*
2*33f37583SAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*33f37583SAndroid Build Coastguard Worker *
4*33f37583SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*33f37583SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*33f37583SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*33f37583SAndroid Build Coastguard Worker *
8*33f37583SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*33f37583SAndroid Build Coastguard Worker *
10*33f37583SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*33f37583SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*33f37583SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*33f37583SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*33f37583SAndroid Build Coastguard Worker * limitations under the License.
15*33f37583SAndroid Build Coastguard Worker */
16*33f37583SAndroid Build Coastguard Worker
17*33f37583SAndroid Build Coastguard Worker #include "apex_classpath.h"
18*33f37583SAndroid Build Coastguard Worker
19*33f37583SAndroid Build Coastguard Worker #include <android-base/file.h>
20*33f37583SAndroid Build Coastguard Worker #include <android-base/result-gmock.h>
21*33f37583SAndroid Build Coastguard Worker #include <gmock/gmock.h>
22*33f37583SAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*33f37583SAndroid Build Coastguard Worker
24*33f37583SAndroid Build Coastguard Worker #include <fstream>
25*33f37583SAndroid Build Coastguard Worker #include <string>
26*33f37583SAndroid Build Coastguard Worker
27*33f37583SAndroid Build Coastguard Worker namespace android {
28*33f37583SAndroid Build Coastguard Worker namespace apex {
29*33f37583SAndroid Build Coastguard Worker
30*33f37583SAndroid Build Coastguard Worker using android::base::WriteStringToFile;
31*33f37583SAndroid Build Coastguard Worker using android::base::testing::Ok;
32*33f37583SAndroid Build Coastguard Worker using android::base::testing::WithMessage;
33*33f37583SAndroid Build Coastguard Worker using ::testing::HasSubstr;
34*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,ParseFromFile)35*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, ParseFromFile) {
36*33f37583SAndroid Build Coastguard Worker TemporaryFile output;
37*33f37583SAndroid Build Coastguard Worker WriteStringToFile(
38*33f37583SAndroid Build Coastguard Worker "export BOOTCLASSPATH /apex/a/jar1:/apex/b/jar2\n"
39*33f37583SAndroid Build Coastguard Worker "export SYSTEMSERVERCLASSPATH\n"
40*33f37583SAndroid Build Coastguard Worker "export UNEXPECTED /apex/c/\n",
41*33f37583SAndroid Build Coastguard Worker output.path);
42*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::ParseFromFile(output.path);
43*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
44*33f37583SAndroid Build Coastguard Worker
45*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("a"), true);
46*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("b"), true);
47*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("c"), true);
48*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("d"), false);
49*33f37583SAndroid Build Coastguard Worker }
50*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,ParseFromFileJarsNotInApex)51*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, ParseFromFileJarsNotInApex) {
52*33f37583SAndroid Build Coastguard Worker TemporaryFile output;
53*33f37583SAndroid Build Coastguard Worker // We accept jars with regex: /apex/<package-name>/*
54*33f37583SAndroid Build Coastguard Worker WriteStringToFile("export BOOTCLASSPATH a:b\n", output.path);
55*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::ParseFromFile(output.path);
56*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
57*33f37583SAndroid Build Coastguard Worker
58*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("a"), false);
59*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("b"), false);
60*33f37583SAndroid Build Coastguard Worker }
61*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,ParseFromFilePackagesWithSamePrefix)62*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, ParseFromFilePackagesWithSamePrefix) {
63*33f37583SAndroid Build Coastguard Worker TemporaryFile output;
64*33f37583SAndroid Build Coastguard Worker WriteStringToFile(
65*33f37583SAndroid Build Coastguard Worker "export BOOTCLASSPATH /apex/media/:/apex/mediaprovider\n"
66*33f37583SAndroid Build Coastguard Worker "export SYSTEMSERVERCLASSPATH /apex/mediafoo/\n",
67*33f37583SAndroid Build Coastguard Worker output.path);
68*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::ParseFromFile(output.path);
69*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
70*33f37583SAndroid Build Coastguard Worker
71*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("media"), true);
72*33f37583SAndroid Build Coastguard Worker // "/apex/mediaprovider" did not end with /
73*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("mediaprovider"), false);
74*33f37583SAndroid Build Coastguard Worker // A prefix of an apex name present should not be accepted
75*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result->HasClassPathJars("m"), false);
76*33f37583SAndroid Build Coastguard Worker }
77*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,ParseFromFileDoesNotExist)78*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, ParseFromFileDoesNotExist) {
79*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::ParseFromFile("/file/does/not/exist");
80*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
81*33f37583SAndroid Build Coastguard Worker "Failed to read classpath info from file"))));
82*33f37583SAndroid Build Coastguard Worker }
83*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,ParseFromFileEmptyJars)84*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, ParseFromFileEmptyJars) {
85*33f37583SAndroid Build Coastguard Worker TemporaryFile output;
86*33f37583SAndroid Build Coastguard Worker WriteStringToFile(
87*33f37583SAndroid Build Coastguard Worker "export BOOTCLASSPATH\n"
88*33f37583SAndroid Build Coastguard Worker "export SYSTEMSERVERCLASSPATH \n"
89*33f37583SAndroid Build Coastguard Worker "export DEX2OATBOOTCLASSPATH \n",
90*33f37583SAndroid Build Coastguard Worker output.path);
91*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::ParseFromFile(output.path);
92*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result, Ok());
93*33f37583SAndroid Build Coastguard Worker }
94*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,DeriveClassPathNoStagedApex)95*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, DeriveClassPathNoStagedApex) {
96*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::DeriveClassPath({});
97*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(
98*33f37583SAndroid Build Coastguard Worker result,
99*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
100*33f37583SAndroid Build Coastguard Worker "Invalid argument: There are no APEX to derive claspath from"))));
101*33f37583SAndroid Build Coastguard Worker }
102*33f37583SAndroid Build Coastguard Worker
TEST(ApexClassPathUnitTest,DeriveClassPathPreferBinaryInStagedApex)103*33f37583SAndroid Build Coastguard Worker TEST(ApexClassPathUnitTest, DeriveClassPathPreferBinaryInStagedApex) {
104*33f37583SAndroid Build Coastguard Worker // Default location uses provided package name to compose binary path
105*33f37583SAndroid Build Coastguard Worker auto result = ClassPath::DeriveClassPath({"/apex/temp@123"}, "different");
106*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result,
107*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
108*33f37583SAndroid Build Coastguard Worker "binary path: /apex/different/bin/derive_classpath"))));
109*33f37583SAndroid Build Coastguard Worker
110*33f37583SAndroid Build Coastguard Worker // When staged apex has same package name, we use that location instead
111*33f37583SAndroid Build Coastguard Worker result = ClassPath::DeriveClassPath({"/apex/temp@123"}, "temp");
112*33f37583SAndroid Build Coastguard Worker ASSERT_THAT(result,
113*33f37583SAndroid Build Coastguard Worker HasError(WithMessage(HasSubstr(
114*33f37583SAndroid Build Coastguard Worker "binary path: /apex/temp@123/bin/derive_classpath"))));
115*33f37583SAndroid Build Coastguard Worker }
116*33f37583SAndroid Build Coastguard Worker
117*33f37583SAndroid Build Coastguard Worker } // namespace apex
118*33f37583SAndroid Build Coastguard Worker } // namespace android
119