1

In my testing environment, we have classes that perform certain actions, some of them using SilkTest stuff. The test procedures are defined by XML files that we parse, turn into ActionImpl classes, and perform stuff with. For example, the following will login to our app, switch users, and then restart the server:

<Script refBean="validateState" retry="false">
    <DataGroups>
        <Step action="log" mod="5.10.13 - Step 1" />
        <Step action="switchUsers" target="mlane" />
        <Step action="restartServer" />
    </DataGroups>
</Script>

In the case of the restartServer action, the code eventually calls the following method, which creates a BaseState using the currently running eclipse.exe that the test is running in.

private PassFail restartServerInEclipse() {
    Desktop desktop = new Desktop();
    BaseState eclipseBaseState = new BaseState("*eclipse.exe", "/Shell[@caption='Java EE*']", TechDomain.SWT, TechDomain.XBROWSER, TechDomain.WIN32);
    desktop.executeBaseState(eclipseBaseState);
    // Do some stuff, like finding CTabItem objects, clicking them, etc.
    return passFail;
}

Let's say I'm running the first test of the day. I just got to work, and decided to run a test. If the code gets to a restartServer action, and calls restartServerInEclipse(), it'll recognize the currently running eclipse.exe, and successfully perform any Silk methods on any Silk objects that I tell it to.

However, without exiting Eclipse or Open Agent, after a test has finished, if I run the same test again, as in, entirely new objects, entirely new test thread, the test ran and stopped, and I clicked the green run button in Eclipse again, I get the following error when it gets to the BaseState eclipseBaseState = new BaseState(...) code:

com.borland.silktest.jtf.common.LaunchApplicationFailedException: Failed to start application '*eclipse.exe' in working directory 'null'. The system cannot find the file specified.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.borland.silktest.jtf.agent.ExceptionTranslatorUtil.createException(ExceptionTranslatorUtil.java:60)
    at com.borland.silktest.jtf.agent.ExceptionTranslatorUtil.translate(ExceptionTranslatorUtil.java:37)
    at com.borland.silktest.jtf.agent.JtfModule.executeBaseState_aroundBody39$advice(JtfModule.java:121)
    at com.borland.silktest.jtf.agent.JtfModule.executeBaseState(JtfModule.java:1)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke(RemoteInvocationTraceInterceptor.java:77)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy24.executeBaseState(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:205)
    at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:38)
    at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78)
    at org.springframework.remoting.rmi.RmiBasedExporter.invoke(RmiBasedExporter.java:72)
    at org.springframework.remoting.rmi.RmiInvocationWrapper.invoke(RmiInvocationWrapper.java:72)
    at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    at org.springframework.remoting.support.RemoteInvocationUtils.fillInClientStackTraceIfPossible(RemoteInvocationUtils.java:47)
    at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:351)
    at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:258)
    at com.borland.silktest.startservice.RmiConnectionUtil$1.invoke(RmiConnectionUtil.java:134)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy0.executeBaseState(Unknown Source)
    at com.borland.silktest.jtf.Agent.executeBaseState(Agent.java:452)
    at com.borland.silktest.jtf.BaseState.execute(BaseState.java:298)
    at com.borland.silktest.jtf.Desktop.executeBaseState(Desktop.java:69)
    at scripts.misc.validation.action.RestartServerActionImpl.restartServerInEclipse(RestartServerActionImpl.java:62)
    at scripts.misc.validation.action.RestartServerActionImpl.evaluate(RestartServerActionImpl.java:25)
    at scripts.misc.validation.ValidateState.evaluateStep(ValidateState.java:108)
    at scripts.misc.validation.ValidateState.script(ValidateState.java:131)
    at scripts.base.BaseScript.runWithRetries(BaseScript.java:204)
    at scripts.base.BaseScript.runIt(BaseScript.java:312)
    at suite.MainThread.script(MainThread.java:667)
    at suite.MainThread.run(MainThread.java:281)

The base state that worked completely fine two seconds previous is now incorrect. As if something about Eclipse changes once the base state is initially set, so it can't re-recognize it.

The only way to get around this is to restart Eclipse and Open Agent, but even that doesn't work sometimes, and I run into some license server issues with OA occasionally, which requires a computer reboot.

Tom
  • 221
  • 4
  • 15
  • Did the caption of the Eclipse process change? The way the base state works, if it can't resolve the locator, it will try to start the application and if you didn't specify a path to the .exe, you'll get the `LaunchApplicationFailedException`. – tehlexx Nov 22 '12 at 08:05
  • The caption didn't change. It still starts with `'Java EE*'` no matter what. – Tom Nov 26 '12 at 11:40
  • That's weird. Could you provide the agent log file from `%APPDATA%/Silk/SilkTest/logs`? If you don't want to post that in public and have a maintenance contract you can also contact Borland tech support. – tehlexx Nov 26 '12 at 12:07
  • Unfortunately we don't have a maintenance contract. [Here is the log file](https://gist.github.com/4148836). – Tom Nov 26 '12 at 15:41

1 Answers1

1

From the log file you posted, I can see that you are switching between testing eclipse.exe and iexplore.exe. The way your script is currently built it is either one or the other. This means that as soon as you switch to Internet Explorer, Silk Test is detaching from Eclipse and will no longer recognize the window.

Since you are starting your applications through other mechanisms anyway, I suggest the attach method, which is cumulative and will add the pattern instead of replacing it, so you'll avoid switching between the applications.

Desktop desktop = new Desktop();
desktop.attach("*\\eclipse.exe", TechDomain.SWT, TechDomain.XBROWSER, TechDomain.WIN32);
desktop.attach("*\\iexplore.exe", TechDomain.SWT, TechDomain.XBROWSER, TechDomain.WIN32);
Shell eclipse = desktop.find("/Shell[@caption='Java EE*']");
BrowserApplication browserApp = desktop.find("/BrowserApplication");
tehlexx
  • 2,821
  • 16
  • 29
  • I'm running into a similar issue with this code. It can find the Shell the first time around, but can't any successive attempt. Using my old code, [here is the log for the first, successful attempt](https://gist.github.com/4154271). And [here is the log for the second, unsuccessful attempt](https://gist.github.com/4154290). It works fine the first time, regardless of the fact that I set an `iexplore.exe` base state first, then switch to a `eclipse.exe` base state. – Tom Nov 27 '12 at 13:49
  • From that set of log files it looks like Silk Test thinks that your Eclipse is hanging. It seems that when it wants to detach from Eclipse because of the IE-only-config it is unable to do so. This could either be because Eclipse's GUI thread is somehow blocked, or a bug in Silk Test. What you could try now is either always have both IE and Eclipse in the attach-config, or maybe try to load a more recent version of Silk Test (yours is ancient! ;-) as a trial and see if it works with that. – tehlexx Nov 27 '12 at 14:28
  • I may just suck it up and move on. It would've been nice to be able to do, but it isn't a necessity. Unfortunately, I am bogged down by policies that prevent me from being able to download the latest version of Silk Test (or to download near anything, for that matter). I truly appreciate all of your help! – Tom Nov 27 '12 at 14:40
  • You could still do the other thing of always having both applications attached. – tehlexx Nov 28 '12 at 07:05
  • Attach them, and then set the base states as I normally would? – Tom Nov 28 '12 at 16:02
  • No, just attach them. Since you're starting your applications manually anyways, the way you used the base state can be replaced by using `attach` and `find`. – tehlexx Nov 28 '12 at 16:30