-
Notifications
You must be signed in to change notification settings - Fork 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
[POC] Remap #129
[POC] Remap #129
Conversation
For what it's worth, as long as you have the original relation/relation ID, then you can just do this: relation_out = state_out.get_relation(r.id) I've seen tests where the state comes as a fixture and so the original relation isn't conveniently available, but
It seems like the main advantage over Overall, I'm -0 on
This needs to use relation_but_different = dataclasses.replace(relation, local_app_data=B)
state_but_different = dataclasses.replace(state, relations=[r for r in state.relations if r.name != "foo"] + [relation_but_different])
I'm +1 on patch.
Minor nit: probably this should be +1 on
For what it's worth, I think
I'm pretty certain this could be: relation = Relation('foo', local_app_data=A)
state = State(relations={relation, ...}, ...)
assert relation not in state.relations That seems simpler to me.
And similar here, I think I would rather do: assert relation not in state.relations
assert secret not in state.secrets
assert storage not in state.storages
assert storedstate not in state.stored_states
# or
assert relation not in state.relations and secret not in state.secrets and storage not in state.storages and storedstate not in state.stored_states So -1 on Edit: I guess the better use-case is not asserting whether something is still in the state (e.g. did a secret get removed) but setting up a state for another event. I suppose the symmetry with adding/inserting is nice in that case. So I guess I'm -0 on |
I'm not a fan of these. I'd much rather have a little bit of boilerplate that any Pythonista can understand, rather than starting to create our own little domain-specific language. Specifics:
I could maybe see myself coming around to However, to make a more informed decision, I'd rather see this in the context of actual, real-world tests, to see what it's actually saving, and whether there are other/better ways to achieve the same thing. |
Per discussion today, we're going to leave this for now, and see what patterns start appearing (and requests start coming) from teams that start writing state-transition / Scenario tests. So closing this for now, and we can always revisit. In addition, we'd like to recommend that developers using Scenario normally create new objects, rather than replace/patch existing ones. This might mean structuring tests and fixtures a bit differently when DRYing things up, but there are reasonable ways to do this. |
This PR adds to
scenario.State
a few utility methods for manipulating state objects.State.remap
"get me the corresponding object"
use case:
You create an object (relation, storedstate, secret, network, storage...), put it in State along with potentially many others
You run scenario
You want to retrieve the 'same' object and see how it was modified by the charm
However scenario's objects are immutable, so you can't do that easily without manually filtering all objects...
Current code:
with
remap
:State.patch
"modify just this component"
Often you want to dynamically create 'variations' of a State:
With
State.patch
:(this could also be used to do delta-based comparisons):
State.insert
In order to dynamically create modified copies of a state, right now you're limited to using the
replace
api. Suppose you want to add a relation:with
insert
:State.without
"Remove just this object"
counterpart to
insert
but removing stuff.with
without
: