You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@nifi.apache.org by Russell Bateman <ru...@windofkeltia.com> on 2017/05/23 21:20:53 UTC

TestRunner question

I wondered if it were possible to split the firing of 
MyProcessor.init()out of TestRunner.run()so that I have finer 
granularity in testing? Maybe I'm abusing init()by what I'm doing in it, 
but I'd like to see that run and give control back to my test case for 
some assertions and other things, before moving on. In fact, it would be 
nice to have granularity for @OnScheduledmethods that way, maybe others too.

    TestRunner runner = TestRunners( new MyProcessor() );
    runner.setProperty(), etc.
    runner.enqueue(), etc.
    *runner.init(), etc.**
    **runner.onScheduled(), etc.*
    runner.run( 1 );

Did I miss a turn somewhere and this is already supported? I've pored 
through the test framework Javadoc and missed it?

Russ


Re: TestRunner question

Posted by Russell Bateman <ru...@windofkeltia.com>.
Thanks, Matt. This is very useful detail and it makes perfect sense that 
it would be that way. It has not been my experience that

     TestRunner runner = TestRunners( new MyProcessor() );

called init()because something I do in there isn't there yet when I look 
at it, but it could be faulty observation on my part or I'm doing 
something else misleading.

I'll look at this more carefully. I'm trying to validate some state 
that's created by init()then do some Mockito work afterward to inject a 
mock removing a "connected wire" deeper down underneathonTrigger(). This 
is a bit awkward. Anyway, thanks for this detail--I'll take note of what 
you've said and put it to good use.

Best,

Russ

On 05/24/2017 08:09 AM, Matt Burgess wrote:
> Russ,
>
> Your init() method should be getting called when you create the
> TestRunner using your processor instance. It calls
> Processor.initialize() and AbstractSessionFactoryProcessor's
> implementation calls its own protected init() method (which is what
> I'm assuming you've overridden). It also calls any methods that were
> annotated as @OnAdded and @OnConfigurationRestored.  These could be
> split out if necessary, or organized such as TestRunner's methods are.
> TestRunner has some overloaded methods for run, the "base" one is:
>
> public void run(final int iterations, final boolean stopOnFinish,
> final boolean initialize, final long runWait)
>
> If you call run() with no parameters, you'll get 1 iteration that
> "initializes" and stops on finish (with a 5 second run-wait). However
> specifying "initialize" as true just invokes any methods with an
> @OnScheduled annotation.
>
> For your use case, if you keep a reference to your instance of
> MyProcessor, you can call your @OnScheduled method explicitly (not via
> TestRunner), then perform your assertions, etc.  Then if you want to
> run onTrigger() but you don't want to reinitialize, you can do:
>
> runner.run(1, true, false)
>
> which says to run once, stop on finish, and don't initialize.
>
> There are a couple examples of manipulating the run() methods in
> CaptureChangeMySQLTest [1]. If you'd like to see the initialize() and
> other stuff split out from the TestRunner instantiation, please feel
> free to file a Jira for the improvement.
>
> Regards,
> Matt
>
> [1] https://github.com/apache/nifi/blob/master/nifi-nar-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/groovy/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQLTest.groovy
>
> On Tue, May 23, 2017 at 5:20 PM, Russell Bateman <ru...@windofkeltia.com> wrote:
>> I wondered if it were possible to split the firing of MyProcessor.init()out
>> of TestRunner.run()so that I have finer granularity in testing? Maybe I'm
>> abusing init()by what I'm doing in it, but I'd like to see that run and give
>> control back to my test case for some assertions and other things, before
>> moving on. In fact, it would be nice to have granularity for
>> @OnScheduledmethods that way, maybe others too.
>>
>>     TestRunner runner = TestRunners( new MyProcessor() );
>>     runner.setProperty(), etc.
>>     runner.enqueue(), etc.
>>     *runner.init(), etc.**
>>     **runner.onScheduled(), etc.*
>>     runner.run( 1 );
>>
>> Did I miss a turn somewhere and this is already supported? I've pored
>> through the test framework Javadoc and missed it?
>>
>> Russ
>>


Re: TestRunner question

Posted by Matt Burgess <ma...@apache.org>.
Russ,

Your init() method should be getting called when you create the
TestRunner using your processor instance. It calls
Processor.initialize() and AbstractSessionFactoryProcessor's
implementation calls its own protected init() method (which is what
I'm assuming you've overridden). It also calls any methods that were
annotated as @OnAdded and @OnConfigurationRestored.  These could be
split out if necessary, or organized such as TestRunner's methods are.
TestRunner has some overloaded methods for run, the "base" one is:

public void run(final int iterations, final boolean stopOnFinish,
final boolean initialize, final long runWait)

If you call run() with no parameters, you'll get 1 iteration that
"initializes" and stops on finish (with a 5 second run-wait). However
specifying "initialize" as true just invokes any methods with an
@OnScheduled annotation.

For your use case, if you keep a reference to your instance of
MyProcessor, you can call your @OnScheduled method explicitly (not via
TestRunner), then perform your assertions, etc.  Then if you want to
run onTrigger() but you don't want to reinitialize, you can do:

runner.run(1, true, false)

which says to run once, stop on finish, and don't initialize.

There are a couple examples of manipulating the run() methods in
CaptureChangeMySQLTest [1]. If you'd like to see the initialize() and
other stuff split out from the TestRunner instantiation, please feel
free to file a Jira for the improvement.

Regards,
Matt

[1] https://github.com/apache/nifi/blob/master/nifi-nar-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/groovy/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQLTest.groovy

On Tue, May 23, 2017 at 5:20 PM, Russell Bateman <ru...@windofkeltia.com> wrote:
> I wondered if it were possible to split the firing of MyProcessor.init()out
> of TestRunner.run()so that I have finer granularity in testing? Maybe I'm
> abusing init()by what I'm doing in it, but I'd like to see that run and give
> control back to my test case for some assertions and other things, before
> moving on. In fact, it would be nice to have granularity for
> @OnScheduledmethods that way, maybe others too.
>
>    TestRunner runner = TestRunners( new MyProcessor() );
>    runner.setProperty(), etc.
>    runner.enqueue(), etc.
>    *runner.init(), etc.**
>    **runner.onScheduled(), etc.*
>    runner.run( 1 );
>
> Did I miss a turn somewhere and this is already supported? I've pored
> through the test framework Javadoc and missed it?
>
> Russ
>