Skip to content

Commit

Permalink
Merge pull request #56 from MummanaSubramanya/add-sqs-keywords
Browse files Browse the repository at this point in the history
Add SQS keywords and tests
  • Loading branch information
samuelpcabral authored Aug 17, 2024
2 parents 8b4540d + 011b590 commit 2f6f6e9
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,6 @@ dmypy.json
.idea
tests/robot/local_tests.robot
log/

# localstack
localstack/.localstack/
15 changes: 0 additions & 15 deletions docker-compose.yml

This file was deleted.

17 changes: 17 additions & 0 deletions localstack/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3.8'
services:
localstack:
image: localstack/localstack:latest
container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
ports:
- '4563-4599:4563-4599'
- '8055:8080'
environment:
- SERVICES=s3,lambda,dynamodb,rds,sqs
- DEBUG=1
- DOCKER_HOST=unix:///var/run/docker.sock
- AWS_DEFAULT_REGION=us-east-1
volumes:
- './init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh'
- .localstack:/var/lib/localstack
- '/var/run/docker.sock:/var/run/docker.sock'
5 changes: 5 additions & 0 deletions localstack/init-aws.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

# Hook file to create resources in localstack
awslocal sqs create-queue --queue-name test-queueName
echo succesfully created queue
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
robotframework>=6.1.1
boto3>=1.34.125
robotframework-pythonlibcore>=4.4.1
boto3-stubs[sqs]>=1.34.125
flake8>=7.1.1
2 changes: 2 additions & 0 deletions src/AWSLibrary/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from AWSLibrary.keywords.sqs import SQSKeywords
from .librarycomponent import LibraryComponent
from robotlibcore import DynamicCore
from AWSLibrary.keywords import (
Expand Down Expand Up @@ -47,5 +48,6 @@ def __init__(self):
ResourceKeywords(self),
DynamoKeywords(self),
CloudWatchKeywords(self),
SQSKeywords(self)
]
DynamicCore.__init__(self, libraries)
4 changes: 3 additions & 1 deletion src/AWSLibrary/keywords/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from AWSLibrary.keywords.resource import ResourceKeywords
from AWSLibrary.keywords.dynamo import DynamoKeywords
from AWSLibrary.keywords.cloudWatch import CloudWatchKeywords
from AWSLibrary.keywords.sqs import SQSKeywords


__all__ = [
SessionKeywords,
S3Keywords,
ResourceKeywords,
DynamoKeywords,
CloudWatchKeywords
CloudWatchKeywords,
SQSKeywords
]
121 changes: 121 additions & 0 deletions src/AWSLibrary/keywords/sqs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import botocore
from AWSLibrary.librarycomponent import LibraryComponent
from robot.api import logger
from robot.api.deco import keyword
from mypy_boto3_sqs import SQSClient


class SQSKeywords(LibraryComponent):

def __init__(self, library):
LibraryComponent.__init__(self, library)
self.endpoint_url = None

@keyword('SQS Set Endpoint Url')
def sqs_set_endpoint(self, url):
""" The complete URL to use for the constructed S3 client. Normally, botocore will automatically construct the
appropriate URL to use when communicating with a service. You can specify a complete URL
(including the “http/https” scheme) to override this behavior.
| =Arguments= | =Description= |
| ``url`` | <str> The complete endpoint URL. |
*Examples:*
| SQS Set Endpoint Url | http://localhost:4566/ |
"""
self.endpoint_url = url

@keyword('Send Message To SQS')
def send_message_to_sqs(self, queue_name: str, message_body: str, message_attributes=None):
""" Send a Message to Queue
| =Arguments= | =Description= |
| ``queue_name`` | <str> The queue name. |
| ``message_body`` | <str> message to send. |
| ``message_attributes`` | <Optional> Metadata to send. |
*Example 1:*
| Send Message To SQS | queue_name | Hello World! |
*Example 2:*
| ${example_type} | Create Dictionary | StringValue | 123 | DataType | String |
| ${message_attributes} | Create Dictionary | Example | ${order_type} |
| Send Message To SQS | sqs_name | Hello World! | ${message_attributes} |
"""
sqs = self._get_sqs_client()
queue_url = self._get_queue_url(queue_name)
if message_attributes is None:
message_attributes = {}

