blob: 2f76b2a5a70ea1f3e39a57dccc1096b16cff3eb1 [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
143 fun testFindErrorsNoErrors() {
144 val expected = setOf<ApiError>()
145 val actual =
146 findErrors(
147 parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200148 parseFlagValues(generateFlagsProto(ENABLED, ENABLED)),
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200149 parseApiVersions(API_VERSIONS.byteInputStream()))
150 assertEquals(expected, actual)
151 }
152
153 @Test
154 fun testFindErrorsDisabledFlaggedApiIsPresent() {
155 val expected =
156 setOf<ApiError>(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200157 DisabledFlaggedApiIsPresentError(Symbol("android/Clazz"), Flag("android.flag.foo")),
Mårten Kongstad40da9702024-04-27 01:42:51 +0200158 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200159 Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
160 DisabledFlaggedApiIsPresentError(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200161 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200162 Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
Mårten Kongstad40da9702024-04-27 01:42:51 +0200163 DisabledFlaggedApiIsPresentError(
Mårten Kongstadb4a14bf2024-04-28 00:21:11 +0200164 Symbol("android/Clazz/setData(I[[ILandroid/util/Utility;)"),
165 Flag("android.flag.foo")),
166 DisabledFlaggedApiIsPresentError(
167 Symbol("android/Clazz/setVariableData(I[Landroid/util/Atom;)"),
168 Flag("android.flag.foo")),
169 DisabledFlaggedApiIsPresentError(
170 Symbol("android/Clazz/innerClassArg(Landroid/Clazz/Builder;)"),
171 Flag("android.flag.foo")),
172 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200173 Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200174 )
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200175 val actual =
176 findErrors(
177 parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200178 parseFlagValues(generateFlagsProto(DISABLED, DISABLED)),
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200179 parseApiVersions(API_VERSIONS.byteInputStream()))
180 assertEquals(expected, actual)
181 }
Mårten Kongstadf242ec82024-04-16 17:12:26 +0200182}