-
Notifications
You must be signed in to change notification settings - Fork 26
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
Encode JSON message data as string. #459
Conversation
Previously, we were just inlining it: "messages": [{"data": {"foo": "bar"}}] What the JS library expects, and really what (RSL4d3)[http://docs.ably.io/client-lib-development-guide/features/#RSL4d3] says: "messages": [{"data": "{\"foo\": \"bar\"}"}] So now we do that.
ac81d2f
to
fff2732
Compare
I've added a test at fff2732 for what we've talked about at ably/wiki#22. If it looks good I can do it in Java as well. Please review @mattheworiordan @paddybyers @SimonWoolf. |
This looks good, but got a few comments:
|
BTW. Once done, I will add a corresponding test to Ruby and then a new spec item to the 0.9 spec |
It would be very unlikely that an incorrectly decoded object is then encoded correctly just as the fixture expects, wouldn't it? Plus, we really can't specify this in a platform-independent manner. Other tests should check this for each platform (they do already if they test RSL4 properly); this one is focused on interoperability.
Renamed "map" to "object" at e7f68e1. (I just picked "map" randomly really, they're called dictionaries in Swift.) |
But it's not testing interoperability because of exactly that reason. Every platform supports JSON-like objects. If a developer is unable to rely on our platform to provide consistent JSON-like objects then we have a much bigger problem. We state clearly we support string, binary and JSON, so those are three types we need to test. I am sorry, but I disagree here and feel we must test that the object received is what we expected else we're open to yet more problems.
Still not sure I would agree with that. We don't support Objects (that is very generic), we support JSON Objects and JSON Arrays, see http://docs.ably.io/client-lib-development-guide/features/#RSL4c3 and http://docs.ably.io/client-lib-development-guide/features/#RSL4d3 |
Yes but the issue is how we represent the expected value in the fixture data when the value is a JSON object or array, or binary, without things getting a bit circular. I think we do have to include an In the case of binary we just have to include a serialised representation in the fixture data (lets say hex instead of base64 because it minimises ambiguity), and the tests know that if the
Yes, but since the JSON spec defines what those values are it seems to make sense to use the names of the corresponding types from the JSON BNF (ie |
PTAL, implemented following @paddybyers ' proposal, and prepended "json" to "array" and "object". |
Thanks lgtm 👍 |
PTAL |
fail("\(err)") | ||
// /~https://github.com/ably/wiki/issues/22 | ||
it("should encode and decode fixture messages as expected") { | ||
let options = AblyTests.commonAppSetup() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not explicitly use JSON
i.e. binaryProtocol = false
and should the test description be updated to reflect that these tests are about JSON based interoperability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I don't see why. Whether this uses JSON or MsgPack doesn't matter, that's not the layer we're testing. We have two fully independent layers:
- Message data encoding JSON-like to string and back again.
- Whole protocol message encoding to JSON or MsgPack and back again.
This test is about the former. When the encoded message data hits the latter, it is already a string in all cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Message data encoding JSON-like to string and back again.
Well you are never technically doing that because every time you use JSON on one end MsgPack on the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't see your point here. How am I never doing that? I am pretty literally doing that, concretely here. Then I'm turning that string (doesn't matter if it's JSON or not) into either MsgPack or a JSON blob or any other protocol-level encoding we might use in the future. Then I'm turning that into maybe a gzipped blob over HTTP and then encrypting that with TLS and then Wi-Fi signals or whatever, all those encodings that also don't affect the first one at all. Am I wrong here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point here is that tests don't know how the internals of a library work and should not care. The point of our interoperability tests was to check that a message when decoded/encoded via JSON or MsgPack are consistent with the types we expect to see. We agreed the only reliable way to get data into the Ably system was via a raw REST request to Ably, and then to check that it was as expected, was also via a raw REST history request to Ably and then to parse the JSON (or inspect the type if binary/string) and compare with what we see the library interprets that over JSON and MsgPack. So if we want to test how our Ably library encoded/decodes objects with a JSON transport it should use that, and if we want to see how our Ably library does that MsgPack it should use a MsgPack transport. This test uses MsgPack, so the JSON encoding / decoding of a message injected or received via a raw request is not being done. That is why in Ruby I have a set of tests using the JSON transport and then using the MsgPack transport but all the time using a raw JSON request to inject or check the fixture in Ably irrespective of the transport being tested for interoperability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of our interoperability tests was to check that a message when decoded/encoded via JSON or MsgPack are consistent with the types we expect to see.
That's the point of the second interoperability test. The point of this one is to check it the message data (not the message itself) when decoded/encoded as string, JSON or base64. We need both precisely because they test two completely independent things.
We agreed the only reliable way to get data into the Ably system was via a raw REST request to Ably, and then to check that it was as expected, was also via a raw REST history request to Ably and then to parse the JSON
That part I agree with, and if that's what you meant then OK. But since I'm doing a direct raw POST with a JSON payload (here) it doesn't matter what I set useBinaryProtocol
to. Same for the raw GET for history. It still doesn't affect how the message gets transmitted via realtime.
This test uses MsgPack, so the JSON encoding / decoding of a message injected or received via a raw request is not being done.
Yes it is, because what we're encoding/decoding is the JSON inside that message, which comes as a string. These lines that decode the JSON from the message data are being executed both if the message came as JSON or as MsgPack. At that point, it's just an ARTMessage
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps I am misunderstanding still, but in these tests, at what point do we publish with a raw JSON message (i.e. getting the fixture into Ably in a guaranteed portable way) and get that message over a JSON transport and confirm the message.data
is as expected then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, and where do we publish over JSON using the library, and then confirm with a raw HTTP request that the JSON in Ably is as expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at what point do we publish with a raw JSON message
Here. That's a POST /channels/.../messages
. fixtureMessage
is a JSON
object (from a library for easy JSON manipulation) and rawData()
converts it into a JSON string. That's quite like cutting and pasting from the messages-encoding.json
directly into the POST request body.
and get that message over a JSON transport
Here. data
there is the HTTP response body, which the JSON
library parses.
and confirm the message.data is as expected
Here. Both persistedMessage
and fixtureMessage
are JSON
objects that don't go through the ARTRealtime
instance at any point. The ARTRealtime
instance is used to test that the iOS library encodes and decodes the data as expected (ie. as expectedValue
or expectedHexValue
tell us), be it JSON, string or base64.
As above, and where do we publish over JSON using the library, and then confirm with a raw HTTP request that the JSON in Ably is as expected?
That's in the second test, here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and get that message over a JSON transport
Here. data there is the HTTP response body, which the JSON library parses.
But that's using client.rest.executeRequest
to get that data. So it's not passing through either a Realtime subscribe API or a history API request. The goal was end-to-end API test, yet that is not using an API that handles encoding & decoding implicitly i.e. publish/subscribe/history.
As above, and where do we publish over JSON using the library, and then confirm with a raw HTTP request that the JSON in Ably is as expected?
That's in the second test, here.
Against, I don't think that is doing the job. You are mixing two concerns into one. We explicitly don't couple publishing & subscribing (regardless of protocol) into a single interoperability test because then you are simply testing that the client library when encoding & then decoding gives you the answer you expect. But that's not the point of interoperability tests.
One comment otherwise LGTM 👍 |
@mattheworiordan PTAL. If it looks good I'll do the same for Java. |
LGTM. Once both are done, can we bump versions so that I can update that customer who had the issue? |
Previously, we were just inlining it:
What the JS library expects, and really what RSL4d3 says:
So now we do that.