try:
response = sqs.send_message(
QueueUrl=queue_url,
MessageBody=message_body,
MessageAttributes=message_attributes
)
logger.info(f"Message sent. Message Details: {response}")
except botocore.exceptions.ClientError as e:
raise Exception(e)

@keyword('Receive Messages From SQS')
def receive_messages_from_sqs(self, queue_name: str, max_number: int = 10, wait_time: int = 10) -> list:
""" Recieve Messages From Queue
| =Arguments= | =Description= |
| ``queue_name`` | <str> The queue name. |
| ``max_number`` | <Optional int> Max number of messages to receive. |
| ``wait_time`` | <Optional int> Wait untill to get the messages. |
*Example:*
| ${messages_list} | Receive Messages From SQS | queue_name |
| Log List | ${messages_list} |
"""
sqs = self._get_sqs_client()
queue_url = self._get_queue_url(queue_name)
try:
response = sqs.receive_message(
QueueUrl=queue_url,
MaxNumberOfMessages=max_number,
WaitTimeSeconds=wait_time,
MessageAttributeNames=['All']
)
messages = response.get('Messages', [])
logger.info(f"Received {len(messages)} message(s).")
return messages
except botocore.exceptions.ClientError as e:
raise Exception(e)

@keyword('Delete All Messages In SQS')
def purge_sqs(self, queue_name: str):
"""
Delete All Messages In SQS
| =Arguments= | =Description= |
| ``queue_name`` | <str> The queue name. |
*Example:*
| Delete All Messages In SQS | queue_name |
"""
sqs = self._get_sqs_client()
queue_url = self._get_queue_url(queue_name)
try:
# Purge the queue (delete all messages)
sqs.purge_queue(QueueUrl=queue_url)
logger.info(f"Queue '{queue_name}' has been purged successfully.")
except botocore.exceptions.ClientError as e:
raise Exception(f"An error occurred while purging the queue: {e}")

def _get_sqs_client(self) -> SQSClient:
"""Retrieve the SQS client."""
return self.library.session.client('sqs', endpoint_url=self.endpoint_url)

def _get_queue_url(self, queue_name: str) -> str:
"""Retrieve the queue URL for the given queue name."""
try:
sqs = self._get_sqs_client()
return sqs.get_queue_url(QueueName=queue_name)['QueueUrl']
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == 'AWS.SimpleQueueService.NonExistentQueue':
raise Exception(f"Queue name '{queue_name}' not found.")
else:
raise Exception(f"An error occurred while getting the queue URL: {e}")
40 changes: 40 additions & 0 deletions tests/robot/testsuites/SqsTests/SampleTests.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
*** Settings ***
Library AWSLibrary
Library Collections
Library SeleniumLibrary
Suite Setup Create Session With Keys ${REGION} ${ACCESS_KEY} ${SECRET_KEY}
Suite Teardown Delete All Sessions

*** Variables ***
${REGION} us-east-1
${ACCESS_KEY} dummy
${SECRET_KEY} dummy


*** Test Cases ***

Send and Recieve Message
SQS Set Endpoint Url http://localhost:4566 # Point to localstack sqs instance
Send Message To SQS test-queueName Hello world!
Sleep 2
${messages} Receive Messages From SQS test-queueName
${dict_message} Set Variable ${messages}[0]
Dictionary Should Contain Key ${dict_message} Body
${actual_value} Get From Dictionary ${dict_message} Body
Should Be Equal ${actual_value} Hello world!

Invalid Queue Name
SQS Set Endpoint Url http://localhost:4566 # Point to localstack sqs instance
TRY
Send Message To SQS invalid-queueName Hello world!
EXCEPT Queue name 'invalid-queueName' not found.
Log caught exception
END

Delete Messages
SQS Set Endpoint Url http://localhost:4566 # Point to localstack sqs instance
Delete All Messages In SQS test-queueName
${messages} Receive Messages From SQS test-queueName
${count} Get Length ${messages}
Should Be Equal As Integers ${count} 0

0 comments on commit 2f6f6e9

Please sign in to comment.