blob: 04c2f80e79039367546ebb52d1a47832ef87a63b [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 Kongstad20de4052024-04-16 11:33:56 +020037 }
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020038 @FlaggedApi("android.flag.bar") public static class Clazz.Builder {
39 }
Mårten Kongstad20de4052024-04-16 11:33:56 +020040 }
41"""
42 .trim()
43
Mårten Kongstadb673d3b2024-04-16 18:34:20 +020044private val API_VERSIONS =
45 """
46 <?xml version="1.0" encoding="utf-8"?>
47 <api version="3">
48 <class name="android/Clazz" since="1">
49 <method name="&lt;init>()V"/>
50 <field name="FOO"/>
Mårten Kongstad40da9702024-04-27 01:42:51 +020051 <method name="getErrorCode()I"/>
Mårten Kongstadb673d3b2024-04-16 18:34:20 +020052 </class>
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020053 <class name="android/Clazz${"$"}Builder" since="2">
54 </class>
Mårten Kongstadb673d3b2024-04-16 18:34:20 +020055 </api>
56"""
57 .trim()
58
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020059private fun generateFlagsProto(
60 fooState: Aconfig.flag_state,
61 barState: Aconfig.flag_state
62): InputStream {
63 val fooFlag =
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020064 Aconfig.parsed_flag
65 .newBuilder()
66 .setPackage("android.flag")
67 .setName("foo")
68 .setState(fooState)
69 .setPermission(Aconfig.flag_permission.READ_ONLY)
70 .build()
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020071 val barFlag =
72 Aconfig.parsed_flag
73 .newBuilder()
74 .setPackage("android.flag")
75 .setName("bar")
76 .setState(barState)
77 .setPermission(Aconfig.flag_permission.READ_ONLY)
78 .build()
79 val flags =
80 Aconfig.parsed_flags.newBuilder().addParsedFlag(fooFlag).addParsedFlag(barFlag).build()
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020081 val binaryProto = ByteArrayOutputStream()
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020082 flags.writeTo(binaryProto)
Mårten Kongstad9238a3a2024-04-16 13:19:50 +020083 return ByteArrayInputStream(binaryProto.toByteArray())
84}
85
Mårten Kongstad7cc21742024-04-18 10:23:20 +020086@RunWith(JUnit4::class)
87class CheckFlaggedApisTest {
Mårten Kongstad20de4052024-04-16 11:33:56 +020088 @Test
89 fun testParseApiSignature() {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020090 val expected =
91 setOf(
Mårten Kongstadece054c2024-05-02 09:45:11 +020092 Pair(Symbol("android/Clazz"), Flag("android.flag.foo")),
93 Pair(Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
94 Pair(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
95 Pair(Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
96 Pair(Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +020097 )
Mårten Kongstad20de4052024-04-16 11:33:56 +020098 val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
99 assertEquals(expected, actual)
100 }
Mårten Kongstad387ff6c2024-04-16 12:42:14 +0200101
102 @Test
103 fun testParseFlagValues() {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200104 val expected: Map<Flag, Boolean> =
105 mapOf(Flag("android.flag.foo") to true, Flag("android.flag.bar") to true)
106 val actual = parseFlagValues(generateFlagsProto(ENABLED, ENABLED))
Mårten Kongstad387ff6c2024-04-16 12:42:14 +0200107 assertEquals(expected, actual)
108 }
Mårten Kongstadb673d3b2024-04-16 18:34:20 +0200109
110 @Test
111 fun testParseApiVersions() {
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200112 val expected: Set<Symbol> =
113 setOf(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200114 Symbol("android/Clazz"),
115 Symbol("android/Clazz/Clazz()"),
116 Symbol("android/Clazz/FOO"),
117 Symbol("android/Clazz/getErrorCode()"),
118 Symbol("android/Clazz/Builder"),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200119 )
Mårten Kongstadb673d3b2024-04-16 18:34:20 +0200120 val actual = parseApiVersions(API_VERSIONS.byteInputStream())
121 assertEquals(expected, actual)
122 }
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200123
124 @Test
125 fun testFindErrorsNoErrors() {
126 val expected = setOf<ApiError>()
127 val actual =
128 findErrors(
129 parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200130 parseFlagValues(generateFlagsProto(ENABLED, ENABLED)),
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200131 parseApiVersions(API_VERSIONS.byteInputStream()))
132 assertEquals(expected, actual)
133 }
134
135 @Test
136 fun testFindErrorsDisabledFlaggedApiIsPresent() {
137 val expected =
138 setOf<ApiError>(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200139 DisabledFlaggedApiIsPresentError(Symbol("android/Clazz"), Flag("android.flag.foo")),
Mårten Kongstad40da9702024-04-27 01:42:51 +0200140 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200141 Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
142 DisabledFlaggedApiIsPresentError(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200143 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200144 Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
Mårten Kongstad40da9702024-04-27 01:42:51 +0200145 DisabledFlaggedApiIsPresentError(
Mårten Kongstadece054c2024-05-02 09:45:11 +0200146 Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200147 )
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200148 val actual =
149 findErrors(
150 parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()),
Mårten Kongstad18ff19a2024-04-26 05:48:57 +0200151 parseFlagValues(generateFlagsProto(DISABLED, DISABLED)),
Mårten Kongstad9238a3a2024-04-16 13:19:50 +0200152 parseApiVersions(API_VERSIONS.byteInputStream()))
153 assertEquals(expected, actual)
154 }
Mårten Kongstadf242ec82024-04-16 17:12:26 +0200155}