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

UI server test coverage & ARGS_SPEC Workbench compatibility #623

Merged
merged 22 commits into from
Aug 25, 2021

Conversation

davemfish
Copy link
Contributor

@davemfish davemfish commented Aug 19, 2021

This PR makes small modifications to ARGS_SPEC options datatypes - changing from sets to lists - and adds a utility function to make sure all ARGS_SPEC dictionaries are JSON serializable.

There are also new tests for all endpoints in ui_server.py. And tests for spec_utils functions were moved into test_args_spec.py.

Fixes #617

Checklist

  • Updated HISTORY.rst (if these changes are user-facing)

  • Updated the user's guide (if needed)

The corresponding workbench PR that depends on these changes is natcap/invest-workbench#165

@davemfish davemfish marked this pull request as ready for review August 23, 2021 20:08
@davemfish davemfish requested a review from emlys August 23, 2021 20:08
Copy link
Member

@emlys emlys left a comment

Choose a reason for hiding this comment

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

Thanks @davemfish! Just a few minor comments.

@@ -25,7 +22,7 @@
v.pyname: _UI_META(
run_name=k,
human_name=v.humanname)
for k, v in natcap.invest.cli._MODEL_UIS.items()}
for k, v in cli._MODEL_UIS.items()}
Copy link
Member

Choose a reason for hiding this comment

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

To be nitpicky, key and value or val instead of one-letter variables?

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 idea

try:
_ = spec_utils.serialize_args_spec(model.ARGS_SPEC)
except TypeError:
self.fail(
Copy link
Member

Choose a reason for hiding this comment

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

Neat, I haven't seen self.fail before! Could we also show the original error traceback?

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 self.fail is new to me too. This seems like the preferred pattern to assert that a specific exception is avoided.

Good idea adding the original error. It's hard (but not impossible) to get the full traceback without ever raising the error. And this TypeError should always be the one explicitly raised by spec_utils.fallback_serializer so I think it's okay to just include that message without traceback. An example with these changes:

E               AssertionError: Failed to avoid TypeError when serializing natcap.invest.carbon.ARGS_SPEC:
E               fallback serializer is missing for <class 'module'>

Copy link
Member

Choose a reason for hiding this comment

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

Oh interesting. I don't usually think about making that distinction between a test failure and (unexpected) error.

response_data = json.loads(response.get_data(as_text=True))
self.assertEqual(
list(response_data),
['type', 'args', 'module_name', 'model_run_name',
Copy link
Member

Choose a reason for hiding this comment

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

It looks like the json module preserves the order of keys, so this should work. But JSON is generally unordered outside of the python implementation, so I think ui_server.post_datastack_file could put them in any order without breaking its contract. Maybe use a set here just in case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great point! I changed all these tests to use sets instead of lists.

actual_data = json.loads(file.read())
self.assertEqual(
list(actual_data),
['args', 'invest_version', 'model_name'])
Copy link
Member

Choose a reason for hiding this comment

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

like above, maybe should be a set? If we do want to guarantee the order of keys in the file produced by write_parameter_set_file, lets put that in the docstring

Copy link
Contributor Author

Choose a reason for hiding this comment

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

order shouldn't matter; changed to a set.

spec = json.loads(response.get_data(as_text=True))
self.assertEqual(
list(spec),
['model_name', 'module', 'userguide_html',
Copy link
Member

Choose a reason for hiding this comment

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

like below, set?

response = test_client.get('/models')
models_dict = json.loads(response.get_data(as_text=True))
for model in models_dict.values():
self.assertEqual(list(model), ['internal_name', 'aliases'])
Copy link
Member

Choose a reason for hiding this comment

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

like below, set?

@davemfish davemfish requested a review from emlys August 25, 2021 13:33
@emlys emlys merged commit 0f8cc29 into natcap:release/3.10 Aug 25, 2021
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