You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-user@jakarta.apache.org by Volker Krebs <vo...@abas.de> on 2004/06/16 16:11:36 UTC

ServletTestRunner and multiple Web Applications

Hello,

in our environment we are running diffrent tests as diffrent Web 
Applications in Tomcat (4.1.29). This means that we deploy a web 
application (e.g. test1) run some test and undeploy test1. Then test2 
gets deployed some tests are run and it gets undeployed. Same with 
test3, test4 and so on.

In cactus 1.5 this seemed to be no problem but since we have updated to 
version 1.6.1 only application test1 can be tested succesfully. The 
application test2 tries to get test1/ServletRedirector which is already 
undeployed.

I've looked at the source and found the reason for that.
In 
org.apache.cactus.server.runner.ServletTestRunner.setSystemProperties(HttpServletRequest) 
thr property BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY (contextURL) 
is read from the Systemproperties. For test1 there is no such 
systemproperty so it will be created from the request. But when test2 is 
run it reads the systemproperties and finds the property which was set 
in test1 (contextpath test1), which leads to an error.

I think it would be nice to make the property "cactus.contextURL" 
optional like in Version 1.5. For example by removing the systemproperty 
"cactus.contextURL" when ServletTestRunner is undeployed.

thanks,

Volker

RE: ServletTestRunner and multiple Web Applications

Posted by Vincent Massol <vm...@pivolis.com>.

> -----Original Message-----
> From: Kazuhito SUGURI [mailto:suguri.kazuhito@lab.ntt.co.jp]
> Sent: 20 June 2004 16:44
> To: cactus-user@jakarta.apache.org
> Subject: Re: ServletTestRunner and multiple Web Applications
> 
> Hi Vincent,
> 
> In article <01...@vma>,
> Sun, 20 Jun 2004 15:07:26 +0200,
> "Vincent Massol" <vm...@pivolis.com> wrote:
> vmassol> >         String contextURL = System.getProperty(
> vmassol> >             BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);
> vmassol> >
> vmassol> >         if (contextURL == null)
> vmassol> > 	{
> vmassol> >                     System.setProperty(
> vmassol> >
> BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
> vmassol> >                         "http://" +
theRequest.getServerName()
> + ":"
> vmassol> >                         + theRequest.getServerPort()
> vmassol> >                         + theRequest.getContextPath());
> vmassol> >         }
> [snip]
> vmassol> I don't think so as calling System.setProperty() overwrites
the
> previous
> vmassol> value.
> 
> What current code doing is
>       if System.getProperty() retruns null, then System.setProperty()
> So, non-null previous value will not be changed.
> Am I missing something?

It's probably me missing something... ;-)

> 
> 
> vmassol> I think that we could change the current behavior but before
> doing so we
> vmassol> must decide whether we want to accept Mark's use case as a
valid
> Cactus
> vmassol> use case. ATM, this is not the case and Cactus is not meant
to
> support
> vmassol> this. And before we take this call, I'd like more information
> from Mark.
> vmassol> Hence the questions I've asked in my answer.
> 
> Yes, we need feedbacks from Mark and other users.
> 

Thanks
-Vincent


Re: ServletTestRunner and multiple Web Applications

Posted by Kazuhito SUGURI <su...@lab.ntt.co.jp>.
Hi Vincent,

In article <01...@vma>,
Sun, 20 Jun 2004 15:07:26 +0200,
"Vincent Massol" <vm...@pivolis.com> wrote: 
vmassol> >         String contextURL = System.getProperty(
vmassol> >             BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);
vmassol> > 
vmassol> >         if (contextURL == null)
vmassol> > 	{
vmassol> >                     System.setProperty(
vmassol> >                         BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
vmassol> >                         "http://" + theRequest.getServerName() + ":"
vmassol> >                         + theRequest.getServerPort()
vmassol> >                         + theRequest.getContextPath());
vmassol> >         }
[snip]
vmassol> I don't think so as calling System.setProperty() overwrites the previous
vmassol> value.

What current code doing is
      if System.getProperty() retruns null, then System.setProperty()
So, non-null previous value will not be changed.
Am I missing something?


vmassol> I think that we could change the current behavior but before doing so we
vmassol> must decide whether we want to accept Mark's use case as a valid Cactus
vmassol> use case. ATM, this is not the case and Cactus is not meant to support
vmassol> this. And before we take this call, I'd like more information from Mark.
vmassol> Hence the questions I've asked in my answer.

