Skip to content

Handles inconsistent JSON-encoding on query property. #9

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

chadwcarlson
Copy link
Contributor

@chadwcarlson chadwcarlson commented Jun 27, 2019

In the PLATFORM_RELATIONSHIPS array, the query property is handled inconsistently.

On postgresql, mongodb, and mysql, it is an object with a single property, is_master. On redis and elasticsearch, it is an empty array. On rabbitmq, solr, memcached, and influxdb, it is omitted entirely.

Previously, this returned the following error when parsing the JSON string:

unexpected error: json: cannot unmarshal array into Go struct field Credential.Query of type struct { IsMaster bool "json:\"is_master\"" }

This is a workaround that includes tests for the two proposed changes to the JSON relationships encoding, so it will not break when fixed:

  • omitting the query property entirely where currently defined as an empty array (TestCredentialsForRelationshipPropertyQueryAbsentReturns).
  • standardize so always present as empty object if not defined (TestCredentialsForRelationshipPropertyQueryDefinedAsEmptyObjectReturns).

Previously in cases where query was not defined at all, Credential.Query.IsMaster defaulted to the type's (bool) zero value (false), so that has been replicated here in the empty array and query-omitted cases.

EDIT: When the Query struct is left unset, it's property IsMaster defaults to its zero-value (for bool, false). This was tested by removing the previous setting lines and only setting Query when the is_master key is present in the JSON. (See below)

Otherwise, the value defined in is_master is used.

gohelper.go Outdated
mappedRawQuery, ok := rels[k][0].RawQuery.(map[string]interface{})
if !ok {
// Handle empty array case
rels[k][0].Query.IsMaster = false
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is accurate. When there's an empty array, it means the master flag is irrelevant, not that it's false. Generally that means there's only one, which may as well be master; so it would default to true. Or, better, it would remain unset entirely to be consistent with the other services.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Crell The last commit keeps the other cases (empty object, empty array, and omitted query) unset, only setting if the is_master key is present. Comparing the test run on query-fix and master, it looks like that unset properties (i.e. IsMaster bool) do default to their "zero values", which in this case is false.

For elasticsearch (empty object)

master:

elasticsearch:[{http dtsla3sy7euhc-master-7rqtwti elasticsearch   elasticsearch.internal  false  169.254.250.214 elasticsearch elasticsearch:5.4 9200 bwhgfsnjp7kzqlf7pd35dfg6mm.elasticsearch.service._.us-2.platformsh.site {false}}]

query-fix:

elasticsearch:[{http rjify4yjcwxaa-master-7rqtwti elasticsearch   elasticsearch.internal  false  169.254.49.124 elasticsearch elasticsearch:5.4 9200 j2dkzht3gs2yr66fb2brhoj4zu.elasticsearch.service._.eu-3.platformsh.site {false} map[]}]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's the query omitted case (influxdb):

master:

influxdb:[{http rjify4yjcwxaa-master-7rqtwti influxdb   influxdb.internal  false  169.254.70.27 influxdb influxdb:1.3 8086 haz5rys6n2dsnjusqa54os3ii4.influxdb.service._.eu-3.platformsh.site {false}}]

query-fix:

influxdb:[{http rjify4yjcwxaa-master-7rqtwti influxdb   influxdb.internal  false  169.254.70.27 influxdb influxdb:1.3 8086 haz5rys6n2dsnjusqa54os3ii4.influxdb.service._.eu-3.platformsh.site {false} <nil>}] redis:[{redis rjify4yjcwxaa-master-7rqtwti redis   redis.internal  false  169.254.39.193 redis redis:5.0 6379 2wye4dawv22vhvozyec3o5hxfm.redis.service._.eu-3.platformsh.site {false} []}]

gohelper.go Outdated
rels[k][0].Query.IsMaster = val.(bool)
} else {
// Handle omitted case
rels[k][0].Query.IsMaster = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Ibid.

}

func TestCredentialsForRelationshipPropertyQueryAbsentReturns(t *testing.T) {
config, err := psh.NewRuntimeConfigReal(helper.RuntimeEnv(psh.EnvList{}), "PLATFORM_")
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if these tests would be more valid if they took an existing config and mutated it, rather than having them lying around as discrete test data? I'm honestly unsure here, nor do I know how much work that would be.

}
RawQuery interface{} `json:"query"`
Copy link
Contributor

Choose a reason for hiding this comment

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

This should probably be rawQuery so that it's not accessible outside this package. It's an internal implementation detail.

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.

2 participants