test_boto3_elasticsearch.py 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for salt.modules.boto3_elasticsearch
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import datetime
  8. import random
  9. import string
  10. import textwrap
  11. import pytest
  12. # Import Salt libs
  13. import salt.loader
  14. import salt.modules.boto3_elasticsearch as boto3_elasticsearch
  15. from salt.ext.six.moves import range
  16. from salt.utils.versions import LooseVersion
  17. # Import Salt Testing libs
  18. from tests.support.mixins import LoaderModuleMockMixin
  19. from tests.support.mock import MagicMock, patch
  20. from tests.support.unit import TestCase, skipIf
  21. # Import 3rd-party libs
  22. try:
  23. import boto3
  24. from botocore.exceptions import ClientError
  25. HAS_BOTO3 = True
  26. except ImportError:
  27. HAS_BOTO3 = False
  28. # the boto3_elasticsearch module relies on the connect_to_region() method
  29. # which was added in boto 2.8.0
  30. # https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12
  31. REQUIRED_BOTO3_VERSION = "1.2.1"
  32. def __virtual__():
  33. """
  34. Returns True/False boolean depending on if Boto3 is installed and correct
  35. version.
  36. """
  37. if not HAS_BOTO3:
  38. return False
  39. if LooseVersion(boto3.__version__) < LooseVersion(REQUIRED_BOTO3_VERSION):
  40. return (
  41. False,
  42. (
  43. "The boto3 module must be greater or equal to version {}"
  44. "".format(REQUIRED_BOTO3_VERSION)
  45. ),
  46. )
  47. return True
  48. REGION = "us-east-1"
  49. ACCESS_KEY = "GKTADJGHEIQSXMKKRBJ08H"
  50. SECRET_KEY = "askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs"
  51. CONN_PARAMETERS = {
  52. "region": REGION,
  53. "key": ACCESS_KEY,
  54. "keyid": SECRET_KEY,
  55. "profile": {},
  56. }
  57. ERROR_MESSAGE = (
  58. "An error occurred ({}) when calling the {} operation: Test-defined error"
  59. )
  60. ERROR_CONTENT = {"Error": {"Code": 101, "Message": "Test-defined error"}}
  61. NOT_FOUND_ERROR = ClientError(
  62. {"Error": {"Code": "ResourceNotFoundException", "Message": "Test-defined error"}},
  63. "msg",
  64. )
  65. DOMAIN_RET = {
  66. "DomainId": "accountno/testdomain",
  67. "DomainName": "testdomain",
  68. "ARN": "arn:aws:es:region:accountno:domain/testdomain",
  69. "Created": True,
  70. "Deleted": False,
  71. "Endpoints": {"vpc": "vpc-testdomain-1234567890.region.es.amazonaws.com"},
  72. "Processing": False,
  73. "UpgradeProcessing": False,
  74. "ElasticsearchVersion": "6.3",
  75. "ElasticsearchClusterConfig": {
  76. "InstanceType": "t2.medium.elasticsearch",
  77. "InstanceCount": 1,
  78. "DedicatedMasterEnabled": False,
  79. "ZoneAwarenessEnabled": False,
  80. },
  81. "EBSOptions": {
  82. "EBSEnabled": True,
  83. "VolumeType": "gp2",
  84. "VolumeSize": 123,
  85. "Iops": 12,
  86. },
  87. "AccessPolicies": textwrap.dedent(
  88. """
  89. {"Version":"2012-10-17","Statement":[{"Effect":"Allow",
  90. "Principal":{"AWS":"*"},"Action":"es:*",
  91. "Resource":"arn:aws:es:region:accountno:domain/testdomain/*"}]}"""
  92. ),
  93. "SnapshotOptions": {"AutomatedSnapshotStartHour": 1},
  94. "VPCOptions": {
  95. "VPCId": "vpc-12345678",
  96. "SubnetIds": ["subnet-deadbeef"],
  97. "AvailabilityZones": ["regiona"],
  98. "SecurityGroupIds": ["sg-87654321"],
  99. },
  100. "CognitoOptions": {"Enabled": False},
  101. "EncryptionAtRestOptions": {"Enabled": False},
  102. "NodeToNodeEncryptionOptions": {"Enabled": False},
  103. "AdvancedOptions": {"rest.action.multi.allow_explicit_index": "true"},
  104. "ServiceSoftwareOptions": {
  105. "CurrentVersion": "R20190221-P1",
  106. "NewVersion": "R20190418",
  107. "UpdateAvailable": True,
  108. "Cancellable": False,
  109. "UpdateStatus": "ELIGIBLE",
  110. "Description": (
  111. "A newer release R20190418 is available. This release "
  112. "will be automatically deployed after somedate"
  113. ),
  114. "AutomatedUpdateDate": None,
  115. },
  116. }
  117. @skipIf(HAS_BOTO3 is False, "The boto module must be installed.")
  118. @skipIf(
  119. LooseVersion(boto3.__version__) < LooseVersion(REQUIRED_BOTO3_VERSION),
  120. "The boto3 module must be greater or equal to version {}".format(
  121. REQUIRED_BOTO3_VERSION
  122. ),
  123. )
  124. class Boto3ElasticsearchTestCase(TestCase, LoaderModuleMockMixin):
  125. """
  126. TestCase for salt.modules.boto3_elasticsearch module
  127. """
  128. conn = None
  129. def setup_loader_modules(self):
  130. self.opts = salt.config.DEFAULT_MINION_OPTS.copy()
  131. utils = salt.loader.utils(
  132. self.opts,
  133. whitelist=["boto3", "args", "systemd", "path", "platform"],
  134. context={},
  135. )
  136. return {boto3_elasticsearch: {"__utils__": utils}}
  137. def setUp(self):
  138. super(Boto3ElasticsearchTestCase, self).setUp()
  139. boto3_elasticsearch.__init__(self.opts)
  140. del self.opts
  141. # Set up MagicMock to replace the boto3 session
  142. # connections keep getting cached from prior tests, can't find the
  143. # correct context object to clear it. So randomize the cache key, to prevent any
  144. # cache hits
  145. CONN_PARAMETERS["key"] = "".join(
  146. random.choice(string.ascii_lowercase + string.digits) for _ in range(50)
  147. )
  148. self.conn = MagicMock()
  149. self.addCleanup(delattr, self, "conn")
  150. self.patcher = patch("boto3.session.Session")
  151. self.addCleanup(self.patcher.stop)
  152. self.addCleanup(delattr, self, "patcher")
  153. mock_session = self.patcher.start()
  154. session_instance = mock_session.return_value
  155. session_instance.configure_mock(client=MagicMock(return_value=self.conn))
  156. self.paginator = MagicMock()
  157. self.addCleanup(delattr, self, "paginator")
  158. self.conn.configure_mock(get_paginator=MagicMock(return_value=self.paginator))
  159. def test_describe_elasticsearch_domain_positive(self):
  160. """
  161. Test that when describing a domain when the domain actually exists,
  162. the .exists method returns a dict with 'result': True
  163. and 'response' with the domain status information.
  164. """
  165. # The patch below is not neccesary per se,
  166. # as .exists returns positive as long as no exception is raised.
  167. with patch.object(
  168. self.conn,
  169. "describe_elasticsearch_domain",
  170. return_value={"DomainStatus": DOMAIN_RET},
  171. ):
  172. self.assertEqual(
  173. boto3_elasticsearch.describe_elasticsearch_domain(
  174. domain_name="testdomain", **CONN_PARAMETERS
  175. ),
  176. {"result": True, "response": DOMAIN_RET},
  177. )
  178. def test_describe_elasticsearch_domain_error(self):
  179. """
  180. Test that when describing a domain when the domain does not exist,
  181. the .exists method returns a dict with 'result': False
  182. and 'error' with boto's ResourceNotFoundException.
  183. """
  184. with patch.object(
  185. self.conn, "describe_elasticsearch_domain", side_effect=NOT_FOUND_ERROR
  186. ):
  187. result = boto3_elasticsearch.describe_elasticsearch_domain(
  188. domain_name="testdomain", **CONN_PARAMETERS
  189. )
  190. self.assertEqual(
  191. result.get("error", ""),
  192. ERROR_MESSAGE.format("ResourceNotFoundException", "msg"),
  193. )
  194. self.assertFalse(result["result"])
  195. def test_create_elasticsearch_domain_positive(self):
  196. """
  197. Test that when creating a domain, and it succeeds,
  198. the .create method returns a dict with 'result': True
  199. and 'response' with the newly created domain's status information.
  200. """
  201. with patch.object(
  202. self.conn,
  203. "create_elasticsearch_domain",
  204. return_value={"DomainStatus": DOMAIN_RET},
  205. ):
  206. kwargs = {
  207. "elasticsearch_version": DOMAIN_RET["ElasticsearchVersion"],
  208. "elasticsearch_cluster_config": DOMAIN_RET[
  209. "ElasticsearchClusterConfig"
  210. ],
  211. "ebs_options": DOMAIN_RET["EBSOptions"],
  212. "access_policies": DOMAIN_RET["AccessPolicies"],
  213. "snapshot_options": DOMAIN_RET["SnapshotOptions"],
  214. "vpc_options": DOMAIN_RET["VPCOptions"],
  215. "cognito_options": DOMAIN_RET["CognitoOptions"],
  216. "encryption_at_rest_options": DOMAIN_RET["EncryptionAtRestOptions"],
  217. "advanced_options": DOMAIN_RET["AdvancedOptions"],
  218. }
  219. kwargs.update(CONN_PARAMETERS)
  220. self.assertEqual(
  221. boto3_elasticsearch.create_elasticsearch_domain(
  222. domain_name="testdomain", **kwargs
  223. ),
  224. {"result": True, "response": DOMAIN_RET},
  225. )
  226. def test_create_elasticsearch_domain_error(self):
  227. """
  228. Test that when creating a domain, and boto3 returns an error,
  229. the .create method returns a dict with 'result': False
  230. and 'error' with the error reported by boto3.
  231. """
  232. with patch.object(
  233. self.conn,
  234. "create_elasticsearch_domain",
  235. side_effect=ClientError(ERROR_CONTENT, "create_domain"),
  236. ):
  237. kwargs = {
  238. "elasticsearch_version": DOMAIN_RET["ElasticsearchVersion"],
  239. "elasticsearch_cluster_config": DOMAIN_RET[
  240. "ElasticsearchClusterConfig"
  241. ],
  242. "ebs_options": DOMAIN_RET["EBSOptions"],
  243. "access_policies": DOMAIN_RET["AccessPolicies"],
  244. "snapshot_options": DOMAIN_RET["SnapshotOptions"],
  245. "vpc_options": DOMAIN_RET["VPCOptions"],
  246. "cognito_options": DOMAIN_RET["CognitoOptions"],
  247. "encryption_at_rest_options": DOMAIN_RET["EncryptionAtRestOptions"],
  248. "advanced_options": DOMAIN_RET["AdvancedOptions"],
  249. }
  250. kwargs.update(CONN_PARAMETERS)
  251. result = boto3_elasticsearch.create_elasticsearch_domain(
  252. "testdomain", **kwargs
  253. )
  254. self.assertEqual(
  255. result.get("error", ""), ERROR_MESSAGE.format(101, "create_domain")
  256. )
  257. def test_delete_domain_positive(self):
  258. """
  259. Test that when deleting a domain, and it succeeds,
  260. the .delete method returns {'result': True}.
  261. """
  262. with patch.object(self.conn, "delete_elasticsearch_domain"):
  263. self.assertEqual(
  264. boto3_elasticsearch.delete_elasticsearch_domain(
  265. "testdomain", **CONN_PARAMETERS
  266. ),
  267. {"result": True},
  268. )
  269. def test_delete_domain_error(self):
  270. """
  271. Test that when deleting a domain, and boto3 returns an error,
  272. the .delete method returns {'result': False, 'error' :'the error'}.
  273. """
  274. with patch.object(
  275. self.conn,
  276. "delete_elasticsearch_domain",
  277. side_effect=ClientError(ERROR_CONTENT, "delete_domain"),
  278. ):
  279. result = boto3_elasticsearch.delete_elasticsearch_domain(
  280. "testdomain", **CONN_PARAMETERS
  281. )
  282. self.assertFalse(result["result"])
  283. self.assertEqual(
  284. result.get("error", ""), ERROR_MESSAGE.format(101, "delete_domain")
  285. )
  286. def test_update_domain_positive(self):
  287. """
  288. Test that when updating a domain succeeds, the .update method returns {'result': True}.
  289. """
  290. with patch.object(
  291. self.conn,
  292. "update_elasticsearch_domain_config",
  293. return_value={"DomainConfig": DOMAIN_RET},
  294. ):
  295. kwargs = {
  296. "elasticsearch_cluster_config": DOMAIN_RET[
  297. "ElasticsearchClusterConfig"
  298. ],
  299. "ebs_options": DOMAIN_RET["EBSOptions"],
  300. "snapshot_options": DOMAIN_RET["SnapshotOptions"],
  301. "vpc_options": DOMAIN_RET["VPCOptions"],
  302. "cognito_options": DOMAIN_RET["CognitoOptions"],
  303. "advanced_options": DOMAIN_RET["AdvancedOptions"],
  304. "access_policies": DOMAIN_RET["AccessPolicies"],
  305. "log_publishing_options": {},
  306. }
  307. kwargs.update(CONN_PARAMETERS)
  308. self.assertEqual(
  309. boto3_elasticsearch.update_elasticsearch_domain_config(
  310. "testdomain", **kwargs
  311. ),
  312. {"result": True, "response": DOMAIN_RET},
  313. )
  314. def test_update_domain_error(self):
  315. """
  316. Test that when updating a domain fails, and boto3 returns an error,
  317. the .update method returns the error.
  318. """
  319. with patch.object(
  320. self.conn,
  321. "update_elasticsearch_domain_config",
  322. side_effect=ClientError(ERROR_CONTENT, "update_domain"),
  323. ):
  324. kwargs = {
  325. "elasticsearch_cluster_config": DOMAIN_RET[
  326. "ElasticsearchClusterConfig"
  327. ],
  328. "ebs_options": DOMAIN_RET["EBSOptions"],
  329. "snapshot_options": DOMAIN_RET["SnapshotOptions"],
  330. "vpc_options": DOMAIN_RET["VPCOptions"],
  331. "cognito_options": DOMAIN_RET["CognitoOptions"],
  332. "advanced_options": DOMAIN_RET["AdvancedOptions"],
  333. "access_policies": DOMAIN_RET["AccessPolicies"],
  334. "log_publishing_options": {},
  335. }
  336. kwargs.update(CONN_PARAMETERS)
  337. result = boto3_elasticsearch.update_elasticsearch_domain_config(
  338. "testdomain", **kwargs
  339. )
  340. self.assertEqual(
  341. result.get("error", ""), ERROR_MESSAGE.format(101, "update_domain")
  342. )
  343. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  344. def test_add_tags_positive(self):
  345. """
  346. Test that when adding tags is succesful, the .add_tags method returns {'result': True}.
  347. """
  348. with patch.object(
  349. self.conn,
  350. "describe_elasticsearch_domain",
  351. return_value={"DomainStatus": DOMAIN_RET},
  352. ):
  353. self.assertEqual(
  354. boto3_elasticsearch.add_tags(
  355. "testdomain", tags={"foo": "bar", "baz": "qux"}, **CONN_PARAMETERS
  356. ),
  357. {"result": True},
  358. )
  359. def test_add_tags_error(self):
  360. """
  361. Test that when adding tags fails, and boto3 returns an error,
  362. the .add_tags function returns {'tagged': False, 'error': 'the error'}.
  363. """
  364. with patch.object(
  365. self.conn, "add_tags", side_effect=ClientError(ERROR_CONTENT, "add_tags")
  366. ), patch.object(
  367. self.conn,
  368. "describe_elasticsearch_domain",
  369. return_value={"DomainStatus": DOMAIN_RET},
  370. ):
  371. result = boto3_elasticsearch.add_tags(
  372. "testdomain", tags={"foo": "bar", "baz": "qux"}, **CONN_PARAMETERS
  373. )
  374. self.assertFalse(result["result"])
  375. self.assertEqual(
  376. result.get("error", ""), ERROR_MESSAGE.format(101, "add_tags")
  377. )
  378. def test_remove_tags_positive(self):
  379. """
  380. Test that when removing tags is succesful, the .remove_tags method returns {'tagged': True}.
  381. """
  382. with patch.object(
  383. self.conn,
  384. "describe_elasticsearch_domain",
  385. return_value={"DomainStatus": DOMAIN_RET},
  386. ):
  387. self.assertEqual(
  388. boto3_elasticsearch.remove_tags(
  389. tag_keys=["foo", "bar"], domain_name="testdomain", **CONN_PARAMETERS
  390. ),
  391. {"result": True},
  392. )
  393. def test_remove_tag_error(self):
  394. """
  395. Test that when removing tags fails, and boto3 returns an error,
  396. the .remove_tags method returns {'tagged': False, 'error': 'the error'}.
  397. """
  398. with patch.object(
  399. self.conn,
  400. "remove_tags",
  401. side_effect=ClientError(ERROR_CONTENT, "remove_tags"),
  402. ), patch.object(
  403. self.conn,
  404. "describe_elasticsearch_domain",
  405. return_value={"DomainStatus": DOMAIN_RET},
  406. ):
  407. result = boto3_elasticsearch.remove_tags(
  408. tag_keys=["foo", "bar"], domain_name="testdomain", **CONN_PARAMETERS
  409. )
  410. self.assertFalse(result["result"])
  411. self.assertEqual(
  412. result.get("error", ""), ERROR_MESSAGE.format(101, "remove_tags")
  413. )
  414. def test_list_tags_positive(self):
  415. """
  416. Test that when listing tags is succesful,
  417. the .list_tags method returns a dict with key 'tags'.
  418. Also test that the tags returned are manipulated properly (i.e. transformed
  419. into a dict with tags).
  420. """
  421. with patch.object(
  422. self.conn,
  423. "describe_elasticsearch_domain",
  424. return_value={"DomainStatus": DOMAIN_RET},
  425. ), patch.object(
  426. self.conn,
  427. "list_tags",
  428. return_value={"TagList": [{"Key": "foo", "Value": "bar"}]},
  429. ):
  430. result = boto3_elasticsearch.list_tags(
  431. domain_name="testdomain", **CONN_PARAMETERS
  432. )
  433. self.assertEqual(result, {"result": True, "response": {"foo": "bar"}})
  434. def test_list_tags_error(self):
  435. """
  436. Test that when listing tags causes boto3 to return an error,
  437. the .list_tags method returns the error.
  438. """
  439. with patch.object(
  440. self.conn, "list_tags", side_effect=ClientError(ERROR_CONTENT, "list_tags")
  441. ), patch.object(
  442. self.conn,
  443. "describe_elasticsearch_domain",
  444. return_value={"DomainStatus": DOMAIN_RET},
  445. ):
  446. result = boto3_elasticsearch.list_tags(
  447. domain_name="testdomain", **CONN_PARAMETERS
  448. )
  449. self.assertFalse(result["result"])
  450. self.assertEqual(
  451. result.get("error", ""), ERROR_MESSAGE.format(101, "list_tags")
  452. )
  453. def test_cancel_elasticsearch_service_software_update_positive(self):
  454. """
  455. Test that when calling cancel_elasticsearch_service_software_update and
  456. it is succesful, it returns {'result': True}.
  457. """
  458. retval = {
  459. "ServiceSoftwareOptions": {
  460. "CurrentVersion": "string",
  461. "NewVersion": "string",
  462. "UpdateAvailable": True,
  463. "Cancellable": True,
  464. "UpdateStatus": "ELIGIBLE",
  465. "Description": "string",
  466. "AutomatedUpdateDate": datetime.datetime(2015, 1, 1),
  467. }
  468. }
  469. with patch.object(
  470. self.conn,
  471. "cancel_elasticsearch_service_software_update",
  472. return_value=retval,
  473. ):
  474. result = boto3_elasticsearch.cancel_elasticsearch_service_software_update(
  475. domain_name="testdomain", **CONN_PARAMETERS
  476. )
  477. self.assertEqual(result, {"result": True})
  478. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  479. def test_cancel_elasticsearch_service_software_update_error(self):
  480. """
  481. Test that when calling cancel_elasticsearch_service_software_update and
  482. boto3 returns an error, it returns {'result': False, 'error': 'the error'}.
  483. """
  484. with patch.object(
  485. self.conn,
  486. "cancel_elasticsearch_service_software_update",
  487. side_effect=ClientError(
  488. ERROR_CONTENT, "cancel_elasticsearch_service_software_update"
  489. ),
  490. ):
  491. result = boto3_elasticsearch.cancel_elasticsearch_service_software_update(
  492. domain_name="testdomain", **CONN_PARAMETERS
  493. )
  494. self.assertFalse(result["result"])
  495. self.assertEqual(
  496. result.get("error", ""),
  497. ERROR_MESSAGE.format(
  498. 101, "cancel_elasticsearch_service_software_update"
  499. ),
  500. )
  501. def test_delete_elasticsearch_service_role_positive(self):
  502. """
  503. Test that when calling delete_elasticsearch_service_role and
  504. it is succesful, it returns {'result': True}.
  505. """
  506. with patch.object(
  507. self.conn, "delete_elasticsearch_service_role", return_value=None
  508. ):
  509. result = boto3_elasticsearch.delete_elasticsearch_service_role(
  510. **CONN_PARAMETERS
  511. )
  512. self.assertEqual(result, {"result": True})
  513. def test_delete_elasticsearch_service_role_error(self):
  514. """
  515. Test that when calling delete_elasticsearch_service_role and boto3 returns
  516. an error, it returns {'result': False, 'error': 'the error'}.
  517. """
  518. with patch.object(
  519. self.conn,
  520. "delete_elasticsearch_service_role",
  521. side_effect=ClientError(ERROR_CONTENT, "delete_elasticsearch_service_role"),
  522. ):
  523. result = boto3_elasticsearch.delete_elasticsearch_service_role(
  524. **CONN_PARAMETERS
  525. )
  526. self.assertFalse(result["result"])
  527. self.assertEqual(
  528. result.get("error", ""),
  529. ERROR_MESSAGE.format(101, "delete_elasticsearch_service_role"),
  530. )
  531. def test_describe_elasticsearch_domain_config_positive(self):
  532. """
  533. Test that when calling describe_elasticsearch_domain_config and
  534. it is succesful, it returns {'result': True}.
  535. """
  536. with patch.object(
  537. self.conn,
  538. "describe_elasticsearch_domain_config",
  539. return_value={"DomainConfig": DOMAIN_RET},
  540. ):
  541. self.assertEqual(
  542. boto3_elasticsearch.describe_elasticsearch_domain_config(
  543. "testdomain", **CONN_PARAMETERS
  544. ),
  545. {"result": True, "response": DOMAIN_RET},
  546. )
  547. def test_describe_elasticsearch_domain_config_error(self):
  548. """
  549. Test that when calling describe_elasticsearch_domain_config and boto3 returns
  550. an error, it returns {'result': False, 'error': 'the error'}.
  551. """
  552. with patch.object(
  553. self.conn,
  554. "describe_elasticsearch_domain_config",
  555. side_effect=ClientError(
  556. ERROR_CONTENT, "describe_elasticsearch_domain_config"
  557. ),
  558. ):
  559. result = boto3_elasticsearch.describe_elasticsearch_domain_config(
  560. domain_name="testdomain", **CONN_PARAMETERS
  561. )
  562. self.assertFalse(result["result"])
  563. self.assertEqual(
  564. result.get("error", ""),
  565. ERROR_MESSAGE.format(101, "describe_elasticsearch_domain_config"),
  566. )
  567. def test_describe_elasticsearch_domains_positive(self):
  568. """
  569. Test that when calling describe_elasticsearch_domains and it is succesful,
  570. it returns {'result': True, 'response': some_data}.
  571. """
  572. with patch.object(
  573. self.conn,
  574. "describe_elasticsearch_domains",
  575. return_value={"DomainStatusList": [DOMAIN_RET]},
  576. ):
  577. self.assertEqual(
  578. boto3_elasticsearch.describe_elasticsearch_domains(
  579. domain_names=["test_domain"], **CONN_PARAMETERS
  580. ),
  581. {"result": True, "response": [DOMAIN_RET]},
  582. )
  583. def test_describe_elasticsearch_domains_error(self):
  584. """
  585. Test that when calling describe_elasticsearch_domains and boto3 returns
  586. an error, it returns {'result': False, 'error': 'the error'}.
  587. """
  588. with patch.object(
  589. self.conn,
  590. "describe_elasticsearch_domains",
  591. side_effect=ClientError(ERROR_CONTENT, "describe_elasticsearch_domains"),
  592. ):
  593. result = boto3_elasticsearch.describe_elasticsearch_domains(
  594. domain_names=["testdomain"], **CONN_PARAMETERS
  595. )
  596. self.assertFalse(result["result"])
  597. self.assertEqual(
  598. result.get("error", ""),
  599. ERROR_MESSAGE.format(101, "describe_elasticsearch_domains"),
  600. )
  601. def test_describe_elasticsearch_instance_type_limits_positive(self):
  602. """
  603. Test that when calling describe_elasticsearch_instance_type_limits and
  604. it succeeds, it returns {'result': True, 'response' some_value}.
  605. """
  606. ret_val = {
  607. "LimitsByRole": {
  608. "string": {
  609. "StorageTypes": [
  610. {
  611. "StorageTypeName": "string",
  612. "StorageSubTypeName": "string",
  613. "StorageTypeLimits": [
  614. {"LimitName": "string", "LimitValues": ["string"]}
  615. ],
  616. }
  617. ],
  618. "InstanceLimits": {
  619. "InstanceCountLimits": {
  620. "MinimumInstanceCount": 123,
  621. "MaximumInstanceCount": 123,
  622. }
  623. },
  624. "AdditionalLimits": [
  625. {"LimitName": "string", "LimitValues": ["string"]}
  626. ],
  627. }
  628. }
  629. }
  630. with patch.object(
  631. self.conn,
  632. "describe_elasticsearch_instance_type_limits",
  633. return_value=ret_val,
  634. ):
  635. self.assertEqual(
  636. boto3_elasticsearch.describe_elasticsearch_instance_type_limits(
  637. domain_name="testdomain",
  638. instance_type="foo",
  639. elasticsearch_version="1.0",
  640. **CONN_PARAMETERS
  641. ),
  642. {"result": True, "response": ret_val["LimitsByRole"]},
  643. )
  644. def test_describe_elasticsearch_instance_type_limits_error(self):
  645. """
  646. Test that when calling describe_elasticsearch_instance_type_limits and boto3 returns
  647. an error, it returns {'result': False, 'error': 'the error'}.
  648. """
  649. with patch.object(
  650. self.conn,
  651. "describe_elasticsearch_instance_type_limits",
  652. side_effect=ClientError(
  653. ERROR_CONTENT, "describe_elasticsearch_instance_type_limits"
  654. ),
  655. ):
  656. result = boto3_elasticsearch.describe_elasticsearch_instance_type_limits(
  657. domain_name="testdomain",
  658. instance_type="foo",
  659. elasticsearch_version="1.0",
  660. **CONN_PARAMETERS
  661. )
  662. self.assertFalse(result["result"])
  663. self.assertEqual(
  664. result.get("error", ""),
  665. ERROR_MESSAGE.format(
  666. 101, "describe_elasticsearch_instance_type_limits"
  667. ),
  668. )
  669. def test_describe_reserved_elasticsearch_instance_offerings_positive(self):
  670. """
  671. Test that when calling describe_reserved_elasticsearch_instance_offerings
  672. and it succeeds, it returns {'result': True, 'response': some_value}.
  673. """
  674. ret_val = {
  675. "NextToken": "string",
  676. "ReservedElasticsearchInstanceOfferings": [
  677. {
  678. "ReservedElasticsearchInstanceOfferingId": "string",
  679. "ElasticsearchInstanceType": "t2.medium.elasticsearch",
  680. "Duration": 123,
  681. "FixedPrice": 123.0,
  682. "UsagePrice": 123.0,
  683. "CurrencyCode": "string",
  684. "PaymentOption": "NO_UPFRONT",
  685. "RecurringCharges": [
  686. {
  687. "RecurringChargeAmount": 123.0,
  688. "RecurringChargeFrequency": "string",
  689. }
  690. ],
  691. }
  692. ],
  693. }
  694. with patch.object(self.paginator, "paginate", return_value=[ret_val]):
  695. self.assertEqual(
  696. boto3_elasticsearch.describe_reserved_elasticsearch_instance_offerings(
  697. reserved_elasticsearch_instance_offering_id="foo", **CONN_PARAMETERS
  698. ),
  699. {
  700. "result": True,
  701. "response": ret_val["ReservedElasticsearchInstanceOfferings"],
  702. },
  703. )
  704. def test_describe_reserved_elasticsearch_instance_offerings_error(self):
  705. """
  706. Test that when calling describe_reserved_elasticsearch_instance_offerings
  707. and boto3 returns an error, it returns {'result': False, 'error': 'the error'}.
  708. """
  709. with patch.object(
  710. self.paginator,
  711. "paginate",
  712. side_effect=ClientError(
  713. ERROR_CONTENT, "describe_reserved_elasticsearch_instance_offerings"
  714. ),
  715. ):
  716. result = boto3_elasticsearch.describe_reserved_elasticsearch_instance_offerings(
  717. reserved_elasticsearch_instance_offering_id="foo", **CONN_PARAMETERS
  718. )
  719. self.assertFalse(result["result"])
  720. self.assertEqual(
  721. result.get("error", ""),
  722. ERROR_MESSAGE.format(
  723. 101, "describe_reserved_elasticsearch_instance_offerings"
  724. ),
  725. )
  726. def test_describe_reserved_elasticsearch_instances_positive(self):
  727. """
  728. Test that when calling describe_reserved_elasticsearch_instances and it
  729. succeeds, it returns {'result': True, 'response': some_value}.
  730. """
  731. ret_val = {
  732. "NextToken": "string",
  733. "ReservedElasticsearchInstances": [
  734. {
  735. "ReservationName": "string",
  736. "ReservedElasticsearchInstanceId": "string",
  737. "ReservedElasticsearchInstanceOfferingId": "string",
  738. "ElasticsearchInstanceType": "t2.medium.elasticsearch",
  739. "StartTime": datetime.datetime(2015, 1, 1),
  740. "Duration": 123,
  741. "FixedPrice": 123.0,
  742. "UsagePrice": 123.0,
  743. "CurrencyCode": "string",
  744. "ElasticsearchInstanceCount": 123,
  745. "State": "string",
  746. "PaymentOption": "ALL_UPFRONT",
  747. "RecurringCharges": [
  748. {
  749. "RecurringChargeAmount": 123.0,
  750. "RecurringChargeFrequency": "string",
  751. },
  752. ],
  753. },
  754. ],
  755. }
  756. with patch.object(self.paginator, "paginate", return_value=[ret_val]):
  757. self.assertEqual(
  758. boto3_elasticsearch.describe_reserved_elasticsearch_instances(
  759. reserved_elasticsearch_instance_id="foo", **CONN_PARAMETERS
  760. ),
  761. {"result": True, "response": ret_val["ReservedElasticsearchInstances"]},
  762. )
  763. def test_describe_reserved_elasticsearch_instances_error(self):
  764. """
  765. Test that when calling describe_reserved_elasticsearch_instances and boto3
  766. returns an error, it returns {'result': False, 'error': 'the error'}.
  767. """
  768. with patch.object(
  769. self.paginator,
  770. "paginate",
  771. side_effect=ClientError(
  772. ERROR_CONTENT, "describe_reserved_elasticsearch_instances"
  773. ),
  774. ):
  775. result = boto3_elasticsearch.describe_reserved_elasticsearch_instances(
  776. reserved_elasticsearch_instance_id="foo", **CONN_PARAMETERS
  777. )
  778. self.assertFalse(result["result"])
  779. self.assertEqual(
  780. result.get("error", ""),
  781. ERROR_MESSAGE.format(101, "describe_reserved_elasticsearch_instances"),
  782. )
  783. def test_get_compatible_elasticsearch_versions_positive(self):
  784. """
  785. Test that when calling get_compatible_elasticsearch_versions and it
  786. succeeds, it returns {'result': True, 'response': some_value}.
  787. """
  788. ret_val = {
  789. "CompatibleElasticsearchVersions": [
  790. {"SourceVersion": "string", "TargetVersions": ["string"]}
  791. ]
  792. }
  793. with patch.object(
  794. self.conn, "get_compatible_elasticsearch_versions", return_value=ret_val
  795. ):
  796. self.assertEqual(
  797. boto3_elasticsearch.get_compatible_elasticsearch_versions(
  798. domain_name="testdomain", **CONN_PARAMETERS
  799. ),
  800. {
  801. "result": True,
  802. "response": ret_val["CompatibleElasticsearchVersions"],
  803. },
  804. )
  805. def test_get_compatible_elasticsearch_versions_error(self):
  806. """
  807. Test that when calling get_compatible_elasticsearch_versions and boto3
  808. returns an error, it returns {'result': False, 'error': 'the error'}.
  809. """
  810. with patch.object(
  811. self.conn,
  812. "get_compatible_elasticsearch_versions",
  813. side_effect=ClientError(
  814. ERROR_CONTENT, "get_compatible_elasticsearch_versions"
  815. ),
  816. ):
  817. result = boto3_elasticsearch.get_compatible_elasticsearch_versions(
  818. domain_name="testdomain", **CONN_PARAMETERS
  819. )
  820. self.assertFalse(result["result"])
  821. self.assertEqual(
  822. result.get("error", ""),
  823. ERROR_MESSAGE.format(101, "get_compatible_elasticsearch_versions"),
  824. )
  825. def test_get_upgrade_history_positive(self):
  826. """
  827. Test that when calling get_upgrade_history and it
  828. succeeds, it returns {'result': True, 'response': some_value}.
  829. """
  830. ret_val = {
  831. "UpgradeHistories": [
  832. {
  833. "UpgradeName": "string",
  834. "StartTimestamp": datetime.datetime(2015, 1, 1),
  835. "UpgradeStatus": "IN_PROGRESS",
  836. "StepsList": [
  837. {
  838. "UpgradeStep": "PRE_UPGRADE_CHECK",
  839. "UpgradeStepStatus": "IN_PROGRESS",
  840. "Issues": ["string"],
  841. "ProgressPercent": 123.0,
  842. }
  843. ],
  844. }
  845. ],
  846. "NextToken": "string",
  847. }
  848. with patch.object(self.paginator, "paginate", return_value=[ret_val]):
  849. self.assertEqual(
  850. boto3_elasticsearch.get_upgrade_history(
  851. domain_name="testdomain", **CONN_PARAMETERS
  852. ),
  853. {"result": True, "response": ret_val["UpgradeHistories"]},
  854. )
  855. def test_get_upgrade_history_error(self):
  856. """
  857. Test that when calling get_upgrade_history and boto3
  858. returns an error, it returns {'result': False, 'error': 'the error'}.
  859. """
  860. with patch.object(
  861. self.paginator,
  862. "paginate",
  863. side_effect=ClientError(ERROR_CONTENT, "get_upgrade_history"),
  864. ):
  865. result = boto3_elasticsearch.get_upgrade_history(
  866. domain_name="testdomain", **CONN_PARAMETERS
  867. )
  868. self.assertFalse(result["result"])
  869. self.assertEqual(
  870. result.get("error", ""),
  871. ERROR_MESSAGE.format(101, "get_upgrade_history"),
  872. )
  873. def test_get_upgrade_status_positive(self):
  874. """
  875. Test that when calling get_upgrade_status and it
  876. succeeds, it returns {'result': True, 'response': some_value}.
  877. """
  878. ret_val = {
  879. "UpgradeStep": "PRE_UPGRADE_CHECK",
  880. "StepStatus": "IN_PROGRESS",
  881. "UpgradeName": "string",
  882. "ResponseMetadata": None,
  883. }
  884. with patch.object(self.conn, "get_upgrade_status", return_value=ret_val):
  885. self.assertEqual(
  886. boto3_elasticsearch.get_upgrade_status(
  887. domain_name="testdomain", **CONN_PARAMETERS
  888. ),
  889. {"result": True, "response": ret_val},
  890. )
  891. def test_get_upgrade_status_error(self):
  892. """
  893. Test that when calling get_upgrade_status and boto3
  894. returns an error, it returns {'result': False, 'error': 'the error'}.
  895. """
  896. with patch.object(
  897. self.conn,
  898. "get_upgrade_status",
  899. side_effect=ClientError(ERROR_CONTENT, "get_upgrade_status"),
  900. ):
  901. result = boto3_elasticsearch.get_upgrade_status(
  902. domain_name="testdomain", **CONN_PARAMETERS
  903. )
  904. self.assertFalse(result["result"])
  905. self.assertEqual(
  906. result.get("error", ""), ERROR_MESSAGE.format(101, "get_upgrade_status")
  907. )
  908. def test_list_domain_names_positive(self):
  909. """
  910. Test that when calling list_domain_names and it
  911. succeeds, it returns {'result': True, 'response': some_value}.
  912. """
  913. ret_val = {"DomainNames": [{"DomainName": "string"}]}
  914. with patch.object(self.conn, "list_domain_names", return_value=ret_val):
  915. self.assertEqual(
  916. boto3_elasticsearch.list_domain_names(**CONN_PARAMETERS),
  917. {
  918. "result": True,
  919. "response": [item["DomainName"] for item in ret_val["DomainNames"]],
  920. },
  921. )
  922. def test_list_domain_names_error(self):
  923. """
  924. Test that when calling list_domain_names and boto3
  925. returns an error, it returns {'result': False, 'error': 'the error'}.
  926. """
  927. with patch.object(
  928. self.conn,
  929. "list_domain_names",
  930. side_effect=ClientError(ERROR_CONTENT, "list_domain_names"),
  931. ):
  932. result = boto3_elasticsearch.list_domain_names(**CONN_PARAMETERS)
  933. self.assertFalse(result["result"])
  934. self.assertEqual(
  935. result.get("error", ""), ERROR_MESSAGE.format(101, "list_domain_names")
  936. )
  937. def test_list_elasticsearch_instance_types_positive(self):
  938. """
  939. Test that when calling list_elasticsearch_instance_types and it
  940. succeeds, it returns {'result': True, 'response': some_value}.
  941. """
  942. ret_val = {
  943. "ElasticsearchInstanceTypes": [
  944. "m3.medium.elasticsearch",
  945. "m3.large.elasticsearch",
  946. "m3.xlarge.elasticsearch",
  947. "m3.2xlarge.elasticsearch",
  948. "m4.large.elasticsearch",
  949. "m4.xlarge.elasticsearch",
  950. "m4.2xlarge.elasticsearch",
  951. "m4.4xlarge.elasticsearch",
  952. "m4.10xlarge.elasticsearch",
  953. "t2.micro.elasticsearch",
  954. "t2.small.elasticsearch",
  955. "t2.medium.elasticsearch",
  956. "r3.large.elasticsearch",
  957. "r3.xlarge.elasticsearch",
  958. "r3.2xlarge.elasticsearch",
  959. "r3.4xlarge.elasticsearch",
  960. "r3.8xlarge.elasticsearch",
  961. "i2.xlarge.elasticsearch",
  962. "i2.2xlarge.elasticsearch",
  963. "d2.xlarge.elasticsearch",
  964. "d2.2xlarge.elasticsearch",
  965. "d2.4xlarge.elasticsearch",
  966. "d2.8xlarge.elasticsearch",
  967. "c4.large.elasticsearch",
  968. "c4.xlarge.elasticsearch",
  969. "c4.2xlarge.elasticsearch",
  970. "c4.4xlarge.elasticsearch",
  971. "c4.8xlarge.elasticsearch",
  972. "r4.large.elasticsearch",
  973. "r4.xlarge.elasticsearch",
  974. "r4.2xlarge.elasticsearch",
  975. "r4.4xlarge.elasticsearch",
  976. "r4.8xlarge.elasticsearch",
  977. "r4.16xlarge.elasticsearch",
  978. "i3.large.elasticsearch",
  979. "i3.xlarge.elasticsearch",
  980. "i3.2xlarge.elasticsearch",
  981. "i3.4xlarge.elasticsearch",
  982. "i3.8xlarge.elasticsearch",
  983. "i3.16xlarge.elasticsearch",
  984. ],
  985. "NextToken": "string",
  986. }
  987. with patch.object(self.paginator, "paginate", return_value=[ret_val]):
  988. self.assertEqual(
  989. boto3_elasticsearch.list_elasticsearch_instance_types(
  990. elasticsearch_version="1.0", **CONN_PARAMETERS
  991. ),
  992. {"result": True, "response": ret_val["ElasticsearchInstanceTypes"]},
  993. )
  994. def test_list_elasticsearch_instance_types_error(self):
  995. """
  996. Test that when calling list_elasticsearch_instance_types and boto3
  997. returns an error, it returns {'result': False, 'error': 'the error'}.
  998. """
  999. with patch.object(
  1000. self.paginator,
  1001. "paginate",
  1002. side_effect=ClientError(ERROR_CONTENT, "list_elasticsearch_instance_types"),
  1003. ):
  1004. result = boto3_elasticsearch.list_elasticsearch_instance_types(
  1005. elasticsearch_version="1.0", **CONN_PARAMETERS
  1006. )
  1007. self.assertFalse(result["result"])
  1008. self.assertEqual(
  1009. result.get("error", ""),
  1010. ERROR_MESSAGE.format(101, "list_elasticsearch_instance_types"),
  1011. )
  1012. def test_list_elasticsearch_versions_positive(self):
  1013. """
  1014. Test that when calling list_elasticsearch_versions and it
  1015. succeeds, it returns {'result': True, 'response': some_value}.
  1016. """
  1017. ret_val = {"ElasticsearchVersions": ["string"], "NextToken": "string"}
  1018. with patch.object(self.paginator, "paginate", return_value=[ret_val]):
  1019. self.assertEqual(
  1020. boto3_elasticsearch.list_elasticsearch_versions(**CONN_PARAMETERS),
  1021. {"result": True, "response": ret_val["ElasticsearchVersions"]},
  1022. )
  1023. def test_list_elasticsearch_versions_error(self):
  1024. """
  1025. Test that when calling list_elasticsearch_versions and boto3
  1026. returns an error, it returns {'result': False, 'error': 'the error'}.
  1027. """
  1028. with patch.object(
  1029. self.paginator,
  1030. "paginate",
  1031. side_effect=ClientError(ERROR_CONTENT, "list_elasticsearch_versions"),
  1032. ):
  1033. result = boto3_elasticsearch.list_elasticsearch_versions(**CONN_PARAMETERS)
  1034. self.assertFalse(result["result"])
  1035. self.assertEqual(
  1036. result.get("error", ""),
  1037. ERROR_MESSAGE.format(101, "list_elasticsearch_versions"),
  1038. )
  1039. def test_purchase_reserved_elasticsearch_instance_offering_positive(self):
  1040. """
  1041. Test that when calling purchase_reserved_elasticsearch_instance_offering and it
  1042. succeeds, it returns {'result': True, 'response': some_value}.
  1043. """
  1044. ret_val = {
  1045. "ReservedElasticsearchInstanceId": "string",
  1046. "ReservationName": "string",
  1047. }
  1048. with patch.object(
  1049. self.conn,
  1050. "purchase_reserved_elasticsearch_instance_offering",
  1051. return_value=ret_val,
  1052. ):
  1053. self.assertEqual(
  1054. boto3_elasticsearch.purchase_reserved_elasticsearch_instance_offering(
  1055. reserved_elasticsearch_instance_offering_id="foo",
  1056. reservation_name="bar",
  1057. **CONN_PARAMETERS
  1058. ),
  1059. {"result": True, "response": ret_val},
  1060. )
  1061. def test_purchase_reserved_elasticsearch_instance_offering_error(self):
  1062. """
  1063. Test that when calling purchase_reserved_elasticsearch_instance_offering and boto3
  1064. returns an error, it returns {'result': False, 'error': 'the error'}.
  1065. """
  1066. with patch.object(
  1067. self.conn,
  1068. "purchase_reserved_elasticsearch_instance_offering",
  1069. side_effect=ClientError(
  1070. ERROR_CONTENT, "purchase_reserved_elasticsearch_instance_offering"
  1071. ),
  1072. ):
  1073. result = boto3_elasticsearch.purchase_reserved_elasticsearch_instance_offering(
  1074. reserved_elasticsearch_instance_offering_id="foo",
  1075. reservation_name="bar",
  1076. **CONN_PARAMETERS
  1077. )
  1078. self.assertFalse(result["result"])
  1079. self.assertEqual(
  1080. result.get("error", ""),
  1081. ERROR_MESSAGE.format(
  1082. 101, "purchase_reserved_elasticsearch_instance_offering"
  1083. ),
  1084. )
  1085. def test_start_elasticsearch_service_software_update_positive(self):
  1086. """
  1087. Test that when calling start_elasticsearch_service_software_update and it
  1088. succeeds, it returns {'result': True, 'response': some_value}.
  1089. """
  1090. ret_val = {
  1091. "ServiceSoftwareOptions": {
  1092. "CurrentVersion": "string",
  1093. "NewVersion": "string",
  1094. "UpdateAvailable": True,
  1095. "Cancellable": True,
  1096. "UpdateStatus": "PENDING_UPDATE",
  1097. "Description": "string",
  1098. "AutomatedUpdateDate": datetime.datetime(2015, 1, 1),
  1099. }
  1100. }
  1101. with patch.object(
  1102. self.conn,
  1103. "start_elasticsearch_service_software_update",
  1104. return_value=ret_val,
  1105. ):
  1106. self.assertEqual(
  1107. boto3_elasticsearch.start_elasticsearch_service_software_update(
  1108. domain_name="testdomain", **CONN_PARAMETERS
  1109. ),
  1110. {"result": True, "response": ret_val["ServiceSoftwareOptions"]},
  1111. )
  1112. def test_start_elasticsearch_service_software_update_error(self):
  1113. """
  1114. Test that when calling start_elasticsearch_service_software_update and boto3
  1115. returns an error, it returns {'result': False, 'error': 'the error'}.
  1116. """
  1117. with patch.object(
  1118. self.conn,
  1119. "start_elasticsearch_service_software_update",
  1120. side_effect=ClientError(
  1121. ERROR_CONTENT, "start_elasticsearch_service_software_update"
  1122. ),
  1123. ):
  1124. result = boto3_elasticsearch.start_elasticsearch_service_software_update(
  1125. domain_name="testdomain", **CONN_PARAMETERS
  1126. )
  1127. self.assertFalse(result["result"])
  1128. self.assertEqual(
  1129. result.get("error", ""),
  1130. ERROR_MESSAGE.format(
  1131. 101, "start_elasticsearch_service_software_update"
  1132. ),
  1133. )
  1134. def test_upgrade_elasticsearch_domain_positive(self):
  1135. """
  1136. Test that when calling upgrade_elasticsearch_domain and it
  1137. succeeds, it returns {'result': True, 'response': some_value}.
  1138. """
  1139. ret_val = {
  1140. "DomainName": "string",
  1141. "TargetVersion": "string",
  1142. "PerformCheckOnly": True,
  1143. }
  1144. with patch.object(
  1145. self.conn, "upgrade_elasticsearch_domain", return_value=ret_val
  1146. ):
  1147. self.assertEqual(
  1148. boto3_elasticsearch.upgrade_elasticsearch_domain(
  1149. domain_name="testdomain", target_version="1.1", **CONN_PARAMETERS
  1150. ),
  1151. {"result": True, "response": ret_val},
  1152. )
  1153. def test_upgrade_elasticsearch_domain_error(self):
  1154. """
  1155. Test that when calling upgrade_elasticsearch_domain and boto3
  1156. returns an error, it returns {'result': False, 'error': 'the error'}.
  1157. """
  1158. with patch.object(
  1159. self.conn,
  1160. "upgrade_elasticsearch_domain",
  1161. side_effect=ClientError(ERROR_CONTENT, "upgrade_elasticsearch_domain"),
  1162. ):
  1163. result = boto3_elasticsearch.upgrade_elasticsearch_domain(
  1164. domain_name="testdomain", target_version="1.1", **CONN_PARAMETERS
  1165. )
  1166. self.assertFalse(result["result"])
  1167. self.assertEqual(
  1168. result.get("error", ""),
  1169. ERROR_MESSAGE.format(101, "upgrade_elasticsearch_domain"),
  1170. )