Queue.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <?php
  2. namespace Codeception\Module;
  3. use Codeception\Module as CodeceptionModule;
  4. use Codeception\TestInterface;
  5. use Codeception\Exception\ModuleConfigException;
  6. use Codeception\Lib\Driver\AmazonSQS;
  7. use Codeception\Lib\Driver\Beanstalk;
  8. use Codeception\Lib\Driver\Iron;
  9. /**
  10. *
  11. * Works with Queue servers.
  12. *
  13. * Testing with a selection of remote/local queueing services, including Amazon's SQS service
  14. * Iron.io service and beanstalkd service.
  15. *
  16. * Supported and tested queue types are:
  17. *
  18. * * [Iron.io](http://iron.io/)
  19. * * [Beanstalkd](http://kr.github.io/beanstalkd/)
  20. * * [Amazon SQS](http://aws.amazon.com/sqs/)
  21. *
  22. * The following dependencies are needed for the listed queue servers:
  23. *
  24. * * Beanstalkd: pda/pheanstalk ~3.0
  25. * * Amazon SQS: aws/aws-sdk-php
  26. * * IronMQ: iron-io/iron_mq
  27. *
  28. * ## Status
  29. *
  30. * * Stability:
  31. * - Iron.io: **stable**
  32. * - Beanstalkd: **stable**
  33. * - Amazon SQS: **stable**
  34. *
  35. * ## Config
  36. *
  37. * The configuration settings depending on which queueing service is being used, all the options are listed
  38. * here. Refer to the configuration examples below to identify the configuration options required for your chosen
  39. * service.
  40. *
  41. * * type - type of queueing server (defaults to beanstalkd).
  42. * * host - hostname/ip address of the queue server or the host for the iron.io when using iron.io service.
  43. * * port: 11300 - port number for the queue server.
  44. * * timeout: 90 - timeout settings for connecting the queue server.
  45. * * token - Iron.io access token.
  46. * * project - Iron.io project ID.
  47. * * key - AWS access key ID.
  48. * * version - AWS version (e.g. latest)
  49. * * endpoint - The full URI of the webservice. This is only required when connecting to a custom endpoint (e.g., a local version of SQS).
  50. * * secret - AWS secret access key.
  51. * Warning:
  52. * Hard-coding your credentials can be dangerous, because it is easy to accidentally commit your credentials
  53. * into an SCM repository, potentially exposing your credentials to more people than intended.
  54. * It can also make it difficult to rotate credentials in the future.
  55. * * profile - AWS credential profile
  56. * - it should be located in ~/.aws/credentials file
  57. * - eg: [default]
  58. * aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
  59. * aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
  60. * [project1]
  61. * aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
  62. * aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
  63. * - Note: Using IAM roles is the preferred technique for providing credentials
  64. * to applications running on Amazon EC2
  65. * http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html?highlight=credentials
  66. *
  67. * * region - A region parameter is also required for AWS, refer to the AWS documentation for possible values list.
  68. *
  69. * ### Example
  70. * #### Example (beanstalkd)
  71. *
  72. * modules:
  73. * enabled: [Queue]
  74. * config:
  75. * Queue:
  76. * type: 'beanstalkd'
  77. * host: '127.0.0.1'
  78. * port: 11300
  79. * timeout: 120
  80. *
  81. * #### Example (Iron.io)
  82. *
  83. * modules:
  84. * enabled: [Queue]
  85. * config:
  86. * Queue:
  87. * 'type': 'iron',
  88. * 'host': 'mq-aws-us-east-1.iron.io',
  89. * 'token': 'your-token',
  90. * 'project': 'your-project-id'
  91. *
  92. * #### Example (AWS SQS)
  93. *
  94. * modules:
  95. * enabled: [Queue]
  96. * config:
  97. * Queue:
  98. * 'type': 'aws',
  99. * 'key': 'your-public-key',
  100. * 'secret': 'your-secret-key',
  101. * 'region': 'us-west-2'
  102. *
  103. * #### Example AWS SQS using profile credentials
  104. *
  105. * modules:
  106. * enabled: [Queue]
  107. * config:
  108. * Queue:
  109. * 'type': 'aws',
  110. * 'profile': 'project1', //see documentation
  111. * 'region': 'us-west-2'
  112. *
  113. * #### Example AWS SQS running on Amazon EC2 instance
  114. *
  115. * modules:
  116. * enabled: [Queue]
  117. * config:
  118. * Queue:
  119. * 'type': 'aws',
  120. * 'region': 'us-west-2'
  121. *
  122. */
  123. class Queue extends CodeceptionModule
  124. {
  125. /**
  126. * @var \Codeception\Lib\Interfaces\Queue
  127. */
  128. public $queueDriver;
  129. /**
  130. * Setup connection and open/setup the connection with config settings
  131. *
  132. * @param \Codeception\TestInterface $test
  133. */
  134. public function _before(TestInterface $test)
  135. {
  136. $this->queueDriver->openConnection($this->config);
  137. }
  138. /**
  139. * Provide and override for the config settings and allow custom settings depending on the service being used.
  140. */
  141. protected function validateConfig()
  142. {
  143. $this->queueDriver = $this->createQueueDriver();
  144. $this->requiredFields = $this->queueDriver->getRequiredConfig();
  145. $this->config = array_merge($this->queueDriver->getDefaultConfig(), $this->config);
  146. parent::validateConfig();
  147. }
  148. /**
  149. * @return \Codeception\Lib\Interfaces\Queue
  150. * @throws ModuleConfigException
  151. */
  152. protected function createQueueDriver()
  153. {
  154. switch ($this->config['type']) {
  155. case 'aws':
  156. case 'sqs':
  157. case 'aws_sqs':
  158. return new AmazonSQS();
  159. case 'iron':
  160. case 'iron_mq':
  161. return new Iron();
  162. case 'beanstalk':
  163. case 'beanstalkd':
  164. case 'beanstalkq':
  165. return new Beanstalk();
  166. default:
  167. throw new ModuleConfigException(
  168. __CLASS__,
  169. "Unknown queue type {$this->config}; Supported queue types are: aws, iron, beanstalk"
  170. );
  171. }
  172. }
  173. // ----------- SEARCH METHODS BELOW HERE ------------------------//
  174. /**
  175. * Check if a queue/tube exists on the queueing server.
  176. *
  177. * ```php
  178. * <?php
  179. * $I->seeQueueExists('default');
  180. * ?>
  181. * ```
  182. *
  183. * @param string $queue Queue Name
  184. */
  185. public function seeQueueExists($queue)
  186. {
  187. $this->assertContains($queue, $this->queueDriver->getQueues());
  188. }
  189. /**
  190. * Check if a queue/tube does NOT exist on the queueing server.
  191. *
  192. * ```php
  193. * <?php
  194. * $I->dontSeeQueueExists('default');
  195. * ?>
  196. * ```
  197. *
  198. * @param string $queue Queue Name
  199. */
  200. public function dontSeeQueueExists($queue)
  201. {
  202. $this->assertNotContains($queue, $this->queueDriver->getQueues());
  203. }
  204. /**
  205. * Check if a queue/tube is empty of all messages
  206. *
  207. * ```php
  208. * <?php
  209. * $I->seeEmptyQueue('default');
  210. * ?>
  211. * ```
  212. *
  213. * @param string $queue Queue Name
  214. */
  215. public function seeEmptyQueue($queue)
  216. {
  217. $this->assertEquals(0, $this->queueDriver->getMessagesCurrentCountOnQueue($queue));
  218. }
  219. /**
  220. * Check if a queue/tube is NOT empty of all messages
  221. *
  222. * ```php
  223. * <?php
  224. * $I->dontSeeEmptyQueue('default');
  225. * ?>
  226. * ```
  227. *
  228. * @param string $queue Queue Name
  229. */
  230. public function dontSeeEmptyQueue($queue)
  231. {
  232. $this->assertNotEquals(0, $this->queueDriver->getMessagesCurrentCountOnQueue($queue));
  233. }
  234. /**
  235. * Check if a queue/tube has a given current number of messages
  236. *
  237. * ```php
  238. * <?php
  239. * $I->seeQueueHasCurrentCount('default', 10);
  240. * ?>
  241. * ```
  242. *
  243. * @param string $queue Queue Name
  244. * @param int $expected Number of messages expected
  245. */
  246. public function seeQueueHasCurrentCount($queue, $expected)
  247. {
  248. $this->assertEquals($expected, $this->queueDriver->getMessagesCurrentCountOnQueue($queue));
  249. }
  250. /**
  251. * Check if a queue/tube does NOT have a given current number of messages
  252. *
  253. * ```php
  254. * <?php
  255. * $I->dontSeeQueueHasCurrentCount('default', 10);
  256. * ?>
  257. * ```
  258. *
  259. * @param string $queue Queue Name
  260. * @param int $expected Number of messages expected
  261. */
  262. public function dontSeeQueueHasCurrentCount($queue, $expected)
  263. {
  264. $this->assertNotEquals($expected, $this->queueDriver->getMessagesCurrentCountOnQueue($queue));
  265. }
  266. /**
  267. * Check if a queue/tube has a given total number of messages
  268. *
  269. * ```php
  270. * <?php
  271. * $I->seeQueueHasTotalCount('default', 10);
  272. * ?>
  273. * ```
  274. *
  275. * @param string $queue Queue Name
  276. * @param int $expected Number of messages expected
  277. */
  278. public function seeQueueHasTotalCount($queue, $expected)
  279. {
  280. $this->assertEquals($expected, $this->queueDriver->getMessagesTotalCountOnQueue($queue));
  281. }
  282. /**
  283. * Check if a queue/tube does NOT have a given total number of messages
  284. *
  285. * ```php
  286. * <?php
  287. * $I->dontSeeQueueHasTotalCount('default', 10);
  288. * ?>
  289. * ```
  290. *
  291. * @param string $queue Queue Name
  292. * @param int $expected Number of messages expected
  293. */
  294. public function dontSeeQueueHasTotalCount($queue, $expected)
  295. {
  296. $this->assertNotEquals($expected, $this->queueDriver->getMessagesTotalCountOnQueue($queue));
  297. }
  298. // ----------- UTILITY METHODS BELOW HERE -------------------------//
  299. /**
  300. * Add a message to a queue/tube
  301. *
  302. * ```php
  303. * <?php
  304. * $I->addMessageToQueue('this is a messages', 'default');
  305. * ?>
  306. * ```
  307. *
  308. * @param string $message Message Body
  309. * @param string $queue Queue Name
  310. */
  311. public function addMessageToQueue($message, $queue)
  312. {
  313. $this->queueDriver->addMessageToQueue($message, $queue);
  314. }
  315. /**
  316. * Clear all messages of the queue/tube
  317. *
  318. * ```php
  319. * <?php
  320. * $I->clearQueue('default');
  321. * ?>
  322. * ```
  323. *
  324. * @param string $queue Queue Name
  325. */
  326. public function clearQueue($queue)
  327. {
  328. $this->queueDriver->clearQueue($queue);
  329. }
  330. // ----------- GRABBER METHODS BELOW HERE -----------------------//
  331. /**
  332. * Grabber method to get the list of queues/tubes on the server
  333. *
  334. * ```php
  335. * <?php
  336. * $queues = $I->grabQueues();
  337. * ?>
  338. * ```
  339. *
  340. * @return array List of Queues/Tubes
  341. */
  342. public function grabQueues()
  343. {
  344. return $this->queueDriver->getQueues();
  345. }
  346. /**
  347. * Grabber method to get the current number of messages on the queue/tube (pending/ready)
  348. *
  349. * ```php
  350. * <?php
  351. * $I->grabQueueCurrentCount('default');
  352. * ?>
  353. * ```
  354. * @param string $queue Queue Name
  355. *
  356. * @return int Count
  357. */
  358. public function grabQueueCurrentCount($queue)
  359. {
  360. return $this->queueDriver->getMessagesCurrentCountOnQueue($queue);
  361. }
  362. /**
  363. * Grabber method to get the total number of messages on the queue/tube
  364. *
  365. * ```php
  366. * <?php
  367. * $I->grabQueueTotalCount('default');
  368. * ?>
  369. * ```
  370. *
  371. * @param $queue Queue Name
  372. *
  373. * @return int Count
  374. */
  375. public function grabQueueTotalCount($queue)
  376. {
  377. return $this->queueDriver->getMessagesTotalCountOnQueue($queue);
  378. }
  379. }