@@ -87,4 +87,164 @@ public void newChannelBuilder_fail() {
8787 TlsChannelCredentials .newBuilder ().requireFakeFeature ().build ());
8888 assertThat (result .getError ()).contains ("FAKE" );
8989 }
90+
91+ @ Test
92+ public void newChannelBuilder_withRegistry () {
93+ io .grpc .NameResolverRegistry registry = new io .grpc .NameResolverRegistry ();
94+ NewChannelBuilderResult result = provider .newChannelBuilder (
95+ "localhost:443" , TlsChannelCredentials .create (), registry , null );
96+ assertThat (result .getChannelBuilder ()).isInstanceOf (NettyChannelBuilder .class );
97+ }
98+
99+ @ Test
100+ public void newChannelBuilder_withProvider () {
101+ io .grpc .NameResolverProvider resolverProvider = new io .grpc .NameResolverProvider () {
102+ @ Override
103+ protected boolean isAvailable () {
104+ return true ;
105+ }
106+
107+ @ Override
108+ protected int priority () {
109+ return 5 ;
110+ }
111+
112+ @ Override
113+ public String getDefaultScheme () {
114+ return "dns" ;
115+ }
116+
117+ @ Override
118+ public io .grpc .NameResolver newNameResolver (java .net .URI targetUri ,
119+ io .grpc .NameResolver .Args args ) {
120+ return null ;
121+ }
122+ };
123+ NewChannelBuilderResult result = provider .newChannelBuilder (
124+ "localhost:443" , TlsChannelCredentials .create (), null ,
125+ resolverProvider );
126+ assertThat (result .getChannelBuilder ()).isInstanceOf (NettyChannelBuilder .class );
127+ }
128+
129+ @ Test
130+ public void newChannelBuilder_registryPropagation_e2e () {
131+ String scheme = "testscheme" ;
132+ final io .grpc .NameResolverRegistry registry = new io .grpc .NameResolverRegistry ();
133+ final java .util .concurrent .atomic .AtomicReference <io .grpc .NameResolverRegistry >
134+ capturedRegistry = new java .util .concurrent .atomic .AtomicReference <>();
135+
136+ final io .grpc .NameResolverProvider resolverProvider = new io .grpc .NameResolverProvider () {
137+ @ Override
138+ protected boolean isAvailable () {
139+ return true ;
140+ }
141+
142+ @ Override
143+ protected int priority () {
144+ return 5 ;
145+ }
146+
147+ @ Override
148+ public String getDefaultScheme () {
149+ return scheme ;
150+ }
151+
152+ @ Override
153+ public io .grpc .NameResolver newNameResolver (java .net .URI targetUri ,
154+ io .grpc .NameResolver .Args args ) {
155+ capturedRegistry .set (args .getNameResolverRegistry ());
156+ return new io .grpc .NameResolver () {
157+ @ Override
158+ public String getServiceAuthority () {
159+ return "authority" ;
160+ }
161+
162+ @ Override
163+ public void start (Listener2 listener ) {
164+ }
165+
166+ @ Override
167+ public void shutdown () {
168+ }
169+ };
170+ }
171+ };
172+ registry .register (resolverProvider );
173+
174+ NewChannelBuilderResult result = provider .newChannelBuilder (
175+ scheme + ":///target" , TlsChannelCredentials .create (), registry ,
176+ null );
177+ assertThat (result .getChannelBuilder ()).isInstanceOf (NettyChannelBuilder .class );
178+ // Verify build() succeeds
179+ result .getChannelBuilder ().build ();
180+
181+ // Verify the registry passed to args is the exact same instance
182+ assertSame ("Registry should be propagated to NameResolver.Args" , registry ,
183+ capturedRegistry .get ());
184+
185+ // Verify default registry (empty) fails
186+ NewChannelBuilderResult defaultResult = provider .newChannelBuilder (
187+ scheme + ":///target" , TlsChannelCredentials .create (),
188+ new io .grpc .NameResolverRegistry (), null );
189+ // The provider might still return a builder, but build() should fail if it
190+ // can't find the resolver.
191+ // However, NettyChannelProvider just delegates to NettyChannelBuilder.
192+ // NettyChannelBuilder delegates to ManagedChannelImplBuilder.
193+ // ManagedChannelImplBuilder.build() calls getNameResolverProvider(), which
194+ // throws if not found.
195+ try {
196+ defaultResult .getChannelBuilder ().build ();
197+ fail ("Should have failed to build() without correct registry" );
198+ } catch (IllegalArgumentException e ) {
199+ // Expected
200+ }
201+ }
202+
203+ @ Test
204+ public void newChannelBuilder_providerPropagation_e2e () {
205+ String scheme = "otherscheme" ;
206+ final io .grpc .NameResolverProvider resolverProvider = new io .grpc .NameResolverProvider () {
207+ @ Override
208+ protected boolean isAvailable () {
209+ return true ;
210+ }
211+
212+ @ Override
213+ protected int priority () {
214+ return 5 ;
215+ }
216+
217+ @ Override
218+ public String getDefaultScheme () {
219+ return scheme ;
220+ }
221+
222+ @ Override
223+ public io .grpc .NameResolver newNameResolver (java .net .URI targetUri ,
224+ io .grpc .NameResolver .Args args ) {
225+ return new io .grpc .NameResolver () {
226+ @ Override
227+ public String getServiceAuthority () {
228+ return "authority" ;
229+ }
230+
231+ @ Override
232+ public void start (Listener2 listener ) {
233+ }
234+
235+ @ Override
236+ public void shutdown () {
237+ }
238+ };
239+ }
240+ };
241+
242+ // Pass explicit provider, null registry
243+ NewChannelBuilderResult result = provider .newChannelBuilder (
244+ scheme + ":///target" , TlsChannelCredentials .create (),
245+ null , resolverProvider );
246+ assertThat (result .getChannelBuilder ()).isInstanceOf (NettyChannelBuilder .class );
247+ // Should succeed because we passed the specific provider
248+ result .getChannelBuilder ().build ();
249+ }
90250}
0 commit comments