IOTData: Fix bug where publish() could only be called once (#5812)
This commit is contained in:
parent
031f89dee0
commit
d68fb04ee1
4
.github/workflows/test_outdated_versions.yml
vendored
4
.github/workflows/test_outdated_versions.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
pytest -sv tests/test_core ./tests/test_apigateway/test_apigateway_integration.py ./tests/test_s3/test_server.py
|
pytest -sv tests/test_core ./tests/test_apigateway/test_apigateway_integration.py tests/test_iotdata ./tests/test_s3/test_server.py
|
||||||
|
|
||||||
- name: Start MotoServer
|
- name: Start MotoServer
|
||||||
run: |
|
run: |
|
||||||
@ -52,7 +52,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TEST_SERVER_MODE: ${{ true }}
|
TEST_SERVER_MODE: ${{ true }}
|
||||||
run: |
|
run: |
|
||||||
pytest -sv tests/test_core tests/test_awslambda tests/test_cloudformation
|
pytest -sv tests/test_core tests/test_awslambda tests/test_cloudformation tests/test_iotdata
|
||||||
- name: "Stop MotoServer"
|
- name: "Stop MotoServer"
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
|
@ -8,6 +8,12 @@ class IoTDataPlaneResponse(BaseResponse):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(service_name="iot-data")
|
super().__init__(service_name="iot-data")
|
||||||
|
|
||||||
|
def _get_action(self) -> str:
|
||||||
|
if self.path and self.path.startswith("/topics/"):
|
||||||
|
# Special usecase - there is no way identify this action, besides the URL
|
||||||
|
return "publish"
|
||||||
|
return super()._get_action()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def iotdata_backend(self):
|
def iotdata_backend(self):
|
||||||
return iotdata_backends[self.current_account][self.region]
|
return iotdata_backends[self.current_account][self.region]
|
||||||
@ -30,18 +36,8 @@ class IoTDataPlaneResponse(BaseResponse):
|
|||||||
payload = self.iotdata_backend.delete_thing_shadow(thing_name=thing_name)
|
payload = self.iotdata_backend.delete_thing_shadow(thing_name=thing_name)
|
||||||
return json.dumps(payload.to_dict())
|
return json.dumps(payload.to_dict())
|
||||||
|
|
||||||
def dispatch_publish(self, request, full_url, headers):
|
|
||||||
# This endpoint requires specialized handling because it has
|
|
||||||
# a uri parameter containing forward slashes that is not
|
|
||||||
# correctly url encoded when we're running in server mode.
|
|
||||||
# https://github.com/pallets/flask/issues/900
|
|
||||||
self.setup_class(request, full_url, headers)
|
|
||||||
self.querystring["Action"] = ["Publish"]
|
|
||||||
topic = self.path.partition("/topics/")[-1]
|
|
||||||
self.querystring["target"] = [unquote(topic)] if "%" in topic else [topic]
|
|
||||||
return self.call_action()
|
|
||||||
|
|
||||||
def publish(self):
|
def publish(self):
|
||||||
topic = self._get_param("target")
|
topic = self.path.split("/topics/")[-1]
|
||||||
|
topic = unquote(topic) if "%" in topic else topic
|
||||||
self.iotdata_backend.publish(topic=topic, payload=self.body)
|
self.iotdata_backend.publish(topic=topic, payload=self.body)
|
||||||
return json.dumps(dict())
|
return json.dumps(dict())
|
||||||
|
@ -10,18 +10,9 @@ response = IoTDataPlaneResponse()
|
|||||||
|
|
||||||
|
|
||||||
url_paths = {
|
url_paths = {
|
||||||
#
|
|
||||||
# Paths for :class:`moto.core.models.MockAWS`
|
|
||||||
#
|
|
||||||
# This route requires special handling.
|
|
||||||
"{0}/topics/(?P<topic>.*)$": response.dispatch_publish,
|
|
||||||
# The remaining routes can be handled by the default dispatcher.
|
|
||||||
"{0}/.*$": response.dispatch,
|
"{0}/.*$": response.dispatch,
|
||||||
#
|
#
|
||||||
# (Flask) Paths for :class:`moto.core.models.ServerModeMockAWS`
|
# (Flask) Paths for :class:`moto.core.models.ServerModeMockAWS`
|
||||||
#
|
#
|
||||||
# This route requires special handling.
|
|
||||||
"{0}/topics/<path:topic>$": response.dispatch_publish,
|
|
||||||
# The remaining routes can be handled by the default dispatcher.
|
|
||||||
"{0}/<path:route>$": response.dispatch,
|
"{0}/<path:route>$": response.dispatch,
|
||||||
}
|
}
|
||||||
|
@ -110,12 +110,16 @@ def test_update():
|
|||||||
def test_publish():
|
def test_publish():
|
||||||
region_name = "ap-northeast-1"
|
region_name = "ap-northeast-1"
|
||||||
client = boto3.client("iot-data", region_name=region_name)
|
client = boto3.client("iot-data", region_name=region_name)
|
||||||
client.publish(topic="test/topic", qos=1, payload=b"pl")
|
client.publish(topic="test/topic1", qos=1, payload=b"pl1")
|
||||||
|
client.publish(topic="test/topic2", qos=1, payload=b"pl2")
|
||||||
|
client.publish(topic="test/topic3", qos=1, payload=b"pl3")
|
||||||
|
|
||||||
if not settings.TEST_SERVER_MODE:
|
if not settings.TEST_SERVER_MODE:
|
||||||
mock_backend = moto.iotdata.models.iotdata_backends[ACCOUNT_ID][region_name]
|
mock_backend = moto.iotdata.models.iotdata_backends[ACCOUNT_ID][region_name]
|
||||||
mock_backend.published_payloads.should.have.length_of(1)
|
mock_backend.published_payloads.should.have.length_of(3)
|
||||||
mock_backend.published_payloads.should.contain(("test/topic", "pl"))
|
mock_backend.published_payloads.should.contain(("test/topic1", "pl1"))
|
||||||
|
mock_backend.published_payloads.should.contain(("test/topic2", "pl2"))
|
||||||
|
mock_backend.published_payloads.should.contain(("test/topic3", "pl3"))
|
||||||
|
|
||||||
|
|
||||||
@mock_iot
|
@mock_iot
|
||||||
|
Loading…
Reference in New Issue
Block a user