Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input from test.json does not pass a simple string to java method correctly #126

Open
mklaehn opened this issue Feb 28, 2018 · 3 comments
Open

Comments

@mklaehn
Copy link

mklaehn commented Feb 28, 2018

Considering the following function class

public class PojoFunction {
    public Object greet(String name) {
        if (name == null || name.isEmpty()) {
            name = "World";
        }
        return new Greeting(name);
    }
    public static class Greeting {
        public final String name;
        public Greeting(String name) {
            this.name = name;
        }
    }
}

and this content for test.json

{
    "tests": [
        {
            "input": {"body": "Johnny"},
            "output": {"body": {"name": "Johnny"}}
        }
    ]
}

causes a test failure.

Test fails due to the String value in the greet function being of the value "Johnny" instead of value Johnny.

Console output:

FAILED           mismatched output found.
                 expected:
                 {"name":"Johnny"}
                 got:
                 HTTP/1.1 200 INVOKED
                 Content-Type: application/json
                 Content-length: 21
                 
                 {"name":"\"Johnny\""}
@zootalures
Copy link
Member

Thanks for raising. This is intended behaviour (see explanation below)

Looking a bit deeper the verbatim frame being sent to the container is :

                 POST hello
		 Content-Length: 8
		 Content-Type:  application/json
....

		 "Johnny"

The CLI is sending a raw json doc of "Johnny" which the FDK is trying to coerce to a string.

The FDK coerces inputs to paramers based on a set of (configurable) coercion rules based on the type of the parameter and (e.g.) the content type of the input.

When the content type is application/json and the param type is a String, the FDK has a choice of either giving you the raw JSON doc ("Johnny") or to assume that the doc is only a JSON string (and not an object or number or array) and to unmarshal it , giving you the JSON value Johnny

We chose the former (Strings and byte array parameter types are assumed to be copies of the body of the request) as it creates more intuitive behaviour when the doc is an object (which would otherwise cause JSON error).

You can override this behaviour (always prefer JSON unmarshalling):

Import the FDK runtime as a maven runtime dep.

  <dependency>
            <groupId>com.fnproject.fn</groupId>
            <artifactId>runtime</artifactId>
            <version>${fnproject.version}</version>
        </dependency>

In your function add an @InputBinding annotation to the input parameter that forces the JacksonCoercion (this will then skip string coercion)

  import com.fnproject.fn.runtime.coercion.jackson.JacksonCoercion; 
  import com.fnproject.fn.api.InputBinding; 

  public Object greet(@InputBinding(JacksonCoercion.class) String name) {

Hope that helps

@mklaehn
Copy link
Author

mklaehn commented Mar 1, 2018

Ok. It helped as far a the generated JSON to look the same as the JSON declared as the body in the test. What it does not help is in succeeding the test.

The full output, I've cut it to size previously due to the "obvious" discrepancy in the expected JSON body output.

Test 1
In gomega FailHandler: Actual 'HTTP/1.1 200 INVOKED
Content-Type: application/json
Content-length: 17

{"name":"Johnny"}' should be valid JSON, but it is not.
Underlying error:invalid character 'H' looking for beginning of value
FAILED           mismatched output found.
                 expected:
                 {"name":"Johnny"}
                 got:
                 HTTP/1.1 200 INVOKED
                 Content-Type: application/json
                 Content-length: 17
                 
                 {"name":"Johnny"}
                 logs:
                 
 -    ( 1.352177808s )

To me it looks like that the evaluation of the response does not extract the response body correctly in order to check against the expected body (as declared in file test.json).

@zootalures
Copy link
Member

yeah this looks like an issue with the cli - fnproject/cli#184

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants