• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Libphonenumber Authors
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 
17 package com.google.i18n.phonenumbers.metadata.source;
18 
19 import static org.junit.Assert.assertThrows;
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.i18n.phonenumbers.MetadataLoader;
25 import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
26 import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection;
27 import com.google.i18n.phonenumbers.metadata.PhoneMetadataCollectionUtil;
28 import com.google.i18n.phonenumbers.metadata.init.MetadataParser;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.concurrent.Callable;
33 import java.util.concurrent.ExecutorService;
34 import java.util.concurrent.Executors;
35 import junit.framework.TestCase;
36 import org.junit.Assert;
37 import org.junit.function.ThrowingRunnable;
38 import org.mockito.Mockito;
39 
40 public class BlockingMetadataBootstrappingGuardTest extends TestCase {
41 
42   private static final String PHONE_METADATA_FILE = "some metadata file";
43   private static final PhoneMetadataCollection PHONE_METADATA =
44       PhoneMetadataCollection.newBuilder()
45           .addMetadata(PhoneMetadata.newBuilder().setId("id").build());
46 
47   private final MetadataLoader metadataLoader = Mockito.mock(MetadataLoader.class);
48   private final MetadataContainer metadataContainer = Mockito.mock(MetadataContainer.class);
49 
50   private BlockingMetadataBootstrappingGuard<MetadataContainer> bootstrappingGuard;
51 
52   @Override
setUp()53   public void setUp() throws IOException {
54     when(metadataLoader.loadMetadata(PHONE_METADATA_FILE))
55         .thenReturn(PhoneMetadataCollectionUtil.toInputStream(PHONE_METADATA));
56     bootstrappingGuard =
57         new BlockingMetadataBootstrappingGuard<>(
58             metadataLoader, MetadataParser.newStrictParser(), metadataContainer);
59   }
60 
test_getOrBootstrap_shouldInvokeBootstrappingOnlyOnce()61   public void test_getOrBootstrap_shouldInvokeBootstrappingOnlyOnce() {
62     bootstrappingGuard.getOrBootstrap(PHONE_METADATA_FILE);
63     bootstrappingGuard.getOrBootstrap(PHONE_METADATA_FILE);
64 
65     verify(metadataLoader, times(1)).loadMetadata(PHONE_METADATA_FILE);
66   }
67 
test_getOrBootstrap_shouldIncludeFileNameInExceptionOnFailure()68   public void test_getOrBootstrap_shouldIncludeFileNameInExceptionOnFailure() {
69     when(metadataLoader.loadMetadata(PHONE_METADATA_FILE)).thenReturn(null);
70 
71     ThrowingRunnable throwingRunnable =
72         new ThrowingRunnable() {
73           @Override
74           public void run() {
75             bootstrappingGuard.getOrBootstrap(PHONE_METADATA_FILE);
76           }
77         };
78 
79     IllegalStateException exception = assertThrows(IllegalStateException.class, throwingRunnable);
80     Assert.assertTrue(exception.getMessage().contains(PHONE_METADATA_FILE));
81   }
82 
test_getOrBootstrap_shouldInvokeBootstrappingOnlyOnceWhenThreadsCallItAtTheSameTime()83   public void test_getOrBootstrap_shouldInvokeBootstrappingOnlyOnceWhenThreadsCallItAtTheSameTime()
84       throws InterruptedException {
85     ExecutorService executorService = Executors.newFixedThreadPool(2);
86 
87     List<BootstrappingRunnable> runnables = new ArrayList<>();
88     runnables.add(new BootstrappingRunnable());
89     runnables.add(new BootstrappingRunnable());
90     executorService.invokeAll(runnables);
91 
92     verify(metadataLoader, times(1)).loadMetadata(PHONE_METADATA_FILE);
93   }
94 
95   private class BootstrappingRunnable implements Callable<MetadataContainer> {
96 
97     @Override
call()98     public MetadataContainer call() {
99       return bootstrappingGuard.getOrBootstrap(PHONE_METADATA_FILE);
100     }
101   }
102 }
103