0a9f4cf9392bc053b4773e5b4e417455d9c0f973
[policy/apex-pdp.git] / testsuites / integration / integration-context-test / src / test / java / org / onap / policy / apex / testsuites / integration / context / locking / ConcurrentContextJvm.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * 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  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.testsuites.integration.context.locking;
23
24 import com.google.gson.Gson;
25
26 import java.net.InetAddress;
27 import java.net.NetworkInterface;
28 import java.net.SocketException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.Enumeration;
33 import java.util.List;
34 import java.util.Map.Entry;
35 import java.util.TreeSet;
36 import java.util.concurrent.ExecutorService;
37 import java.util.concurrent.Future;
38 import java.util.concurrent.TimeUnit;
39
40 import org.onap.policy.apex.context.ContextAlbum;
41 import org.onap.policy.apex.context.Distributor;
42 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
43 import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
44 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
45 import org.onap.policy.apex.testsuites.integration.context.utils.ConfigrationProvider;
46 import org.onap.policy.apex.testsuites.integration.context.utils.ConfigrationProviderImpl;
47 import org.onap.policy.apex.testsuites.integration.context.utils.Constants;
48 import org.onap.policy.common.parameters.ParameterGroup;
49 import org.onap.policy.common.parameters.ParameterService;
50 import org.slf4j.ext.XLogger;
51 import org.slf4j.ext.XLoggerFactory;
52
53
54 /**
55  * The Class ConcurrentContextJVM tests concurrent use of context in a single JVM.
56  *
57  * @author Liam Fallon (liam.fallon@ericsson.com)
58  */
59 public final class ConcurrentContextJvm {
60     // Logger for this class
61     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextJvm.class);
62
63     private static final int IPV4_ADDRESS_LENGTH = 4;
64
65     private final int jvmNo;
66
67     private final ExecutorService executorService;
68
69     private final ConfigrationProvider configrationProvider;
70
71     private ConcurrentContextJvm(final int jvmNo, final ConfigrationProvider configrationProvider) {
72         this.jvmNo = jvmNo;
73         this.configrationProvider = configrationProvider;
74         final String name = configrationProvider.getTestName() + ":ConcurrentContextThread_" + jvmNo;
75         this.executorService = configrationProvider.getExecutorService(name, configrationProvider.getThreadCount());
76     }
77
78     /**
79      * This method executes the test of concurrent use of context in a single JVM.
80      *
81      * @throws ApexException the Apex exception occurs while running the test
82      */
83     public void execute() throws ApexException {
84         LOGGER.debug("starting JVMs and threads . . .");
85
86         final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor" + jvmNo, "0.0.1");
87         final Distributor distributor = configrationProvider.getDistributor(distributorKey);
88         final ContextAlbum contextAlbum = configrationProvider.getContextAlbum(distributor);
89         assert (contextAlbum != null);
90
91         final List<Future<?>> tasks = new ArrayList<>(configrationProvider.getThreadCount());
92
93         for (int t = 0; t < configrationProvider.getThreadCount(); t++) {
94             tasks.add(executorService.submit(new ConcurrentContextThread(jvmNo, t, configrationProvider)));
95         }
96
97         try {
98             executorService.shutdown();
99             // wait for threads to finish, if not Timeout
100             executorService.awaitTermination(10, TimeUnit.MINUTES);
101         } catch (final InterruptedException interruptedException) {
102             LOGGER.error("Exception while waiting for threads to finish", interruptedException);
103             // restore the interrupt status
104             Thread.currentThread().interrupt();
105         }
106
107         LOGGER.debug("threads finished, end value is {}", contextAlbum.get(Constants.TEST_VALUE));
108
109         distributor.clear();
110
111         LOGGER.info("Shutting down now ... ");
112         executorService.shutdownNow();
113     }
114
115
116
117     /**
118      * The main method.
119      *
120      * @param args the args
121      * @throws Exception Any exception thrown by the test code
122      */
123     @SuppressWarnings("unchecked")
124     public static void main(final String[] args) throws Exception {
125         configure();
126
127         LOGGER.info("JVM Arguments: " + Arrays.toString(args));
128         // CHECKSTYLE:OFF: checkstyle:magicNumber
129
130         // An even number of arguments greater than 3
131         if (args.length < 9) {
132             LOGGER.error("invalid arguments: " + Arrays.toString(args));
133             LOGGER.error("usage: TestConcurrentContextJVM testType jvmNo threadCount threadLoops albumSize "
134                     + "lockType [parameterKey parameterJson].... ");
135             return;
136         }
137
138
139         final String testName = getStringValue("testType", args, 0);
140         final int jvmNo = getIntValue("jvmNo", args, 1);
141         final int threadCount = getIntValue("threadCount", args, 2);
142         final int threadLoops = getIntValue("threadLoops", args, 3);
143         final int albumSize = getIntValue("albumSize", args, 4);
144         final int lockType = getIntValue("lockType", args, 5);
145         final String hazelCastfileLocation = getStringValue("hazelcast file location", args, 6);
146
147         System.setProperty("hazelcast.config", hazelCastfileLocation);
148
149         for (int p = 7; p < args.length - 1; p += 2) {
150             @SuppressWarnings("rawtypes")
151             final Class parametersClass = Class.forName(args[p]);
152             final ParameterGroup parameters = (ParameterGroup) new Gson().fromJson(args[p + 1], parametersClass);
153             ParameterService.register(parameters);
154         }
155
156         for (final Entry<String, ParameterGroup> parameterEntry : ParameterService.getAll()) {
157             LOGGER.info("Parameter class " + parameterEntry.getKey() + "=" + parameterEntry.getValue().toString());
158         }
159
160         try {
161             final ConfigrationProvider configrationProvider =
162                     new ConfigrationProviderImpl(testName, 1, threadCount, threadLoops, albumSize, lockType);
163             final ConcurrentContextJvm concurrentContextJvm = new ConcurrentContextJvm(jvmNo, configrationProvider);
164             concurrentContextJvm.execute();
165
166         } catch (final Exception e) {
167             LOGGER.error("error running test in JVM", e);
168         }
169         // CHECKSTYLE:ON: checkstyle:magicNumber
170     }
171
172     private static String getStringValue(final String key, final String[] args, final int position) {
173         try {
174             return args[position];
175         } catch (final Exception e) {
176             final String msg = "invalid argument " + key;
177             LOGGER.error(msg, e);
178             throw new ApexRuntimeException(msg, e);
179         }
180     }
181
182     private static int getIntValue(final String key, final String[] args, final int position) {
183         final String value = getStringValue(key, args, position);
184         try {
185             return Integer.parseInt(value);
186         } catch (final Exception e) {
187             final String msg = "Expects number found " + value;
188             LOGGER.error(msg, e);
189             throw new ApexRuntimeException(msg, e);
190         }
191     }
192
193
194     /**
195      * This method sets up any static configuration required by the JVM.
196      *
197      * @throws ApexException on configuration errors
198      */
199     public static void configure() throws ApexException {
200         System.setProperty("java.net.preferIPv4Stack", "true");
201         // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to
202         // work. IN order to
203         // ensure that all
204         // the JVMs in a test pick up the same IP address, this function sets te address to be the
205         // first non-loopback
206         // IPv4 address
207         // on a host
208         final TreeSet<String> ipAddressSet = new TreeSet<>();
209
210         Enumeration<NetworkInterface> nets;
211         try {
212             nets = NetworkInterface.getNetworkInterfaces();
213         } catch (final SocketException e) {
214             throw new ApexException("cound not get network interfaces for test", e);
215         }
216
217         for (final NetworkInterface netint : Collections.list(nets)) {
218             final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
219             for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
220                 // Look for real IPv4 Internet addresses
221                 if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == IPV4_ADDRESS_LENGTH) {
222                     ipAddressSet.add(inetAddress.getHostAddress());
223                 }
224             }
225         }
226
227         if (ipAddressSet.isEmpty()) {
228             throw new ApexException("cound not find real IP address for test");
229         }
230         LOGGER.info("Setting jgroups.tcp.address to: " + ipAddressSet.first());
231         System.setProperty("jgroups.tcp.address", ipAddressSet.first());
232     }
233 }