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

JSON schema to validate actor ls #326

Merged
merged 1 commit into from
Apr 26, 2018
Merged

Conversation

acruikshank
Copy link
Contributor

@acruikshank acruikshank commented Apr 23, 2018

Addresses https://app.zenhub.com/workspace/o/filecoin-project/go-filecoin/issues/241.

This PR adds a JSON schema file to the project and a test that validates entries returned by the actor/ls command coming back from the server are valid.

Notes

This PR adds gojsonschema as a testing dependency. We also update go-ipfs-cmds to the head of the feat/filecoin branch to address an unmarshalling bug.

@acruikshank acruikshank changed the title JSON schema to validate actor ls [WIP] JSON schema to validate actor ls Apr 23, 2018
@acruikshank acruikshank changed the title [WIP] JSON schema to validate actor ls JSON schema to validate actor ls Apr 23, 2018
Copy link
Contributor

@phritz phritz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whyrusleeping is your primary stakeholder here i believe.

@@ -50,6 +50,7 @@ func deps() {
"go get -u github.com/alecthomas/gometalinter",
"gometalinter --install",
"go get -u github.com/stretchr/testify",
"go get -u github.com/xeipuuv/gojsonschema",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason we don't want to gx this dependency?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phritz What is the process by which we gx a GitHub-hosted project that PL didn't author?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import follows the pattern we've used for the github.com/stretchr/testify. I went part way down the path of gxing this dependency, but it felt kind of wrong for code used only for testing. The package doesn't have a .gx version in github so it will be challenging to maintain it. I'd be happy to add it to package.json, but I'd like some guidance that it's actually appropriate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no that's the explanation i was looking for

@@ -32,6 +32,12 @@ var actorLsCmd = &cmds.Command{
Type: &actorView{},
Encoders: cmds.EncoderMap{
cmds.JSON: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, a *actorView) error {
// go-ipfs-cmds decodes each json obj from the daemon into the same struct.
// This sometimes causes actors to show fields from actors we've already emitted.
// This is a work-around pending a fix in the go-ipfs-cmds codebase.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most useful if you can include a link that way people don't have to go searching for the issue/fix


assert.True(result.Valid())
for _, desc := range result.Errors() {
fmt.Printf("- %s\n", desc)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it maybe better to use assert.Fail or similar instead of printfing here and elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

Copy link
Contributor

@laser laser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, lookin' good. You put a lot of work into those schemas - and nice bug catch.

My request: I think you should run the actor ls command and assert that its output conforms to some schema instead of what you're doing now, which is to skip the command-running stuff and encode a single actorView to JSON. If using a JSON schema file to validate NDJSON isn't possible, then I suggest capturing the output of a command, splitting its output on newlines and running those newline-delimited JSON objects through your JSON schema-validator.

"github.com/stretchr/testify/require"
"github.com/xeipuuv/gojsonschema"
"gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
"gx/ipfs/QmdtiofXbibTe6Day9ii5zjBZpSRm8vhfoerrNuY3sAQ7e/go-hamt-ipld"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's likely that nobody told you this, but we have a convention for organizing dependencies in Golang source code.

return gojsonschema.Validate(schemaLoader, jsonLoader)
}

t.Run("Emitted AccountActor JSON conforms to schema", func(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you're testing that the JSON that we create from an actorView conforms to our JSON schema - but I don't see that you're testing that this is the JSON that we emit from any command.

This distinction is important: The intent of the original story was to ensure that the JSON that we returned from a command conformed to some schema. We created that story because of a bug I introduced to the dag get command's implementation which broke the Filecoin Explorer but did not change the way that we were encoding Go values to JSON.

@@ -0,0 +1,157 @@
{
"definitions": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work. Creating these things by hand is a pain.

Question: Are you aware of any way to use a JSON schema file to validate some NDJSON?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like we could just autogenerate these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also relevant: ipfs/go-ipfs-cmds#94

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can autogenerate this schema, but there are some reasons why I chose not to:

  1. Writing JSON schema isn't very hard.
  2. JSON Schema has a lot of flexibility how it's structured. It's easy to write (or generate) a version that accurately validates, but provides no meaningful feedback on which element failed. I went through a few variations to get a design that worked well.
  3. An autogenerated schema can, at best, validate that a particular document conforms to one particular permutation of all possible ways to assemble the types. Specifying where content is required and how types relate are things that requires some understanding of the code's meaning.

@acruikshank
Copy link
Contributor Author

@laser Re: assertions on actor ls. I've added schema validation in TestActorDaemon which is as close as we can really get to testing the actual command.

@laser
Copy link
Contributor

laser commented Apr 24, 2018

@acruikshank

@laser Re: assertions on actor ls. I've added schema validation in TestActorDaemon which is as close as we can really get to testing the actual command.

Looking good! I just approved the PR.

@acruikshank
Copy link
Contributor Author

@phritz and @whyrusleeping I think I've addressed most of your concerns. Could you take another look?

Copy link
Contributor

@phritz phritz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having something like these schema tests is really important. With why's approval let's adopt this as policy now unless he has an easier idea. If we do then update https://github.com/filecoin-project/go-filecoin/blob/master/CONTRIBUTING.md#testing-philosophy to point to this example as canonical.

BTW you probably have too many reviewers.

@whyrusleeping
Copy link
Member

seems fine to me. Didn't review thoroughly, but nothing blocking over here.

update go-ipfs-cmds to version with unmarshalling fix and remove workaround
@acruikshank acruikshank merged commit 80a31fc into master Apr 26, 2018
@dignifiedquire dignifiedquire deleted the feat/add_json_schema_test branch April 27, 2018 10:09
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

Successfully merging this pull request may close these issues.

4 participants