How Can I Verify varargs To RPC Calls Before Runtime? - java

I can make an RPC call in Java like this:
final FlowHandle flowHandle = rpcOps.startFlowDynamic(
TransferObligation.Initiator.class,
linearId, newLender, true);
The first parameter is the class to invoke and the next three are arguments to the class passed via varargs.
As we can see by the class definition the args match and the call works fine:
public Initiator(UniqueIdentifier linearId, Party newLender, Boolean anonymous) {
this.linearId = linearId;
this.newLender = newLender;
this.anonymous = anonymous;
}
However, if I add or remove args from the constructor the code will still compile and I will only notice at runtime (or integration testing - assuming I have enough test coverage).
The same applies if I pass the wrong args in the first place in the RPC call.
e.g. the following compiles fine but gives a runtime error:
final FlowHandle flowHandle = rpcOps.startFlowDynamic(
TransferObligation.Initiator.class,
linearId, newLender, true, 100000L, "Random String");
Is it possible to check for these errors with something other than test cases?
e.g. Static analysis using a custom IDEA code inspection or a custom SonarQube rule
EDIT: It appears that the Kotlin API has a type safe way of starting the flows (using inline reified extension functions) that the Java API does not, so I have removed the kotlin tag and updated the references to Java examples.

Along with CordaRPCOps.startFlowDynamic which as you mentioned has a varargs parameter for the Flow constructor arguments, there is CordaRPCOps.startFlow methods, which is basically nothing more than extension function for type-safe invocation of flows.
CordaRPSOps.kt

Related

JMeter setTestLogicalAction from JMeterContext gives "Cannot reach instance method"

JMeter 5.1. The following link gives a working code Restarting a user thread conditionally in JMeter where setTestLogicalAction is called from SampleResult. the method is indeed listed in methods in https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html.
However, it's also listed in https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html but using org.apache.jmeter.threads.JMeterContext.setTestLogicalAction gives
ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: `` import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter . . . '' : Cannot reach instance method: setTestLogicalAction( org.apache.jmeter.threads.JMeterContext$TestLogicalAction ) from static context: org.apache.jmeter.threads.JMeterContext
Why can't I use setTestLogicalAction from JMeterContext? What do I miss about classes in java?
Also, the code from above mentioned post works in beanshell, but neither that nor modified as above code works in JSR223+Groovy. After taking notice that methods are not static, code is as below (both paths were tried, finally I list them together) in groovy, no errors, but thread continues, not restarted...
jmco = new org.apache.jmeter.threads.JMeterContext();
jmsr = new org.apache.jmeter.samplers.SampleResult();
jmco.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
jmsr.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
Can I use setTestLogicalAction in groovy script?
P.S. interesting how beanshell can call non-static method w/o instantiation ...
ADDED 2019/04/01:
def mycontext = org.apache.jmeter.threads.JMeterContextService.getContext()
mycontext.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
the code was changed to the above after suggestion in Dmitri answer, but the code does not restart the thread.
If you're not that good at programming go for Flow Control Action sampler instead of trying to replicate its functionality in code, in any case it will be faster.
There is no need to instantiate neither JMeterContext nor SampleResult as they're pre-defined in JSR223 Test Elements, moreover you're doing this wrong, i.e. correct way of accessing JMeterContext is calling JMeterContextService.getContext() function
Since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting so I would recommend forgetting about Beanshell.
prev.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_CURRENT_LOOP)
worked for me (from a Groovy based post processor).

JUnit - How to unit test method that reads files in a directory and uses external libraries

