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

[policy] implement policy equality and tostring #569

Merged
merged 2 commits into from
Feb 5, 2018
Merged

Conversation

mikz
Copy link
Contributor

@mikz mikz commented Feb 1, 2018

Implement __eq and __tostring metamethods, so
you can compare policies to see if they are the same.

Also rename apicast.policy.policy to correct place: apicast.policy.
Because it is not a policy per se that can be used, but just a "class".

@mikz mikz force-pushed the policy-equality branch 2 times, most recently from cd7f450 to df10bce Compare February 1, 2018 16:02
@mikz mikz requested a review from davidor February 1, 2018 16:02
--- upstream
location /{
content_by_lua_block {
require('cli')
Copy link
Contributor

@davidor davidor Feb 1, 2018

Choose a reason for hiding this comment

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

I'm a bit confused bit this change. A policy chain with { "name": "policy.echo" } like we had before should still raise a deprecation error, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes in this PR still, but in will need some touches in #566
This test is about prefixing it with apicast, so this example is more stable than the policies one.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. Didn't think about the implications of this in the other PR.


assert.are.not_equal(p1, p2)
end)
end)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick, just for completeness, maybe add a test comparing a policy against itself.

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 one :)

end)
end)

describe('instance equality', function()
Copy link
Contributor

Choose a reason for hiding this comment

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

I can imagine that module equality is useful for comparing policies and loading them, but what's the use case for comparing policy instances?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is useful in tests. Like checking that policy is in the chain: https://github.com/3scale/apicast/pull/566/files#diff-b0a6bd0538ae4f76e9bf6a2a045f51beR36

Copy link
Contributor

Choose a reason for hiding this comment

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

But this means that two instances of the same policy will be considered to be equal even if they have a different configuration. I think this could be misleading.

Copy link
Contributor Author

@mikz mikz Feb 1, 2018

Choose a reason for hiding this comment

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

True, that is a fair point. But how to solve that? I need to somehow test instances and verifying the configuration would need to use deep equality which is not an easy thing in lua.

But maybe we could check the config just with referential equality and that should be enough for cases I need. But there does not have to be common "config" option, so each policy would have to implement own equality based on properties it sets :/
Thats exactly what you said in #569 (comment) :)

Copy link
Contributor

Choose a reason for hiding this comment

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

You mentioned that this is only useful in tests.
If you only need this for the specific line that you linked here, I think that using 2 asserts to check version and name is better than introducing this 'dangerous' equality function for instances.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we are interested in having module eq but not instance eq, wouldn't it be enough to delete the __eq entry from this metatable? : https://github.com/3scale/apicast/pull/569/files#diff-b9119890f218a45887b39e830dfc0bb9R43

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, but then to compare them we would have to get the metatable and then __index from it to get the module for comparison.

Copy link
Contributor

@davidor davidor Feb 2, 2018

Choose a reason for hiding this comment

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

I see that to access the equality method you'll need to do getmetatable(p1.new()).__index._eq. I don't know if there's a better way to do this.

If this is only going to be used in a test, I'd say it's not that bad. I prefer to have that line somewhere in the tests (as long as it's documented) rather than introduce a dangerous equality function in the codebase. But this is a matter of preference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, there can be some helper function in the test to abstract it away.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Resolved by having .policy property in the metatable. I think that is best of the both worlds. Allows you easily to get the "module" from the instance so it can be compared, but does not rely on existence of __index (that is entirely up the the creator of the policy)

it('shows name and version', function()
local p1 = policy.new('NAME', 'VERSION').new()

assert.equal('Policy: NAME (VERSION)', tostring(p1))
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks a bit strange to me because the policy module and the instances have the same string representation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, but I have no good ideas how to differentiate them. This is useful when passing them to inspect and there you can kind of see if it is an instance or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

We could include the config in the instances. Although it might be a very big table depending on the policy.

Copy link
Contributor

@davidor davidor Feb 1, 2018

Choose a reason for hiding this comment

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

Hmm now that I think about it, we don't have a self.config for each policy.
I guess that for now this is good enough. As you said, with inspect we'll be able to clearly differentiate them.

@mikz mikz force-pushed the policy-equality branch 3 times, most recently from 3014c3f to d0d4884 Compare February 5, 2018 16:31
@@ -31,7 +40,7 @@ function _M.new(name, version)
_NAME = name,
_VERSION = version or '0.0',
}
local mt = { __index = policy }
local mt = { __index = policy, __tostring = __tostring, policy = policy }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@davidor solved it by having a property in the metatable. I think that is best of both worlds.

@mikz mikz requested a review from davidor February 5, 2018 16:39
@mikz mikz merged commit 6a025b7 into master Feb 5, 2018
@mikz mikz deleted the policy-equality branch February 5, 2018 16:49
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