1+ /*
2+ * Copyright © 2025 Cask Data, Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+ * use this file except in compliance with the License. You may obtain a copy of
6+ * 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, WITHOUT
12+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+ * License for the specific language governing permissions and limitations under
14+ * the License.
15+ */
16+
17+ package io .cdap .cdap .internal .app .upgrade ;
18+
19+ import static org .mockito .ArgumentMatchers .eq ;
20+ import static org .mockito .Mockito .times ;
21+ import static org .mockito .Mockito .verify ;
22+ import static org .mockito .Mockito .when ;
23+
24+ import com .google .common .collect .ImmutableList ;
25+ import com .google .common .collect .ImmutableMap ;
26+ import io .cdap .cdap .api .metadata .MetadataEntity ;
27+ import io .cdap .cdap .api .metadata .MetadataScope ;
28+ import io .cdap .cdap .metadata .MetadataAdmin ;
29+ import io .cdap .cdap .proto .id .ApplicationId ;
30+ import io .cdap .cdap .proto .id .NamespaceId ;
31+ import io .cdap .cdap .proto .id .PluginId ;
32+ import io .cdap .cdap .spi .metadata .Metadata ;
33+ import io .cdap .cdap .spi .metadata .MetadataRecord ;
34+ import io .cdap .cdap .spi .metadata .SearchRequest ;
35+ import io .cdap .cdap .spi .metadata .SearchResponse ;
36+ import java .util .Arrays ;
37+ import java .util .Collection ;
38+ import java .util .Collections ;
39+ import java .util .List ;
40+ import org .junit .Assert ;
41+ import org .junit .Before ;
42+ import org .junit .Test ;
43+ import org .junit .runner .RunWith ;
44+ import org .junit .runners .Parameterized ;
45+ import org .junit .runners .Parameterized .Parameters ;
46+ import org .mockito .Mock ;
47+ import org .mockito .MockitoAnnotations ;
48+
49+ /**
50+ * Parameterized tests for {@link MetadataApplicationPluginMappingFetcher} using a parameter class.
51+ */
52+ @ RunWith (Parameterized .class )
53+ public class MetadataApplicationPluginMappingFetcherTest {
54+
55+ // A static inner class to hold the parameters for each test case
56+ static class TestCaseParams {
57+
58+ final String name ;
59+ final SearchResponse userResponse ;
60+ final SearchResponse systemResponse ;
61+ final List <ApplicationPluginMapping > expectedMappings ;
62+
63+ TestCaseParams (String name , SearchResponse userResponse , SearchResponse systemResponse ,
64+ List <ApplicationPluginMapping > expectedMappings ) {
65+ this .name = name ;
66+ this .userResponse = userResponse ;
67+ this .systemResponse = systemResponse ;
68+ this .expectedMappings = expectedMappings ;
69+ }
70+ }
71+
72+ @ Parameters (name = "{index}: {0}" )
73+ public static Collection <Object []> data () {
74+ SearchResponse emptyResponse = new SearchResponse (SearchRequest .of ("*" ).build (), null , 0 ,
75+ Integer .MAX_VALUE , 0 , Collections .emptyList ());
76+
77+ SearchResponse userPluginResponse = new SearchResponse (SearchRequest .of ("*" ).build (), null , 0 ,
78+ Integer .MAX_VALUE , 0 , ImmutableList .of (new MetadataRecord (
79+ MetadataEntity .builder ().append ("namespace" , "default" )
80+ .append ("artifact" , "trash-plugin" )
81+ .append ("version" , "1.2.0" )
82+ .append (MetadataEntity .TYPE , "batchsink" )
83+ .appendAsType (MetadataEntity .PLUGIN , "trash" )
84+ .build (),
85+ new Metadata (
86+ MetadataScope .SYSTEM , ImmutableMap .of ("default:pipeline_1" , "1" )))));
87+
88+ SearchResponse systemPluginResponse = new SearchResponse (SearchRequest .of ("*" ).build (), null , 0 ,
89+ Integer .MAX_VALUE , 0 , ImmutableList .of (new MetadataRecord (
90+ MetadataEntity .builder ().append ("namespace" , "system" )
91+ .append ("artifact" , "google-cloud" )
92+ .append ("version" , "0.24.0" )
93+ .append (MetadataEntity .TYPE , "batchsource" )
94+ .appendAsType (MetadataEntity .PLUGIN , "GCS" )
95+ .build (),
96+ new Metadata (
97+ MetadataScope .SYSTEM , ImmutableMap .of ("default:pipeline_1" , "1" )))));
98+
99+ ApplicationPluginMapping applicationSystemPluginMapping =
100+ new ApplicationPluginMapping (new ApplicationId ("default" , "pipeline_1" ),
101+ new PluginId ("system" , "google-cloud" , "0.24.0" , "GCS" , "batchsource" ));
102+ ApplicationPluginMapping applicationUserPluginMapping =
103+ new ApplicationPluginMapping (new ApplicationId ("default" , "pipeline_1" ),
104+ new PluginId ("default" , "trash-plugin" , "1.2.0" , "trash" , "batchsink" ));
105+
106+ return Arrays .asList (new Object [][]{
107+ {new TestCaseParams ("No Plugin Mappings" , emptyResponse , emptyResponse ,
108+ Collections .emptyList ())},
109+ {new TestCaseParams ("Only System Plugin Mappings" , emptyResponse , systemPluginResponse ,
110+ ImmutableList .of (applicationSystemPluginMapping ))},
111+ {new TestCaseParams ("Only User Plugin Mappings" , userPluginResponse , emptyResponse ,
112+ ImmutableList .of (applicationUserPluginMapping ))},
113+ {new TestCaseParams ("Both Plugin Mappings present" , userPluginResponse ,
114+ systemPluginResponse ,
115+ ImmutableList .of (applicationUserPluginMapping , applicationSystemPluginMapping ))}
116+ });
117+ }
118+
119+ @ Mock
120+ private MetadataAdmin metadataAdmin ;
121+
122+ private MetadataApplicationPluginMappingFetcher mappingFetcher ;
123+
124+ private final TestCaseParams params ;
125+
126+ public MetadataApplicationPluginMappingFetcherTest (TestCaseParams params ) {
127+ this .params = params ;
128+ }
129+
130+ @ Before
131+ public void setUp () {
132+ MockitoAnnotations .initMocks (this );
133+ mappingFetcher = new MetadataApplicationPluginMappingFetcher (metadataAdmin );
134+ }
135+
136+ @ Test
137+ public void testFetchApplicationPluginMapping () throws Exception {
138+ // Arrange
139+ SearchRequest userPluginRequest = SearchRequest .of ("*" ).addType ("plugin" )
140+ .addNamespace (NamespaceId .DEFAULT .getNamespace ())
141+ .build ();
142+ SearchRequest systemPluginRequest = SearchRequest .of ("*" ).addType ("plugin" )
143+ .addNamespace (NamespaceId .SYSTEM .getNamespace ()).build ();
144+
145+ when (metadataAdmin .search (eq (userPluginRequest ))).thenReturn (params .userResponse );
146+ when (metadataAdmin .search (eq (systemPluginRequest ))).thenReturn (params .systemResponse );
147+
148+ // Act
149+ List <ApplicationPluginMapping > actual = mappingFetcher .fetchApplicationPluginMapping (
150+ NamespaceId .DEFAULT );
151+
152+ // Assert
153+ Assert .assertEquals (String .format ("Test case '%s' failed." , params .name ),
154+ params .expectedMappings , actual );
155+ verify (metadataAdmin , times (1 )).search (userPluginRequest );
156+ verify (metadataAdmin , times (1 )).search (systemPluginRequest );
157+ }
158+ }
0 commit comments