I have this method that I am using in a NetBeans plugin:
public static SourceCodeFile getCurrentlyOpenedFile() {
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
/* Get Java file currently displaying in the IDE if there is an opened project */
if (openedProject != null) {
TopComponent activeTC = TopComponent.getRegistry().getActivated();
DataObject dataLookup = activeTC.getLookup().lookup(DataObject.class);
File file = FileUtil.toFile(dataLookup.getPrimaryFile()); // Currently opened file
// Check if the opened file is a Java file
if (FilenameUtils.getExtension(file.getAbsoluteFile().getAbsolutePath()).equalsIgnoreCase("java")) {
return new SourceCodeFile(file);
} else {
return null;
}
} else {
return null;
}
}
Basically, using NetBeans API, it detects the file currently opened by the user in the IDE. Then, it loads it and creates a SourceCodeFile object out of it.
Now I want to unit test this method using JUnit. The problem is that I don't know how to test it.
Since it doesn't receive any argument as parameter, I can't test how it behaves given wrong arguments. I also thought about trying to manipulate openedProject in order to test the method behaviour given some different values to that object, but as far as I'm concernet, I can't manipulate a variable in JUnit that way. I also cannot check what the method returns, because the unit test will always return null, since it doesn't detect any opened file in NetBeans.
So, my question is: how can I approach the unit testing of this method?
Well, your method does take parameters, "between the lines":
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
basically fetches the object to work on.
So the first step would be to change that method signature, to:
public static SourceCodeFile getCurrentlyOpenedFile(Project project) {
...
Of course, that object isn't used, except for that null check. So the next level would be to have a distinct method like
SourceCodeFile lookup(DataObject dataLookup) {
In other words: your real problem is that you wrote hard-to-test code. The "default" answer is: you have to change your production code, to make easier to test.
For example by ripping it apart, and putting all the different aspects into smaller helper methods.
You see, that last method lookup(), that one takes a parameter, and now it becomes (somehow) possible to think up test cases for this. Probably you will have to use a mocking framework such as Mockito to pass mocked instances of that DataObject class within your test code.
Long story short: there are no detours here. You can't test your code (in reasonable ways) as it is currently structured. Re-structure your production code, then all your ideas about "when I pass X, then Y should happen" can work out.
Disclaimer: yes, theoretically, you could test the above code, by heavily relying on frameworks like PowerMock(ito) or JMockit. These frameworks allow you to contol (mock) calls to static methods, or to new(). So they would give you full control over everything in your method. But that would basically force your tests to know everything that is going on in the method under test. Which is a really bad thing.

Eclipse Groovy DSLDs and static compilation

Is it possible to define Eclipse Groovy DSLD (DSL Definition) which can be statically compilable?
I tried to use DSLD example provided by Eclipse, so I created TestDsl.dsld:
contribute(currentType(subType('groovy.lang.GroovyObject'))) {
property (
name : 'newProp',
type : String,
provider : 'Sample DSL',
doc : 'This is a sample. You should see this in content assist for GroovyObjects: <pre>newProp</pre>')
}
Then I wrote a test class using previous property. This class should be compiled statically. Eclipse is showing new property as a valid one, but then it fails to compile.
Same result occurs using both #CompileStatic and #TypeChecked.
DSLDs introduce new methods and properties into content assist and type inferencing. This does not guarantee the methods or properties will be available at compile- or run-time. They operate more like hints than anything.
Quite often, DSLDs are used to fill a gap that exists between the static type checker and the dynamic execution state of your program. If you want something that is compatible with #TypeChecked or #CompileStatic, you may need to write a TypeChekingExtension instead of a DSLD contribution.

How to test a method that takes Class<T>

am working on a Jenkins plugin and evaluating unit testing software at the same time, and came upon a learning opportunity. The software wrote a test case for this method-
public boolean isApplicable(Class<? extends AbstractProject> aClass) {
// indicates that this builder can be used with all
// kinds of project types
return true;
}
Seems pretty straightforward. The test case doesn't compile though, and I have not been able to figure out how to fix it from my limited knowledge of using wildcards. My current attempt-
AbstractProject ap = new FreeStyleProject(null, null);;
Assert.assertTrue(testedObject.isApplicable(ap));
(FreeStyleProject extends AbstractProject)
This gives the error message
The method isApplicable(Class) in the type FitnesseBuilder.DescriptorImpl is not applicable for the arguments (AbstractProject)
I have tried a variety of types to pass to that argument, but cannot seem to get it to accept anything. Anyone feel like giving me a quick lesson?
You need to pass the Class<T> object, not an instance of that class:
// AbstractProject ap = new FreeStyleProject(null, null);
Assert.assertTrue(testedObject.isApplicable(FreeStyleProject.class));
Of course, FreeStyleProject class needs to extend AbstractProject (since the first line of your current code compiles, it does that already).
Try Assert.assertTrue(testedObject.isApplicable(FreeStyleProject.class)); as it takes an instance of Class rather than AbstractProject

How can I convince GroovyShell to maintain state over eval() calls?

I'm trying to use Groovy to create an interactive scripting / macro mode for my application. The application is OSGi and much of the information the scripts may need is not know up front. I figured I could use GroovyShell and call eval() multiple times continually appending to the namespace as OSGi bundles are loaded. GroovyShell maintains variable state over multiple eval calls, but not class definitions or methods.
goal: Create a base class during startup. As OSGi bundles load, create derived classes as needed.
I am not sure about what you mean about declared classes not existing between evals, the following two scripts work as expected when evaled one after another:
class C {{println 'hi'}}
new C()
...
new C()
However methods become bound to the class that declared them, and GroovyShell creates a new class for each instance. If you do not need the return value of any of the scripts and they are truly scripts (not classes with main methods) you can attach the following to the end of every evaluated scrips.
Class klass = this.getClass()
this.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
binding[it.name] = this.&"$it.name"
}
}
If you depend on the return value you can hand-manage the evaluation and run the script as part of your parsing (warning, untested code follows, for illustrative uses only)...
String scriptText = ...
Script script = shell.parse(scriptText)
def returnValue = script.run()
Class klass = script.getClass()
script.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
shell.context[it.name] = this.&"$it.name"
}
}
// do whatever with returnValue...
There is one last caveat I am sure you are aware of. Statically typed variables are not kept between evals as they are not stored in the binding. So in the previous script the variable 'klass' will not be kept between script invocations and will disappear. To rectify that simply remove the type declarations on the first use of all variables, that means they will be read and written to the binding.
Ended up injecting code before each script compilation. End goal is that the user written script has a domain-specific-language available for use.
This might be what you are looking for?
From Groovy in Action
def binding = new Binding(x: 6, y: 4)
def shell = new GroovyShell(binding)
def expression = '''f = x * y'''
shell.evaluate(expression)
assert binding.getVariable("f") == 24
An appropriate use of Binding will allow you to maintain state?

Categories

Resources