|
14 | 14 |
|
15 | 15 | import collections |
16 | 16 | import itertools |
| 17 | +import pytest |
17 | 18 | import typing |
18 | 19 |
|
19 | 20 | from google.api import resource_pb2 |
20 | 21 | from google.cloud import extended_operations_pb2 as ex_ops_pb2 |
21 | 22 | from google.protobuf import descriptor_pb2 |
22 | 23 |
|
23 | 24 | from gapic.schema import imp |
24 | | -from gapic.schema.wrappers import CommonResource |
| 25 | +from gapic.schema.wrappers import CommonResource, MessageType |
| 26 | +from gapic.schema import wrappers |
25 | 27 |
|
26 | 28 | from test_utils.test_utils import ( |
27 | 29 | get_method, |
@@ -693,3 +695,57 @@ def test_extended_operations_lro_detection(): |
693 | 695 | # because Service objects can't perform the lookup. |
694 | 696 | # Instead we kick that can to the API object and make it do the lookup and verification. |
695 | 697 | assert lro.operation_service == "CustomOperations" |
| 698 | + |
| 699 | + |
| 700 | +def test_resource_messages_throws_informative_collision_error(): |
| 701 | + # 1. Create options with explicit colliding resource types AND valid patterns |
| 702 | + opts_1 = descriptor_pb2.MessageOptions() |
| 703 | + opts_1.Extensions[resource_pb2.resource].type = "ces.googleapis.com/Tool" |
| 704 | + opts_1.Extensions[resource_pb2.resource].pattern.append("ces/{ces}/tool") |
| 705 | + |
| 706 | + opts_2 = descriptor_pb2.MessageOptions() |
| 707 | + opts_2.Extensions[resource_pb2.resource].type = "workspace.googleapis.com/Tool" |
| 708 | + opts_2.Extensions[resource_pb2.resource].pattern.append("workspaces/{workspace}/tool") |
| 709 | + |
| 710 | + # 2. Use the test helpers to build the messages |
| 711 | + msg_1 = make_message("MessageOne", options=opts_1) |
| 712 | + msg_2 = make_message("MessageTwo", options=opts_2) |
| 713 | + |
| 714 | + # 3. Build the service with BOTH methods (so the property loops) |
| 715 | + # AND visible_resources (so the internal lookups succeed). |
| 716 | + service = make_service( |
| 717 | + name="MyService", |
| 718 | + methods=( |
| 719 | + make_method("GetToolOne", input_message=msg_1), |
| 720 | + make_method("GetToolTwo", input_message=msg_2), |
| 721 | + ), |
| 722 | + visible_resources={ |
| 723 | + "ces.googleapis.com/Tool": msg_1, |
| 724 | + "workspace.googleapis.com/Tool": msg_2, |
| 725 | + } |
| 726 | + ) |
| 727 | + |
| 728 | + # 4. Assert that asking the service for its resources throws the custom error |
| 729 | + expected_error_regex = r"(?s)Namespace collision detected.*--resource-name-alias" |
| 730 | + |
| 731 | + with pytest.raises(ValueError, match=expected_error_regex): |
| 732 | + _ = service.resource_messages |
| 733 | + |
| 734 | + |
| 735 | +def test_resource_messages_raises_on_malformed_typeless_resource(): |
| 736 | + # 1. Create a malformed resource: it has a pattern, but no type! |
| 737 | + opts = descriptor_pb2.MessageOptions() |
| 738 | + opts.Extensions[resource_pb2.resource].pattern.append("workspaces/{workspace}") |
| 739 | + |
| 740 | + malformed_msg = make_message("MalformedMessage", options=opts) |
| 741 | + |
| 742 | + service = make_service( |
| 743 | + name="MyService", |
| 744 | + methods=( |
| 745 | + make_method("DoThing", input_message=malformed_msg), |
| 746 | + ) |
| 747 | + ) |
| 748 | + |
| 749 | + # 2. Trigger the property and expect it to fail fast with the AIP-123 URL |
| 750 | + with pytest.raises(ValueError, match="https://google.aip.dev/123"): |
| 751 | + _ = service.resource_messages |
0 commit comments