I've created a Jira to track the elimination of PowerMock from these tests
in particular, which will probably involve doing the major refactoring
mentioned in item #4 in my previous email.

https://issues.apache.org/jira/browse/GEODE-6052

On Wed, Nov 14, 2018 at 10:57 AM Ryan McMahon <mcmellaw...@apache.org>
wrote:

> I will write up a story to address the use of PowerMock in these JMX tests
> in particular.  I remember attempting to avoid PowerMock when writing this
> test, because I agree that it should be avoided.  I just want to explain my
> thinking so that we can discuss what would have been a better approach.
>
> In this particular set of tests, I used it to mock two static methods:
> 1. InternalDistributedSystem.getConnectedInstance()
> 2. LogService.getLogger()
>
> I considered making these instance methods as part of this ticket.  When I
> started down that path, I found there are 41 calls to
> InternalDistributedSystem.getConnectedInstance(), and many of the callers
> have no reference to an instance of InternalDistributedSystem.  While I
> think this is a solvable problem, it would have vastly increased the scope
> of the work involved.  Would this ticket have been the place to do that
> work?  I am under the impression that we have some Jira tickets
> specifically related to removing statics.  Are those more aptly fit for
> that work?
>
> I agree that the LogService could have been injected in the
> MBeanJMXAdapter constructor, so that would have been a reasonable API
> change to make this testable without mocking the static LogService.
> However, I'm still interested in what people think about the
> InternalDistributedSystem case described above.
>
> There are ways I could have changed the public API of
> InternalDistributedSystem and related classes to make them testable without
> the use of PowerMock.  There are a lot of ways to do this, but they all
> boil down to adding test hooks in public API.  Is that better than using
> PowerMock?  I see the following options:
>
> 1. Don't test at this level which requires mocking statics
> 2. Use PowerMock
> 3. Add test hooks (perhaps make InternalDistributedSystem wrap a singleton
> which you can swap for a test object, but there are other ways to do this)
> 4. Do major refactoring to eliminate the statics involved
>
> I don't think that not testing at this level is a great solution.  We've
> discussed the disadvantages of PowerMock already, so the cons of #2 are
> well known.  I am not a fan of adding public API test hooks, and in this
> case I'd rather use PowerMock honestly, but that is highly subjective.  And
> #4 is the "ideal world" case, but isn't always practically possible given
> the scope of the work involved.
>
> I'm curious what other people think about this topic?
>
> Thanks,
> Ryan
>
>
>
>
>
>
> On Tue, Nov 6, 2018 at 10:40 AM Kirk Lund <kl...@apache.org> wrote:
>
>> I think we should try really hard to avoid using PowerMock. If you have
>> some code that you need to use PowerMock to make it testable, please
>> consider refactoring the code to a) avoid statics, b) pass all
>> dependencies
>> in via the constructor.
>>
>> The following was spit out by one of my unit test runs. None of the
>> logging
>> or log4j tests in my PR involve PowerMock. Also, this unit test run had no
>> FAILED tests, so this would appear to be generated by some unit test that
>> uses PowerMock and PASSED.
>>
>> > Task :geode-core:test
>> 2018-11-06 18:03:49,443 Distributed system shutdown hook ERROR Could not
>> reconfigure JMX java.lang.LinkageError: loader constraint violation:
>> loader
>> (instance of org/powermock/core/classloader/MockClassLoader) previously
>> initiated loading for a different type with name
>> "javax/management/MBeanServer"
>> at java.lang.ClassLoader.defineClass1(Native Method)
>> at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
>> at
>>
>> org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:262)
>> at
>>
>> org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:206)
>> at
>>
>> org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
>> at
>>
>> org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
>> at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
>> at
>>
>> org.apache.logging.log4j.core.jmx.Server.unregisterAllMatching(Server.java:335)
>> at
>>
>> org.apache.logging.log4j.core.jmx.Server.unregisterLoggerContext(Server.java:259)
>> at
>>
>> org.apache.logging.log4j.core.jmx.Server.reregisterMBeansAfterReconfigure(Server.java:164)
>> at
>>
>> org.apache.logging.log4j.core.jmx.Server.reregisterMBeansAfterReconfigure(Server.java:140)
>> at
>>
>> org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:558)
>> at
>>
>> org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:619)
>> at
>>
>> org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:636)
>> at
>> org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:231)
>> at
>>
>> org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:243)
>> at
>>
>> org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
>> at org.apache.logging.log4j.LogManager.getContext(LogManager.java:174)
>> at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:661)
>> at
>> org.apache.geode.internal.logging.LogService.getLogger(LogService.java:64)
>> at
>>
>> org.apache.geode.internal.tcp.ConnectionTable.<clinit>(ConnectionTable.java:61)
>> at
>>
>> org.apache.geode.distributed.DistributedSystem.setThreadsSocketPolicy(DistributedSystem.java:263)
>> at
>>
>> org.apache.geode.distributed.internal.InternalDistributedSystem.lambda$static$0(InternalDistributedSystem.java:2320)
>> at java.lang.Thread.run(Thread.java:748)
>>
>

Reply via email to