• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package com.android.bedstead.enterprise;
17 
18 import com.android.bedstead.enterprise.annotations.CanSetPolicyTest;
19 import com.android.bedstead.enterprise.annotations.CannotSetPolicyTest;
20 import com.android.bedstead.enterprise.annotations.PolicyAppliesTest;
21 import com.android.bedstead.enterprise.annotations.PolicyDoesNotApplyTest;
22 import com.android.bedstead.harrier.BedsteadFrameworkMethod;
23 import com.android.bedstead.harrier.FrameworkMethodWithParameter;
24 import com.android.bedstead.harrier.annotations.PolicyArgument;
25 import com.android.bedstead.nene.exceptions.NeneException;
26 
27 import org.junit.runners.model.FrameworkMethod;
28 
29 import java.lang.annotation.Annotation;
30 import java.lang.reflect.InvocationTargetException;
31 import java.lang.reflect.Method;
32 import java.util.ArrayList;
33 import java.util.HashSet;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.stream.Collectors;
38 import java.util.stream.Stream;
39 
40 /**
41  * Generate policy argument tests
42  */
43 public final class PolicyArgumentTestsGenerator {
44 
45     /**
46      * Generates extra tests for test functions using
47      * {@link PolicyArgument} annotation in the function parameter
48      */
generate( FrameworkMethod frameworkMethod, Stream<FrameworkMethod> expandedMethods)49     public static Stream<FrameworkMethod> generate(
50             FrameworkMethod frameworkMethod, Stream<FrameworkMethod> expandedMethods) {
51         try {
52             Class<?>[] policyClasses;
53             PolicyAppliesTest policyAppliesTestAnnotation =
54                     frameworkMethod.getMethod().getAnnotation(PolicyAppliesTest.class);
55             PolicyDoesNotApplyTest policyDoesNotApplyTestAnnotation =
56                     frameworkMethod.getMethod().getAnnotation(PolicyDoesNotApplyTest.class);
57             CanSetPolicyTest canSetPolicyTestAnnotation =
58                     frameworkMethod.getMethod().getAnnotation(CanSetPolicyTest.class);
59             CannotSetPolicyTest cannotSetPolicyTestAnnotation =
60                     frameworkMethod.getMethod().getAnnotation(CannotSetPolicyTest.class);
61 
62             if (policyAppliesTestAnnotation != null) {
63                 policyClasses = policyAppliesTestAnnotation.policy();
64             } else if (policyDoesNotApplyTestAnnotation != null) {
65                 policyClasses = policyDoesNotApplyTestAnnotation.policy();
66             } else if (canSetPolicyTestAnnotation != null) {
67                 policyClasses = canSetPolicyTestAnnotation.policy();
68             } else if (cannotSetPolicyTestAnnotation != null) {
69                 policyClasses = cannotSetPolicyTestAnnotation.policy();
70             } else {
71                 throw new NeneException("PolicyArgument annotation can only by used with a test "
72                         + "that is marked with either @PolicyAppliesTest, "
73                         + "@PolicyDoesNotApplyTest, @CanSetPolicyTest or @CannotSetPolicyTest.");
74             }
75 
76             Map<String, Set<Annotation>> policyClassToAnnotationsMap =
77                     Policy.getAnnotationsForPolicies(
78                             Policy.getEnterprisePolicyWithCallingClass(policyClasses));
79 
80             List<FrameworkMethod> expandedMethodList = expandedMethods.collect(Collectors.toList());
81             Set<FrameworkMethod> tempExpandedFrameworkMethodSet = new HashSet<>();
82             for (Class<?> policyClass : policyClasses) {
83                 Method validArgumentsMethod = policyClass.getDeclaredMethod("validArguments");
84                 Set<?> validArguments =
85                         (Set<?>) validArgumentsMethod.invoke(policyClass.newInstance());
86                 if (validArguments.isEmpty()) {
87                     throw new NeneException(
88                             "Empty valid arguments passed for "
89                                     + policyClass.getSimpleName()
90                                     + " policy");
91                 }
92 
93                 Set<Annotation> policyAnnotations =
94                         policyClassToAnnotationsMap.get(policyClass.getName());
95 
96                 for (FrameworkMethod expandedMethod : expandedMethodList) {
97                     List<Annotation> parameterizedAnnotations =
98                             ((BedsteadFrameworkMethod) expandedMethod)
99                                     .getParameterizedAnnotations();
100                     for (Annotation parameterizedAnnotation : parameterizedAnnotations) {
101                         if ((policyAppliesTestAnnotation != null
102                                 && policyAnnotations.contains((parameterizedAnnotation)))
103                                 || (policyDoesNotApplyTestAnnotation != null)
104                                 || (canSetPolicyTestAnnotation != null
105                                 && policyAnnotations.contains(parameterizedAnnotation))
106                                 || (cannotSetPolicyTestAnnotation != null)) {
107                             tempExpandedFrameworkMethodSet.addAll(
108                                     applyPolicyArgumentParameter(expandedMethod, validArguments));
109                         }
110                     }
111                 }
112             }
113 
114             return tempExpandedFrameworkMethodSet.stream();
115         } catch (NoSuchMethodException
116                  | InvocationTargetException
117                  | IllegalAccessException
118                  | InstantiationException e) {
119             // Should never happen as validArguments method will always have a default
120             // implementation for every EnterprisePolicy
121             throw new NeneException(
122                     "PolicyArgument parameter annotation cannot be added to a test "
123                             + "without the validArguments method specified for the "
124                             + "EnterprisePolicy",
125                     e);
126         }
127     }
128 
applyPolicyArgumentParameter( FrameworkMethod frameworkMethod, Set<?> validArguments)129     private static List<FrameworkMethodWithParameter> applyPolicyArgumentParameter(
130             FrameworkMethod frameworkMethod, Set<?> validArguments) {
131         List<FrameworkMethodWithParameter> expandedMethods = new ArrayList<>(validArguments.size());
132         for (Object arg : validArguments) {
133             expandedMethods.add(new FrameworkMethodWithParameter(frameworkMethod, arg));
134         }
135         return expandedMethods;
136     }
137 }
138