blob: 1f36a640dc153bd97b68a3d1dde167d0d10b80ef [file] [log] [blame]
Mårten Kongstadf242ec82024-04-16 17:12:26 +02001/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.checkflaggedapis
17
Mårten Kongstad387ff6c2024-04-16 12:42:14 +020018import android.aconfig.Aconfig
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020019import android.aconfig.Aconfig.flag_state.DISABLED
20import android.aconfig.Aconfig.flag_state.ENABLED
Mårten Kongstad387ff6c2024-04-16 12:42:14 +020021import java.io.ByteArrayInputStream
22import java.io.ByteArrayOutputStream
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020023import java.io.InputStream
Mårten Kongstad20de4052024-04-16 11:33:56 +020024import org.junit.Assert.assertEquals
Mårten Kongstadf242ec82024-04-16 17:12:26 +020025import org.junit.Test
26import org.junit.runner.RunWith
Mårten Kongstad7cc21742024-04-18 10:23:20 +020027import org.junit.runners.JUnit4
Mårten Kongstadf242ec82024-04-16 17:12:26 +020028
Mårten Kongstad20de4052024-04-16 11:33:56 +020029private val API_SIGNATURE =
30 """
31 // Signature format: 2.0
32 package android {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020033 @FlaggedApi("android.flag.foo") public final class Clazz {
Mårten Kongstad40da9702024-04-27 01:42:51 +020034 ctor @FlaggedApi("android.flag.foo") public Clazz();
Mårten Kongstad20de4052024-04-16 11:33:56 +020035 field @FlaggedApi("android.flag.foo") public static final int FOO = 1; // 0x1
Mårten Kongstad40da9702024-04-27 01:42:51 +020036 method @FlaggedApi("android.flag.foo") public int getErrorCode();
Mårten Kongstadb4a14bf2024-04-28 00:21:11 +020037 method @FlaggedApi("android.flag.foo") public boolean setData(int, int[][], @NonNull android.util.Utility<T, U>);
38 method @FlaggedApi("android.flag.foo") public boolean setVariableData(int, android.util.Atom...);
39 method @FlaggedApi("android.flag.foo") public boolean innerClassArg(android.Clazz.Builder);
Mårten Kongstad20de4052024-04-16 11:33:56 +020040 }
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020041 @FlaggedApi("android.flag.bar") public static class Clazz.Builder {
42 }
Mårten Kongstad20de4052024-04-16 11:33:56 +020043 }
44"""
45 .trim()
46
Mårten Kongstadb673d3b2024-04-16 18:34:20 +020047private val API_VERSIONS =
48 """
49 <?xml version="1.0" encoding="utf-8"?>
50 <api version="3">
51 <class name="android/Clazz" since="1">
52 <method name="&lt;init>()V"/>
53 <field name="FOO"/>
Mårten Kongstad40da9702024-04-27 01:42:51 +020054 <method name="getErrorCode()I"/>
Mårten Kongstadb4a14bf2024-04-28 00:21:11 +020055 <method name="setData(I[[ILandroid/util/Utility;)Z"/>
56 <method name="setVariableData(I[Landroid/util/Atom;)Z"/>
57 <method name="innerClassArg(Landroid/Clazz${"$"}Builder;)"/>
Mårten Kongstadb673d3b2024-04-16 18:34:20 +020058 </class>
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020059 <class name="android/Clazz${"$"}Builder" since="2">
60 </class>
Mårten Kongstadb673d3b2024-04-16 18:34:20 +020061 </api>
62"""
63 .trim()
64
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020065private fun generateFlagsProto(
66 fooState: Aconfig.flag_state,
67 barState: Aconfig.flag_state
68): InputStream {
69 val fooFlag =
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020070 Aconfig.parsed_flag
71 .newBuilder()
72 .setPackage("android.flag")
73 .setName("foo")
74 .setState(fooState)
75 .setPermission(Aconfig.flag_permission.READ_ONLY)
76 .build()
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020077 val barFlag =
78 Aconfig.parsed_flag
79 .newBuilder()
80 .setPackage("android.flag")
81 .setName("bar")
82 .setState(barState)
83 .setPermission(Aconfig.flag_permission.READ_ONLY)
84 .build()
85 val flags =
86 Aconfig.parsed_flags.newBuilder().addParsedFlag(fooFlag).addParsedFlag(barFlag).build()
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020087 val binaryProto = ByteArrayOutputStream()
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020088 flags.writeTo(binaryProto)
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020089 return ByteArrayInputStream(binaryProto.toByteArray())
90}
91
Mårten Kongstad7cc21742024-04-18 10:23:20 +020092@RunWith(JUnit4::class)
93class CheckFlaggedApisTest {
Mårten Kongstad20de4052024-04-16 11:33:56 +020094 @Test
95 fun testParseApiSignature() {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020096 val expected =
97 setOf(
Mårten Kongstadece054c2024-05-02 09:45:11 +020098 Pair(Symbol("android/Clazz"), Flag("android.flag.foo")),
99 Pair(Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
100 Pair(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
101 Pair(Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
Mårten Kongstadb4a14bf2024-04-28 00:21:11 +0200102 Pair(
103 Symbol("android/Clazz/setData(I[[ILandroid/util/Utility;)"),
104 Flag("android.flag.foo")),
105 Pair(
106 Symbol("android/Clazz/setVariableData(I[Landroid/util/Atom;)"),
107 Flag("android.flag.foo")),
108 Pair(
109 Symbol("android/Clazz/innerClassArg(Landroid/Clazz/Builder;)"),
110 Flag("android.flag.foo")),
Mårten Kongstadece054c2024-05-02 09:45:11 +0200111 Pair(Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200112 )
Mårten Kongstad20de4052024-04-16 11:33:56 +0200113 val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
114 assertEquals(expected, actual)
115 }
Mårten Kongstad387ff6c2024-04-16 12:42:14 +0200116
117 @Test
118 fun testParseFlagValues() {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200119 val expected: Map<Flag, Boolean> =
120 mapOf(Flag("android.flag.foo") to true, Flag("android.flag.bar") to true)
121 val actual = parseFlagValues(generateFlagsProto(ENABLED, ENABLED))
Mårten Kongstad387ff6c2024-04-16 12:42:14 +0200122 assertEquals(expected, actual)
123 }
Mårten Kongstadb673d3b2024-04-16 18:34:20 +0200124
125 @Test
126 fun testParseApiVersions() {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200127 val expected: Set<Symbol> =
128 setOf(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200129 Symbol("android/Clazz"),
130 Symbol("android/Clazz/Clazz()"),
131 Symbol("android/Clazz/FOO"),
132 Symbol("android/Clazz/getErrorCode()"),
Mårten Kongstadb4a14bf2024-04-28 00:21:11 +0200133 Symbol("android/Clazz/setData(I[[ILandroid/util/Utility;)"),
134 Symbol("android/Clazz/setVariableData(I[Landroid/util/Atom;)"),
135 Symbol("android/Clazz/innerClassArg(Landroid/Clazz/Builder;)"),
Mårten Kongstadece054c2024-05-02 09:45:11 +0200136 Symbol("android/Clazz/Builder"),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200137 )
Mårten Kongstadb673d3b2024-04-16 18:34:20 +0200138 val actual = parseApiVersions(API_VERSIONS.byteInputStream())
139 assertEquals(expected, actual)
140 }
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200141
142 @Test
Mårten Kongstad02525a82024-05-06 10:28:02 +0200143 fun testParseApiVersionsNestedClasses() {
144 val apiVersions =
145 """
146 <?xml version="1.0" encoding="utf-8"?>
147 <api version="3">
148 <class name="android/Clazz${'$'}Foo${'$'}Bar" since="1">
149 <method name="&lt;init>()V"/>
150 </class>
151 </api>
152 """
153 .trim()
154 val expected: Set<Symbol> =
155 setOf(
156 Symbol("android/Clazz/Foo/Bar"),
157 Symbol("android/Clazz/Foo/Bar/Bar()"),
158 )
159 val actual = parseApiVersions(apiVersions.byteInputStream())
160 assertEquals(expected, actual)
161 }
162
163 @Test
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200164 fun testFindErrorsNoErrors() {
165 val expected = setOf<ApiError>()
166 val actual =
167 findErrors(
168 parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200169 parseFlagValues(generateFlagsProto(ENABLED, ENABLED)),
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200170 parseApiVersions(API_VERSIONS.byteInputStream()))
171 assertEquals(expected, actual)
172 }
173
174 @Test
175 fun testFindErrorsDisabledFlaggedApiIsPresent() {
176 val expected =
177 setOf<ApiError>(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200178 DisabledFlaggedApiIsPresentError(Symbol("android/Clazz"), Flag("android.flag.foo")),
Mårten Kongstad40da9702024-04-27 01:42:51 +0200179 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200180 Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
181 DisabledFlaggedApiIsPresentError(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200182 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200183 Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
Mårten Kongstad40da9702024-04-27 01:42:51 +0200184 DisabledFlaggedApiIsPresentError(
Mårten Kongstadb4a14bf2024-04-28 00:21:11 +0200185 Symbol("android/Clazz/setData(I[[ILandroid/util/Utility;)"),
186 Flag("android.flag.foo")),
187 DisabledFlaggedApiIsPresentError(
188 Symbol("android/Clazz/setVariableData(I[Landroid/util/Atom;)"),
189 Flag("android.flag.foo")),
190 DisabledFlaggedApiIsPresentError(
191 Symbol("android/Clazz/innerClassArg(Landroid/Clazz/Builder;)"),
192 Flag("android.flag.foo")),
193 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200194 Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200195 )
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200196 val actual =
197 findErrors(
198 parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200199 parseFlagValues(generateFlagsProto(DISABLED, DISABLED)),
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200200 parseApiVersions(API_VERSIONS.byteInputStream()))
201 assertEquals(expected, actual)
202 }
Mårten Kongstadf242ec82024-04-16 17:12:26 +0200203}