PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/hadoop-1.1.2/src/contrib/hod/testing/testHod.py

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Python | 310 lines | 294 code | 3 blank | 13 comment | 12 complexity | 80aa356775d416416785433395166866 MD5 | raw file
  1. #Licensed to the Apache Software Foundation (ASF) under one
  2. #or more contributor license agreements. See the NOTICE file
  3. #distributed with this work for additional information
  4. #regarding copyright ownership. The ASF licenses this file
  5. #to you under the Apache License, Version 2.0 (the
  6. #"License"); you may not use this file except in compliance
  7. #with the License. You may obtain a copy of the License at
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #Unless required by applicable law or agreed to in writing, software
  10. #distributed under the License is distributed on an "AS IS" BASIS,
  11. #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. #See the License for the specific language governing permissions and
  13. #limitations under the License.
  14. import unittest, getpass, os, sys, re, threading, time
  15. myDirectory = os.path.realpath(sys.argv[0])
  16. rootDirectory = re.sub("/testing/.*", "", myDirectory)
  17. sys.path.append(rootDirectory)
  18. import tempfile
  19. from testing.lib import BaseTestSuite, MockLogger, MockHadoopCluster
  20. from hodlib.Hod.hod import hodRunner, hodState
  21. from hodlib.Common.desc import NodePoolDesc
  22. excludes = []
  23. # Information about all clusters is written to a file called clusters.state.
  24. from hodlib.Hod.hod import CLUSTER_DATA_FILE as TEST_CLUSTER_DATA_FILE, \
  25. INVALID_STATE_FILE_MSGS
  26. # Temp directory prefix
  27. TMP_DIR_PREFIX=os.path.join('/tmp', 'hod-%s' % (getpass.getuser()))
  28. # build a config object with all required keys for initializing hod.
  29. def setupConf():
  30. cfg = {
  31. 'hod' : {
  32. 'original-dir' : os.getcwd(),
  33. 'stream' : True,
  34. # store all the info about clusters in this directory
  35. 'user_state' : '/tmp/hodtest',
  36. 'debug' : 3,
  37. 'java-home' : os.getenv('JAVA_HOME'),
  38. 'cluster' : 'dummy',
  39. 'cluster-factor' : 1.8,
  40. 'xrs-port-range' : (32768,65536),
  41. 'allocate-wait-time' : 3600,
  42. 'temp-dir' : '/tmp/hod'
  43. },
  44. # just set everything to dummy. Need something to initialize the
  45. # node pool description object.
  46. 'resource_manager' : {
  47. 'id' : 'dummy',
  48. 'batch-home' : 'dummy',
  49. 'queue' : 'dummy',
  50. }
  51. }
  52. cfg['nodepooldesc'] = NodePoolDesc(cfg['resource_manager'])
  53. return cfg
  54. # Test class that defines methods to test invalid arguments to hod operations.
  55. class test_InvalidArgsOperations(unittest.TestCase):
  56. def setUp(self):
  57. self.cfg = setupConf()
  58. # initialize the mock objects
  59. self.log = MockLogger()
  60. self.cluster = MockHadoopCluster()
  61. # Use the test logger. This will be used for test verification.
  62. self.client = hodRunner(self.cfg, log=self.log, cluster=self.cluster)
  63. # Create the hodState object to set the test state you want.
  64. self.state = hodState(self.cfg['hod']['user_state'])
  65. if not os.path.exists(self.cfg['hod']['user_state']):
  66. os.path.mkdir(self.cfg['hod']['user_state'])
  67. p = os.path.join(self.cfg['hod']['user_state'], '%s.state' % TEST_CLUSTER_DATA_FILE)
  68. # ensure cluster data file exists, so write works in the tests.
  69. f = open(p, 'w')
  70. f.close()
  71. def tearDown(self):
  72. # clean up cluster data file and directory
  73. p = os.path.join(self.cfg['hod']['user_state'], '%s.state' % TEST_CLUSTER_DATA_FILE)
  74. os.remove(p)
  75. os.rmdir(self.cfg['hod']['user_state'])
  76. # Test that list works with deleted cluster directories - more than one entries which are invalid.
  77. def testListInvalidDirectory(self):
  78. userState = { os.path.join(TMP_DIR_PREFIX, 'testListInvalidDirectory1') : '123.dummy.id1',
  79. os.path.join(TMP_DIR_PREFIX, 'testListInvalidDirectory2') : '123.dummy.id2' }
  80. self.__setupClusterState(userState)
  81. self.client._op_list(['list'])
  82. # assert that required errors are logged.
  83. for clusterDir in userState.keys():
  84. self.assertTrue(self.log.hasMessage('cluster state unknown\t%s\t%s' \
  85. % (userState[clusterDir], clusterDir), 'info'))
  86. # simulate a test where a directory is deleted, and created again, without deallocation
  87. clusterDir = os.path.join(TMP_DIR_PREFIX, 'testListEmptyDirectory')
  88. os.makedirs(clusterDir)
  89. self.assertTrue(os.path.isdir(clusterDir))
  90. userState = { clusterDir : '123.dummy.id3' }
  91. self.__setupClusterState(userState, False)
  92. self.client._op_list(['list'])
  93. self.assertTrue(self.log.hasMessage('cluster state unknown\t%s\t%s' \
  94. % (userState[clusterDir], clusterDir), 'info'))
  95. os.rmdir(clusterDir)
  96. # Test that info works with a deleted cluster directory
  97. def testInfoInvalidDirectory(self):
  98. clusterDir = os.path.join(TMP_DIR_PREFIX, 'testInfoInvalidDirectory')
  99. userState = { clusterDir : '456.dummy.id' }
  100. self.__setupClusterState(userState)
  101. self.client._op_info(['info', clusterDir])
  102. self.assertTrue(self.log.hasMessage("Cannot find information for cluster with id '%s' in previously allocated cluster directory '%s'." % (userState[clusterDir], clusterDir), 'critical'))
  103. # simulate a test where a directory is deleted, and created again, without deallocation
  104. clusterDir = os.path.join(TMP_DIR_PREFIX, 'testInfoEmptyDirectory')
  105. os.makedirs(clusterDir)
  106. self.assertTrue(os.path.isdir(clusterDir))
  107. userState = { clusterDir : '456.dummy.id1' }
  108. self.__setupClusterState(userState, False)
  109. self.client._op_info(['info', clusterDir])
  110. self.assertTrue(self.log.hasMessage("Cannot find information for cluster with id '%s' in previously allocated cluster directory '%s'." % (userState[clusterDir], clusterDir), 'critical'))
  111. os.rmdir(clusterDir)
  112. # Test info works with an invalid cluster directory
  113. def testInfoNonExistentDirectory(self):
  114. clusterDir = '/tmp/hod/testInfoNonExistentDirectory'
  115. self.client._op_info(['info', clusterDir])
  116. self.assertTrue(self.log.hasMessage("Invalid hod.clusterdir(--hod.clusterdir or -d). %s : No such directory" % (clusterDir), 'critical'))
  117. # Test that deallocation works on a deleted cluster directory
  118. # by clearing the job, and removing the state
  119. def testDeallocateInvalidDirectory(self):
  120. clusterDir = os.path.join(TMP_DIR_PREFIX,'testDeallocateInvalidDirectory')
  121. jobid = '789.dummy.id'
  122. userState = { clusterDir : jobid }
  123. self.__setupClusterState(userState)
  124. self.client._op_deallocate(['deallocate', clusterDir])
  125. # verify job was deleted
  126. self.assertTrue(self.cluster.wasOperationPerformed('delete_job', jobid))
  127. # verify appropriate message was logged.
  128. self.assertTrue(self.log.hasMessage("Cannot find information for cluster with id '%s' in previously allocated cluster directory '%s'." % (userState[clusterDir], clusterDir), 'critical'))
  129. self.assertTrue(self.log.hasMessage("Freeing resources allocated to the cluster.", 'critical'))
  130. # verify that the state information was cleared.
  131. userState = self.state.read(TEST_CLUSTER_DATA_FILE)
  132. self.assertFalse(clusterDir in userState.keys())
  133. # simulate a test where a directory is deleted, and created again, without deallocation
  134. clusterDir = os.path.join(TMP_DIR_PREFIX,'testDeallocateEmptyDirectory')
  135. os.makedirs(clusterDir)
  136. self.assertTrue(os.path.isdir(clusterDir))
  137. jobid = '789.dummy.id1'
  138. userState = { clusterDir : jobid }
  139. self.__setupClusterState(userState, False)
  140. self.client._op_deallocate(['deallocate', clusterDir])
  141. # verify job was deleted
  142. self.assertTrue(self.cluster.wasOperationPerformed('delete_job', jobid))
  143. # verify appropriate message was logged.
  144. self.assertTrue(self.log.hasMessage("Cannot find information for cluster with id '%s' in previously allocated cluster directory '%s'." % (userState[clusterDir], clusterDir), 'critical'))
  145. self.assertTrue(self.log.hasMessage("Freeing resources allocated to the cluster.", 'critical'))
  146. # verify that the state information was cleared.
  147. userState = self.state.read(TEST_CLUSTER_DATA_FILE)
  148. self.assertFalse(clusterDir in userState.keys())
  149. os.rmdir(clusterDir)
  150. # Test that deallocation works on a nonexistent directory.
  151. def testDeallocateNonExistentDirectory(self):
  152. clusterDir = os.path.join(TMP_DIR_PREFIX,'testDeallocateNonExistentDirectory')
  153. self.client._op_deallocate(['deallocate', clusterDir])
  154. # there should be no call..
  155. self.assertFalse(self.cluster.wasOperationPerformed('delete_job', None))
  156. self.assertTrue(self.log.hasMessage("Invalid hod.clusterdir(--hod.clusterdir or -d). %s : No such directory" % (clusterDir), 'critical'))
  157. # Test that allocation on an previously deleted directory fails.
  158. def testAllocateOnDeletedDirectory(self):
  159. clusterDir = os.path.join(TMP_DIR_PREFIX, 'testAllocateOnDeletedDirectory')
  160. os.makedirs(clusterDir)
  161. self.assertTrue(os.path.isdir(clusterDir))
  162. jobid = '1234.abc.com'
  163. userState = { clusterDir : jobid }
  164. self.__setupClusterState(userState, False)
  165. self.client._op_allocate(['allocate', clusterDir, '3'])
  166. self.assertTrue(self.log.hasMessage("Found a previously allocated cluster at "\
  167. "cluster directory '%s'. HOD cannot determine if this cluster "\
  168. "can be automatically deallocated. Deallocate the cluster if it "\
  169. "is unused." % (clusterDir), 'critical'))
  170. os.rmdir(clusterDir)
  171. def __setupClusterState(self, clusterStateMap, verifyDirIsAbsent=True):
  172. for clusterDir in clusterStateMap.keys():
  173. # ensure directory doesn't exist, just in case.
  174. if verifyDirIsAbsent:
  175. self.assertFalse(os.path.exists(clusterDir))
  176. # set up required state.
  177. self.state.write(TEST_CLUSTER_DATA_FILE, clusterStateMap)
  178. # verify everything is stored correctly.
  179. state = self.state.read(TEST_CLUSTER_DATA_FILE)
  180. for clusterDir in clusterStateMap.keys():
  181. self.assertTrue(clusterDir in state.keys())
  182. self.assertEquals(clusterStateMap[clusterDir], state[clusterDir])
  183. class test_InvalidHodStateFiles(unittest.TestCase):
  184. def setUp(self):
  185. self.rootDir = '/tmp/hod-%s' % getpass.getuser()
  186. self.cfg = setupConf() # creat a conf
  187. # Modify hod.user_state
  188. self.cfg['hod']['user_state'] = tempfile.mkdtemp(dir=self.rootDir,
  189. prefix='HodTestSuite.test_InvalidHodStateFiles_')
  190. self.log = MockLogger() # mock logger
  191. self.cluster = MockHadoopCluster() # mock hadoop cluster
  192. self.client = hodRunner(self.cfg, log=self.log, cluster=self.cluster)
  193. self.state = hodState(self.cfg['hod']['user_state'])
  194. self.statePath = os.path.join(self.cfg['hod']['user_state'], '%s.state' % \
  195. TEST_CLUSTER_DATA_FILE)
  196. self.clusterDir = tempfile.mkdtemp(dir=self.rootDir,
  197. prefix='HodTestSuite.test_InvalidHodStateFiles_')
  198. def testOperationWithInvalidStateFile(self):
  199. jobid = '1234.hadoop.apache.org'
  200. # create user state file with invalid permissions
  201. stateFile = open(self.statePath, "w")
  202. os.chmod(self.statePath, 000) # has no read/write permissions
  203. self.client._hodRunner__cfg['hod']['operation'] = \
  204. "info %s" % self.clusterDir
  205. ret = self.client.operation()
  206. os.chmod(self.statePath, 700) # restore permissions
  207. stateFile.close()
  208. os.remove(self.statePath)
  209. # print self.log._MockLogger__logLines
  210. self.assertTrue(self.log.hasMessage(INVALID_STATE_FILE_MSGS[0] % \
  211. os.path.realpath(self.statePath), 'critical'))
  212. self.assertEquals(ret, 1)
  213. def testAllocateWithInvalidStateFile(self):
  214. jobid = '1234.hadoop.apache.org'
  215. # create user state file with invalid permissions
  216. stateFile = open(self.statePath, "w")
  217. os.chmod(self.statePath, 0400) # has no write permissions
  218. self.client._hodRunner__cfg['hod']['operation'] = \
  219. "allocate %s %s" % (self.clusterDir, '3')
  220. ret = self.client.operation()
  221. os.chmod(self.statePath, 700) # restore permissions
  222. stateFile.close()
  223. os.remove(self.statePath)
  224. # print self.log._MockLogger__logLines
  225. self.assertTrue(self.log.hasMessage(INVALID_STATE_FILE_MSGS[2] % \
  226. os.path.realpath(self.statePath), 'critical'))
  227. self.assertEquals(ret, 1)
  228. def testAllocateWithInvalidStateStore(self):
  229. jobid = '1234.hadoop.apache.org'
  230. self.client._hodRunner__cfg['hod']['operation'] = \
  231. "allocate %s %s" % (self.clusterDir, 3)
  232. ###### check with no executable permissions ######
  233. stateFile = open(self.statePath, "w") # create user state file
  234. os.chmod(self.cfg['hod']['user_state'], 0600)
  235. ret = self.client.operation()
  236. os.chmod(self.cfg['hod']['user_state'], 0700) # restore permissions
  237. stateFile.close()
  238. os.remove(self.statePath)
  239. # print self.log._MockLogger__logLines
  240. self.assertTrue(self.log.hasMessage(INVALID_STATE_FILE_MSGS[0] % \
  241. os.path.realpath(self.statePath), 'critical'))
  242. self.assertEquals(ret, 1)
  243. ###### check with no write permissions ######
  244. stateFile = open(self.statePath, "w") # create user state file
  245. os.chmod(self.cfg['hod']['user_state'], 0500)
  246. ret = self.client.operation()
  247. os.chmod(self.cfg['hod']['user_state'], 0700) # restore permissions
  248. stateFile.close()
  249. os.remove(self.statePath)
  250. # print self.log._MockLogger__logLines
  251. self.assertTrue(self.log.hasMessage(INVALID_STATE_FILE_MSGS[0] % \
  252. os.path.realpath(self.statePath), 'critical'))
  253. self.assertEquals(ret, 1)
  254. def tearDown(self):
  255. if os.path.exists(self.clusterDir): os.rmdir(self.clusterDir)
  256. if os.path.exists(self.cfg['hod']['user_state']):
  257. os.rmdir(self.cfg['hod']['user_state'])
  258. class HodTestSuite(BaseTestSuite):
  259. def __init__(self):
  260. # suite setup
  261. BaseTestSuite.__init__(self, __name__, excludes)
  262. pass
  263. def cleanUp(self):
  264. # suite tearDown
  265. pass
  266. def RunHodTests():
  267. # modulename_suite
  268. suite = HodTestSuite()
  269. testResult = suite.runTests()
  270. suite.cleanUp()
  271. return testResult
  272. if __name__ == "__main__":
  273. RunHodTests()