1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
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
12 ******************************************************************************/
13 package org
.eclipse
.titan
.executorapi
.test
;
17 import org
.eclipse
.titan
.executor
.jni
.McStateEnum
;
18 import org
.eclipse
.titan
.executor
.jni
.Timeval
;
19 import org
.eclipse
.titan
.executor
.jni
.VerdictTypeEnum
;
20 import org
.eclipse
.titan
.executorapi
.HostController
;
21 import org
.eclipse
.titan
.executorapi
.IJniExecutorObserver
;
22 import org
.eclipse
.titan
.executorapi
.JniExecutor
;
23 import org
.eclipse
.titan
.executorapi
.exception
.JniExecutorIllegalArgumentException
;
24 import org
.eclipse
.titan
.executorapi
.exception
.JniExecutorJniLoadException
;
25 import org
.eclipse
.titan
.executorapi
.exception
.JniExecutorStartSessionException
;
26 import org
.eclipse
.titan
.executorapi
.exception
.JniExecutorWrongStateException
;
27 import org
.eclipse
.titan
.executorapi
.util
.Log
;
30 * Wrapper class for synchronous usage of JniExecutor. SINGLETON
32 public final class JniExecutorSync
implements IJniExecutorObserver
{
34 /** Default timeout of synchronous functions of the asynchronous requests in ms */
35 private static final int DEFAULT_TIMEOUT
= 0;
38 * lock for synchronous access of mRequestOngoing
40 private final Object mLockObject
= new Object();
43 * Flag for signaling the asynchronous requests, used for the synchronous versions of the functions
45 private volatile boolean mRequestOngoing
= false;
48 * true, if setObserver() was called
50 private boolean mObserverSet
= false;
53 * Timeout of synchronous functions of the asynchronous requests in ms
55 private long mTimeout
= DEFAULT_TIMEOUT
;
58 * Private constructor, because it is a singleton.
60 private JniExecutorSync() {
64 * Lazy holder for the singleton (Bill Pugh solution)
65 * 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.
66 * @see "http://en.wikipedia.org/wiki/Singleton_pattern#Initialization_On_Demand_Holder_Idiom"
68 private static class SingletonHolder
{
69 private static final JniExecutorSync mInstance
= new JniExecutorSync();
73 * @return the singleton instance
75 public static JniExecutorSync
getInstance() {
76 return SingletonHolder
.mInstance
;
80 public void statusChanged( final McStateEnum aNewState
) {
82 // in case of final states
83 // synchronous function is signaled that function can be ended
84 if ( !isIntermediateState( aNewState
) ) {
91 public void error( final int aSeverity
, final String aMsg
) {
92 Log
.fi( aSeverity
, aMsg
);
98 public void notify(final Timeval aTime
, final String aSource
, final int aSeverity
, final String aMsg
) {
102 public void verdict(String aTestcase
, VerdictTypeEnum aVerdictType
) {
106 public void verdictStats(Map
<VerdictTypeEnum
, Integer
> aVerdictStats
) {
109 public void init() throws JniExecutorWrongStateException
, JniExecutorJniLoadException
{
110 JniExecutor
.getInstance().init();
111 mRequestOngoing
= false;
112 mObserverSet
= false;
115 public void addHostController( final HostController aHc
) throws JniExecutorIllegalArgumentException
, JniExecutorWrongStateException
{
116 JniExecutor
.getInstance().addHostController( aHc
);
119 public void setConfigFileName( final String aConfigFileName
) throws JniExecutorWrongStateException
, JniExecutorIllegalArgumentException
{
120 JniExecutor
.getInstance().setConfigFileName( aConfigFileName
);
123 public void startSession() throws JniExecutorWrongStateException
, JniExecutorStartSessionException
{
124 JniExecutor
.getInstance().startSession();
127 public int getExecuteCfgLen() throws JniExecutorWrongStateException
{
128 return JniExecutor
.getInstance().getExecuteCfgLen();
133 * @param aTimeout the new timeout value in ms,
134 * or 0, if no timeout
136 public void setTimeout( final long aTimeout
) {
141 * Sets observer if it's not set yet.
142 * It must be called before the 1st asynchronous function call.
143 * @throws JniExecutorWrongStateException
145 private void setObserver() throws JniExecutorWrongStateException
{
146 if ( !mObserverSet
) {
147 JniExecutor
.getInstance().setObserver( this );
152 // ------------ SYNCHRONOUS VERSION OF ASYNCHRONOUS FUNCTIONS --------------------
155 public void startHostControllersSync() throws JniExecutorWrongStateException
{
156 // observer is set before the 1st async request
159 JniExecutor
.getInstance().startHostControllers();
163 public void configureSync() throws JniExecutorWrongStateException
{
164 // observer is set before the 1st async request
167 JniExecutor
.getInstance().configure();
171 public void createMTCSync() throws JniExecutorWrongStateException
{
173 JniExecutor
.getInstance().createMTC();
177 public void executeControlSync( final String aModule
) throws JniExecutorWrongStateException
, JniExecutorIllegalArgumentException
{
179 JniExecutor
.getInstance().executeControl( aModule
);
183 public void executeTestcaseSync( final String aModule
, final String aTestcase
) throws JniExecutorWrongStateException
, JniExecutorIllegalArgumentException
{
185 JniExecutor
.getInstance().executeTestcase( aModule
, aTestcase
);
189 public void executeCfgSync( final int aIndex
) throws JniExecutorWrongStateException
, JniExecutorIllegalArgumentException
{
191 JniExecutor
.getInstance().executeCfg( aIndex
);
195 public void continueExecutionSync() throws JniExecutorWrongStateException
{
197 JniExecutor
.getInstance().continueExecution();
201 public void exitMTCSync() throws JniExecutorWrongStateException
{
203 JniExecutor
.getInstance().exitMTC();
207 public void shutdownSessionSync() {
209 JniExecutor
.getInstance().shutdownSession();
213 private void startSync() {
215 synchronized (mLockObject
) {
216 Log
.i("startSync()");
217 // Make sure, that ...Sync() functions do NOT call each other
218 if ( mRequestOngoing
) {
219 //This should not happen, another request is ongoing
220 Log
.i(" startSync() mRequestOngoing == true --- This should not happen, another request is ongoing");
222 mRequestOngoing
= true;
227 private void endSync() {
229 synchronized (mLockObject
) {
230 if ( !mRequestOngoing
) {
231 // The request is already finished, faster than the ...Sync() function
232 Log
.i(" endSync() mRequestOngoing == false --- The request is already finished");
236 if ( mTimeout
== 0 ) {
240 mLockObject
.wait( mTimeout
);
242 } catch (InterruptedException e
) {
251 private void signalEndSync() {
253 synchronized (mLockObject
) {
254 Log
.i("signalEndSync()");
255 if ( !mRequestOngoing
) {
256 // There is no synchronous function called
257 Log
.i(" signalEndSync() There is no synchronous function called");
259 mLockObject
.notifyAll();
260 mRequestOngoing
= false;
266 * Checks if state is intermediate state. Intermediate state is a state, when asynchronous request is ongoing.
267 * When it is finished, it will switched to some final state automatically.
268 * @param aState the state to check
269 * @return if state is intermediate
271 private static boolean isIntermediateState( final McStateEnum aState
) {
273 aState
== McStateEnum
.MC_LISTENING
|| // it is stable, but cannot be a result state of any async request
274 aState
== McStateEnum
.MC_CONFIGURING
||
275 aState
== McStateEnum
.MC_CREATING_MTC
||
276 aState
== McStateEnum
.MC_TERMINATING_MTC
||
277 aState
== McStateEnum
.MC_EXECUTING_CONTROL
||
278 aState
== McStateEnum
.MC_EXECUTING_TESTCASE
||
279 aState
== McStateEnum
.MC_TERMINATING_TESTCASE
||
280 aState
== McStateEnum
.MC_SHUTDOWN
;