Yes, we need feedbacks from Mark and other users.

Regards,
----
Kazuhito SUGURI
mailto:suguri.kazuhito@lab.ntt.co.jp

RE: ServletTestRunner and multiple Web Applications

Posted by Vincent Massol <vm...@pivolis.com>.

> -----Original Message-----
> From: Kazuhito SUGURI [mailto:suguri.kazuhito@lab.ntt.co.jp]
> Sent: 19 June 2004 19:52
> To: cactus-user@jakarta.apache.org
> Subject: Re: ServletTestRunner and multiple Web Applications
> 
> Hi Vincent,
> 
> In article <05...@vma>,
> Sat, 19 Jun 2004 15:46:16 +0200,
> "Vincent Massol" <vm...@pivolis.com> wrote:
> vmassol> This means that it was pure luck that Cactus was working for
you
> vmassol> before... ;-)
> 
> indeed...
> 
> 
> vmassol> Also, the call to setSystemProperties() happen in the doGet()
> method,
> vmassol> i.e. for each call to the Servlet Test Runner. Thus, if the
> contextURL
> vmassol> property changes, it should work fine, no? It means that you
> would need
> vmassol> to change this property between your 2 webapp tests, which
seems
> normal
> vmassol> to me. What am I missing?
> 
> The following is extracted from
ServeltTestRunner#setSystemProperties()
> of Cactus-1.6.1:
>         String contextURL = System.getProperty(
>             BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);
> 
>         if (contextURL == null)
> 	{
>                     System.setProperty(
>                         BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
>                         "http://" + theRequest.getServerName() + ":"
>                         + theRequest.getServerPort()
>                         + theRequest.getContextPath());
>         }
> The lifetime of the System object may be the point.
> I think, but not sure, once the contextURL property is set
> for the first test, the same property value may be used for other
tests
> if the server is not re-started.

I don't think so as calling System.setProperty() overwrites the previous
value.

> 
> 
> One more thing. One may try to set the contextURL System property
> for each app by using WEB-INF/classes/cactus.properties.
> However, ConfigurationInitializer#initialize() will not update
> the System property if it already exists.

Yes, that's more likely the problem here.

> So, I think, once a ServletTestRunner of app1 set the cntextURL
property,
> no other apps can change that.
> 
> 
> A way to solve this is to change
ServeltTestRunner#setSystemProperties()
> method as like as follows (shows core logic only):
> 	ResourceBundle config =
PropertyResourceBundle.getBundle("cactus");
> 	String contextURL =
> config.getString(BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);
> 	if (contextURL == null)
> 	{
> 	    contextURL = "http://" + theRequest.getServerName() + ":"
> 	                + theRequest.getServerPort()
> 	                + theRequest.getContextPath();
> 
> 	}
>
System.setProperty(BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
> 	                   contextURL);
> 
> What do you think?

I think that we could change the current behavior but before doing so we
must decide whether we want to accept Mark's use case as a valid Cactus
use case. ATM, this is not the case and Cactus is not meant to support
this. And before we take this call, I'd like more information from Mark.
Hence the questions I've asked in my answer.

Also, the code you mention will only solve the problem for the Servlet
Test Runner but NOT for the other integrations (Ant, Maven, etc). 

So I'd rather:
1/ Mark use Cactus as it is meant
2/ or Mark can convince us that he has a valid use case, in which case
we need to modify Cactus in several places to support this.

Thanks
-Vincent


Re: ServletTestRunner and multiple Web Applications

Posted by Kazuhito SUGURI <su...@lab.ntt.co.jp>.
Hi Vincent,

In article <05...@vma>,
Sat, 19 Jun 2004 15:46:16 +0200,
"Vincent Massol" <vm...@pivolis.com> wrote: 
vmassol> This means that it was pure luck that Cactus was working for you
vmassol> before... ;-)

indeed...


vmassol> Also, the call to setSystemProperties() happen in the doGet() method,
vmassol> i.e. for each call to the Servlet Test Runner. Thus, if the contextURL
vmassol> property changes, it should work fine, no? It means that you would need
vmassol> to change this property between your 2 webapp tests, which seems normal
vmassol> to me. What am I missing?

