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

Pogs interfaces #66

Merged
merged 13 commits into from
Apr 28, 2017
Merged

Pogs interfaces #66

merged 13 commits into from
Apr 28, 2017

Conversation

zenhack
Copy link
Contributor

@zenhack zenhack commented Feb 24, 2017

Addresses #62.

//cc @zombiezen, when you have the time.

pogs/extract.go Outdated
@@ -25,6 +25,14 @@ type extracter struct {
nodes nodemap.Map
}

var (
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't really need the doc comment.

var clientType = reflect.TypeOf((*capnp.Client)(nil)).Elem()

pogs/extract.go Outdated
}
client := p.Interface().Client()
if client != nil {
if !val.Type().Implements(clientType) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you actually want

if val.Type() != clientType {

pogs/extract.go Outdated
@@ -376,6 +397,15 @@ func isTypeMatch(r reflect.Type, s schema.Type) bool {
case schema.Type_Which_list:
e, _ := s.List().ElementType()
return r.Kind() == reflect.Slice && isTypeMatch(r.Elem(), e)
case schema.Type_Which_interface:
if !r.Implements(clientType) && r.Kind() == reflect.Struct {
field, ok := r.FieldByName("Client")
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like for this to check for a more strict bound:

  1. Has one field
  2. That field is called Client
  3. That field is of type capnp.Client

pogs/insert.go Outdated
default:
return fmt.Errorf("unknown field type %v", typ.Which())
}
return nil
}

func getCapPtr(seg *capnp.Segment, val reflect.Value) capnp.Ptr {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: just capPtr


import (
"golang.org/x/net/context"
"testing"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: group stdlib packages apart from others

Base EchoBase
}

func TestInsertIFace(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.

Any reason to not add these to the broader table test? I think I have better error handling in there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using reflect.DeepEqual on interfaces doesn't really do what we want in this case, and it seemed prudent to have something that tested the behavior of the interface, which would require special casing in the general test anyway. I think at the time I decided making it work would be more disruptive to the existing tests than really made sense. I'm willing to be convinced otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've removed reflect.DeepEqual usage. WDYT now? 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@zombiezen, I think I've addressed everything besides this point. Any thoughts on my comment above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@zombiezen, ping?

@zombiezen
Copy link
Contributor

Sorry, lost track of this with other stuff. I'll take a look tomorrow.

Copy link
Contributor

@zombiezen zombiezen left a comment

Choose a reason for hiding this comment

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

Sorry, I forgot I had some comments queued up that I never sent.

extractedBase := EchoBase{}
err = Extract(&extractedBase, air.EchoBase_TypeID, base.Struct)
checkFatal(t, "Extract", err)
if extractedBase.Echo.Client != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would start the Client off as non-nil and check that it got set to nil.

Base EchoBase
}

func TestInsertIFace(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've removed reflect.DeepEqual usage. WDYT now? 😃

pogs/extract.go Outdated
@@ -376,6 +391,24 @@ func isTypeMatch(r reflect.Type, s schema.Type) bool {
case schema.Type_Which_list:
e, _ := s.List().ElementType()
return r.Kind() == reflect.Slice && isTypeMatch(r.Elem(), e)
case schema.Type_Which_interface:
if r.Implements(clientType) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you want r == clientType here.

So far just Insert, and I haven't tested this; it builds and the
existing tests still pass, but I need to get some other work done, so
I'm putting it down for the moment.
...and fix a corresponding bug.
This involved factoring out/moving a handful of things to global scope
that were previously only visible from inside TestInsertIFace.

Still TODO is handling things inside lists; this hasn't been tested and
I suspect it doesn't work.
Passes. Note that this adds a type to the aircraft schema.
The only bit left is the question about moving the new tests into the
big table, which I need to stare at a bit.
@zenhack
Copy link
Contributor Author

zenhack commented Apr 18, 2017

I think I can make the tests work with the table; I'll have to add a bit of logic to actually call testEcho when the interface is (expectedly) not nil. So it won't be checking for equality really, but that's OK I think. I'll get to this soon.

I addressed your other two comments.

The last of the insert tests is actually failing right now, and
thinking about it I'm not sure how it could be made to pass; It's
not clear the wire format can represent that.
@zenhack
Copy link
Contributor Author

zenhack commented Apr 19, 2017

@zombiezen, I added interface stuff to the main table based tests. It's actually failing currentlly in a case where I'm trying to insert a slice of structs, where some of them have a nil client and some don't; the resulting message ends up with them all filled in.

I bet I know what's going on: the composite list wire format can't actually represent lists of structs that have different numbers of pointers filled in, so there's an extra pointer at the end of some of the structs that's being interpreted as a capability pointer. CapNProto doesn't have a notion of a nil/null pointer, just an "absent" one, so I don't think there's a "correct" way to encode a list like this.

I'm not sure how to handle this case besides just mentioning in the docs that you can't do that. Thoughts?

@zombiezen
Copy link
Contributor

I bet I know what's going on: the composite list wire format can't actually represent lists of structs that have different numbers of pointers filled in, so there's an extra pointer at the end of some of the structs that's being interpreted as a capability pointer.

But there is a null pointer for capabilities, this happens all over the place. It's the zero word. That seems like a legitimate failure to me. Any pointer type in Cap'n Proto can be null.

@zenhack
Copy link
Contributor Author

zenhack commented Apr 28, 2017

Ah, you're right -- I missed that reading the spec. I will dig a bit deeper then.

@zenhack
Copy link
Contributor Author

zenhack commented Apr 28, 2017

@zombiezen, fixed.

I hadn't been aware of this before. This also fixes the test failure;
presumably I made some mistake in re-implementing the logic.
@zombiezen zombiezen merged commit 917bd4b into capnproto:master Apr 28, 2017
@zombiezen
Copy link
Contributor

Thanks! Sorry this took a while, but I'm happy with how it turned out.

@zenhack
Copy link
Contributor Author

zenhack commented Apr 29, 2017

Cool. No worries about the delays; things come up.

@zenhack zenhack deleted the pogs-interfaces branch April 3, 2022 22:16
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.

None yet

2 participants