LAUNCH: Added multi launch listener for handling. 13/13313/4
authorTaeyoung Son <taeyoung2.son@samsung.com>
Tue, 3 Dec 2013 08:49:07 +0000 (17:49 +0900)
committerTaeyoung Son <taeyoung2.son@samsung.com>
Wed, 4 Dec 2013 10:17:22 +0000 (19:17 +0900)
When you launch application twice to same device quickly, second launch will be set value "launched already".

Change-Id: Ib5021f1420bb755904ce9f01ed7866035efacd36
Signed-off-by: Taeyoung Son <taeyoung2.son@samsung.com>
org.tizen.common.gom/META-INF/MANIFEST.MF
org.tizen.common/META-INF/MANIFEST.MF
org.tizen.common/src/org/tizen/common/CommonPlugin.java
org.tizen.common/src/org/tizen/common/launch/LaunchMessages.java
org.tizen.common/src/org/tizen/common/launch/LaunchMessages.properties
org.tizen.common/src/org/tizen/common/launch/LaunchesListener.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/launch/context/ILaunchContext.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/launch/context/LaunchContext.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/launch/context/LaunchContextConstants.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/launch/context/LaunchContextTest.java [new file with mode: 0644]

index 4771dac..403ac21 100644 (file)
@@ -6,7 +6,8 @@ Bundle-Version: 2.0.0.qualifier
 Bundle-Activator: org.tizen.common.gom.GomPlugin
 Bundle-Vendor: %Bundle-Vendor
 Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.ui
+ org.eclipse.ui,
+ org.tizen.common
 Bundle-ClassPath: .
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
@@ -21,11 +22,7 @@ Import-Package: org.eclipse.core.resources,
  org.eclipse.swt.graphics,
  org.eclipse.swt.widgets,
  org.slf4j,
- org.tizen.common,
  org.tizen.common.connection,
- org.tizen.common.launch,
- org.tizen.common.util,
- org.tizen.common.util.log,
  org.tizen.sdblib
 Export-Package: org.tizen.common.gom.launch,
  org.tizen.common.gom.smartlaunch
index 8828e61..da3f38a 100755 (executable)
@@ -194,6 +194,7 @@ Export-Package:
  org.tizen.common.file,
  org.tizen.common.file.filter,
  org.tizen.common.launch,
+ org.tizen.common.launch.context,
  org.tizen.common.rds,
  org.tizen.common.rds.ui.preference,
  org.tizen.common.sdb.command,
index 93fbd46..1330150 100755 (executable)
@@ -31,6 +31,7 @@ import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.RegistryFactory;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
@@ -40,6 +41,7 @@ import org.tizen.common.core.command.Executor;
 import org.tizen.common.core.command.Prompter;
 import org.tizen.common.core.command.prompter.EclipsePrompter;
 import org.tizen.common.core.command.prompter.SWTPrompter;
+import org.tizen.common.launch.LaunchesListener;
 import org.tizen.common.rds.ui.preference.RdsPreferencePage;
 import org.tizen.common.ui.page.preference.SdbPreferencePage;
 import org.tizen.common.ui.page.preference.TizenBasePreferencePage;
@@ -96,6 +98,7 @@ public class CommonPlugin extends AbstractUIPlugin {
         initializeExecutor();
         initializeSmartDeviceBridge();
         initializeCrashReportService();
+        DebugPlugin.getDefault().getLaunchManager().addLaunchListener(new LaunchesListener());
     }
 
     /*
index dc14080..f381d09 100644 (file)
@@ -35,6 +35,7 @@ public class LaunchMessages extends NLS {
     public static String FAIL;
     public static String SUCCESS;
 
+    public static String LAUNCHED_ALREADY;
     public static String LAUNCH_ERROR;
     public static String NO_TARGET;
 
index e307be1..1a36d4c 100644 (file)
@@ -2,6 +2,7 @@ FAIL = Fail
 SUCCESS = Success\r
 \r
 LAUNCH_ERROR = Unable to launch\r
+LAUNCHED_ALREADY=Could not launch the {0} application because the {0} application is currently in launch.\r
 \r
 NO_TARGET = There is no target to launch.\n\\r
  Please select an emulator or a device in Connection Explorer.\r
diff --git a/org.tizen.common/src/org/tizen/common/launch/LaunchesListener.java b/org.tizen.common/src/org/tizen/common/launch/LaunchesListener.java
new file mode 100644 (file)
index 0000000..c9d27b0
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * common
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Taeyoung Son <taeyoung2.son@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * Kangho Kim <kh5325.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+
+package org.tizen.common.launch;
+
+import static org.tizen.common.launch.context.LaunchContextConstants.CONFIG_ATTR_DEVICE_NAME;
+import static org.tizen.common.launch.context.LaunchContextConstants.CONFIG_ATTR_DEVICE_SERIAL_NO;
+import static org.tizen.common.launch.context.LaunchContextConstants.CONFIG_ATTR_PROJECT_NAME;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchesListener2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.launch.context.LaunchContext;
+import org.tizen.common.util.ArrayUtil;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.SmartDevelopmentBridge;
+
+/**
+ * Handle multi launch
+ * 
+ * @author Taeyoung Son {@literal <taeyoung.son@samsung.com>} (S-Core)
+ */
+public class LaunchesListener implements ILaunchesListener2 {
+    Logger logger = LoggerFactory.getLogger(getClass());
+
+    public static final String LAUNCH_ATTR_KEY_IS_LAUNCHING = "LAUNCH_ATTR_KEY_IS_LAUNCHING"; //$NON-NLS-1$
+    public static final String LAUNCH_ATTR_VALUE_LAUNCHING_ALREADY = "launched already"; //$NON-NLS-1$
+
+    private List<LaunchContext> contexts = new ArrayList<LaunchContext>();
+
+    @Override
+    public synchronized void launchesAdded(ILaunch[] launches) {
+        for (ILaunch launch : launches) {
+            try {
+                ILaunchConfiguration config = launch.getLaunchConfiguration();
+                if (config == null) {
+                    logger.debug("launch configuration is null.");
+                    continue;
+                }
+
+                String projectName = config.getAttribute(CONFIG_ATTR_PROJECT_NAME, "");
+                String serialNum = config.getAttribute(CONFIG_ATTR_DEVICE_SERIAL_NO, "");
+
+                if (getContext(projectName, serialNum) != null) {
+                    launch.setAttribute(LAUNCH_ATTR_KEY_IS_LAUNCHING, LAUNCH_ATTR_VALUE_LAUNCHING_ALREADY);
+                    continue;
+                } else {
+                    addContext(projectName, serialNum);
+                }
+            } catch (CoreException e) {
+                //TODO: need to consider handle exception.
+                logger.error(e.getMessage(),e);
+            }
+        }
+    }
+
+    /**
+     * Adds launch context.
+     * @param projectName
+     * @param deviceSerialNum
+     */
+    private void addContext(String projectName, String deviceSerialNum) {
+        LaunchContext context = new LaunchContext();
+
+        setProjectName(context, projectName);
+        context.setValue(CONFIG_ATTR_DEVICE_SERIAL_NO, deviceSerialNum);
+
+        contexts.add(context);
+    }
+
+    /**
+     * Sets project name.
+     * @param context
+     * @param projectName
+     */
+    protected void setProjectName(LaunchContext context, String projectName) {
+        context.setValue(CONFIG_ATTR_PROJECT_NAME, projectName);
+    }
+
+    /**
+     * Gets device.
+     * @param config
+     * @return
+     * @throws CoreException
+     */
+    protected IDevice getDevice(ILaunchConfiguration config) throws CoreException {
+        IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
+        if (ArrayUtil.isEmpty(devices)) {
+            return null;
+        }
+
+        String deviceName = config.getAttribute(CONFIG_ATTR_DEVICE_NAME, "");
+        String deviceSerial = config.getAttribute(CONFIG_ATTR_DEVICE_SERIAL_NO, "");
+
+        for (IDevice device : devices) {
+            if (device.isEmulator()
+                    && deviceName.equals(device.getDeviceName())) {
+                return device;
+            } else if (deviceSerial.equals(device.getSerialNumber())){
+                return  device;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets context from {@code contexts}.
+     * @param projectName the project name to find context.
+     * @param serialNum then device's serial number to find context.
+     * @return {@link LaunchContext}. If context does not exist in {@code contexts}, return null.
+     */
+    public LaunchContext getContext(String projectName, String serialNum) {
+        for (int i=0; i<contexts.size();i++) {
+            LaunchContext tmpContext = contexts.get(i);
+
+            if (getProjectName(tmpContext).equals(projectName)
+                    && (tmpContext.getValue(CONFIG_ATTR_DEVICE_SERIAL_NO).equals(serialNum))) {
+                return tmpContext;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets project name
+     * @param context
+     * @return
+     */
+    private static String getProjectName(LaunchContext context) {
+        return (String) context.getValue(CONFIG_ATTR_PROJECT_NAME);
+    }
+
+    @Override
+    public void launchesChanged(ILaunch[] launches) {
+        //nothing to do.
+    }
+
+    @Override
+    public void launchesRemoved(ILaunch[] launches) {
+        for (ILaunch launch : launches) {
+            try {
+                String projectName = launch.getLaunchConfiguration().getAttribute(CONFIG_ATTR_PROJECT_NAME, "");
+                String deviceSerialNum = launch.getLaunchConfiguration().getAttribute(CONFIG_ATTR_DEVICE_SERIAL_NO, "");
+
+                LaunchContext context = getContext(projectName, deviceSerialNum);
+                contexts.remove(context);
+            } catch (CoreException e) {
+              //TODO: need to consider handle exception.
+                logger.error(e.getMessage(),e);
+            }
+        }
+    }
+
+    @Override
+    public void launchesTerminated(ILaunch[] launches) {
+      //TODO: need to consider this.
+        for (ILaunch launch : launches) {
+            try {
+                String projectName = launch.getLaunchConfiguration().getAttribute(CONFIG_ATTR_PROJECT_NAME, "");
+                String deviceSerialNum = launch.getLaunchConfiguration().getAttribute(CONFIG_ATTR_DEVICE_SERIAL_NO, "");
+
+                LaunchContext context = getContext(projectName, deviceSerialNum);
+                contexts.remove(context);
+            } catch (CoreException e) {
+              //TODO: need to consider handle exception.
+                logger.error(e.getMessage(),e);
+            }
+        }
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/launch/context/ILaunchContext.java b/org.tizen.common/src/org/tizen/common/launch/context/ILaunchContext.java
new file mode 100644 (file)
index 0000000..5d18514
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * common
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Gyeongseok Seo <gyeongseok.seo@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * Kangho Kim <kh5325.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+
+package org.tizen.common.launch.context;
+
+
+@SuppressWarnings("hiding")
+/**
+ * Launch Context interface.
+ * 
+ * @author Gyeongseok Seo {@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ *
+ * @param <Object> context object - context can be any type of Java Class
+ */
+public interface ILaunchContext<Object> {
+       /**
+        * getting all keys
+        * 
+        * @return Array of all keys
+        */
+       public abstract Object[] getKeys();
+
+       /**
+        * getting The value of the corresponding key
+        * 
+        * @param key - context key
+        * @return context value
+        */
+       public abstract Object getValue(Object key);
+
+       /**
+        * Setting The value and value of the corresponding key
+        * 
+        * @param key - context key
+        * @param value - value of the corresponding key
+        * @return previous value of the corresponding key
+        */
+       public abstract Object setValue(Object key, Object value);
+}
diff --git a/org.tizen.common/src/org/tizen/common/launch/context/LaunchContext.java b/org.tizen.common/src/org/tizen/common/launch/context/LaunchContext.java
new file mode 100644 (file)
index 0000000..19488a4
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * common
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Gyeongseok Seo <gyeongseok.seo@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * Kangho Kim <kh5325.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+
+package org.tizen.common.launch.context;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Step context class, this class implement ILaunchContext
+ * 
+ * @author Gyeongseok Seo {@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ *
+ */
+public class LaunchContext implements ILaunchContext<Object> {
+       /**
+        * context map, it's HashMap. it contains of context's key and value.
+        */
+       protected HashMap<Object, Object> ctxmap = new HashMap<Object, Object>();
+
+       @Override
+       public Object[] getKeys() {
+               ArrayList<Object> keys = new ArrayList<Object>();
+               keys.addAll( ctxmap.keySet() );
+
+               return keys.toArray();
+       }
+
+       @Override
+       public Object getValue(Object key) {
+               return ctxmap.get(key);
+       }
+
+       @Override
+       public Object setValue(Object key, Object value) {
+               return ctxmap.put(key, value);
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/launch/context/LaunchContextConstants.java b/org.tizen.common/src/org/tizen/common/launch/context/LaunchContextConstants.java
new file mode 100644 (file)
index 0000000..10950e8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * common
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Taeyoung Son <taeyoung2.son@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * Kangho Kim <kh5325.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+
+package org.tizen.common.launch.context;
+
+import org.tizen.common.CommonPlugin;
+
+/**
+ * LaunchContextConstants class.
+ * 
+ * @author Taeyoung Son {@literal <taeyoung.son@samsung.com>} (S-Core)
+ */
+public class LaunchContextConstants {
+    public static final String CONFIG_ATTR_DEVICE_NAME = CommonPlugin.PLUGIN_ID + ".CONFIG_ATTR_DEVICE_NAME"; //$NON-NLS-1$
+    public static final String CONFIG_ATTR_DEVICE_SERIAL_NO = CommonPlugin.PLUGIN_ID + "CONFIG_ATTR_DEVICE_SERIAL_NO"; //$NON-NLS-1$
+    public static final String CONFIG_ATTR_DEVICE_TYPE = CommonPlugin.PLUGIN_ID + ".CONFIG_ATTR_DEVICE_TYPE"; //$NON-NLS-1$
+    public static final String CONFIG_ATTR_PROJECT_NAME = CommonPlugin.PLUGIN_ID + ".CONFIG_ATTR_PROJECT_NAME"; //$NON-NLS-1$;
+
+    /**
+     * Device type
+     * 
+     * @author Taeyoung Son {@literal <taeyoung.son@samsung.com>} (S-Core)
+     */
+    public enum DeviceType {
+        EMULATOR,
+        DEVICE
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/launch/context/LaunchContextTest.java b/org.tizen.common/test/src/org/tizen/common/launch/context/LaunchContextTest.java
new file mode 100644 (file)
index 0000000..c128221
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Web IDE - launch
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * GyeongSeok Seo <gyeongseok.seo@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.common.launch.context;
+
+import static org.junit.Assert.*;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.spy;
+
+import org.junit.Test;
+import org.tizen.common.launch.context.LaunchContext;
+
+/**
+ * LaunchContextTest
+ * <br>
+ * Test case for {@link LaunchContext}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * @author Gyeongseok Seo {@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ *
+ * @see LaunchContext
+ */
+public class
+LaunchContextTest
+{
+
+       /**
+        * Test {@link LaunchContext#getKeys()}
+        * <br>
+        * @throws Exception in case of failure in test
+        * <br>
+        * @see {@link LaunchContext#getKeys()}
+        */
+       @Test
+       public void
+       testGetKeys()
+       throws Exception
+       {
+               LaunchContext ctx = new LaunchContext();
+               LaunchContext spy = spy ( ctx );
+               assertNotNull( spy.getKeys() );
+               
+               String mockKeys[] = { "1", "2", "3", "4", "5" };
+               String mockValue[] = { "t1", "t2", "t3", "t4", "t5" };
+
+               for ( int i = 0; i < mockKeys.length; i++ ) {
+                       spy.setValue( mockKeys[i], mockValue[i] );
+                       verify( spy ).setValue( mockKeys[i], mockValue[i] );
+               }
+
+               for ( Object key : spy.getKeys() ) {
+                       assertTrue( spy.ctxmap.containsKey( key ) );
+               }
+               verify( spy, times(2) ).getKeys();
+       }
+
+       /**
+        * Test {@link LaunchContext#getValue(Object)}
+        * <br>
+        * @throws Exception in case of failure in test
+        * <br>
+        * @see {@link LaunchContext#getValue(Object)}
+        */
+       @Test
+       public void
+       testGetValue()
+       throws Exception
+       {
+               // null test
+               LaunchContext ctx = new LaunchContext();
+               LaunchContext spy = spy ( ctx );
+
+               spy.setValue(null, null);
+               assertNull( spy.getValue(null) );
+               verify( spy ).getValue(null);
+
+               spy.setValue(null, "test");
+               assertNotNull( spy.getValue(null) );
+               assertEquals( "test", spy.getValue(null) );
+               verify( spy, times(3) ).getValue(null);
+
+               // object test
+               spy.setValue("test1", "tizen1");
+               spy.setValue("test2", "tizen2");
+               assertEquals( "tizen1", spy.getValue("test1") );
+               assertEquals( "tizen2", spy.getValue("test2") );
+               verify( spy, times(1) ).getValue("test1");
+               verify( spy, times(1) ).getValue("test2");
+
+               spy.setValue( "ctx", ctx);
+               assertEquals( ctx,  spy.getValue("ctx") );
+               verify( spy, times(1) ).getValue("ctx");
+       }
+
+       /**
+        * Test {@link LaunchContext#setValue(Object, Object)}
+        * <br>
+        * @throws Exception in case of failure in test
+        * <br>
+        * @see {@link LaunchContext#setValue(Object, Object)}
+        */
+       @Test
+       public void
+       testSetValue()
+       throws Exception
+       {
+               // null test
+               LaunchContext ctx = new LaunchContext();
+               LaunchContext spy = spy ( ctx );
+
+               spy.setValue(null, null);
+               assertNull( spy.getValue(null) );
+               verify( spy ).setValue(null, null);
+
+               spy.setValue(null, "test");
+               assertNotNull( spy.getValue(null) );
+               assertEquals( "test", spy.getValue(null) );
+               verify( spy, times(1) ).setValue(null, "test");
+
+               // object test
+               spy.setValue("test1", "tizen1");
+               spy.setValue("test2", "tizen2");
+               assertEquals( "tizen1", spy.getValue("test1") );
+               assertEquals( "tizen2", spy.getValue("test2") );
+               verify( spy, times(1) ).setValue("test1", "tizen1");
+               verify( spy, times(1) ).setValue("test2", "tizen2");
+
+               spy.setValue( "ctx", ctx);
+               assertEquals( ctx,  spy.getValue("ctx") );
+               verify( spy, times(1) ).setValue("ctx", ctx);
+       }
+
+}