The following is extracted from ServeltTestRunner#setSystemProperties()
of Cactus-1.6.1:
        String contextURL = System.getProperty(
            BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);

        if (contextURL == null)
	{
                    System.setProperty(
                        BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
                        "http://" + theRequest.getServerName() + ":"
                        + theRequest.getServerPort()
                        + theRequest.getContextPath());
        }
The lifetime of the System object may be the point.
I think, but not sure, once the contextURL property is set
for the first test, the same property value may be used for other tests
if the server is not re-started.


One more thing. One may try to set the contextURL System property
for each app by using WEB-INF/classes/cactus.properties.
However, ConfigurationInitializer#initialize() will not update
the System property if it already exists.
So, I think, once a ServletTestRunner of app1 set the cntextURL property,
no other apps can change that.


A way to solve this is to change ServeltTestRunner#setSystemProperties()
method as like as follows (shows core logic only): 
	ResourceBundle config = PropertyResourceBundle.getBundle("cactus");
	String contextURL = config.getString(BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);
	if (contextURL == null)
	{
	    contextURL = "http://" + theRequest.getServerName() + ":"
	                + theRequest.getServerPort()
	                + theRequest.getContextPath();

	}
        System.setProperty(BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
	                   contextURL);

What do you think?
----
Kazuhito SUGURI
mailto:suguri.kazuhito@lab.ntt.co.jp

RE: ServletTestRunner and multiple Web Applications

Posted by Vincent Massol <vm...@pivolis.com>.

