View Javadoc
1   /*
2   * Licensed to the Apache Software Foundation (ASF) under one
3   * or more contributor license agreements.  See the NOTICE file
4   * distributed with this work for additional information
5   * regarding copyright ownership.  The ASF licenses this file
6   * to you under the Apache License, Version 2.0 (the
7   * "License"); you may not use this file except in compliance
8   * with the License.  You may obtain a copy of the License at
9   *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18  package org.apache.commons.crypto.random;
19  
20  import java.lang.Thread.State;
21  import java.security.GeneralSecurityException;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.List;
25  import java.util.concurrent.TimeUnit;
26  
27  import org.junit.jupiter.api.Test;
28  import org.junit.jupiter.api.Timeout;
29  
30  public abstract class AbstractRandomTest {
31  
32      /**
33       * Test will timeout if secure random implementation always returns a constant value.
34       */
35      private void checkRandomBytes(final CryptoRandom random, final int len) {
36          final byte[] bytes = new byte[len];
37          final byte[] bytes1 = new byte[len];
38          random.nextBytes(bytes);
39          random.nextBytes(bytes1);
40  
41          while (Arrays.equals(bytes1, new byte[len]) || Arrays.equals(bytes, bytes1)) {
42              random.nextBytes(bytes1);
43          }
44      }
45  
46      public abstract CryptoRandom getCryptoRandom() throws GeneralSecurityException;
47  
48      @Test
49      @Timeout(value = 120000, unit = TimeUnit.MILLISECONDS)
50      public void testRandomBytes() throws Exception {
51          try (CryptoRandom random = getCryptoRandom()) {
52              // len = 16
53              checkRandomBytes(random, 16);
54              // len = 32
55              checkRandomBytes(random, 32);
56              // len = 128
57              checkRandomBytes(random, 128);
58              // len = 256
59              checkRandomBytes(random, 256);
60          }
61      }
62  
63      @Test
64      @Timeout(value = 120000, unit = TimeUnit.MILLISECONDS)
65      public void testRandomBytesMultiThreaded() throws Exception {
66          final int threadCount = 100;
67          try (final CryptoRandom random = getCryptoRandom()) {
68              final List<Thread> threads = new ArrayList<>(threadCount);
69  
70              for (int i = 0; i < threadCount; i++) {
71                  final Thread t = new Thread(() -> {
72                      checkRandomBytes(random, 10);
73                      checkRandomBytes(random, 1000);
74                      checkRandomBytes(random, 100000);
75                  });
76                  t.start();
77                  threads.add(t);
78              }
79  
80              for (final Thread t : threads) {
81                  if (!t.getState().equals(State.NEW)) {
82                      t.join();
83                  }
84              }
85  
86          }
87      }
88  }