<?php namespace Codeception\Module; use Codeception\Module as CodeceptionModule; use Codeception\TestInterface; use Codeception\Exception\ModuleConfigException; use Codeception\Lib\Driver\AmazonSQS; use Codeception\Lib\Driver\Beanstalk; use Codeception\Lib\Driver\Iron; /** * * Works with Queue servers. * * Testing with a selection of remote/local queueing services, including Amazon's SQS service * Iron.io service and beanstalkd service. * * Supported and tested queue types are: * * * [Iron.io](http://iron.io/) * * [Beanstalkd](http://kr.github.io/beanstalkd/) * * [Amazon SQS](http://aws.amazon.com/sqs/) * * The following dependencies are needed for the listed queue servers: * * * Beanstalkd: pda/pheanstalk ~3.0 * * Amazon SQS: aws/aws-sdk-php * * IronMQ: iron-io/iron_mq * * ## Status * * * Maintainer: **nathanmac** * * Stability: * - Iron.io: **stable** * - Beanstalkd: **stable** * - Amazon SQS: **stable** * * Contact: nathan.macnamara@outlook.com * * ## Config * * The configuration settings depending on which queueing service is being used, all the options are listed * here. Refer to the configuration examples below to identify the configuration options required for your chosen * service. * * * type - type of queueing server (defaults to beanstalkd). * * host - hostname/ip address of the queue server or the host for the iron.io when using iron.io service. * * port: 11300 - port number for the queue server. * * timeout: 90 - timeout settings for connecting the queue server. * * token - Iron.io access token. * * project - Iron.io project ID. * * key - AWS access key ID. * * version - AWS version (e.g. latest) * * endpoint - The full URI of the webservice. This is only required when connecting to a custom endpoint (e.g., a local version of SQS). * * secret - AWS secret access key. * Warning: * Hard-coding your credentials can be dangerous, because it is easy to accidentally commit your credentials * into an SCM repository, potentially exposing your credentials to more people than intended. * It can also make it difficult to rotate credentials in the future. * * profile - AWS credential profile * - it should be located in ~/.aws/credentials file * - eg: [default] * aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID * aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY * [project1] * aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID * aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY * - Note: Using IAM roles is the preferred technique for providing credentials * to applications running on Amazon EC2 * http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html?highlight=credentials * * * region - A region parameter is also required for AWS, refer to the AWS documentation for possible values list. * * ### Example * #### Example (beanstalkd) * * modules: * enabled: [Queue] * config: * Queue: * type: 'beanstalkd' * host: '127.0.0.1' * port: 11300 * timeout: 120 * * #### Example (Iron.io) * * modules: * enabled: [Queue] * config: * Queue: * 'type': 'iron', * 'host': 'mq-aws-us-east-1.iron.io', * 'token': 'your-token', * 'project': 'your-project-id' * * #### Example (AWS SQS) * * modules: * enabled: [Queue] * config: * Queue: * 'type': 'aws', * 'key': 'your-public-key', * 'secret': 'your-secret-key', * 'region': 'us-west-2' * * #### Example AWS SQS using profile credentials * * modules: * enabled: [Queue] * config: * Queue: * 'type': 'aws', * 'profile': 'project1', //see documentation * 'region': 'us-west-2' * * #### Example AWS SQS running on Amazon EC2 instance * * modules: * enabled: [Queue] * config: * Queue: * 'type': 'aws', * 'region': 'us-west-2' * */ class Queue extends CodeceptionModule { /** * @var \Codeception\Lib\Interfaces\Queue */ public $queueDriver; /** * Setup connection and open/setup the connection with config settings * * @param \Codeception\TestInterface $test */ public function _before(TestInterface $test) { $this->queueDriver->openConnection($this->config); } /** * Provide and override for the config settings and allow custom settings depending on the service being used. */ protected function validateConfig() { $this->queueDriver = $this->createQueueDriver(); $this->requiredFields = $this->queueDriver->getRequiredConfig(); $this->config = array_merge($this->queueDriver->getDefaultConfig(), $this->config); parent::validateConfig(); } /** * @return \Codeception\Lib\Interfaces\Queue * @throws ModuleConfigException */ protected function createQueueDriver() { switch ($this->config['type']) { case 'aws': case 'sqs': case 'aws_sqs': return new AmazonSQS(); case 'iron': case 'iron_mq': return new Iron(); case 'beanstalk': case 'beanstalkd': case 'beanstalkq': return new Beanstalk(); default: throw new ModuleConfigException( __CLASS__, "Unknown queue type {$this->config}; Supported queue types are: aws, iron, beanstalk" ); } } // ----------- SEARCH METHODS BELOW HERE ------------------------// /** * Check if a queue/tube exists on the queueing server. * * ```php * <?php * $I->seeQueueExists('default'); * ?> * ``` * * @param string $queue Queue Name */ public function seeQueueExists($queue) { $this->assertContains($queue, $this->queueDriver->getQueues()); } /** * Check if a queue/tube does NOT exist on the queueing server. * * ```php * <?php * $I->dontSeeQueueExists('default'); * ?> * ``` * * @param string $queue Queue Name */ public function dontSeeQueueExists($queue) { $this->assertNotContains($queue, $this->queueDriver->getQueues()); } /** * Check if a queue/tube is empty of all messages * * ```php * <?php * $I->seeEmptyQueue('default'); * ?> * ``` * * @param string $queue Queue Name */ public function seeEmptyQueue($queue) { $this->assertEquals(0, $this->queueDriver->getMessagesCurrentCountOnQueue($queue)); } /** * Check if a queue/tube is NOT empty of all messages * * ```php * <?php * $I->dontSeeEmptyQueue('default'); * ?> * ``` * * @param string $queue Queue Name */ public function dontSeeEmptyQueue($queue) { $this->assertNotEquals(0, $this->queueDriver->getMessagesCurrentCountOnQueue($queue)); } /** * Check if a queue/tube has a given current number of messages * * ```php * <?php * $I->seeQueueHasCurrentCount('default', 10); * ?> * ``` * * @param string $queue Queue Name * @param int $expected Number of messages expected */ public function seeQueueHasCurrentCount($queue, $expected) { $this->assertEquals($expected, $this->queueDriver->getMessagesCurrentCountOnQueue($queue)); } /** * Check if a queue/tube does NOT have a given current number of messages * * ```php * <?php * $I->dontSeeQueueHasCurrentCount('default', 10); * ?> * ``` * * @param string $queue Queue Name * @param int $expected Number of messages expected */ public function dontSeeQueueHasCurrentCount($queue, $expected) { $this->assertNotEquals($expected, $this->queueDriver->getMessagesCurrentCountOnQueue($queue)); } /** * Check if a queue/tube has a given total number of messages * * ```php * <?php * $I->seeQueueHasTotalCount('default', 10); * ?> * ``` * * @param string $queue Queue Name * @param int $expected Number of messages expected */ public function seeQueueHasTotalCount($queue, $expected) { $this->assertEquals($expected, $this->queueDriver->getMessagesTotalCountOnQueue($queue)); } /** * Check if a queue/tube does NOT have a given total number of messages * * ```php * <?php * $I->dontSeeQueueHasTotalCount('default', 10); * ?> * ``` * * @param string $queue Queue Name * @param int $expected Number of messages expected */ public function dontSeeQueueHasTotalCount($queue, $expected) { $this->assertNotEquals($expected, $this->queueDriver->getMessagesTotalCountOnQueue($queue)); } // ----------- UTILITY METHODS BELOW HERE -------------------------// /** * Add a message to a queue/tube * * ```php * <?php * $I->addMessageToQueue('this is a messages', 'default'); * ?> * ``` * * @param string $message Message Body * @param string $queue Queue Name */ public function addMessageToQueue($message, $queue) { $this->queueDriver->addMessageToQueue($message, $queue); } /** * Clear all messages of the queue/tube * * ```php * <?php * $I->clearQueue('default'); * ?> * ``` * * @param string $queue Queue Name */ public function clearQueue($queue) { $this->queueDriver->clearQueue($queue); } // ----------- GRABBER METHODS BELOW HERE -----------------------// /** * Grabber method to get the list of queues/tubes on the server * * ```php * <?php * $queues = $I->grabQueues(); * ?> * ``` * * @return array List of Queues/Tubes */ public function grabQueues() { return $this->queueDriver->getQueues(); } /** * Grabber method to get the current number of messages on the queue/tube (pending/ready) * * ```php * <?php * $I->grabQueueCurrentCount('default'); * ?> * ``` * @param string $queue Queue Name * * @return int Count */ public function grabQueueCurrentCount($queue) { return $this->queueDriver->getMessagesCurrentCountOnQueue($queue); } /** * Grabber method to get the total number of messages on the queue/tube * * ```php * <?php * $I->grabQueueTotalCount('default'); * ?> * ``` * * @param $queue Queue Name * * @return int Count */ public function grabQueueTotalCount($queue) { return $this->queueDriver->getMessagesTotalCountOnQueue($queue); } }