> -----Original Message-----
> From: Kazuhito SUGURI [mailto:suguri.kazuhito@lab.ntt.co.jp]
> Sent: dimanche 27 juin 2004 16:46
> To: cactus-user@jakarta.apache.org
> Subject: Re: ServletTestRunner and multiple Web Applications
> 
> Hi Vincent,
> 
> In article <20...@smtp-ft3.fr.colt.net>,
> Sun, 27 Jun 2004 13:11:15 +0200,
> "Vincent Massol" <vm...@pivolis.com> wrote:
> vmassol> Ok, I've committed the fix for the ServletTestRunner. I haven't
> written any
> vmassol> automated test case for it though... :-( (it's quite hard to
> do...)
> vmassol>
> vmassol> Could you let me know if it works? (I've uploaded a nightly build
> in
> vmassol> http://cvs.apache.org/builds/jakarta-cactus/nightly/2004-06-27/).
> 
> The committed change may not work for Volker.
> ConfigurationInitializer#addSystemProperties() will not change
> system property value if the one already exists.
> 
> >    private static void addSystemProperties(ResourceBundle theBundle)
> >    {
> >        Enumeration keys = theBundle.getKeys();
> >
> >        while (keys.hasMoreElements())
> >        {
> >            String key = (String) keys.nextElement();
> >            // Only set the system property if it does not already exist.
> >            // This allows to have a cactus properties file and override
> >            // some values on the command line.
> >            if (System.getProperty(key) == null)
> >            {
> >                System.setProperty(key, theBundle.getString(key));
> >            }
> >        }
> >    }

True... :-)

> 
> Can we change the logic without breaking other use cases?

I've committed a second attempt... Let me know if you think it cannot work.
I think I have preserved the existing use cases.

Thanks!
-Vincen

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.711 / Virus Database: 467 - Release Date: 25/06/2004
 


Re: ServletTestRunner and multiple Web Applications

Posted by Kazuhito SUGURI <su...@lab.ntt.co.jp>.
Hi Vincent,

In article <20...@smtp-ft3.fr.colt.net>,
Sun, 27 Jun 2004 13:11:15 +0200,
"Vincent Massol" <vm...@pivolis.com> wrote: 
vmassol> Ok, I've committed the fix for the ServletTestRunner. I haven't written any
vmassol> automated test case for it though... :-( (it's quite hard to do...) 
vmassol> 
vmassol> Could you let me know if it works? (I've uploaded a nightly build in
vmassol> http://cvs.apache.org/builds/jakarta-cactus/nightly/2004-06-27/).

The committed change may not work for Volker.
ConfigurationInitializer#addSystemProperties() will not change
system property value if the one already exists.

>    private static void addSystemProperties(ResourceBundle theBundle)
>    {
>        Enumeration keys = theBundle.getKeys();
>
>        while (keys.hasMoreElements())
>        {
>            String key = (String) keys.nextElement();
>            // Only set the system property if it does not already exist.
>            // This allows to have a cactus properties file and override
>            // some values on the command line.
>            if (System.getProperty(key) == null)
>            {
>                System.setProperty(key, theBundle.getString(key));
>            }
>        }
>    }

Can we change the logic without breaking other use cases?

Regards,
----
Kazuhito SUGURI
mailto:suguri.kazuhito@lab.ntt.co.jp

RE: ServletTestRunner and multiple Web Applications

Posted by Vincent Massol <vm...@pivolis.com>.
Hi Volker,

Ok I understand now and yes your use case is valid :-)

The problem lies in our ConfigurationInitializer class which is called from
a lot of different places. For example it's called in static blocks in
ServletTestCase, FitlerTestCase and JspTestCase classes, i.e. in each of
your Cactus test cases. The reason is that there's no hook in JUnit for
executing things once at the level of a TestCase (you have to use a Suite
for that and so far we have not forced Cactus users to use a Cactus suite to
wrap all of their test cases...). Thus the hook we created was a static
block.

Thus to prevent multiple initializations we set a static isInitialized flag
and do not reinitialize the config:

    public static synchronized void initialize()
    {
        if (!isInitialized)
        {    
            initializeConfig();
            initializeLoggingConfig();
            isInitialized = true;
        }
    }

This is what is causing you the trouble.

I guess one easy thing we could do is to reinitialize the config in the
init() method of the ServletTestRunner. That will solve it for the
ServletTestRunner because it is running in the *same* JVM as the Cactus
server-side code...

However, that will not fix it for the other front ends where it's more
tricky. We'll need to tackle it on a case by case basis...

Ok, I've committed the fix for the ServletTestRunner. I haven't written any
automated test case for it though... :-( (it's quite hard to do...) 

Could you let me know if it works? (I've uploaded a nightly build in
http://cvs.apache.org/builds/jakarta-cactus/nightly/2004-06-27/).

Thanks
-Vincent

> -----Original Message-----
> From: Volker Krebs [mailto:volker.krebs@abas.de]
> Sent: lundi 21 juin 2004 08:33
> To: Cactus Users List
> Subject: Re: ServletTestRunner and multiple Web Applications
> 
> Hello,
> 
> Vincent Massol wrote:
> > Hi Volker,
> >
> > Your use case (using the same cactus installation to test different web
> > applications) is not supported by Cactus. I'm actually surprised it
> > could work at all! :-)
> >
> > The way to run Cactus tests on a given web application is by cactifying
> > this web application. So if you have 2 web applications, you're supposed
> > to cactify 2 web applications, each installing its own cactus
> > redirectors.
> >
> > This means that it was pure luck that Cactus was working for you
> > before... ;-)
> >
> > That said, I'm curious to understand better your use case as I'm always
> > happy to improve Cactus. I have a few questions:
> >
> > - where are the cactus tests located? In test1 webapp? In test2 webapp?
> > In another webapp?
> > - in which webapp are the cactus redirectors installed?
> >
> I'm not quite sure if my use case is wrong for cactus. What I am doing
> is deploying und undeploying cactified webapplications each with its own
> cactus.jar, ServletRedirector and tests. The Tomcat gets not restarted
> between the test applications.
> 
> > Also, the call to setSystemProperties() happen in the doGet() method,
> > i.e. for each call to the Servlet Test Runner. Thus, if the contextURL
> > property changes, it should work fine, no? It means that you would need
> > to change this property between your 2 webapp tests, which seems normal
> > to me. What am I missing?
> >
> Like Kazuhito wrote, the lifetime of the system property is the point,
> it does not get deleted after an redeployment of an webapplication. So
> the new System.setProperties is never called, because we still got that
> property from the previous application.
> But you are wright, when I manualy set the property in each application
> everything works fine. But I can only do this by calling
> System.setProperties("cactus.contextURL"...) in each test application.
> If I try to use the cactus.properties it gets ignored (I think that is
> what Kazuhito also meant).
> 
> Maybe one easy way to get rid of the system property is to delete it
> when ServletTestRunner gets undeployed. Than anything should work like
> before.
> 
> thanks,
> 
> Volker
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cactus-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: cactus-user-help@jakarta.apache.org
> 
> 
> ---
> Incoming mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.711 / Virus Database: 467 - Release Date: 25/06/2004
> 

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.711 / Virus Database: 467 - Release Date: 25/06/2004
 


Re: ServletTestRunner and multiple Web Applications

Posted by Volker Krebs <vo...@abas.de>.
Hello,

Vincent Massol wrote:
> Hi Volker,
> 
> Your use case (using the same cactus installation to test different web
> applications) is not supported by Cactus. I'm actually surprised it
> could work at all! :-)
> 
> The way to run Cactus tests on a given web application is by cactifying
> this web application. So if you have 2 web applications, you're supposed
> to cactify 2 web applications, each installing its own cactus
> redirectors.
> 
> This means that it was pure luck that Cactus was working for you
> before... ;-)
> 
> That said, I'm curious to understand better your use case as I'm always
> happy to improve Cactus. I have a few questions:
> 
> - where are the cactus tests located? In test1 webapp? In test2 webapp?
> In another webapp?
> - in which webapp are the cactus redirectors installed?
> 
I'm not quite sure if my use case is wrong for cactus. What I am doing 
is deploying und undeploying cactified webapplications each with its own 
cactus.jar, ServletRedirector and tests. The Tomcat gets not restarted 
between the test applications.

> Also, the call to setSystemProperties() happen in the doGet() method,
> i.e. for each call to the Servlet Test Runner. Thus, if the contextURL
> property changes, it should work fine, no? It means that you would need
> to change this property between your 2 webapp tests, which seems normal
> to me. What am I missing?
> 
Like Kazuhito wrote, the lifetime of the system property is the point, 
it does not get deleted after an redeployment of an webapplication. So 
the new System.setProperties is never called, because we still got that 
property from the previous application.
But you are wright, when I manualy set the property in each application 
everything works fine. But I can only do this by calling 
System.setProperties("cactus.contextURL"...) in each test application. 
If I try to use the cactus.properties it gets ignored (I think that is 
what Kazuhito also meant).

Maybe one easy way to get rid of the system property is to delete it 
when ServletTestRunner gets undeployed. Than anything should work like 
before.

thanks,

Volker

RE: ServletTestRunner and multiple Web Applications

Posted by Vincent Massol <vm...@pivolis.com>.
Hi Volker,

Your use case (using the same cactus installation to test different web
applications) is not supported by Cactus. I'm actually surprised it
could work at all! :-)

The way to run Cactus tests on a given web application is by cactifying
this web application. So if you have 2 web applications, you're supposed
to cactify 2 web applications, each installing its own cactus
redirectors.

This means that it was pure luck that Cactus was working for you
before... ;-)

