You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2013/11/19 19:17:19 UTC
[5/7] AMBARI-3810. Unittests for File resource an all it's attributes
(Eugene Chekanskiy via dlysnichenko)
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestPuppetExecutor.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestPuppetExecutor.py b/ambari-agent/src/test/python/TestPuppetExecutor.py
deleted file mode 100644
index 42cfe38..0000000
--- a/ambari-agent/src/test/python/TestPuppetExecutor.py
+++ /dev/null
@@ -1,314 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-from unittest import TestCase
-from PuppetExecutor import PuppetExecutor
-from RepoInstaller import RepoInstaller
-from Grep import Grep
-from pprint import pformat
-import socket, threading, tempfile
-import os, time
-import sys
-import json
-from AmbariConfig import AmbariConfig
-from mock.mock import patch, MagicMock, call
-from threading import Thread
-from shell import shellRunner
-import manifestGenerator
-
-class TestPuppetExecutor(TestCase):
-
-
- def test_build(self):
- puppetexecutor = PuppetExecutor("/tmp", "/x", "/y", "/z", AmbariConfig().getConfig())
- command = puppetexecutor.puppetCommand("site.pp")
- self.assertEquals("puppet", command[0], "puppet binary wrong")
- self.assertEquals("apply", command[1], "local apply called")
- self.assertEquals("--confdir=/tmp", command[2],"conf dir tmp")
- self.assertEquals("--detailed-exitcodes", command[3], "make sure output \
- correct")
-
- @patch.object(shellRunner,'run')
- def test_isJavaAvailable(self, cmdrun_mock):
- puppetInstance = PuppetExecutor("/tmp", "/x", "/y", '/tmpdir',
- AmbariConfig().getConfig())
- command = {'configurations':{'global':{'java64_home':'/usr/jdk/jdk123'}}}
-
- cmdrun_mock.return_value = {'exitCode': 1, 'output': 'Command not found', 'error': ''}
- self.assertEquals(puppetInstance.isJavaAvailable(command), False)
-
- cmdrun_mock.return_value = {'exitCode': 0, 'output': 'OK', 'error': ''}
- self.assertEquals(puppetInstance.isJavaAvailable(command), True)
-
- @patch.object(manifestGenerator, 'generateManifest')
- @patch.object(PuppetExecutor, 'isJavaAvailable')
- @patch.object(PuppetExecutor, 'runPuppetFile')
- def test_run_command(self, runPuppetFileMock, isJavaAvailableMock, generateManifestMock):
- tmpdir = tempfile.gettempdir()
- puppetInstance = PuppetExecutor("/tmp", "/x", "/y", tmpdir, AmbariConfig().getConfig())
- jsonFile = open('../../main/python/ambari_agent/test.json', 'r')
- jsonStr = jsonFile.read()
- parsedJson = json.loads(jsonStr)
- parsedJson["taskId"] = 1
- def side_effect1(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
- result["exitcode"] = 0
- runPuppetFileMock.side_effect = side_effect1
- generateManifestMock.return_value = ''
- puppetInstance.reposInstalled = False
- isJavaAvailableMock.return_value = True
- res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertEquals(res["exitcode"], 0)
- self.assertTrue(puppetInstance.reposInstalled)
-
- def side_effect2(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
- result["exitcode"] = 999
- runPuppetFileMock.side_effect = side_effect2
- puppetInstance.reposInstalled = False
- isJavaAvailableMock.return_value = True
- res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertEquals(res["exitcode"], 999)
- self.assertFalse(puppetInstance.reposInstalled)
-
- generateManifestMock.return_value = 'error during manifest generation'
- res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertTrue(generateManifestMock.called)
- self.assertEquals(res["exitcode"], 1)
- generateManifestMock.return_value = ''
-
- def side_effect2(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
- result["exitcode"] = 0
- runPuppetFileMock.side_effect = side_effect2
- puppetInstance.reposInstalled = False
- isJavaAvailableMock.return_value = False
- parsedJson['roleCommand'] = "START"
- parsedJson['configurations'] = {'global':{'java64_home':'/usr/jdk/jdk123'}}
- res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
-
- JAVANOTVALID_MSG = "Cannot access JDK! Make sure you have permission to execute {0}/bin/java"
- errMsg = JAVANOTVALID_MSG.format('/usr/jdk/jdk123')
- self.assertEquals(res["exitcode"], 1)
- self.assertEquals(res["stderr"], errMsg)
- self.assertFalse(puppetInstance.reposInstalled)
-
- parsedJson['configurations'] = {'random':{'name1':'value2'}}
- res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertEquals(res["exitcode"], 1)
- self.assertEquals(res["stderr"], "Cannot access JDK! Make sure java64_home is specified in global config")
-
-
- @patch.object(PuppetExecutor, 'isJavaAvailable')
- @patch.object(RepoInstaller, 'generate_repo_manifests')
- @patch.object(PuppetExecutor, 'runPuppetFile')
- def test_overwrite_repos(self, runPuppetFileMock, generateRepoManifestMock, isJavaAvailableMock):
- tmpdir = tempfile.gettempdir()
- puppetInstance = PuppetExecutor("/tmp", "/x", "/y", tmpdir, AmbariConfig().getConfig())
- jsonFile = open('../../main/python/ambari_agent/test.json', 'r')
- jsonStr = jsonFile.read()
- parsedJson = json.loads(jsonStr)
- parsedJson["taskId"] = 77
- parsedJson['roleCommand'] = "START"
- def side_effect(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
- result["exitcode"] = 0
- runPuppetFileMock.side_effect = side_effect
-
- isJavaAvailableMock.return_value = True
-
- #If ambari-agent has been just started and no any commands were executed by
- # PuppetExecutor.runCommand, then no repo files were updated by
- # RepoInstaller.generate_repo_manifests
- self.assertEquals(0, generateRepoManifestMock.call_count)
- self.assertFalse(puppetInstance.reposInstalled)
-
- # After executing of the first command, RepoInstaller.generate_repo_manifests
- # generates a .pp file for updating repo files
- puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertTrue(puppetInstance.reposInstalled)
- self.assertEquals(1, generateRepoManifestMock.call_count)
- isJavaAvailableMock.assert_called_with("java64_home")
-
- # After executing of the next commands, repo manifest aren't generated again
- puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertTrue(puppetInstance.reposInstalled)
- self.assertEquals(1, generateRepoManifestMock.call_count)
- puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
- self.assertTrue(puppetInstance.reposInstalled)
- self.assertEquals(1, generateRepoManifestMock.call_count)
-
- @patch("os.path.exists")
- def test_configure_environ(self, osPathExistsMock):
- config = AmbariConfig().getConfig()
- tmpdir = tempfile.gettempdir()
- puppetInstance = PuppetExecutor("/tmp", "/x", "/y", tmpdir, config)
- environ = puppetInstance.configureEnviron({})
- self.assertEquals(environ, {})
-
- config.set('puppet','ruby_home',"test/ruby_home")
- puppetInstance = PuppetExecutor("/tmp", "/x", "/y", tmpdir, config)
- osPathExistsMock.return_value = True
- environ = puppetInstance.configureEnviron({"PATH" : "test_path"})
- self.assertEquals(environ["PATH"], "test/ruby_home/bin:test_path")
- self.assertEquals(environ["MY_RUBY_HOME"], "test/ruby_home")
-
- def test_condense_bad2(self):
- puppetexecutor = PuppetExecutor("/tmp", "/x", "/y", "/z", AmbariConfig().getConfig())
- grep = Grep()
- puppetexecutor.grep = grep
- grep.ERROR_LAST_LINES_BEFORE = 2
- grep.ERROR_LAST_LINES_AFTER = 3
- string_err = open('dummy_puppet_output_error2.txt', 'r').read().replace("\n", os.linesep)
- result = puppetexecutor.condenseOutput(string_err, '', 1)
- stripped_string = string_err.strip()
- lines = stripped_string.splitlines(True)
- d = lines[1:6]
- d = grep.cleanByTemplate("".join(d).strip(), "warning").splitlines(True)
- result_check = True
- for l in d:
- result_check &= grep.filterMarkup(l) in result
- self.assertEquals(result_check, True, "Failed to condence fail log")
- self.assertEquals(('warning' in result.lower()), False, "Failed to condence fail log")
- self.assertEquals(len(result.splitlines(True)), 5, "Failed to condence fail log")
-
- def test_condense_bad3(self):
- puppetexecutor = PuppetExecutor("/tmp", "/x", "/y", "/z", AmbariConfig().getConfig())
- grep = Grep()
- puppetexecutor.grep = grep
- string_err = open('dummy_puppet_output_error3.txt', 'r').read().replace("\n", os.linesep)
- result = puppetexecutor.condenseOutput(string_err, '', 1)
- stripped_string = string_err.strip()
- lines = stripped_string.splitlines(True)
- #sys.stderr.write(result)
- d = lines[0:31]
- d = grep.cleanByTemplate("".join(d).strip(), "warning").splitlines(True)
- result_check = True
- for l in d:
- result_check &= grep.filterMarkup(l) in result
- self.assertEquals(result_check, True, "Failed to condence fail log")
- self.assertEquals(('warning' in result.lower()), False, "Failed to condence fail log")
- self.assertEquals(len(result.splitlines(True)), 19, "Failed to condence fail log")
-
- def test_condense_good(self):
- puppetexecutor = PuppetExecutor("/tmp", "/x", "/y", "/z", AmbariConfig().getConfig())
- grep = Grep()
- puppetexecutor.grep = grep
- grep.OUTPUT_LAST_LINES = 2
- string_good = open('dummy_puppet_output_good.txt', 'r').read().replace("\n", os.linesep)
- result = puppetexecutor.condenseOutput(string_good, PuppetExecutor.NO_ERROR, 0)
- stripped_string = string_good.strip()
- lines = stripped_string.splitlines(True)
- result_check = lines[45].strip() in result and lines[46].strip() in result
- self.assertEquals(result_check, True, "Failed to condence output log")
- self.assertEquals(len(result.splitlines(True)), 2, "Failed to condence output log")
-
- @patch("shell.kill_process_with_children")
- def test_watchdog_1(self, kill_process_with_children_mock):
- """
- Tests whether watchdog works
- """
- subproc_mock = self.Subprocess_mockup()
- config = AmbariConfig().getConfig()
- config.set('puppet','timeout_seconds',"0.1")
- executor_mock = self.PuppetExecutor_mock("/home/centos/ambari_repo_info/ambari-agent/src/main/puppet/",
- "/usr/",
- "/root/workspace/puppet-install/facter-1.6.10/",
- "/tmp", config, subproc_mock)
- _, tmpoutfile = tempfile.mkstemp()
- _, tmperrfile = tempfile.mkstemp()
- result = { }
- puppetEnv = { "RUBYLIB" : ""}
- kill_process_with_children_mock.side_effect = lambda pid : subproc_mock.terminate()
- subproc_mock.returncode = None
- thread = Thread(target = executor_mock.runPuppetFile, args = ("fake_puppetFile", result, puppetEnv, tmpoutfile, tmperrfile))
- thread.start()
- time.sleep(0.1)
- subproc_mock.finished_event.wait()
- self.assertEquals(subproc_mock.was_terminated, True, "Subprocess should be terminated due to timeout")
-
-
- def test_watchdog_2(self):
- """
- Tries to catch false positive watchdog invocations
- """
- subproc_mock = self.Subprocess_mockup()
- config = AmbariConfig().getConfig()
- config.set('puppet','timeout_seconds',"5")
- executor_mock = self.PuppetExecutor_mock("/home/centos/ambari_repo_info/ambari-agent/src/main/puppet/",
- "/usr/",
- "/root/workspace/puppet-install/facter-1.6.10/",
- "/tmp", config, subproc_mock)
- _, tmpoutfile = tempfile.mkstemp()
- _, tmperrfile = tempfile.mkstemp()
- result = { }
- puppetEnv = { "RUBYLIB" : ""}
- subproc_mock.returncode = 0
- thread = Thread(target = executor_mock.runPuppetFile, args = ("fake_puppetFile", result, puppetEnv, tmpoutfile, tmperrfile))
- thread.start()
- time.sleep(0.1)
- subproc_mock.should_finish_event.set()
- subproc_mock.finished_event.wait()
- self.assertEquals(subproc_mock.was_terminated, False, "Subprocess should not be terminated before timeout")
- self.assertEquals(subproc_mock.returncode, 0, "Subprocess should not be terminated before timeout")
-
-
- class PuppetExecutor_mock(PuppetExecutor):
-
-
-
- def __init__(self, puppetModule, puppetInstall, facterInstall, tmpDir, config, subprocess_mockup):
- self.subprocess_mockup = subprocess_mockup
- PuppetExecutor.__init__(self, puppetModule, puppetInstall, facterInstall, tmpDir, config)
- pass
-
- def lauch_puppet_subprocess(self, puppetcommand, tmpout, tmperr, puppetEnv):
- self.subprocess_mockup.tmpout = tmpout
- self.subprocess_mockup.tmperr = tmperr
- return self.subprocess_mockup
-
- def runShellKillPgrp(self, puppet):
- puppet.terminate() # note: In real code, subprocess.terminate() is not called
- pass
-
- class Subprocess_mockup():
-
- returncode = 0
-
- started_event = threading.Event()
- should_finish_event = threading.Event()
- finished_event = threading.Event()
- was_terminated = False
- tmpout = None
- tmperr = None
- pid=-1
-
- def communicate(self):
- self.started_event.set()
- self.tmpout.write("Dummy output")
- self.tmpout.flush()
-
- self.tmperr.write("Dummy err")
- self.tmperr.flush()
- self.should_finish_event.wait()
- self.finished_event.set()
- pass
-
- def terminate(self):
- self.was_terminated = True
- self.returncode = 17
- self.should_finish_event.set()
-
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestPuppetExecutorManually.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestPuppetExecutorManually.py b/ambari-agent/src/test/python/TestPuppetExecutorManually.py
deleted file mode 100644
index 90151b6..0000000
--- a/ambari-agent/src/test/python/TestPuppetExecutorManually.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-from unittest import TestCase
-from ambari_agent.PuppetExecutor import PuppetExecutor
-from pprint import pformat
-import socket
-import os
-import sys
-import logging
-from AmbariConfig import AmbariConfig
-import tempfile
-
-FILEPATH="runme.pp"
-logger = logging.getLogger()
-
-class TestPuppetExecutor(TestCase):
-
- def test_run(self):
- """
- Used to run arbitrary puppet manifest. Test tries to find puppet manifest 'runme.pp' and runs it.
- Test does not make any assertions
- """
- if not os.path.isfile(FILEPATH):
- return
-
- logger.info("***** RUNNING " + FILEPATH + " *****")
- cwd = os.getcwd()
- puppetexecutor = PuppetExecutor(cwd, "/x", "/y", "/tmp", AmbariConfig().getConfig())
- result = {}
- puppetEnv = os.environ
- _, tmpoutfile = tempfile.mkstemp()
- _, tmperrfile = tempfile.mkstemp()
- result = puppetexecutor.runPuppetFile(FILEPATH, result, puppetEnv, tmpoutfile, tmperrfile)
- logger.info("*** Puppet output: " + str(result['stdout']))
- logger.info("*** Puppet errors: " + str(result['stderr']))
- logger.info("*** Puppet retcode: " + str(result['exitcode']))
- logger.info("****** DONE *****")
-
-
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestPythonExecutor.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestPythonExecutor.py b/ambari-agent/src/test/python/TestPythonExecutor.py
deleted file mode 100644
index c27c0f5..0000000
--- a/ambari-agent/src/test/python/TestPythonExecutor.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-import pprint
-
-from unittest import TestCase
-import threading
-import tempfile
-import time
-from threading import Thread
-
-from PythonExecutor import PythonExecutor
-from AmbariConfig import AmbariConfig
-from mock.mock import MagicMock, patch
-
-
-class TestPythonExecutor(TestCase):
-
- @patch("shell.kill_process_with_children")
- def test_watchdog_1(self, kill_process_with_children_mock):
- """
- Tests whether watchdog works
- """
- subproc_mock = self.Subprocess_mockup()
- executor = PythonExecutor("/tmp", AmbariConfig().getConfig())
- _, tmpoutfile = tempfile.mkstemp()
- _, tmperrfile = tempfile.mkstemp()
- PYTHON_TIMEOUT_SECONDS = 0.1
- kill_process_with_children_mock.side_effect = lambda pid : subproc_mock.terminate()
-
- def launch_python_subprocess_method(command, tmpout, tmperr):
- subproc_mock.tmpout = tmpout
- subproc_mock.tmperr = tmperr
- return subproc_mock
- executor.launch_python_subprocess = launch_python_subprocess_method
- runShellKillPgrp_method = MagicMock()
- runShellKillPgrp_method.side_effect = lambda python : python.terminate()
- executor.runShellKillPgrp = runShellKillPgrp_method
- subproc_mock.returncode = None
- thread = Thread(target = executor.run_file, args = ("fake_puppetFile", ["arg1", "arg2"],
- tmpoutfile, tmperrfile, PYTHON_TIMEOUT_SECONDS))
- thread.start()
- time.sleep(0.1)
- subproc_mock.finished_event.wait()
- self.assertEquals(subproc_mock.was_terminated, True, "Subprocess should be terminated due to timeout")
-
-
- def test_watchdog_2(self):
- """
- Tries to catch false positive watchdog invocations
- """
- subproc_mock = self.Subprocess_mockup()
- executor = PythonExecutor("/tmp", AmbariConfig().getConfig())
- _, tmpoutfile = tempfile.mkstemp()
- _, tmperrfile = tempfile.mkstemp()
- PYTHON_TIMEOUT_SECONDS = 5
-
- def launch_python_subprocess_method(command, tmpout, tmperr):
- subproc_mock.tmpout = tmpout
- subproc_mock.tmperr = tmperr
- return subproc_mock
- executor.launch_python_subprocess = launch_python_subprocess_method
- runShellKillPgrp_method = MagicMock()
- runShellKillPgrp_method.side_effect = lambda python : python.terminate()
- executor.runShellKillPgrp = runShellKillPgrp_method
- subproc_mock.returncode = 0
- thread = Thread(target = executor.run_file, args = ("fake_puppetFile", ["arg1", "arg2"],
- tmpoutfile, tmperrfile, PYTHON_TIMEOUT_SECONDS))
- thread.start()
- time.sleep(0.1)
- subproc_mock.should_finish_event.set()
- subproc_mock.finished_event.wait()
- self.assertEquals(subproc_mock.was_terminated, False, "Subprocess should not be terminated before timeout")
- self.assertEquals(subproc_mock.returncode, 0, "Subprocess should not be terminated before timeout")
-
-
- def test_execution_results(self):
- subproc_mock = self.Subprocess_mockup()
- executor = PythonExecutor("/tmp", AmbariConfig().getConfig())
- _, tmpoutfile = tempfile.mkstemp()
- _, tmperrfile = tempfile.mkstemp()
- PYTHON_TIMEOUT_SECONDS = 5
-
- def launch_python_subprocess_method(command, tmpout, tmperr):
- subproc_mock.tmpout = tmpout
- subproc_mock.tmperr = tmperr
- return subproc_mock
- executor.launch_python_subprocess = launch_python_subprocess_method
- runShellKillPgrp_method = MagicMock()
- runShellKillPgrp_method.side_effect = lambda python : python.terminate()
- executor.runShellKillPgrp = runShellKillPgrp_method
- subproc_mock.returncode = 0
- subproc_mock.should_finish_event.set()
- result = executor.run_file("file", ["arg1", "arg2"], tmpoutfile, tmperrfile, PYTHON_TIMEOUT_SECONDS)
- self.assertEquals(result, {'exitcode': 0, 'stderr': 'Dummy err', 'stdout': 'Dummy output'})
-
-
- def test_is_successfull(self):
- executor = PythonExecutor("/tmp", AmbariConfig().getConfig())
-
- executor.python_process_has_been_killed = False
- self.assertTrue(executor.isSuccessfull(0))
- self.assertFalse(executor.isSuccessfull(1))
-
- executor.python_process_has_been_killed = True
- self.assertFalse(executor.isSuccessfull(0))
- self.assertFalse(executor.isSuccessfull(1))
-
-
-
- class Subprocess_mockup():
- """
- It's not trivial to use PyMock instead of class here because we need state
- and complex logics
- """
-
- returncode = 0
-
- started_event = threading.Event()
- should_finish_event = threading.Event()
- finished_event = threading.Event()
- was_terminated = False
- tmpout = None
- tmperr = None
- pid=-1
-
- def communicate(self):
- self.started_event.set()
- self.tmpout.write("Dummy output")
- self.tmpout.flush()
-
- self.tmperr.write("Dummy err")
- self.tmperr.flush()
- self.should_finish_event.wait()
- self.finished_event.set()
- pass
-
- def terminate(self):
- self.was_terminated = True
- self.returncode = 17
- self.should_finish_event.set()
-
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestRegistration.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestRegistration.py b/ambari-agent/src/test/python/TestRegistration.py
deleted file mode 100644
index cfa89ad..0000000
--- a/ambari-agent/src/test/python/TestRegistration.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-from unittest import TestCase
-import os
-import tempfile
-from mock.mock import patch
-from mock.mock import MagicMock
-from ambari_agent.Register import Register
-from ambari_agent.AmbariConfig import AmbariConfig
-from ambari_agent.HostInfo import HostInfo
-
-class TestRegistration(TestCase):
-
- @patch.object(HostInfo, 'get_os_type')
- def test_registration_build(self, get_os_type_method):
- config = AmbariConfig().getConfig()
- tmpdir = tempfile.gettempdir()
- config.set('agent', 'prefix', tmpdir)
- config.set('agent', 'current_ping_port', '33777')
- get_os_type_method.return_value = 'redhat'
- ver_file = os.path.join(tmpdir, "version")
- with open(ver_file, "w") as text_file:
- text_file.write("1.3.0")
-
- register = Register(config)
- data = register.build(1)
- #print ("Register: " + pprint.pformat(data))
- self.assertEquals(len(data['hardwareProfile']) > 0, True, "hardwareProfile should contain content")
- self.assertEquals(data['hostname'] != "", True, "hostname should not be empty")
- self.assertEquals(data['publicHostname'] != "", True, "publicHostname should not be empty")
- self.assertEquals(data['responseId'], 1)
- self.assertEquals(data['timestamp'] > 1353678475465L, True, "timestamp should not be empty")
- self.assertEquals(len(data['agentEnv']) > 0, True, "agentEnv should not be empty")
- self.assertEquals(data['agentVersion'], '1.3.0', "agentVersion should not be empty")
- print data['agentEnv']['umask']
- self.assertEquals(not data['agentEnv']['umask']== "", True, "agents umask should not be empty")
- self.assertEquals(data['currentPingPort'] == 33777, True, "current ping port should be 33777")
- self.assertEquals(len(data), 8)
-
- os.remove(ver_file)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestRepoInstaller.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestRepoInstaller.py b/ambari-agent/src/test/python/TestRepoInstaller.py
deleted file mode 100644
index 2628cf7..0000000
--- a/ambari-agent/src/test/python/TestRepoInstaller.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-from unittest import TestCase
-from ambari_agent.RepoInstaller import RepoInstaller
-import tempfile
-import json, os
-import shutil
-from ambari_agent.AmbariConfig import AmbariConfig
-from mock.mock import patch, MagicMock, call
-
-class TestRepoInstaller(TestCase):
-
- def setUp(self):
- self.dir = tempfile.mkdtemp()
- jsonCommand = file('../../main/python/ambari_agent/test.json').read()
- self.parsedJson= json.loads(jsonCommand)
- self.config = AmbariConfig().getConfig()
- self.repoInstaller = RepoInstaller(self.parsedJson, self.dir, '../../main/puppet/modules', 1, self.config)
-
- pass
-
- def tearDown(self):
- shutil.rmtree(self.dir)
- pass
-
-
- def test_prepare_repos_info(self):
- localParsedJson = json.loads('{"hostLevelParams" : {"repo_info" : {"test" : "test"}}}')
- localRepoInstaller = RepoInstaller(localParsedJson, self.dir, '../../main/puppet/modules', 1, self.config)
- localRepoInstaller.prepareReposInfo()
- self.assertEquals(localRepoInstaller.repoInfoList['test'], "test")
-
- localParsedJson = json.loads('{"hostLevelParams" : {"repo_info" : "1"}}')
- localRepoInstaller = RepoInstaller(localParsedJson, self.dir, '../../main/puppet/modules', 1, self.config)
- localRepoInstaller.prepareReposInfo()
- self.assertEquals(localRepoInstaller.repoInfoList, 1)
-
- localParsedJson = json.loads('{"hostLevelParams" : {"repo_info" : ""}}')
- localRepoInstaller = RepoInstaller(localParsedJson, self.dir, '../../main/puppet/modules', 1, self.config)
- localRepoInstaller.prepareReposInfo()
- self.assertEquals(localRepoInstaller.repoInfoList, [])
-
-
- def test_generate_files(self):
- localParsedJson = json.loads('{"hostLevelParams": { "repo_info" : [{"baseUrl":"http://public-repo-1.hortonworks.com/HDP-1.1.1.16/repos/centos5"\
- ,"osType":"centos5","repoId":"HDP-1.1.1.16_TEST","repoName":"HDP_TEST", "mirrorsList":"http://mirrors.fedoraproject.org/mirrorlist"}]}}')
- localRepoInstaller = RepoInstaller(localParsedJson, self.dir, '../../main/puppet/modules', 1, self.config)
- localRepoInstaller.prepareReposInfo()
- result = localRepoInstaller.generateFiles()
- self.assertTrue(result[0].endswith("HDP-1.1.1.16_TEST-1.pp"))
-
- @patch.object(RepoInstaller, 'prepareReposInfo')
- @patch.object(RepoInstaller, 'generateFiles')
- def testInstallRepos(self, generateFilesMock, prepareReposInfoMock):
- result = self.repoInstaller.generate_repo_manifests()
- self.assertTrue(prepareReposInfoMock.called)
- self.assertTrue(generateFilesMock.called)
- print('generate_repo_manifests result: ' + result.__str__())
- pass
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestScript.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestScript.py b/ambari-agent/src/test/python/TestScript.py
deleted file mode 100644
index e4fc24c..0000000
--- a/ambari-agent/src/test/python/TestScript.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-import ConfigParser
-import os
-
-import pprint
-
-from unittest import TestCase
-import threading
-import tempfile
-import time
-from threading import Thread
-
-
-import StringIO
-import sys, logging, pprint
-from ambari_agent import AgentException
-from resource_management.libraries.script import Script
-from resource_management.core.environment import Environment
-from mock.mock import MagicMock, patch
-
-class TestScript(TestCase):
-
- def setUp(self):
- # disable stdout
- out = StringIO.StringIO()
- sys.stdout = out
-
-
-
- @patch("resource_management.core.providers.package.PackageProvider")
- def test_install_packages(self, package_provider_mock):
- no_such_entry_config = {
- }
- empty_config = {
- 'hostLevelParams' : {
- 'package_list' : ''
- }
- }
- dummy_config = {
- 'hostLevelParams' : {
- 'package_list' : "[{\"type\":\"rpm\",\"name\":\"hbase\"},"
- "{\"type\":\"rpm\",\"name\":\"yet-another-package\"}]"
- }
- }
-
- # Testing config without any keys
- with Environment(".") as env:
- script = Script()
- Script.config = no_such_entry_config
- script.install_packages(env)
- self.assertEquals(len(env.resource_list), 0)
-
- # Testing empty package list
- with Environment(".") as env:
- script = Script()
- Script.config = empty_config
- script.install_packages(env)
- self.assertEquals(len(env.resource_list), 0)
-
- # Testing installing of a list of packages
- with Environment(".") as env:
- Script.config = dummy_config
- script.install_packages("env")
- resource_dump = pprint.pformat(env.resource_list)
- self.assertEqual(resource_dump, "[Package['hbase'], Package['yet-another-package']]")
-
-
- def tearDown(self):
- # enable stdout
- sys.stdout = sys.__stdout__
-
-
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestSecurity.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestSecurity.py b/ambari-agent/src/test/python/TestSecurity.py
deleted file mode 100644
index dc9d1fa..0000000
--- a/ambari-agent/src/test/python/TestSecurity.py
+++ /dev/null
@@ -1,347 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-import StringIO
-import sys, subprocess
-
-from ambari_agent import NetUtil
-from ambari_agent.security import CertificateManager
-from mock.mock import MagicMock, patch, ANY
-import mock.mock
-import unittest
-from ambari_agent import ProcessHelper, main
-import logging
-import signal
-from ambari_agent.AmbariConfig import AmbariConfig
-import ConfigParser
-import ssl
-import os
-import tempfile
-from ambari_agent.Controller import Controller
-from ambari_agent import security
-
-aa = mock.mock.mock_open()
-class TestSecurity(unittest.TestCase):
-
- def setUp(self):
- # disable stdout
- out = StringIO.StringIO()
- sys.stdout = out
- # Create config
- self.config = AmbariConfig().getConfig()
- # Instantiate CachedHTTPSConnection (skip connect() call)
- with patch.object(security.VerifiedHTTPSConnection, "connect"):
- self.cachedHTTPSConnection = security.CachedHTTPSConnection(self.config)
-
-
- def tearDown(self):
- # enable stdout
- sys.stdout = sys.__stdout__
-
-
- ### VerifiedHTTPSConnection ###
-
- @patch.object(security.CertificateManager, "initSecurity")
- @patch("socket.create_connection")
- @patch("ssl.wrap_socket")
- def test_VerifiedHTTPSConnection_connect(self, wrap_socket_mock,
- create_connection_mock,
- init_security_mock):
- init_security_mock.return_value = None
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- connection = security.VerifiedHTTPSConnection("example.com",
- self.config.get('server', 'secured_url_port'), self.config)
- connection._tunnel_host = False
- connection.sock = None
- connection.connect()
- self.assertTrue(wrap_socket_mock.called)
-
- ### VerifiedHTTPSConnection with no certificates creation
- @patch.object(security.CertificateManager, "initSecurity")
- @patch("socket.create_connection")
- @patch("ssl.wrap_socket")
- def test_Verified_HTTPSConnection_non_secure_connect(self, wrap_socket_mock,
- create_connection_mock,
- init_security_mock):
- connection = security.VerifiedHTTPSConnection("example.com",
- self.config.get('server', 'secured_url_port'), self.config)
- connection._tunnel_host = False
- connection.sock = None
- connection.connect()
- self.assertFalse(init_security_mock.called)
-
- ### VerifiedHTTPSConnection with two-way SSL authentication enabled
- @patch.object(security.CertificateManager, "initSecurity")
- @patch("socket.create_connection")
- @patch("ssl.wrap_socket")
- def test_Verified_HTTPSConnection_two_way_ssl_connect(self, wrap_socket_mock,
- create_connection_mock,
- init_security_mock):
- wrap_socket_mock.side_effect=ssl.SSLError()
- connection = security.VerifiedHTTPSConnection("example.com",
- self.config.get('server', 'secured_url_port'), self.config)
- connection._tunnel_host = False
- connection.sock = None
- try:
- connection.connect()
- except ssl.SSLError:
- pass
- self.assertTrue(init_security_mock.called)
-
- ### CachedHTTPSConnection ###
-
- @patch.object(security.VerifiedHTTPSConnection, "connect")
- def test_CachedHTTPSConnection_connect(self, vhc_connect_mock):
- self.config.set('server', 'hostname', 'dummy.server.hostname')
- self.config.set('server', 'secured_url_port', '443')
- # Testing not connected case
- self.cachedHTTPSConnection.connected = False
- self.cachedHTTPSConnection.connect()
- self.assertTrue(vhc_connect_mock.called)
- vhc_connect_mock.reset_mock()
- # Testing already connected case
- self.cachedHTTPSConnection.connect()
- self.assertFalse(vhc_connect_mock.called)
-
-
- @patch.object(security.CachedHTTPSConnection, "connect")
- def test_forceClear(self, connect_mock):
- # Testing if httpsconn instance changed
- old = self.cachedHTTPSConnection.httpsconn
- self.cachedHTTPSConnection.forceClear()
- self.assertNotEqual(old, self.cachedHTTPSConnection.httpsconn)
-
-
- @patch.object(security.CachedHTTPSConnection, "connect")
- def test_request(self, connect_mock):
- httpsconn_mock = MagicMock(create = True)
- self.cachedHTTPSConnection.httpsconn = httpsconn_mock
-
- dummy_request = MagicMock(create = True)
- dummy_request.get_method.return_value = "dummy_get_method"
- dummy_request.get_full_url.return_value = "dummy_full_url"
- dummy_request.get_data.return_value = "dummy_get_data"
- dummy_request.headers = "dummy_headers"
-
- responce_mock = MagicMock(create = True)
- responce_mock.read.return_value = "dummy responce"
- httpsconn_mock.getresponse.return_value = responce_mock
-
- # Testing normal case
- responce = self.cachedHTTPSConnection.request(dummy_request)
-
- self.assertEqual(responce, responce_mock.read.return_value)
- httpsconn_mock.request.assert_called_once_with(
- dummy_request.get_method.return_value,
- dummy_request.get_full_url.return_value,
- dummy_request.get_data.return_value,
- dummy_request.headers)
-
- # Testing case of exception
- try:
- def side_eff():
- raise Exception("Dummy exception")
- httpsconn_mock.read.side_effect = side_eff
- responce = self.cachedHTTPSConnection.request(dummy_request)
- self.fail("Should raise IOError")
- except Exception, err:
- # Expected
- pass
-
-
- ### CertificateManager ###
-
-
- @patch("ambari_agent.hostname.hostname")
- def test_getAgentKeyName(self, hostname_mock):
- hostname_mock.return_value = "dummy.hostname"
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- man = CertificateManager(self.config)
- res = man.getAgentKeyName()
- self.assertEquals(res, "/dummy-keysdir/dummy.hostname.key")
-
-
- @patch("ambari_agent.hostname.hostname")
- def test_getAgentCrtName(self, hostname_mock):
- hostname_mock.return_value = "dummy.hostname"
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- man = CertificateManager(self.config)
- res = man.getAgentCrtName()
- self.assertEquals(res, "/dummy-keysdir/dummy.hostname.crt")
-
-
- @patch("ambari_agent.hostname.hostname")
- def test_getAgentCrtReqName(self, hostname_mock):
- hostname_mock.return_value = "dummy.hostname"
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- man = CertificateManager(self.config)
- res = man.getAgentCrtReqName()
- self.assertEquals(res, "/dummy-keysdir/dummy.hostname.csr")
-
-
- def test_getSrvrCrtName(self):
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- man = CertificateManager(self.config)
- res = man.getSrvrCrtName()
- self.assertEquals(res, "/dummy-keysdir/ca.crt")
-
-
- @patch("os.path.exists")
- @patch.object(security.CertificateManager, "loadSrvrCrt")
- @patch.object(security.CertificateManager, "getAgentKeyName")
- @patch.object(security.CertificateManager, "genAgentCrtReq")
- @patch.object(security.CertificateManager, "getAgentCrtName")
- @patch.object(security.CertificateManager, "reqSignCrt")
- def test_checkCertExists(self, reqSignCrt_mock, getAgentCrtName_mock,
- genAgentCrtReq_mock, getAgentKeyName_mock,
- loadSrvrCrt_mock, exists_mock):
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- getAgentKeyName_mock.return_value = "dummy AgentKeyName"
- getAgentCrtName_mock.return_value = "dummy AgentCrtName"
- man = CertificateManager(self.config)
-
- # Case when all files exist
- exists_mock.side_effect = [True, True, True]
- man.checkCertExists()
- self.assertFalse(loadSrvrCrt_mock.called)
- self.assertFalse(genAgentCrtReq_mock.called)
- self.assertFalse(reqSignCrt_mock.called)
-
- # Absent server cert
- exists_mock.side_effect = [False, True, True]
- man.checkCertExists()
- self.assertTrue(loadSrvrCrt_mock.called)
- self.assertFalse(genAgentCrtReq_mock.called)
- self.assertFalse(reqSignCrt_mock.called)
- loadSrvrCrt_mock.reset_mock()
-
- # Absent agent key
- exists_mock.side_effect = [True, False, True]
- man.checkCertExists()
- self.assertFalse(loadSrvrCrt_mock.called)
- self.assertTrue(genAgentCrtReq_mock.called)
- self.assertFalse(reqSignCrt_mock.called)
- genAgentCrtReq_mock.reset_mock()
-
- # Absent agent cert
- exists_mock.side_effect = [True, True, False]
- man.checkCertExists()
- self.assertFalse(loadSrvrCrt_mock.called)
- self.assertFalse(genAgentCrtReq_mock.called)
- self.assertTrue(reqSignCrt_mock.called)
- reqSignCrt_mock.reset_mock()
-
-
-
- @patch('urllib2.urlopen')
- @patch.object(security.CertificateManager, "getSrvrCrtName")
- def test_loadSrvrCrt(self, getSrvrCrtName_mock, urlopen_mock):
- read_mock = MagicMock(create=True)
- read_mock.read.return_value = "dummy_cert"
- urlopen_mock.return_value = read_mock
- _, tmpoutfile = tempfile.mkstemp()
- getSrvrCrtName_mock.return_value = tmpoutfile
-
- man = CertificateManager(self.config)
- man.loadSrvrCrt()
-
- # Checking file contents
- saved = open(tmpoutfile, 'r').read()
- self.assertEqual(saved, read_mock.read.return_value)
-
- os.unlink(tmpoutfile)
-
-
- @patch("ambari_agent.hostname.hostname")
- @patch('__builtin__.open', create=True, autospec=True)
- @patch.dict('os.environ', {'DUMMY_PASSPHRASE': 'dummy-passphrase'})
- @patch('json.dumps')
- @patch('urllib2.Request')
- @patch('urllib2.urlopen')
- @patch('json.loads')
- def test_reqSignCrt(self, loads_mock, urlopen_mock, request_mock, dumps_mock, open_mock, hostname_mock):
- self.config.set('security', 'keysdir', '/dummy-keysdir')
- self.config.set('security', 'passphrase_env_var_name', 'DUMMY_PASSPHRASE')
- man = CertificateManager(self.config)
- hostname_mock.return_value = "dummy-hostname"
-
- open_mock.return_value.read.return_value = "dummy_request"
- urlopen_mock.return_value.read.return_value = "dummy_server_request"
- loads_mock.return_value = {
- 'result': 'OK',
- 'signedCa': 'dummy-crt'
- }
-
- # Test normal server interaction
- man.reqSignCrt()
-
- self.assertEqual(dumps_mock.call_args[0][0], {
- 'csr' : 'dummy_request',
- 'passphrase' : 'dummy-passphrase'
- })
- self.assertEqual(open_mock.return_value.write.call_args[0][0], 'dummy-crt')
-
- # Test negative server reply
- dumps_mock.reset_mock()
- open_mock.return_value.write.reset_mock()
- loads_mock.return_value = {
- 'result': 'FAIL',
- 'signedCa': 'fail-crt'
- }
-
- # If certificate signing failed, then exception must be raised
- try:
- man.reqSignCrt()
- self.fail()
- except ssl.SSLError:
- pass
- self.assertFalse(open_mock.return_value.write.called)
-
- # Test connection fail
- dumps_mock.reset_mock()
- open_mock.return_value.write.reset_mock()
-
- try:
- man.reqSignCrt()
- self.fail("Expected exception here")
- except Exception, err:
- # expected
- pass
-
-
-
-
- @patch("subprocess.Popen")
- @patch("subprocess.Popen.communicate")
- def test_genAgentCrtReq(self, communicate_mock, popen_mock):
- man = CertificateManager(self.config)
- p = MagicMock(spec=subprocess.Popen)
- p.communicate = communicate_mock
- popen_mock.return_value = p
- man.genAgentCrtReq()
- self.assertTrue(popen_mock.called)
- self.assertTrue(communicate_mock.called)
-
-
- @patch.object(security.CertificateManager, "checkCertExists")
- def test_initSecurity(self, checkCertExists_method):
- man = CertificateManager(self.config)
- man.initSecurity()
- self.assertTrue(checkCertExists_method.called)
-
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestShell.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestShell.py b/ambari-agent/src/test/python/TestShell.py
deleted file mode 100644
index 895630e..0000000
--- a/ambari-agent/src/test/python/TestShell.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python2.6
-# -*- coding: utf-8 -*-
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-import os
-import unittest
-import tempfile
-from mock.mock import patch, MagicMock, call
-from ambari_agent.AmbariConfig import AmbariConfig
-from ambari_agent import shell
-from shell import shellRunner
-from sys import platform as _platform
-import subprocess, time
-
-class TestShell(unittest.TestCase):
-
-
- @patch("os.setuid")
- def test_changeUid(self, os_setUIDMock):
- shell.threadLocal.uid = 9999
- shell.changeUid()
- self.assertTrue(os_setUIDMock.called)
-
-
- @patch("pwd.getpwnam")
- def test_shellRunner_run(self, getpwnamMock):
- sh = shellRunner()
- result = sh.run(['echo'])
- self.assertEquals(result['exitCode'], 0)
- self.assertEquals(result['error'], '')
-
- getpwnamMock.return_value = [os.getuid(), os.getuid(), os.getuid()]
- result = sh.run(['echo'], 'non_exist_user_name')
- self.assertEquals(result['exitCode'], 0)
- self.assertEquals(result['error'], '')
-
- def test_kill_process_with_children(self):
- if _platform == "linux" or _platform == "linux2": # Test is Linux-specific
- gracefull_kill_delay_old = shell.gracefull_kill_delay
- shell.gracefull_kill_delay = 0.1
- sleep_cmd = "sleep 314159265"
- test_cmd = """ (({0}) | ({0} | {0})) """.format(sleep_cmd)
- # Starting process tree (multiple process groups)
- test_process = subprocess.Popen(test_cmd, shell=True)
- time.sleep(0.3) # Delay to allow subprocess to start
- # Check if processes are running
- ps_cmd = """ps aux | grep "{0}" | grep -v grep """.format(sleep_cmd)
- ps_process = subprocess.Popen(ps_cmd, stdout=subprocess.PIPE, shell=True)
- (out, err) = ps_process.communicate()
- self.assertTrue(sleep_cmd in out)
- # Kill test process
- shell.kill_process_with_children(test_process.pid)
- test_process.communicate()
- # Now test process should not be running
- ps_process = subprocess.Popen(ps_cmd, stdout=subprocess.PIPE, shell=True)
- (out, err) = ps_process.communicate()
- self.assertFalse(sleep_cmd in out)
- shell.gracefull_kill_delay = gracefull_kill_delay_old
- else:
- # Do not run under other systems
- pass
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestStackVersionsFileHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestStackVersionsFileHandler.py b/ambari-agent/src/test/python/TestStackVersionsFileHandler.py
deleted file mode 100644
index d44a8e5..0000000
--- a/ambari-agent/src/test/python/TestStackVersionsFileHandler.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-
-from unittest import TestCase
-import unittest
-import StringIO
-import socket
-import os, sys
-from mock.mock import patch
-from mock.mock import MagicMock
-from mock.mock import create_autospec
-import os, errno, tempfile
-from ambari_agent import StackVersionsFileHandler
-import logging
-
-stackVersionsFileHandler = \
- StackVersionsFileHandler.StackVersionsFileHandler("/tmp")
-dummyVersionsFile = os.path.join('dummy_files', 'dummy_current_stack')
-
-class TestStackVersionsFileHandler(TestCase):
-
- logger = logging.getLogger()
-
- @patch.object(stackVersionsFileHandler, 'touch_file')
- def test_read_stack_version(self, touch_method):
- stackVersionsFileHandler.versionsFilePath = dummyVersionsFile
- result = stackVersionsFileHandler.read_stack_version("NAGIOS_SERVER")
- self.assertEquals(result, '{"stackName":"HDP","stackVersion":"1.2.1"}')
- result = stackVersionsFileHandler.read_stack_version("GANGLIA_SERVER")
- self.assertEquals(result, '{"stackName":"HDP","stackVersion":"1.2.2"}')
- result = stackVersionsFileHandler.read_stack_version("NOTEXISTING")
- self.assertEquals(result, stackVersionsFileHandler.DEFAULT_VER)
- self.assertTrue(touch_method.called)
-
-
- @patch.object(stackVersionsFileHandler, 'touch_file')
- def test_read_all_stack_versions(self, touch_method):
- stackVersionsFileHandler.versionsFilePath = dummyVersionsFile
- result = stackVersionsFileHandler.read_all_stack_versions()
- self.assertEquals(len(result.keys()), 4)
- self.assertEquals(result["NAGIOS_SERVER"],
- '{"stackName":"HDP","stackVersion":"1.2.1"}')
- self.assertEquals(result["HCATALOG"],
- '{"stackName":"HDP","stackVersion":"1.2.2"}')
- self.assertTrue(touch_method.called)
-
-
- def test_extract(self):
- s = ' NAGIOS_SERVER \t {"stackName":"HDP","stackVersion":"1.3.0"} '
- comp, ver = stackVersionsFileHandler.extract(s)
- self.assertEqual(comp, "NAGIOS_SERVER")
- self.assertEqual(ver, '{"stackName":"HDP","stackVersion":"1.3.0"}')
- # testing wrong value
- s = " NAGIOS_SERVER "
- comp, ver = stackVersionsFileHandler.extract(s)
- self.assertEqual(comp, stackVersionsFileHandler.DEFAULT_VER)
- self.assertEqual(ver, stackVersionsFileHandler.DEFAULT_VER)
-
-
- def test_touch_file(self):
- tmpfile = tempfile.mktemp()
- stackVersionsFileHandler.versionsFilePath = tmpfile
- stackVersionsFileHandler.touch_file()
- result = os.path.isfile(tmpfile)
- self.assertEqual(result, True)
-
-
- def test_write_stack_version(self):
- #saving old values
- oldFilePathValue = stackVersionsFileHandler.versionsFilePath
- oldversionsFileDir = stackVersionsFileHandler.versionsFileDir
- oldVerFile = stackVersionsFileHandler.VER_FILE
- #preparations and invocation
- tmpfile = tempfile.mktemp()
- stackVersionsFileHandler.versionsFilePath = tmpfile
- stackVersionsFileHandler.VER_FILE = \
- os.path.basename(tmpfile)
- stackVersionsFileHandler.versionsFileDir = \
- os.path.dirname(tmpfile)
- stackVersionsFileHandler.touch_file()
- stackVersionsFileHandler.write_stack_version(
- "NAGIOS_SERVER", '"stackVersion":"1.3.0"')
- # Checking if backup file exists
- expectedBackupFile = tmpfile + ".bak"
- self.assertTrue(os.path.isfile(expectedBackupFile))
- os.remove(expectedBackupFile)
- # Checking content of created file
- content = stackVersionsFileHandler.read_all_stack_versions()
- self.assertEquals(len(content), 1)
- self.assertEqual(content['NAGIOS_SERVER'], '"stackVersion":"1.3.0"')
- self.assertTrue(os.path.isfile(tmpfile))
- os.remove(tmpfile)
- # Restoring old values
- stackVersionsFileHandler.versionsFilePath = oldFilePathValue
- stackVersionsFileHandler.versionsFileDir = oldversionsFileDir
- stackVersionsFileHandler.VER_FILE = oldVerFile
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/TestStatusCheck.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/TestStatusCheck.py b/ambari-agent/src/test/python/TestStatusCheck.py
deleted file mode 100644
index e246189..0000000
--- a/ambari-agent/src/test/python/TestStatusCheck.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env python2.6
-
-'''
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-'''
-import string
-import random
-import os
-from unittest import TestCase
-from ambari_agent.StatusCheck import StatusCheck
-import AmbariConfig
-import logging
-from mock.mock import patch, Mock
-
-
-USERNAME_LENGTH=10
-USERNAME_CHARS=string.ascii_uppercase +string.ascii_lowercase + string.digits + '-_'
-
-PID_DIR='/pids_dir'
-
-COMPONENT_LIVE = 'LIVE_COMPONENT'
-COMPONENT_LIVE_PID = 'live_' + StatusCheck.USER_PATTERN + '_comp.pid'
-
-COMPONENT_DEAD = 'DEAD_COMPONENT'
-COMPONENT_DEAD_PID = 'dead_' + StatusCheck.USER_PATTERN + '_comp.pid'
-
-class TestStatusCheck(TestCase):
-
- logger = logging.getLogger()
-
- def generateUserName(self):
- return ''.join(random.choice(USERNAME_CHARS) for x in range(USERNAME_LENGTH))
-
- def setUp(self):
-
- self.pidPathesVars = [
- {'var' : '',
- 'defaultValue' : PID_DIR}
- ]
-
- self.serviceToPidDict = {
- COMPONENT_LIVE : COMPONENT_LIVE_PID,
- COMPONENT_DEAD : COMPONENT_DEAD_PID
- }
-
- live_user = self.generateUserName()
- self.logger.info('Live user: ' + live_user)
- self.live_pid_file_name = string.replace(COMPONENT_LIVE_PID, StatusCheck.USER_PATTERN, live_user)
- self.live_pid_full_path = PID_DIR + os.sep + self.live_pid_file_name
-
- dead_user = self.generateUserName()
- self.logger.info('Dead user: ' + live_user)
- self.dead_pid_file_name = string.replace(COMPONENT_DEAD_PID, StatusCheck.USER_PATTERN, dead_user)
- self.dead_pid_full_path = PID_DIR + os.sep + self.dead_pid_file_name
-
- self.pidFilesDict = {self.live_pid_file_name : self.live_pid_full_path,
- self.dead_pid_file_name : self.dead_pid_full_path}
-
- self.is_live_values = {self.live_pid_full_path : True,
- self.dead_pid_full_path : False}
-
- self.servicesToLinuxUser = {COMPONENT_LIVE : 'live_user',
- COMPONENT_DEAD : 'dead_user'}
-
- self.globalConfig = {'live_user' : live_user,
- 'dead_user' : dead_user}
-
-
- # Ensure that status checker return True for running process
- @patch.object(StatusCheck, 'getIsLive')
- def test_live(self, get_is_live_mock):
-
- statusCheck = StatusCheck(self.serviceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
-
- self.assertTrue(StatusCheck.USER_PATTERN in self.serviceToPidDict[COMPONENT_LIVE])
- self.assertTrue(StatusCheck.USER_PATTERN in self.serviceToPidDict[COMPONENT_DEAD])
-
- statusCheck.pidFilesDict = self.pidFilesDict
-
- get_is_live_mock.side_effect = lambda pid_path : self.is_live_values[pid_path]
-
- status = statusCheck.getStatus(COMPONENT_LIVE)
- self.assertEqual(status, True)
-
- @patch.object(logger, 'info')
- def test_dont_relog_serToPidDict(self, logger_info_mock):
- TestStatusCheck.timesLogged = 0
-
- def my_side_effect(*args, **kwargs):
- TestStatusCheck.timesLogged += args[0].find('Service to pid dictionary: ')+1
-
-
- logger_info_mock.side_effect = my_side_effect
-
- # call this three times
- statusCheck = StatusCheck(self.serviceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
- statusCheck = StatusCheck(self.serviceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
- statusCheck = StatusCheck(self.serviceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
- # logged not more then once
- self.assert_(TestStatusCheck.timesLogged <= 1, "test_dont_relog_serToPidDict logged more then once")
-
- # Ensure that status checker return True for running process even if multiple
- # pids for a service component exist
- @patch.object(StatusCheck, 'getIsLive')
- def test_live_if_multiple_pids(self, get_is_live_mock):
-
- one_more_pid_file_name = string.replace(COMPONENT_LIVE_PID, StatusCheck.USER_PATTERN,
- 'any_other_linux_user')
- one_more_pid_full_path = PID_DIR + os.sep + one_more_pid_file_name
-
- self.pidFilesDict[one_more_pid_file_name] = one_more_pid_full_path
- self.is_live_values[one_more_pid_full_path] = False
-
- statusCheck = StatusCheck(self.serviceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
-
- statusCheck.pidFilesDict = self.pidFilesDict
-
- get_is_live_mock.side_effect = lambda pid_path : self.is_live_values[pid_path]
-
- status = statusCheck.getStatus(COMPONENT_LIVE)
- self.assertEqual(status, True)
-
- # Ensure that status checker prints error message if there is no linux user
- # for service, which pid depends on user
- @patch.object(StatusCheck, 'getIsLive')
- @patch.object(logger, "error")
- def test_no_user_mapping(self, error_mock, get_is_live_mock):
-
-
- badServiceToPidDict = self.serviceToPidDict.copy()
- badServiceToPidDict['BAD_COMPONENT'] = 'prefix' + StatusCheck.USER_PATTERN
-
- statusCheck = StatusCheck(badServiceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
-
- statusCheck.pidFilesDict = self.pidFilesDict
-
- get_is_live_mock.side_effect = lambda pid_path : self.is_live_values[pid_path]
-
- status = statusCheck.getStatus(COMPONENT_LIVE)
- self.assertTrue(error_mock.called)
-
- # Ensure that status checker return False for dead process
- @patch.object(StatusCheck, 'getIsLive')
- def test_dead(self, get_is_live_mock):
- statusCheck = StatusCheck(self.serviceToPidDict, self.pidPathesVars,
- self.globalConfig, self.servicesToLinuxUser)
-
- statusCheck.pidFilesDict = self.pidFilesDict
-
- get_is_live_mock.side_effect = lambda pid_path : self.is_live_values[pid_path]
- status = statusCheck.getStatus(COMPONENT_DEAD)
- self.assertEqual(status, False)
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py b/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
new file mode 100644
index 0000000..98817e9
--- /dev/null
+++ b/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
@@ -0,0 +1,420 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+from Queue import Queue
+
+from unittest import TestCase
+from ambari_agent.LiveStatus import LiveStatus
+from ambari_agent.PuppetExecutor import PuppetExecutor
+from ambari_agent.ActionQueue import ActionQueue
+from ambari_agent.AmbariConfig import AmbariConfig
+import os, errno, time, pprint, tempfile, threading
+import StringIO
+import sys
+from threading import Thread
+
+from mock.mock import patch, MagicMock, call
+from ambari_agent.StackVersionsFileHandler import StackVersionsFileHandler
+from ambari_agent.CustomServiceOrchestrator import CustomServiceOrchestrator
+
+
+class TestActionQueue(TestCase):
+
+ def setUp(self):
+ out = StringIO.StringIO()
+ sys.stdout = out
+ # save original open() method for later use
+ self.original_open = open
+
+
+ def tearDown(self):
+ sys.stdout = sys.__stdout__
+
+ datanode_install_command = {
+ 'commandType': 'EXECUTION_COMMAND',
+ 'role': u'DATANODE',
+ 'roleCommand': u'INSTALL',
+ 'commandId': '1-1',
+ 'taskId': 3,
+ 'clusterName': u'cc',
+ 'serviceName': u'HDFS',
+ 'configurations':{'global' : {}},
+ 'configurationTags':{'global' : { 'tag': 'v1' }}
+ }
+
+ datanode_upgrade_command = {
+ 'commandId': 17,
+ 'role' : "role",
+ 'taskId' : "taskId",
+ 'clusterName' : "clusterName",
+ 'serviceName' : "serviceName",
+ 'roleCommand' : 'UPGRADE',
+ 'hostname' : "localhost.localdomain",
+ 'hostLevelParams': "hostLevelParams",
+ 'clusterHostInfo': "clusterHostInfo",
+ 'commandType': "EXECUTION_COMMAND",
+ 'configurations':{'global' : {}},
+ 'roleParams': {},
+ 'commandParams' : {
+ 'source_stack_version' : 'HDP-1.2.1',
+ 'target_stack_version' : 'HDP-1.3.0'
+ }
+ }
+
+ namenode_install_command = {
+ 'commandType': 'EXECUTION_COMMAND',
+ 'role': u'NAMENODE',
+ 'roleCommand': u'INSTALL',
+ 'commandId': '1-1',
+ 'taskId': 4,
+ 'clusterName': u'cc',
+ 'serviceName': u'HDFS',
+ }
+
+ snamenode_install_command = {
+ 'commandType': 'EXECUTION_COMMAND',
+ 'role': u'SECONDARY_NAMENODE',
+ 'roleCommand': u'INSTALL',
+ 'commandId': '1-1',
+ 'taskId': 5,
+ 'clusterName': u'cc',
+ 'serviceName': u'HDFS',
+ }
+
+ nagios_install_command = {
+ 'commandType': 'EXECUTION_COMMAND',
+ 'role': u'NAGIOS',
+ 'roleCommand': u'INSTALL',
+ 'commandId': '1-1',
+ 'taskId': 6,
+ 'clusterName': u'cc',
+ 'serviceName': u'HDFS',
+ }
+
+ hbase_install_command = {
+ 'commandType': 'EXECUTION_COMMAND',
+ 'role': u'HBASE',
+ 'roleCommand': u'INSTALL',
+ 'commandId': '1-1',
+ 'taskId': 7,
+ 'clusterName': u'cc',
+ 'serviceName': u'HDFS',
+ }
+
+ status_command = {
+ "serviceName" : 'HDFS',
+ "commandType" : "STATUS_COMMAND",
+ "clusterName" : "",
+ "componentName" : "DATANODE",
+ 'configurations':{}
+ }
+
+
+ @patch.object(ActionQueue, "process_command")
+ @patch.object(Queue, "get")
+ def test_ActionQueueStartStop(self, get_mock, process_command_mock):
+ actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
+ actionQueue.start()
+ time.sleep(0.1)
+ actionQueue.stop()
+ actionQueue.join()
+ self.assertEqual(actionQueue.stopped(), True, 'Action queue is not stopped.')
+ self.assertTrue(process_command_mock.call_count > 1)
+
+
+ @patch("traceback.print_exc")
+ @patch.object(ActionQueue, "execute_command")
+ @patch.object(ActionQueue, "execute_status_command")
+ def test_process_command(self, execute_status_command_mock,
+ execute_command_mock, print_exc_mock):
+ actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
+ execution_command = {
+ 'commandType' : ActionQueue.EXECUTION_COMMAND,
+ }
+ status_command = {
+ 'commandType' : ActionQueue.STATUS_COMMAND,
+ }
+ wrong_command = {
+ 'commandType' : "SOME_WRONG_COMMAND",
+ }
+ # Try wrong command
+ actionQueue.process_command(wrong_command)
+ self.assertFalse(execute_command_mock.called)
+ self.assertFalse(execute_status_command_mock.called)
+ self.assertFalse(print_exc_mock.called)
+
+ execute_command_mock.reset_mock()
+ execute_status_command_mock.reset_mock()
+ print_exc_mock.reset_mock()
+ # Try normal execution
+ actionQueue.process_command(execution_command)
+ self.assertTrue(execute_command_mock.called)
+ self.assertFalse(execute_status_command_mock.called)
+ self.assertFalse(print_exc_mock.called)
+
+ execute_command_mock.reset_mock()
+ execute_status_command_mock.reset_mock()
+ print_exc_mock.reset_mock()
+
+ actionQueue.process_command(status_command)
+ self.assertFalse(execute_command_mock.called)
+ self.assertTrue(execute_status_command_mock.called)
+ self.assertFalse(print_exc_mock.called)
+
+ execute_command_mock.reset_mock()
+ execute_status_command_mock.reset_mock()
+ print_exc_mock.reset_mock()
+
+ # Try exception to check proper logging
+ def side_effect(self):
+ raise Exception("TerribleException")
+ execute_command_mock.side_effect = side_effect
+ actionQueue.process_command(execution_command)
+ self.assertTrue(print_exc_mock.called)
+
+ print_exc_mock.reset_mock()
+
+ execute_status_command_mock.side_effect = side_effect
+ actionQueue.process_command(execution_command)
+ self.assertTrue(print_exc_mock.called)
+
+
+
+ @patch("__builtin__.open")
+ @patch.object(ActionQueue, "status_update_callback")
+ def test_execute_command(self, status_update_callback_mock, open_mock):
+ # Make file read calls visible
+ def open_side_effect(file, mode):
+ if mode == 'r':
+ file_mock = MagicMock()
+ file_mock.read.return_value = "Read from " + str(file)
+ return file_mock
+ else:
+ return self.original_open(file, mode)
+ open_mock.side_effect = open_side_effect
+
+ config = AmbariConfig().getConfig()
+ tempdir = tempfile.gettempdir()
+ config.set('agent', 'prefix', tempdir)
+ actionQueue = ActionQueue(config, 'dummy_controller')
+ unfreeze_flag = threading.Event()
+ puppet_execution_result_dict = {
+ 'stdout': 'out',
+ 'stderr': 'stderr',
+ }
+ def side_effect(command, tmpoutfile, tmperrfile):
+ unfreeze_flag.wait()
+ return puppet_execution_result_dict
+ def patched_aq_execute_command(command):
+ # We have to perform patching for separate thread in the same thread
+ with patch.object(PuppetExecutor, "runCommand") as runCommand_mock:
+ runCommand_mock.side_effect = side_effect
+ actionQueue.execute_command(command)
+ ### Test install/start/stop command ###
+ ## Test successful execution with configuration tags
+ puppet_execution_result_dict['status'] = 'COMPLETE'
+ puppet_execution_result_dict['exitcode'] = 0
+ # We call method in a separate thread
+ execution_thread = Thread(target = patched_aq_execute_command ,
+ args = (self.datanode_install_command, ))
+ execution_thread.start()
+ # check in progress report
+ # wait until ready
+ while True:
+ time.sleep(0.1)
+ report = actionQueue.result()
+ if len(report['reports']) != 0:
+ break
+ expected = {'status': 'IN_PROGRESS',
+ 'stderr': 'Read from {0}/errors-3.txt'.format(tempdir),
+ 'stdout': 'Read from {0}/output-3.txt'.format(tempdir),
+ 'clusterName': u'cc',
+ 'roleCommand': u'INSTALL',
+ 'serviceName': u'HDFS',
+ 'role': u'DATANODE',
+ 'actionId': '1-1',
+ 'taskId': 3,
+ 'exitCode': 777}
+ self.assertEqual(report['reports'][0], expected)
+ # Continue command execution
+ unfreeze_flag.set()
+ # wait until ready
+ while report['reports'][0]['status'] == 'IN_PROGRESS':
+ time.sleep(0.1)
+ report = actionQueue.result()
+ # check report
+ configname = os.path.join(tempdir, 'config.json')
+ expected = {'status': 'COMPLETED',
+ 'stderr': 'stderr',
+ 'stdout': 'out',
+ 'clusterName': u'cc',
+ 'configurationTags': {'global': {'tag': 'v1'}},
+ 'roleCommand': u'INSTALL',
+ 'serviceName': u'HDFS',
+ 'role': u'DATANODE',
+ 'actionId': '1-1',
+ 'taskId': 3,
+ 'exitCode': 0}
+ self.assertEqual(len(report['reports']), 1)
+ self.assertEqual(report['reports'][0], expected)
+ self.assertTrue(os.path.isfile(configname))
+ # Check that we had 2 status update calls ( IN_PROGRESS and COMPLETE)
+ self.assertEqual(status_update_callback_mock.call_count, 2)
+ os.remove(configname)
+
+ # now should not have reports (read complete/failed reports are deleted)
+ report = actionQueue.result()
+ self.assertEqual(len(report['reports']), 0)
+
+ ## Test failed execution
+ puppet_execution_result_dict['status'] = 'FAILED'
+ puppet_execution_result_dict['exitcode'] = 13
+ # We call method in a separate thread
+ execution_thread = Thread(target = patched_aq_execute_command ,
+ args = (self.datanode_install_command, ))
+ execution_thread.start()
+ unfreeze_flag.set()
+ # check in progress report
+ # wait until ready
+ report = actionQueue.result()
+ while len(report['reports']) == 0 or \
+ report['reports'][0]['status'] == 'IN_PROGRESS':
+ time.sleep(0.1)
+ report = actionQueue.result()
+ # check report
+ expected = {'status': 'FAILED',
+ 'stderr': 'stderr',
+ 'stdout': 'out',
+ 'clusterName': u'cc',
+ 'roleCommand': u'INSTALL',
+ 'serviceName': u'HDFS',
+ 'role': u'DATANODE',
+ 'actionId': '1-1',
+ 'taskId': 3,
+ 'exitCode': 13}
+ self.assertEqual(len(report['reports']), 1)
+ self.assertEqual(report['reports'][0], expected)
+
+ # now should not have reports (read complete/failed reports are deleted)
+ report = actionQueue.result()
+ self.assertEqual(len(report['reports']), 0)
+
+ ### Test upgrade command ###
+ puppet_execution_result_dict['status'] = 'COMPLETE'
+ puppet_execution_result_dict['exitcode'] = 0
+ execution_thread = Thread(target = patched_aq_execute_command ,
+ args = (self.datanode_upgrade_command, ))
+ execution_thread.start()
+ unfreeze_flag.set()
+ # wait until ready
+ report = actionQueue.result()
+ while len(report['reports']) == 0 or \
+ report['reports'][0]['status'] == 'IN_PROGRESS':
+ time.sleep(0.1)
+ report = actionQueue.result()
+ # check report
+ expected = {'status': 'COMPLETED',
+ 'stderr': 'stderr',
+ 'stdout': 'out',
+ 'clusterName': 'clusterName',
+ 'roleCommand': 'UPGRADE',
+ 'serviceName': 'serviceName',
+ 'role': 'role',
+ 'actionId': 17,
+ 'taskId': 'taskId',
+ 'exitCode': 0}
+ self.assertEqual(len(report['reports']), 1)
+ self.assertEqual(report['reports'][0], expected)
+
+ # now should not have reports (read complete/failed reports are deleted)
+ report = actionQueue.result()
+ self.assertEqual(len(report['reports']), 0)
+
+
+ @patch.object(ActionQueue, "status_update_callback")
+ @patch.object(StackVersionsFileHandler, "read_stack_version")
+ @patch.object(ActionQueue, "execute_command")
+ @patch.object(LiveStatus, "build")
+ def test_execute_status_command(self, build_mock, execute_command_mock,
+ read_stack_version_mock,
+ status_update_callback):
+ actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
+ build_mock.return_value = "dummy report"
+ # Try normal execution
+ actionQueue.execute_status_command(self.status_command)
+ report = actionQueue.result()
+ expected = 'dummy report'
+ self.assertEqual(len(report['componentStatus']), 1)
+ self.assertEqual(report['componentStatus'][0], expected)
+
+
+ def test_determine_command_format_version(self):
+ v1_command = {
+ 'commandParams': {
+ 'schema_version': '1.0'
+ }
+ }
+ v2_command = {
+ 'commandParams': {
+ 'schema_version': '2.0'
+ }
+ }
+ current_command = {
+ # Absent 'commandParams' section
+ }
+ actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
+ self.assertEqual(actionQueue.determine_command_format_version(v1_command),
+ ActionQueue.COMMAND_FORMAT_V1)
+ self.assertEqual(actionQueue.determine_command_format_version(v2_command),
+ ActionQueue.COMMAND_FORMAT_V2)
+ self.assertEqual(actionQueue.determine_command_format_version(current_command),
+ ActionQueue.COMMAND_FORMAT_V1)
+
+
+ @patch.object(ActionQueue, "determine_command_format_version")
+ @patch("__builtin__.open")
+ @patch.object(PuppetExecutor, "runCommand")
+ @patch.object(CustomServiceOrchestrator, "runCommand")
+ @patch.object(ActionQueue, "status_update_callback")
+ def test_command_execution_depending_on_command_format(self,
+ status_update_callback_mock,
+ custom_ex_runCommand_mock,
+ puppet_runCommand_mock, open_mock,
+ determine_command_format_version_mock):
+ actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
+ ret = {
+ 'stdout' : '',
+ 'stderr' : '',
+ 'exitcode': 1,
+ }
+ puppet_runCommand_mock.return_value = ret
+ determine_command_format_version_mock.return_value = \
+ ActionQueue.COMMAND_FORMAT_V1
+ actionQueue.execute_command(self.datanode_install_command)
+ self.assertTrue(puppet_runCommand_mock.called)
+ self.assertFalse(custom_ex_runCommand_mock.called)
+
+ puppet_runCommand_mock.reset_mock()
+
+ custom_ex_runCommand_mock.return_value = ret
+ determine_command_format_version_mock.return_value = \
+ ActionQueue.COMMAND_FORMAT_V2
+ actionQueue.execute_command(self.datanode_install_command)
+ self.assertFalse(puppet_runCommand_mock.called)
+ self.assertTrue(custom_ex_runCommand_mock.called)
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/ambari_agent/TestActualConfigHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestActualConfigHandler.py b/ambari-agent/src/test/python/ambari_agent/TestActualConfigHandler.py
new file mode 100644
index 0000000..2461499
--- /dev/null
+++ b/ambari-agent/src/test/python/ambari_agent/TestActualConfigHandler.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+import tempfile
+from unittest import TestCase
+from ambari_agent.AmbariConfig import AmbariConfig
+from ambari_agent.ActualConfigHandler import ActualConfigHandler
+import os
+import logging
+import json
+
+class TestActualConfigHandler(TestCase):
+
+ logger = logging.getLogger()
+
+ def test_read_write(self):
+ config = AmbariConfig().getConfig()
+ tmpdir = tempfile.gettempdir()
+ config.set('agent', 'prefix', tmpdir)
+ handler = ActualConfigHandler(config)
+
+ tags = { "global": "version1", "core-site": "version2" }
+ handler.write_actual(tags)
+ output = handler.read_actual()
+ self.assertEquals(tags, output)
+ os.remove(os.path.join(tmpdir, ActualConfigHandler.CONFIG_NAME))
+
+ def test_read_empty(self):
+ config = AmbariConfig().getConfig()
+ tmpdir = tempfile.gettempdir()
+ config.set('agent', 'prefix', tmpdir)
+ handler = ActualConfigHandler(config)
+
+ conf_file = open(os.path.join(tmpdir, ActualConfigHandler.CONFIG_NAME), 'w')
+ conf_file.write("")
+ conf_file.close()
+
+ output = handler.read_actual()
+ self.assertEquals(None, output)
+ os.remove(os.path.join(tmpdir, ActualConfigHandler.CONFIG_NAME))
+
+ def test_read_write_component(self):
+ config = AmbariConfig().getConfig()
+ tmpdir = tempfile.gettempdir()
+ config.set('agent', 'prefix', tmpdir)
+ handler = ActualConfigHandler(config)
+
+ tags1 = { "global": "version1", "core-site": "version2" }
+ handler.write_actual(tags1)
+ handler.copy_to_component('FOO')
+
+ output1 = handler.read_actual_component('FOO')
+ output2 = handler.read_actual_component('GOO')
+
+ self.assertEquals(tags1, output1)
+ self.assertEquals(None, output2)
+
+ tags2 = { "global": "version1", "core-site": "version2" }
+ handler.write_actual(tags2)
+
+ output3 = handler.read_actual()
+ output4 = handler.read_actual_component('FOO')
+ self.assertEquals(tags2, output3)
+ self.assertEquals(tags1, output4)
+ os.remove(os.path.join(tmpdir, "FOO_" + ActualConfigHandler.CONFIG_NAME))
+ os.remove(os.path.join(tmpdir, ActualConfigHandler.CONFIG_NAME))
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/ambari_agent/TestAgentActions.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAgentActions.py b/ambari-agent/src/test/python/ambari_agent/TestAgentActions.py
new file mode 100644
index 0000000..dc3c919
--- /dev/null
+++ b/ambari-agent/src/test/python/ambari_agent/TestAgentActions.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+from unittest import TestCase
+
+
+class TestAgentActions(TestCase):
+#This feature is not yet implemented in ActionQueue
+ def test_installAndConfigAction(self):
+ pass
+#This feature is not yet implemented in ActionQueue
+ def test_startAndStopAction(self):
+ pass
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/ambari_agent/TestAmbariAgent.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAmbariAgent.py b/ambari-agent/src/test/python/ambari_agent/TestAmbariAgent.py
new file mode 100644
index 0000000..f98132e
--- /dev/null
+++ b/ambari-agent/src/test/python/ambari_agent/TestAmbariAgent.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+import unittest
+import subprocess
+import os
+import sys
+from mock.mock import MagicMock, patch, ANY
+from ambari_agent.Controller import AGENT_AUTO_RESTART_EXIT_CODE
+from ambari_agent import AmbariAgent
+
+
+class TestAmbariAgent(unittest.TestCase):
+
+ @patch.object(subprocess, "Popen")
+ @patch("os.path.isfile")
+ @patch("os.remove")
+ def test_main(self, os_remove_mock, os_path_isfile_mock, subprocess_popen_mock):
+ facter1 = MagicMock()
+ facter2 = MagicMock()
+ subprocess_popen_mock.side_effect = [facter1, facter2]
+ facter1.returncode = 77
+ facter2.returncode = 55
+ os_path_isfile_mock.return_value = True
+ if not (os.environ.has_key("PYTHON")):
+ os.environ['PYTHON'] = "test/python/path"
+ sys.argv[0] = "test data"
+ AmbariAgent.main()
+
+ self.assertTrue(subprocess_popen_mock.called)
+ self.assertTrue(subprocess_popen_mock.call_count == 2)
+ self.assertTrue(facter1.communicate.called)
+ self.assertTrue(facter2.communicate.called)
+ self.assertTrue(os_path_isfile_mock.called)
+ self.assertTrue(os_path_isfile_mock.call_count == 2)
+ self.assertTrue(os_remove_mock.called)
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/e5c6e113/ambari-agent/src/test/python/ambari_agent/TestCertGeneration.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestCertGeneration.py b/ambari-agent/src/test/python/ambari_agent/TestCertGeneration.py
new file mode 100644
index 0000000..94bb9f6
--- /dev/null
+++ b/ambari-agent/src/test/python/ambari_agent/TestCertGeneration.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+import os
+import tempfile
+import shutil
+from unittest import TestCase
+import ConfigParser
+import security
+from security import CertificateManager
+from ambari_agent import AmbariConfig
+
+class TestCertGeneration(TestCase):
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp()
+ config = ConfigParser.RawConfigParser()
+ config.add_section('server')
+ config.set('server', 'hostname', 'example.com')
+ config.set('server', 'url_port', '777')
+ config.add_section('security')
+ config.set('security', 'keysdir', self.tmpdir)
+ config.set('security', 'server_crt', 'ca.crt')
+ self.certMan = CertificateManager(config)
+
+ def test_generation(self):
+ self.certMan.genAgentCrtReq()
+ self.assertTrue(os.path.exists(self.certMan.getAgentKeyName()))
+ self.assertTrue(os.path.exists(self.certMan.getAgentCrtReqName()))
+ def tearDown(self):
+ shutil.rmtree(self.tmpdir)
+
+