View Javadoc
1   /*
2    *    Copyright 2009-2023 the original author or 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    *       https://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 org.apache.ibatis.io;
17  
18  import java.io.IOException;
19  import java.lang.reflect.Method;
20  
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.Test;
23  
24  /**
25   * Unit test for VFS getInstance method in multi-thread environment
26   *
27   * @author jasonleaster
28   */
29  class VFSTest {
30  
31    @Test
32    void getInstanceShouldNotBeNull() {
33      VFS vsf = VFS.getInstance();
34      Assertions.assertNotNull(vsf);
35    }
36  
37    @Test
38    void getInstanceShouldNotBeNullInMultiThreadEnv() throws InterruptedException {
39      final int threadCount = 3;
40  
41      Thread[] threads = new Thread[threadCount];
42      InstanceGetterProcedure[] procedures = new InstanceGetterProcedure[threadCount];
43  
44      for (int i = 0; i < threads.length; i++) {
45        String threadName = "Thread##" + i;
46  
47        procedures[i] = new InstanceGetterProcedure();
48        threads[i] = new Thread(procedures[i], threadName);
49      }
50  
51      for (Thread thread : threads) {
52        thread.start();
53      }
54  
55      for (Thread thread : threads) {
56        thread.join();
57      }
58  
59      // All caller got must be the same instance
60      for (int i = 0; i < threadCount - 1; i++) {
61        Assertions.assertEquals(procedures[i].instanceGot, procedures[i + 1].instanceGot);
62      }
63    }
64  
65    @Test
66    void getExistMethod() {
67      Method method = VFS.getMethod(VFS.class, "list", String.class);
68      Assertions.assertNotNull(method);
69    }
70  
71    @Test
72    void getNotExistMethod() {
73      Method method = VFS.getMethod(VFS.class, "listXxx", String.class);
74      Assertions.assertNull(method);
75    }
76  
77    @Test
78    void invoke() throws IOException, NoSuchMethodException {
79      VFS vfs = VFS.invoke(VFS.class.getMethod("getInstance"), VFS.class);
80      Assertions.assertEquals(vfs, VFS.getInstance());
81  
82      Assertions.assertThrows(RuntimeException.class, () -> {
83        // java.lang.IllegalArgumentException: wrong number of arguments
84        VFS.invoke(VFS.class.getMethod("getInstance"), VFS.class, "unnecessaryArgument");
85      });
86  
87      Assertions.assertThrows(IOException.class, () -> {
88        // InvocationTargetException.getTargetException -> IOException
89        VFS.invoke(Resources.class.getMethod("getResourceAsProperties", String.class), Resources.class,
90            "invalidResource");
91      });
92  
93      Assertions.assertThrows(RuntimeException.class, () -> {
94        // Other InvocationTargetException
95        VFS.invoke(Integer.class.getMethod("valueOf", String.class), Resources.class, "InvalidIntegerNumber");
96      });
97  
98    }
99  
100   private static class InstanceGetterProcedure implements Runnable {
101 
102     volatile VFS instanceGot;
103 
104     @Override
105     public void run() {
106       instanceGot = VFS.getInstance();
107     }
108   }
109 }