Commit | Line | Data |
---|---|---|
970ed795 | 1 | /****************************************************************************** |
3abe9331 | 2 | * Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
3 | * All rights reserved. This program and the accompanying materials |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | ******************************************************************************/ | |
8 | package org.eclipse.titan.executorapi.test; | |
9 | ||
10 | import java.util.Map; | |
11 | ||
12 | import org.eclipse.titan.executor.jni.McStateEnum; | |
13 | import org.eclipse.titan.executor.jni.Timeval; | |
14 | import org.eclipse.titan.executor.jni.VerdictTypeEnum; | |
15 | import org.eclipse.titan.executorapi.HostController; | |
16 | import org.eclipse.titan.executorapi.IJniExecutorObserver; | |
17 | import org.eclipse.titan.executorapi.JniExecutor; | |
18 | import org.eclipse.titan.executorapi.exception.JniExecutorIllegalArgumentException; | |
19 | import org.eclipse.titan.executorapi.exception.JniExecutorJniLoadException; | |
20 | import org.eclipse.titan.executorapi.exception.JniExecutorStartSessionException; | |
21 | import org.eclipse.titan.executorapi.exception.JniExecutorWrongStateException; | |
22 | import org.eclipse.titan.executorapi.util.Log; | |
23 | ||
24 | /** | |
25 | * Wrapper class for synchronous usage of JniExecutor. SINGLETON | |
26 | */ | |
27 | public final class JniExecutorSync implements IJniExecutorObserver { | |
28 | ||
29 | /** Default timeout of synchronous functions of the asynchronous requests in ms */ | |
30 | private static final int DEFAULT_TIMEOUT = 0; | |
31 | ||
32 | /** | |
33 | * lock for synchronous access of mRequestOngoing | |
34 | */ | |
35 | private final Object mLockObject = new Object(); | |
36 | ||
37 | /** | |
38 | * Flag for signaling the asynchronous requests, used for the synchronous versions of the functions | |
39 | */ | |
40 | private volatile boolean mRequestOngoing = false; | |
41 | ||
42 | /** | |
43 | * true, if setObserver() was called | |
44 | */ | |
45 | private boolean mObserverSet = false; | |
46 | ||
47 | /** | |
48 | * Timeout of synchronous functions of the asynchronous requests in ms | |
49 | */ | |
50 | private long mTimeout = DEFAULT_TIMEOUT; | |
51 | ||
52 | /** | |
53 | * Private constructor, because it is a singleton. | |
54 | */ | |
55 | private JniExecutorSync() { | |
56 | } | |
57 | ||
58 | /** | |
59 | * Lazy holder for the singleton (Bill Pugh solution) | |
60 | * Until we need an instance, the holder class will not be initialized until required and you can still use other static members of the singleton class. | |
61 | * @see "http://en.wikipedia.org/wiki/Singleton_pattern#Initialization_On_Demand_Holder_Idiom" | |
62 | */ | |
63 | private static class SingletonHolder { | |
64 | private static final JniExecutorSync mInstance = new JniExecutorSync(); | |
65 | } | |
66 | ||
67 | /** | |
68 | * @return the singleton instance | |
69 | */ | |
70 | public static JniExecutorSync getInstance() { | |
71 | return SingletonHolder.mInstance; | |
72 | } | |
73 | ||
74 | @Override | |
75 | public void statusChanged( final McStateEnum aNewState ) { | |
76 | Log.fi( aNewState ); | |
77 | // in case of final states | |
78 | // synchronous function is signaled that function can be ended | |
79 | if ( !isIntermediateState( aNewState ) ) { | |
80 | signalEndSync(); | |
81 | } | |
82 | Log.fo(); | |
83 | } | |
84 | ||
85 | @Override | |
86 | public void error( final int aSeverity, final String aMsg ) { | |
87 | Log.fi( aSeverity, aMsg ); | |
88 | signalEndSync(); | |
89 | Log.fo(); | |
90 | } | |
91 | ||
92 | @Override | |
93 | public void notify(final Timeval aTime, final String aSource, final int aSeverity, final String aMsg) { | |
94 | } | |
95 | ||
96 | @Override | |
97 | public void verdict(String aTestcase, VerdictTypeEnum aVerdictType) { | |
98 | } | |
99 | ||
100 | @Override | |
101 | public void verdictStats(Map<VerdictTypeEnum, Integer> aVerdictStats) { | |
102 | } | |
103 | ||
104 | public void init() throws JniExecutorWrongStateException, JniExecutorJniLoadException { | |
105 | JniExecutor.getInstance().init(); | |
106 | mRequestOngoing = false; | |
107 | mObserverSet = false; | |
108 | } | |
109 | ||
110 | public void addHostController( final HostController aHc ) throws JniExecutorIllegalArgumentException, JniExecutorWrongStateException { | |
111 | JniExecutor.getInstance().addHostController( aHc ); | |
112 | } | |
113 | ||
114 | public void setConfigFileName( final String aConfigFileName ) throws JniExecutorWrongStateException, JniExecutorIllegalArgumentException { | |
115 | JniExecutor.getInstance().setConfigFileName( aConfigFileName ); | |
116 | } | |
117 | ||
118 | public void startSession() throws JniExecutorWrongStateException, JniExecutorStartSessionException { | |
119 | JniExecutor.getInstance().startSession(); | |
120 | } | |
121 | ||
122 | public int getExecuteCfgLen() throws JniExecutorWrongStateException { | |
123 | return JniExecutor.getInstance().getExecuteCfgLen(); | |
124 | } | |
125 | ||
126 | /** | |
127 | * Sets new timeout | |
128 | * @param aTimeout the new timeout value in ms, | |
129 | * or 0, if no timeout | |
130 | */ | |
131 | public void setTimeout( final long aTimeout ) { | |
132 | mTimeout = aTimeout; | |
133 | } | |
134 | ||
135 | /** | |
136 | * Sets observer if it's not set yet. | |
137 | * It must be called before the 1st asynchronous function call. | |
138 | * @throws JniExecutorWrongStateException | |
139 | */ | |
140 | private void setObserver() throws JniExecutorWrongStateException { | |
141 | if ( !mObserverSet ) { | |
142 | JniExecutor.getInstance().setObserver( this ); | |
143 | mObserverSet = true; | |
144 | } | |
145 | } | |
146 | ||
147 | // ------------ SYNCHRONOUS VERSION OF ASYNCHRONOUS FUNCTIONS -------------------- | |
148 | ||
149 | ||
150 | public void startHostControllersSync() throws JniExecutorWrongStateException { | |
151 | // observer is set before the 1st async request | |
152 | setObserver(); | |
153 | startSync(); | |
154 | JniExecutor.getInstance().startHostControllers(); | |
155 | endSync(); | |
156 | } | |
157 | ||
158 | public void configureSync() throws JniExecutorWrongStateException { | |
159 | // observer is set before the 1st async request | |
160 | setObserver(); | |
161 | startSync(); | |
162 | JniExecutor.getInstance().configure(); | |
163 | endSync(); | |
164 | } | |
165 | ||
166 | public void createMTCSync() throws JniExecutorWrongStateException { | |
167 | startSync(); | |
168 | JniExecutor.getInstance().createMTC(); | |
169 | endSync(); | |
170 | } | |
171 | ||
172 | public void executeControlSync( final String aModule ) throws JniExecutorWrongStateException, JniExecutorIllegalArgumentException { | |
173 | startSync(); | |
174 | JniExecutor.getInstance().executeControl( aModule ); | |
175 | endSync(); | |
176 | } | |
177 | ||
178 | public void executeTestcaseSync( final String aModule, final String aTestcase ) throws JniExecutorWrongStateException, JniExecutorIllegalArgumentException { | |
179 | startSync(); | |
180 | JniExecutor.getInstance().executeTestcase( aModule, aTestcase ); | |
181 | endSync(); | |
182 | } | |
183 | ||
184 | public void executeCfgSync( final int aIndex ) throws JniExecutorWrongStateException, JniExecutorIllegalArgumentException { | |
185 | startSync(); | |
186 | JniExecutor.getInstance().executeCfg( aIndex ); | |
187 | endSync(); | |
188 | } | |
189 | ||
190 | public void continueExecutionSync() throws JniExecutorWrongStateException { | |
191 | startSync(); | |
192 | JniExecutor.getInstance().continueExecution(); | |
193 | endSync(); | |
194 | } | |
195 | ||
196 | public void exitMTCSync() throws JniExecutorWrongStateException { | |
197 | startSync(); | |
198 | JniExecutor.getInstance().exitMTC(); | |
199 | endSync(); | |
200 | } | |
201 | ||
202 | public void shutdownSessionSync() { | |
203 | startSync(); | |
204 | JniExecutor.getInstance().shutdownSession(); | |
205 | endSync(); | |
206 | } | |
207 | ||
208 | private void startSync() { | |
209 | Log.fi(); | |
210 | synchronized (mLockObject) { | |
211 | Log.i("startSync()"); | |
212 | // Make sure, that ...Sync() functions do NOT call each other | |
213 | if ( mRequestOngoing ) { | |
214 | //This should not happen, another request is ongoing | |
215 | Log.i(" startSync() mRequestOngoing == true --- This should not happen, another request is ongoing"); | |
216 | } | |
217 | mRequestOngoing = true; | |
218 | } | |
219 | Log.fo(); | |
220 | } | |
221 | ||
222 | private void endSync() { | |
223 | Log.fi(); | |
224 | synchronized (mLockObject) { | |
225 | if ( !mRequestOngoing ) { | |
226 | // The request is already finished, faster than the ...Sync() function | |
227 | Log.i(" endSync() mRequestOngoing == false --- The request is already finished"); | |
228 | } | |
229 | else { | |
230 | try { | |
231 | if ( mTimeout == 0 ) { | |
232 | // no timeout | |
233 | mLockObject.wait(); | |
234 | } else { | |
235 | mLockObject.wait( mTimeout ); | |
236 | } | |
237 | } catch (InterruptedException e) { | |
238 | Log.f(e.toString()); | |
239 | } | |
240 | } | |
241 | Log.i("endSync()"); | |
242 | } | |
243 | Log.fo(); | |
244 | } | |
245 | ||
246 | private void signalEndSync() { | |
247 | Log.fi(); | |
248 | synchronized (mLockObject) { | |
249 | Log.i("signalEndSync()"); | |
250 | if ( !mRequestOngoing ) { | |
251 | // There is no synchronous function called | |
252 | Log.i(" signalEndSync() There is no synchronous function called"); | |
253 | } | |
254 | mLockObject.notifyAll(); | |
255 | mRequestOngoing = false; | |
256 | } | |
257 | Log.fo(); | |
258 | } | |
259 | ||
260 | /** | |
261 | * Checks if state is intermediate state. Intermediate state is a state, when asynchronous request is ongoing. | |
262 | * When it is finished, it will switched to some final state automatically. | |
263 | * @param aState the state to check | |
264 | * @return if state is intermediate | |
265 | */ | |
266 | private static boolean isIntermediateState( final McStateEnum aState ) { | |
267 | return | |
268 | aState == McStateEnum.MC_LISTENING || // it is stable, but cannot be a result state of any async request | |
269 | aState == McStateEnum.MC_CONFIGURING || | |
270 | aState == McStateEnum.MC_CREATING_MTC || | |
271 | aState == McStateEnum.MC_TERMINATING_MTC || | |
272 | aState == McStateEnum.MC_EXECUTING_CONTROL || | |
273 | aState == McStateEnum.MC_EXECUTING_TESTCASE || | |
274 | aState == McStateEnum.MC_TERMINATING_TESTCASE || | |
275 | aState == McStateEnum.MC_SHUTDOWN; | |
276 | } | |
277 | } |