You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Jeremy Boynes <jb...@apache.org> on 2006/08/15 17:28:22 UTC
Debugging the runtime, was: IDE Plugins
On Aug 15, 2006, at 6:39 AM, Meeraj Kunnumpurath wrote:
>>> Rather hack the code you can just set the "tuscany.installDir"
>>> system
> property
> Thanks Jeremy, I did see the usage of tuscany.installDir. My question
> was in the absence of the system property, does the runtime always
> need
> to resolve the extensions directory relative to the directory from
> which
> the launcher jar was loaded. Can it do the same if the
> MainLauncherBooter was loaded from an exploded directory rather than a
> Jar?
The "tuscany.installDir" property was designed to support debug of a
user's application code. A user typically does not have the source
for Tuscany in their IDE or have all the individual jars on their
classpath - they have a project with their code and have Tuscany
installed somewhere. It's like if I have a web application - I don't
have the source for Tomcat or WebSphere available and I don't import
individual jars into a project.
What we're trying to do is extend that environment so that the
"user" (us) has all of the guts of the runtime exposed so that they
can debug part of it e.g. step through the core or debug an
extension. If we just add them to the classpath (e.g. as dependencies
in Maven or as libraries in an IDE) we distort things even further:
1) there's no installation to speak of - just a bunch of jars on the
classpath. Components that rely on having an installation directory
structure (such as the DSE) won't work. The property is a way around
that but does not really solve the problem, because ...
2) the launcher isolates the application from the runtime by loading
the runtime in a separate classloader. The jars for that classloader
are found by scanning a directory in the installation directory (or
specified by the property "tuscany.bootDir"). By placing these jars
in the system classloader the isolation is broken. This is great for
us debugging the runtime except for the subtle (or not so subtle)
classloader problems it may cause - it's different, which means that
code will not debug the same.
This is not a problem unique to Tuscany and is one that has been
solved before. The one of those solutions we have chosen leverages on
the capabilities of the IoC architecture we used for the runtime and
for the SCA programming model in general. That solution is to have
components clearly define the things that they are dependent on (the
IoC contract) and then have a test framework set up those
dependencies in order to exercise the component. Those dependencies
need to be fairly granular - e.g. at the level of a simple interface
not "the entire runtime"
If you do that you can partition your testing into two phases:
1) component testing, where some test harness sets up the
dependencies for a component and then exercises the component in
those contexts.
2) integration testing, where you already know from 1) how the
component will behave, so you focus on making sure that the things
that use your component set up the contexts it expects
The SCA programming model expects and supports users who write and
test applications in this way. The spec has gone to a lot of effort
to allow users to test their components without needing a running SCA
environment. The use of an IoC architecture in the Java C&I model is
specifically designed to enable that.
If I am implementing a component, the C&I model explicitly calls out
the IoC contract - it clearly defines the Services, References and
Properties that a component has. That is the context for component
testing that can be set by a test harness. If my component is
implemented in Java, that test harness can be something as simple as
JUnit with EasyMock for the references.
Once you've tested your components, then they can be assembled into
composites for integration testing. That is where you would ensure
the bindings and policies set up are appropriate for the way in which
you want to use the component.
We have chosen to use SCA to assemble the runtime and this means
these same techniques can be used to debug runtime components as
well. Extension components can be tested on their own with
dependencies resolved by a test harness such as JUnit with EasyMock.
You should be able to test all the codepaths in an extension this way
- all it takes is writing some test cases. This is easily debuggable
in an IDE, just like a user's application code would be.
Once you know the component works as expected, your extension can
then be integration tested with a real live runtime. This will
involve deploying application components that use it, either as
implementations (for a container extension), or to talk to other
applications (for a binding). This may involve deploying to another
runtime e.g. to a web container so that inbound HTTP requests can be
tested. There will be a lot of moving parts, but that is in the
nature of integration tests.
Putting it simply, the more testing you do at the component level the
easier integration testing will be. We have extensions out there with
few if any component level tests. This means all testing (if any) and
debugging is done at the integration level which means there are lot
of moving parts to set up and get right even before starting to test
your component.
Putting it another way, people writing extensions should write unit
tests for their components - it's easier for them and easier for others.
--
Jeremy
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org