That said, I'm curious to understand better your use case as I'm always
happy to improve Cactus. I have a few questions:

- where are the cactus tests located? In test1 webapp? In test2 webapp?
In another webapp?
- in which webapp are the cactus redirectors installed?

Also, the call to setSystemProperties() happen in the doGet() method,
i.e. for each call to the Servlet Test Runner. Thus, if the contextURL
property changes, it should work fine, no? It means that you would need
to change this property between your 2 webapp tests, which seems normal
to me. What am I missing?

Thanks
-Vincent

> -----Original Message-----
> From: Volker Krebs [mailto:volker.krebs@abas.de]
> Sent: 16 June 2004 16:12
> To: cactus-user@jakarta.apache.org
> Subject: ServletTestRunner and multiple Web Applications
> 
> Hello,
> 
> in our environment we are running diffrent tests as diffrent Web
> Applications in Tomcat (4.1.29). This means that we deploy a web
> application (e.g. test1) run some test and undeploy test1. Then test2
> gets deployed some tests are run and it gets undeployed. Same with
> test3, test4 and so on.
> 
> In cactus 1.5 this seemed to be no problem but since we have updated
to
> version 1.6.1 only application test1 can be tested succesfully. The
> application test2 tries to get test1/ServletRedirector which is
already
> undeployed.
> 
> I've looked at the source and found the reason for that.
> In
>
org.apache.cactus.server.runner.ServletTestRunner.setSystemProperties(Ht
tp
> ServletRequest)
> thr property BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY
(contextURL)
> is read from the Systemproperties. For test1 there is no such
> systemproperty so it will be created from the request. But when test2
is
> run it reads the systemproperties and finds the property which was set
> in test1 (contextpath test1), which leads to an error.
> 
> I think it would be nice to make the property "cactus.contextURL"
> optional like in Version 1.5. For example by removing the
systemproperty
> "cactus.contextURL" when ServletTestRunner is undeployed.
> 
> thanks,
> 
> Volker
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cactus-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: cactus-user-help@jakarta.apache.org