TestController.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. '''
  4. Licensed to the Apache Software Foundation (ASF) under one
  5. or more contributor license agreements. See the NOTICE file
  6. distributed with this work for additional information
  7. regarding copyright ownership. The ASF licenses this file
  8. to you under the Apache License, Version 2.0 (the
  9. "License"); you may not use this file except in compliance
  10. with the License. You may obtain a copy of the License at
  11. http://www.apache.org/licenses/LICENSE-2.0
  12. Unless required by applicable law or agreed to in writing, software
  13. distributed under the License is distributed on an "AS IS" BASIS,
  14. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. See the License for the specific language governing permissions and
  16. limitations under the License.
  17. '''
  18. import StringIO
  19. import ssl
  20. import unittest, threading
  21. import sys
  22. from mock.mock import patch, MagicMock, call, Mock
  23. import logging
  24. import platform
  25. from threading import Event
  26. import json
  27. with patch("platform.linux_distribution", return_value = ('Suse','11','Final')):
  28. from ambari_agent import Controller, ActionQueue, Register
  29. from ambari_agent import hostname
  30. from ambari_agent.Controller import AGENT_AUTO_RESTART_EXIT_CODE
  31. from ambari_commons import OSCheck
  32. @patch.object(platform, "linux_distribution", new = ('Suse','11','Final'))
  33. class TestController(unittest.TestCase):
  34. logger = logging.getLogger()
  35. @patch("threading.Thread")
  36. @patch("threading.Lock")
  37. @patch.object(Controller, "NetUtil")
  38. @patch.object(hostname, "hostname")
  39. def setUp(self, hostname_method, NetUtil_mock, lockMock, threadMock):
  40. Controller.logger = MagicMock()
  41. lockMock.return_value = MagicMock()
  42. NetUtil_mock.return_value = MagicMock()
  43. hostname_method.return_value = "test_hostname"
  44. config = MagicMock()
  45. #config.get.return_value = "something"
  46. config.get.return_value = "5"
  47. self.controller = Controller.Controller(config)
  48. self.controller.netutil.MINIMUM_INTERVAL_BETWEEN_HEARTBEATS = 0.1
  49. self.controller.netutil.HEARTBEAT_NOT_IDDLE_INTERVAL_SEC = 0.1
  50. @patch("json.dumps")
  51. @patch("time.sleep")
  52. @patch("pprint.pformat")
  53. @patch.object(Controller, "randint")
  54. @patch.object(Controller, "LiveStatus")
  55. def test_registerWithServer(self, LiveStatus_mock, randintMock, pformatMock, sleepMock,
  56. dumpsMock):
  57. out = StringIO.StringIO()
  58. sys.stdout = out
  59. LiveStatus_mock.SERVICES = ["foo"]
  60. LiveStatus_mock.CLIENT_COMPONENTS = ["foo"]
  61. LiveStatus_mock.COMPONENTS = ["foo"]
  62. register = MagicMock()
  63. self.controller.register = register
  64. self.controller.sendRequest = MagicMock()
  65. dumpsMock.return_value = '{"valid_object": true}'
  66. self.controller.sendRequest.return_value = {"log":"Error text", "exitstatus":"1"}
  67. self.assertEqual({u'exitstatus': u'1', u'log': u'Error text'}, self.controller.registerWithServer())
  68. self.assertEqual(LiveStatus_mock.SERVICES, [])
  69. self.assertEqual(LiveStatus_mock.CLIENT_COMPONENTS, [])
  70. self.assertEqual(LiveStatus_mock.COMPONENTS, [])
  71. self.controller.sendRequest.return_value = {"responseId":1}
  72. self.assertEqual({"responseId":1}, self.controller.registerWithServer())
  73. self.controller.sendRequest.return_value = {"responseId":1, "statusCommands": "commands", "log":"", "exitstatus":"0"}
  74. self.controller.addToStatusQueue = MagicMock(name="addToStatusQueue")
  75. self.controller.isRegistered = False
  76. self.assertEqual({'exitstatus': '0', 'responseId': 1, 'log': '', 'statusCommands': 'commands'}, self.controller.registerWithServer())
  77. self.controller.addToStatusQueue.assert_called_with("commands")
  78. calls = []
  79. def side_effect(*args):
  80. if len(calls) == 0:
  81. calls.append(1)
  82. raise Exception("test")
  83. return "request"
  84. self.controller.sendRequest.return_value = {"responseId":1}
  85. dumpsMock.side_effect = side_effect
  86. self.controller.isRegistered = False
  87. self.assertEqual({"responseId":1}, self.controller.registerWithServer())
  88. self.assertTrue(randintMock.called)
  89. self.assertTrue(sleepMock.called)
  90. sys.stdout = sys.__stdout__
  91. self.controller.sendRequest = Controller.Controller.sendRequest
  92. self.controller.addToStatusQueue = Controller.Controller.addToStatusQueue
  93. @patch("pprint.pformat")
  94. def test_addToQueue(self, pformatMock):
  95. actionQueue = MagicMock()
  96. self.controller.actionQueue = actionQueue
  97. self.controller.addToQueue(None)
  98. self.assertFalse(actionQueue.put.called)
  99. self.controller.addToQueue("cmd")
  100. self.assertTrue(actionQueue.put.called)
  101. @patch("pprint.pformat")
  102. @patch.object(Controller, "LiveStatus")
  103. def test_addToStatusQueue(self, LiveStatus_mock, pformatMock):
  104. LiveStatus_mock.SERVICES = ["foo"]
  105. LiveStatus_mock.CLIENT_COMPONENTS = ["foo"]
  106. LiveStatus_mock.COMPONENTS = ["foo"]
  107. commands = json.loads('[{"clusterName":"dummy_cluster"}]')
  108. actionQueue = MagicMock()
  109. self.controller.actionQueue = actionQueue
  110. updateComponents = Mock()
  111. self.controller.updateComponents = updateComponents
  112. self.controller.addToStatusQueue(None)
  113. self.assertFalse(actionQueue.put_status.called)
  114. self.assertFalse(updateComponents.called)
  115. self.controller.addToStatusQueue(commands)
  116. self.assertTrue(actionQueue.put_status.called)
  117. self.assertFalse(updateComponents.called)
  118. LiveStatus_mock.SERVICES = []
  119. LiveStatus_mock.CLIENT_COMPONENTS = []
  120. LiveStatus_mock.COMPONENTS = []
  121. self.controller.addToStatusQueue(commands)
  122. self.assertTrue(updateComponents.called)
  123. self.assertTrue(actionQueue.put_status.called)
  124. @patch("urllib2.build_opener")
  125. @patch("urllib2.install_opener")
  126. @patch.object(Controller, "ActionQueue")
  127. @patch.object(OSCheck, "get_os_type")
  128. @patch.object(OSCheck, "get_os_version")
  129. def test_run(self, get_os_version_mock, get_os_type_mock, ActionQueue_mock, installMock, buildMock):
  130. aq = MagicMock()
  131. ActionQueue_mock.return_value = aq
  132. get_os_type_mock.return_value = "suse"
  133. get_os_version_mock.return_value = "11"
  134. buildMock.return_value = "opener"
  135. registerAndHeartbeat = MagicMock("registerAndHeartbeat")
  136. calls = []
  137. def side_effect():
  138. if len(calls) == 0:
  139. self.controller.repeatRegistration = True
  140. calls.append(1)
  141. registerAndHeartbeat.side_effect = side_effect
  142. self.controller.registerAndHeartbeat = registerAndHeartbeat
  143. # repeat registration
  144. self.controller.run()
  145. self.assertTrue(buildMock.called)
  146. installMock.called_once_with("opener")
  147. self.assertEqual(2, registerAndHeartbeat.call_count)
  148. # one call, +1
  149. registerAndHeartbeat.side_effect = None
  150. self.controller.run()
  151. self.assertEqual(3, registerAndHeartbeat.call_count)
  152. # Action queue should be started during calls
  153. self.assertTrue(ActionQueue_mock.called)
  154. self.assertTrue(aq.start.called)
  155. @patch("urllib2.build_opener")
  156. @patch("urllib2.install_opener")
  157. @patch.object(ActionQueue.ActionQueue, "run")
  158. @patch.object(OSCheck, "get_os_type")
  159. @patch.object(OSCheck, "get_os_version")
  160. def test_repeatRegistration(self, get_os_version_mock, get_os_type_mock,
  161. run_mock, installMock, buildMock):
  162. registerAndHeartbeat = MagicMock(name="registerAndHeartbeat")
  163. get_os_type_mock.return_value = "suse"
  164. get_os_version_mock.return_value = "11"
  165. self.controller.registerAndHeartbeat = registerAndHeartbeat
  166. self.controller.run()
  167. self.assertTrue(installMock.called)
  168. self.assertTrue(buildMock.called)
  169. self.controller.registerAndHeartbeat.assert_called_once_with()
  170. calls = []
  171. def switchBool():
  172. if len(calls) == 0:
  173. self.controller.repeatRegistration = True
  174. calls.append(1)
  175. self.controller.repeatRegistration = False
  176. registerAndHeartbeat.side_effect = switchBool
  177. self.controller.run()
  178. self.assertEqual(2, registerAndHeartbeat.call_count)
  179. self.controller.registerAndHeartbeat = \
  180. Controller.Controller.registerAndHeartbeat
  181. @patch("time.sleep")
  182. def test_registerAndHeartbeatWithException(self, sleepMock):
  183. registerWithServer = MagicMock(name="registerWithServer")
  184. registerWithServer.return_value = {"response":"resp"}
  185. self.controller.registerWithServer = registerWithServer
  186. heartbeatWithServer = MagicMock(name="heartbeatWithServer")
  187. self.controller.heartbeatWithServer = heartbeatWithServer
  188. actionQueue = MagicMock(name="actionQueue")
  189. self.controller.actionQueue = actionQueue
  190. Controller.Controller.__sendRequest__ = MagicMock(side_effect=Exception())
  191. self.controller.isRegistered = True
  192. self.controller.registerAndHeartbeat()
  193. registerWithServer.assert_called_once_with()
  194. heartbeatWithServer.assert_called_once_with()
  195. self.controller.registerWithServer =\
  196. Controller.Controller.registerWithServer
  197. self.controller.heartbeatWithServer =\
  198. Controller.Controller.registerWithServer
  199. @patch("time.sleep")
  200. def test_registerAndHeartbeat(self, sleepMock):
  201. registerWithServer = MagicMock(name="registerWithServer")
  202. registerWithServer.return_value = {"response":"resp"}
  203. self.controller.registerWithServer = registerWithServer
  204. heartbeatWithServer = MagicMock(name="heartbeatWithServer")
  205. self.controller.heartbeatWithServer = heartbeatWithServer
  206. actionQueue = MagicMock(name="actionQueue")
  207. self.controller.actionQueue = actionQueue
  208. listener1 = MagicMock()
  209. listener2 = MagicMock()
  210. self.controller.registration_listeners.append(listener1)
  211. self.controller.registration_listeners.append(listener2)
  212. self.controller.isRegistered = True
  213. self.controller.registerAndHeartbeat()
  214. registerWithServer.assert_called_once_with()
  215. heartbeatWithServer.assert_called_once_with()
  216. self.assertTrue(listener1.called)
  217. self.assertTrue(listener2.called)
  218. self.controller.registerWithServer = \
  219. Controller.Controller.registerWithServer
  220. self.controller.heartbeatWithServer = \
  221. Controller.Controller.registerWithServer
  222. @patch("time.sleep")
  223. def test_registerAndHeartbeat_check_registration_listener(self, sleepMock):
  224. registerWithServer = MagicMock(name="registerWithServer")
  225. registerWithServer.return_value = {"response":"resp"}
  226. self.controller.registerWithServer = registerWithServer
  227. heartbeatWithServer = MagicMock(name="heartbeatWithServer")
  228. self.controller.heartbeatWithServer = heartbeatWithServer
  229. actionQueue = MagicMock(name="actionQueue")
  230. self.controller.actionQueue = actionQueue
  231. self.controller.isRegistered = True
  232. self.controller.registerAndHeartbeat()
  233. registerWithServer.assert_called_once_with()
  234. heartbeatWithServer.assert_called_once_with()
  235. self.controller.registerWithServer = \
  236. Controller.Controller.registerWithServer
  237. self.controller.heartbeatWithServer = \
  238. Controller.Controller.registerWithServer
  239. @patch("time.sleep")
  240. @patch.object(Controller.Controller, "sendRequest")
  241. def test_registerWithIOErrors(self, sendRequestMock, sleepMock):
  242. # Check that server continues to heartbeat after connection errors
  243. registerMock = MagicMock(name="Register")
  244. registerMock.build.return_value = {}
  245. actionQueue = MagicMock()
  246. actionQueue.isIdle.return_value = True
  247. self.controller.actionQueue = actionQueue
  248. self.controller.register = registerMock
  249. self.controller.responseId = 1
  250. self.controller.TEST_IOERROR_COUNTER = 1
  251. self.controller.isRegistered = False
  252. def util_throw_IOErrors(*args, **kwargs):
  253. """
  254. Throws IOErrors 10 times and then stops heartbeats/registrations
  255. """
  256. if self.controller.TEST_IOERROR_COUNTER == 10:
  257. self.controller.isRegistered = True
  258. self.controller.TEST_IOERROR_COUNTER += 1
  259. raise IOError("Sample error")
  260. actionQueue.isIdle.return_value = False
  261. sendRequestMock.side_effect = util_throw_IOErrors
  262. self.controller.registerWithServer()
  263. self.assertTrue(sendRequestMock.call_count > 5)
  264. @patch("os._exit")
  265. def test_restartAgent(self, os_exit_mock):
  266. self.controller.restartAgent()
  267. self.assertTrue(os_exit_mock.called)
  268. self.assertTrue(os_exit_mock.call_args[0][0] == AGENT_AUTO_RESTART_EXIT_CODE)
  269. @patch("urllib2.Request")
  270. @patch.object(Controller, "security")
  271. def test_sendRequest(self, security_mock, requestMock):
  272. conMock = MagicMock()
  273. security_mock.CachedHTTPSConnection.return_value = conMock
  274. url = "http://ambari.apache.org:8081/agent"
  275. data = "data"
  276. requestMock.return_value = "request"
  277. self.controller.cachedconnect = None
  278. conMock.request.return_value = '{"valid_object": true}'
  279. actual = self.controller.sendRequest(url, data)
  280. expected = json.loads('{"valid_object": true}')
  281. self.assertEqual(actual, expected)
  282. security_mock.CachedHTTPSConnection.assert_called_once_with(
  283. self.controller.config)
  284. requestMock.called_once_with(url, data,
  285. {'Content-Type': 'application/json'})
  286. conMock.request.return_value = '{invalid_object}'
  287. try:
  288. self.controller.sendRequest(url, data)
  289. self.fail("Should throw exception!")
  290. except IOError, e: # Expected
  291. self.assertEquals('Response parsing failed! Request data: ' + data +
  292. '; Response: {invalid_object}', e.message)
  293. exceptionMessage = "Connection Refused"
  294. conMock.request.side_effect = Exception(exceptionMessage)
  295. try:
  296. self.controller.sendRequest(url, data)
  297. self.fail("Should throw exception!")
  298. except IOError, e: # Expected
  299. self.assertEquals('Request to ' + url + ' failed due to ' +
  300. exceptionMessage, e.message)
  301. @patch.object(threading._Event, "wait")
  302. @patch("time.sleep")
  303. @patch("json.dumps")
  304. def test_heartbeatWithServer(self, dumpsMock, sleepMock, event_mock):
  305. out = StringIO.StringIO()
  306. sys.stdout = out
  307. hearbeat = MagicMock()
  308. self.controller.heartbeat = hearbeat
  309. dumpsMock.return_value = "data"
  310. sendRequest = MagicMock(name="sendRequest")
  311. self.controller.sendRequest = sendRequest
  312. self.controller.responseId = 1
  313. response = {"responseId":"2", "restartAgent":"false"}
  314. sendRequest.return_value = response
  315. def one_heartbeat(*args, **kwargs):
  316. self.controller.DEBUG_STOP_HEARTBEATING = True
  317. return response
  318. sendRequest.side_effect = one_heartbeat
  319. actionQueue = MagicMock()
  320. actionQueue.isIdle.return_value = True
  321. # one successful request, after stop
  322. self.controller.actionQueue = actionQueue
  323. self.controller.heartbeatWithServer()
  324. self.assertTrue(sendRequest.called)
  325. calls = []
  326. def retry(*args, **kwargs):
  327. if len(calls) == 0:
  328. calls.append(1)
  329. response["responseId"] = "3"
  330. raise Exception()
  331. if len(calls) > 0:
  332. self.controller.DEBUG_STOP_HEARTBEATING = True
  333. return response
  334. # exception, retry, successful and stop
  335. sendRequest.side_effect = retry
  336. self.controller.DEBUG_STOP_HEARTBEATING = False
  337. self.controller.heartbeatWithServer()
  338. self.assertEqual(1, self.controller.DEBUG_SUCCESSFULL_HEARTBEATS)
  339. # retry registration
  340. self.controller.responseId = 2
  341. response["registrationCommand"] = "true"
  342. sendRequest.side_effect = one_heartbeat
  343. self.controller.DEBUG_STOP_HEARTBEATING = False
  344. self.controller.heartbeatWithServer()
  345. self.assertTrue(self.controller.repeatRegistration)
  346. # components are not mapped
  347. self.controller.responseId = 2
  348. response["registrationCommand"] = "false"
  349. response["hasMappedComponents"] = False
  350. sendRequest.side_effect = one_heartbeat
  351. self.controller.DEBUG_STOP_HEARTBEATING = False
  352. self.controller.heartbeatWithServer()
  353. self.assertFalse(self.controller.hasMappedComponents)
  354. # components are mapped
  355. self.controller.responseId = 2
  356. response["hasMappedComponents"] = True
  357. sendRequest.side_effect = one_heartbeat
  358. self.controller.DEBUG_STOP_HEARTBEATING = False
  359. self.controller.heartbeatWithServer()
  360. self.assertTrue(self.controller.hasMappedComponents)
  361. # components are mapped
  362. self.controller.responseId = 2
  363. del response["hasMappedComponents"]
  364. sendRequest.side_effect = one_heartbeat
  365. self.controller.DEBUG_STOP_HEARTBEATING = False
  366. self.controller.heartbeatWithServer()
  367. self.assertTrue(self.controller.hasMappedComponents)
  368. # wrong responseId => restart
  369. self.controller.responseId = 2
  370. response = {"responseId":"2", "restartAgent":"false"}
  371. restartAgent = MagicMock(name="restartAgent")
  372. self.controller.restartAgent = restartAgent
  373. self.controller.DEBUG_STOP_HEARTBEATING = False
  374. self.controller.heartbeatWithServer()
  375. restartAgent.assert_called_once_with()
  376. # executionCommands
  377. self.controller.responseId = 1
  378. addToQueue = MagicMock(name="addToQueue")
  379. self.controller.addToQueue = addToQueue
  380. response["executionCommands"] = "executionCommands"
  381. self.controller.DEBUG_STOP_HEARTBEATING = False
  382. self.controller.heartbeatWithServer()
  383. addToQueue.assert_has_calls([call("executionCommands")])
  384. # statusCommands
  385. self.controller.responseId = 1
  386. addToStatusQueue = MagicMock(name="addToStatusQueue")
  387. self.controller.addToStatusQueue = addToStatusQueue
  388. response["statusCommands"] = "statusCommands"
  389. self.controller.DEBUG_STOP_HEARTBEATING = False
  390. self.controller.heartbeatWithServer()
  391. addToStatusQueue.assert_has_calls([call("statusCommands")])
  392. # restartAgent command
  393. self.controller.responseId = 1
  394. self.controller.DEBUG_STOP_HEARTBEATING = False
  395. response["restartAgent"] = "true"
  396. restartAgent = MagicMock(name="restartAgent")
  397. self.controller.restartAgent = restartAgent
  398. self.controller.heartbeatWithServer()
  399. restartAgent.assert_called_once_with()
  400. # actionQueue not idle
  401. self.controller.responseId = 1
  402. self.controller.DEBUG_STOP_HEARTBEATING = False
  403. actionQueue.isIdle.return_value = False
  404. response["restartAgent"] = "false"
  405. self.controller.heartbeatWithServer()
  406. sleepMock.assert_called_with(
  407. self.controller.netutil.MINIMUM_INTERVAL_BETWEEN_HEARTBEATS)
  408. # Check that server continues to heartbeat after connection errors
  409. self.controller.responseId = 1
  410. self.controller.TEST_IOERROR_COUNTER = 1
  411. sendRequest.reset()
  412. def util_throw_IOErrors(*args, **kwargs):
  413. """
  414. Throws IOErrors 100 times and then stops heartbeats/registrations
  415. """
  416. if self.controller.TEST_IOERROR_COUNTER == 10:
  417. self.controller.DEBUG_STOP_HEARTBEATING = True
  418. self.controller.TEST_IOERROR_COUNTER += 1
  419. raise IOError("Sample error")
  420. self.controller.DEBUG_STOP_HEARTBEATING = False
  421. actionQueue.isIdle.return_value = False
  422. sendRequest.side_effect = util_throw_IOErrors
  423. self.controller.heartbeatWithServer()
  424. self.assertTrue(sendRequest.call_count > 5)
  425. sleepMock.assert_called_with(
  426. self.controller.netutil.MINIMUM_INTERVAL_BETWEEN_HEARTBEATS)
  427. sys.stdout = sys.__stdout__
  428. self.controller.sendRequest = Controller.Controller.sendRequest
  429. self.controller.sendRequest = Controller.Controller.addToQueue
  430. self.controller.sendRequest = Controller.Controller.addToStatusQueue
  431. @patch("pprint.pformat")
  432. @patch("time.sleep")
  433. @patch("json.loads")
  434. @patch("json.dumps")
  435. def test_certSigningFailed(self, dumpsMock, loadsMock, sleepMock, pformatMock):
  436. register = MagicMock()
  437. self.controller.register = register
  438. dumpsMock.return_value = "request"
  439. response = {"responseId":1,}
  440. loadsMock.return_value = response
  441. self.controller.sendRequest = Mock(side_effect=ssl.SSLError())
  442. self.controller.repeatRegistration=True
  443. self.controller.registerWithServer()
  444. #Conroller thread and the agent stop if the repeatRegistration flag is False
  445. self.assertFalse(self.controller.repeatRegistration)
  446. @patch.object(Controller, "LiveStatus")
  447. def test_updateComponents(self, LiveStatus_mock):
  448. LiveStatus_mock.SERVICES = []
  449. LiveStatus_mock.CLIENT_COMPONENTS = []
  450. LiveStatus_mock.COMPONENTS = []
  451. self.controller.componentsUrl = "foo_url/"
  452. sendRequest = Mock()
  453. self.controller.sendRequest = sendRequest
  454. self.controller.sendRequest.return_value = {"clusterName":"dummy_cluster_name",
  455. "stackName":"dummy_stack_name",
  456. "stackVersion":"dummy_stack_version",
  457. "components":{"PIG":{"PIG":"CLIENT"},
  458. "MAPREDUCE":{"MAPREDUCE_CLIENT":"CLIENT",
  459. "JOBTRACKER":"MASTER","TASKTRACKER":"SLAVE"}}}
  460. self.controller.updateComponents("dummy_cluster_name")
  461. sendRequest.assert_called_with('foo_url/dummy_cluster_name', None)
  462. services_expected = [u'MAPREDUCE', u'PIG']
  463. client_components_expected = [
  464. {'serviceName':u'MAPREDUCE','componentName':u'MAPREDUCE_CLIENT'},
  465. {'serviceName':u'PIG','componentName':u'PIG'}
  466. ]
  467. components_expected = [
  468. {'serviceName':u'MAPREDUCE','componentName':u'TASKTRACKER'},
  469. {'serviceName':u'MAPREDUCE','componentName':u'JOBTRACKER'}
  470. ]
  471. self.assertEquals(LiveStatus_mock.SERVICES, services_expected)
  472. self.assertEquals(LiveStatus_mock.CLIENT_COMPONENTS, client_components_expected)
  473. self.assertEquals(LiveStatus_mock.COMPONENTS, components_expected)
  474. if __name__ == "__main__":
  475. unittest.main(verbosity=2)