Repository: Azure/WALinuxAgent
Pull request #813 (2017-07-24 19:35:55)

[#801] -- Agent fails to clean-up PID files
[#801] -- Agent fails to clean-up PID files
[#811] -- Comments inline in /etc/waagent.conf cause config to not be read
[#812] -- Agent fails and isn't recoverable if an extension's log directory is not present anymore

Signed-off-by: Brendan Dixon <brendandixon@me.com>


Patch:
diff --git a/README.md b/README.md
index 995f547f..2ed87997 100644
--- a/README.md
+++ b/README.md
@@ -168,7 +168,10 @@ script.
 ### CONFIGURATION
 
 A configuration file (/etc/waagent.conf) controls the actions of
-waagent. A sample configuration file is shown below:
+waagent. Blank lines and lines whose first character is a `#` are
+ignored (end-of-line comments are *not* supported).
+
+A sample configuration file is shown below:
 
 ```
 Provisioning.Enabled=y
diff --git a/azurelinuxagent/agent.py b/azurelinuxagent/agent.py
index d1ac3544..f6d54067 100644
--- a/azurelinuxagent/agent.py
+++ b/azurelinuxagent/agent.py
@@ -64,7 +64,19 @@ class Agent(object):
         logger.add_logger_appender(logger.AppenderType.CONSOLE, level,
                                  path="/dev/console")
 
+        ext_log_dir = conf.get_ext_log_dir()
+        try:
+            if os.path.isfile(ext_log_dir):
+                raise Exception("{0} is a file".format(ext_log_dir))
+            if not os.path.isdir(ext_log_dir):
+                os.makedirs(ext_log_dir)
+        except Exception as e:
+            logger.error(
+                "Exception occurred while creating extension "
+                "log directory {0}: {1}".format(ext_log_dir, e))
+
         #Init event reporter
+        event.init_event_status(conf.get_lib_dir())
         event_dir = os.path.join(conf.get_lib_dir(), "events")
         event.init_event_logger(event_dir)
         event.enable_unhandled_err_dump("WALA")
diff --git a/azurelinuxagent/common/event.py b/azurelinuxagent/common/event.py
index 5e63f5e4..1cd5edde 100644
--- a/azurelinuxagent/common/event.py
+++ b/azurelinuxagent/common/event.py
@@ -67,25 +67,29 @@ class EventStatus(object):
     EVENT_STATUS_FILE = "event_status.json"
 
     def __init__(self, status_dir=conf.get_lib_dir()):
-        self._path = os.path.join(status_dir, EventStatus.EVENT_STATUS_FILE)
-        self._load()
+        self._path = None
+        self._status = {}
 
     def clear(self):
-        self.status = {}
+        self._status = {}
         self._save()
 
     def event_marked(self, name, version, op):
-        return self._event_name(name, version, op) in self.status
+        return self._event_name(name, version, op) in self._status
 
     def event_succeeded(self, name, version, op):
         event = self._event_name(name, version, op)
-        if event not in self.status:
+        if event not in self._status:
             return True
-        return self.status[event] == True
+        return self._status[event] == True
+
+    def initialize(self, status_dir=conf.get_lib_dir()):
+        self._path = os.path.join(status_dir, EventStatus.EVENT_STATUS_FILE)
+        self._load()
 
     def mark_event_status(self, name, version, op, status):
         event = self._event_name(name, version, op)
-        self.status[event] = (status == True)
+        self._status[event] = (status == True)
         self._save()
 
     def _event_name(self, name, version, op):
@@ -93,18 +97,18 @@ class EventStatus(object):
 
     def _load(self):
         try:
-            self.status = {}
+            self._status = {}
             if os.path.isfile(self._path):
                 with open(self._path, 'r') as f:
-                    self.status = json.load(f)
+                    self._status = json.load(f)
         except Exception as e:
             logger.warn("Exception occurred loading event status: {0}".format(e))
-            self.status = {}
+            self._status = {}
 
     def _save(self):
         try:
             with open(self._path, 'w') as f:
-                json.dump(self.status, f)
+                json.dump(self._status, f)
         except Exception as e:
             logger.warn("Exception occurred saving event status: {0}".format(e))
 
@@ -130,7 +134,7 @@ class EventLogger(object):
 
     def save_event(self, data):
         if self.event_dir is None:
-            logger.warn("Event reporter is not initialized.")
+            logger.warn("Cannot save event -- Event reporter is not initialized.")
             return
 
         if not os.path.exists(self.event_dir):
@@ -230,7 +234,7 @@ def add_event(name, op="", is_success=True, duration=0, version=CURRENT_VERSION,
               message="", evt_type="", is_internal=False, log_event=True,
               reporter=__event_logger__):
     if reporter.event_dir is None:
-        logger.warn("Event reporter is not initialized.")
+        logger.warn("Cannot add event -- Event reporter is not initialized.")
         _log_event(name, op, message, is_success=is_success)
         return
 
@@ -246,7 +250,7 @@ def add_periodic(
     message="", evt_type="", is_internal=False, log_event=True, force=False,
     reporter=__event_logger__):
     if reporter.event_dir is None:
-        logger.warn("Event reporter is not initialized.")
+        logger.warn("Cannot add periodic event -- Event reporter is not initialized.")
         _log_event(name, op, message, is_success=is_success)
         return
 
@@ -266,9 +270,11 @@ def should_emit_event(name, version, op, status):
         not __event_status__.event_marked(name, version, op) or \
         __event_status__.event_succeeded(name, version, op) != status
 
-def init_event_logger(event_dir, reporter=__event_logger__):
-    reporter.event_dir = event_dir
+def init_event_logger(event_dir):
+    __event_logger__.event_dir = event_dir
 
+def init_event_status(status_dir):
+    __event_status__.initialize(status_dir)
 
 def dump_unhandled_err(name):
     if hasattr(sys, 'last_type') and hasattr(sys, 'last_value') and \
diff --git a/azurelinuxagent/ga/monitor.py b/azurelinuxagent/ga/monitor.py
index f0bd4e43..307a514a 100644
--- a/azurelinuxagent/ga/monitor.py
+++ b/azurelinuxagent/ga/monitor.py
@@ -36,8 +36,8 @@ from azurelinuxagent.common.protocol.restapi import TelemetryEventParam, \
                                                     set_properties
 from azurelinuxagent.common.utils.textutil import parse_doc, findall, find, getattrib
 from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, \
-                                            DISTRO_CODE_NAME, AGENT_LONG_VERSION, \
-                                            AGENT_NAME, CURRENT_VERSION
+            DISTRO_CODE_NAME, AGENT_LONG_VERSION, \
+            AGENT_NAME, CURRENT_AGENT, CURRENT_VERSION
 
 
 def parse_event(data_str):
diff --git a/azurelinuxagent/ga/update.py b/azurelinuxagent/ga/update.py
index 39109eda..d5b82879 100644
--- a/azurelinuxagent/ga/update.py
+++ b/azurelinuxagent/ga/update.py
@@ -426,11 +426,12 @@ class UpdateHandler(object):
         return len(self.agents) > 0 and self.agents[0].version > base_version
 
     def _ensure_no_orphans(self, orphan_wait_interval=ORPHAN_WAIT_INTERVAL):
-        previous_pid_file, pid_file = self._write_pid_file()
-        if previous_pid_file is not None:
+        pid_files, ignored = self._write_pid_file()
+        for pid_file in pid_files:
             try:
-                pid = fileutil.read_file(previous_pid_file)
+                pid = fileutil.read_file(pid_file)
                 wait_interval = orphan_wait_interval
+
                 while self.osutil.check_pid_alive(pid):
                     wait_interval -= GOAL_STATE_INTERVAL
                     if wait_interval <= 0:
@@ -447,6 +448,8 @@ class UpdateHandler(object):
                         pid)
                     time.sleep(GOAL_STATE_INTERVAL)
 
+                os.remove(pid_file)
+
             except Exception as e:
                 logger.warn(
                     u"Exception occurred waiting for orphan agent to terminate: {0}",
@@ -503,22 +506,18 @@ class UpdateHandler(object):
                                     protocol.client \
                                 else None
 
-    def _get_pid_files(self):
+    def _get_pid_parts(self):
         pid_file = conf.get_agent_pid_file_path()
-        
         pid_dir = os.path.dirname(pid_file)
         pid_name = os.path.basename(pid_file)
-        
         pid_re = re.compile("(\d+)_{0}".format(re.escape(pid_name)))
-        pid_files = [int(pid_re.match(f).group(1)) for f in os.listdir(pid_dir) if pid_re.match(f)]
-        pid_files.sort()
+        return pid_dir, pid_name, pid_re
 
-        pid_index = -1 if len(pid_files) <= 0 else pid_files[-1]
-        previous_pid_file = None \
-                        if pid_index < 0 \
-                        else os.path.join(pid_dir, "{0}_{1}".format(pid_index, pid_name))
-        pid_file = os.path.join(pid_dir, "{0}_{1}".format(pid_index+1, pid_name))
-        return previous_pid_file, pid_file
+    def _get_pid_files(self):
+        pid_dir, pid_name, pid_re = self._get_pid_parts()
+        pid_files = [os.path.join(pid_dir, f) for f in os.listdir(pid_dir) if pid_re.match(f)]
+        pid_files.sort(key=lambda f: int(pid_re.match(os.path.basename(f)).group(1)))
+        return pid_files
 
     @property
     def _is_clean_start(self):
@@ -615,7 +614,18 @@ class UpdateHandler(object):
         return
 
     def _write_pid_file(self):
-        previous_pid_file, pid_file = self._get_pid_files()
+        pid_files = self._get_pid_files()
+
+        pid_dir, pid_name, pid_re = self._get_pid_parts()
+
+        previous_pid_file = None \
+                        if len(pid_files) <= 0 \
+                        else pid_files[-1]
+        pid_index = -1 \
+                    if previous_pid_file is None \
+                    else int(pid_re.match(os.path.basename(previous_pid_file)).group(1))
+        pid_file = os.path.join(pid_dir, "{0}_{1}".format(pid_index+1, pid_name))
+
         try:
             fileutil.write_file(pid_file, ustr(os.getpid()))
             logger.info(u"{0} running as process {1}", CURRENT_AGENT, ustr(os.getpid()))
@@ -626,7 +636,8 @@ class UpdateHandler(object):
                 CURRENT_AGENT,
                 pid_file,
                 ustr(e))
-        return previous_pid_file, pid_file
+
+        return pid_files, pid_file
 
 
 class GuestAgent(object):


Test patch:
diff --git a/tests/common/test_event.py b/tests/common/test_event.py
index d6710578..a5bb050d 100644
--- a/tests/common/test_event.py
+++ b/tests/common/test_event.py
@@ -22,7 +22,7 @@ from datetime import datetime
 import azurelinuxagent.common.event as event
 import azurelinuxagent.common.logger as logger
 
-from azurelinuxagent.common.event import init_event_logger, add_event, \
+from azurelinuxagent.common.event import add_event, \
                                     mark_event_status, should_emit_event
 from azurelinuxagent.common.future import ustr
 from azurelinuxagent.common.version import CURRENT_VERSION
@@ -32,18 +32,19 @@ from tests.tools import *
 
 class TestEvent(AgentTestCase):
     def test_event_status_event_marked(self):
-        d = tempfile.mkdtemp()
-        es = event.EventStatus(d)
+        es = event.__event_status__
 
         self.assertFalse(es.event_marked("Foo", "1.2", "FauxOperation"))
         es.mark_event_status("Foo", "1.2", "FauxOperation", True)
         self.assertTrue(es.event_marked("Foo", "1.2", "FauxOperation"))
 
-        es = event.EventStatus(d)
+        event.__event_status__ = event.EventStatus()
+        event.init_event_status(self.tmp_dir)
+        es = event.__event_status__
         self.assertTrue(es.event_marked("Foo", "1.2", "FauxOperation"))
 
     def test_event_status_defaults_to_success(self):
-        es = event.EventStatus(tempfile.mkdtemp())
+        es = event.__event_status__
         self.assertTrue(es.event_succeeded("Foo", "1.2", "FauxOperation"))
 
     def test_event_status_records_status(self):
@@ -57,13 +58,14 @@ class TestEvent(AgentTestCase):
         self.assertFalse(es.event_succeeded("Foo", "1.2", "FauxOperation"))
 
     def test_event_status_preserves_state(self):
-        d = tempfile.mkdtemp()
-        es = event.EventStatus(d)
+        es = event.__event_status__
 
         es.mark_event_status("Foo", "1.2", "FauxOperation", False)
         self.assertFalse(es.event_succeeded("Foo", "1.2", "FauxOperation"))
 
-        es = event.EventStatus(d)
+        event.__event_status__ = event.EventStatus()
+        event.init_event_status(self.tmp_dir)
+        es = event.__event_status__
         self.assertFalse(es.event_succeeded("Foo", "1.2", "FauxOperation"))
 
     def test_should_emit_event_ignores_unknown_operations(self):
@@ -107,7 +109,6 @@ class TestEvent(AgentTestCase):
 
     @patch('azurelinuxagent.common.event.EventLogger.add_event')
     def test_periodic_emits_if_not_previously_sent(self, mock_event):
-        init_event_logger(tempfile.mkdtemp())
         event.__event_logger__.reset_periodic()
 
         event.add_periodic(logger.EVERY_DAY, "FauxEvent")
@@ -115,7 +116,6 @@ class TestEvent(AgentTestCase):
 
     @patch('azurelinuxagent.common.event.EventLogger.add_event')
     def test_periodic_does_not_emit_if_previously_sent(self, mock_event):
-        init_event_logger(tempfile.mkdtemp())
         event.__event_logger__.reset_periodic()
 
         event.add_periodic(logger.EVERY_DAY, "FauxEvent")
@@ -126,7 +126,6 @@ class TestEvent(AgentTestCase):
 
     @patch('azurelinuxagent.common.event.EventLogger.add_event')
     def test_periodic_emits_if_forced(self, mock_event):
-        init_event_logger(tempfile.mkdtemp())
         event.__event_logger__.reset_periodic()
 
         event.add_periodic(logger.EVERY_DAY, "FauxEvent")
@@ -137,7 +136,6 @@ class TestEvent(AgentTestCase):
 
     @patch('azurelinuxagent.common.event.EventLogger.add_event')
     def test_periodic_emits_after_elapsed_delta(self, mock_event):
-        init_event_logger(tempfile.mkdtemp())
         event.__event_logger__.reset_periodic()
 
         event.add_periodic(logger.EVERY_DAY, "FauxEvent")
@@ -154,7 +152,6 @@ class TestEvent(AgentTestCase):
 
     @patch('azurelinuxagent.common.event.EventLogger.add_event')
     def test_periodic_forwards_args(self, mock_event):
-        init_event_logger(tempfile.mkdtemp())
         event.__event_logger__.reset_periodic()
 
         event.add_periodic(logger.EVERY_DAY, "FauxEvent")
@@ -164,68 +161,58 @@ class TestEvent(AgentTestCase):
             log_event=True, message='', op='', version=str(CURRENT_VERSION))
 
     def test_save_event(self):
-        tmp_evt = tempfile.mkdtemp()
-        init_event_logger(tmp_evt)
         add_event('test', message='test event')
-        self.assertTrue(len(os.listdir(tmp_evt)) == 1)
-        shutil.rmtree(tmp_evt)
+        self.assertTrue(len(os.listdir(self.tmp_dir)) == 1)
 
     def test_save_event_rollover(self):
-        tmp_evt = tempfile.mkdtemp()
-        init_event_logger(tmp_evt)
         add_event('test', message='first event')
         for i in range(0, 999):
             add_event('test', message='test event {0}'.format(i))
 
-        events = os.listdir(tmp_evt)
+        events = os.listdir(self.tmp_dir)
         events.sort()
         self.assertTrue(len(events) == 1000)
 
-        first_event = os.path.join(tmp_evt, events[0])
+        first_event = os.path.join(self.tmp_dir, events[0])
         with open(first_event) as first_fh:
             first_event_text = first_fh.read()
             self.assertTrue('first event' in first_event_text)
 
         add_event('test', message='last event')
-        events = os.listdir(tmp_evt)
+        events = os.listdir(self.tmp_dir)
         events.sort()
         self.assertTrue(len(events) == 1000, "{0} events found, 1000 expected".format(len(events)))
 
-        first_event = os.path.join(tmp_evt, events[0])
+        first_event = os.path.join(self.tmp_dir, events[0])
         with open(first_event) as first_fh:
             first_event_text = first_fh.read()
             self.assertFalse('first event' in first_event_text)
             self.assertTrue('test event 0' in first_event_text)
 
-        last_event = os.path.join(tmp_evt, events[-1])
+        last_event = os.path.join(self.tmp_dir, events[-1])
         with open(last_event) as last_fh:
             last_event_text = last_fh.read()
             self.assertTrue('last event' in last_event_text)
 
-        shutil.rmtree(tmp_evt)
-
     def test_save_event_cleanup(self):
-        tmp_evt = tempfile.mkdtemp()
-        init_event_logger(tmp_evt)
-
         for i in range(0, 2000):
-            evt = os.path.join(tmp_evt, '{0}.tld'.format(ustr(1491004920536531 + i)))
+            evt = os.path.join(self.tmp_dir, '{0}.tld'.format(ustr(1491004920536531 + i)))
             with open(evt, 'w') as fh:
                 fh.write('test event {0}'.format(i))
 
-        events = os.listdir(tmp_evt)
+        events = os.listdir(self.tmp_dir)
         self.assertTrue(len(events) == 2000, "{0} events found, 2000 expected".format(len(events)))
         add_event('test', message='last event')
 
-        events = os.listdir(tmp_evt)
+        events = os.listdir(self.tmp_dir)
         events.sort()
         self.assertTrue(len(events) == 1000, "{0} events found, 1000 expected".format(len(events)))
-        first_event = os.path.join(tmp_evt, events[0])
+        first_event = os.path.join(self.tmp_dir, events[0])
         with open(first_event) as first_fh:
             first_event_text = first_fh.read()
             self.assertTrue('test event 1001' in first_event_text)
 
-        last_event = os.path.join(tmp_evt, events[-1])
+        last_event = os.path.join(self.tmp_dir, events[-1])
         with open(last_event) as last_fh:
             last_event_text = last_fh.read()
             self.assertTrue('last event' in last_event_text)
diff --git a/tests/ga/test_update.py b/tests/ga/test_update.py
index f342a087..1b47983b 100644
--- a/tests/ga/test_update.py
+++ b/tests/ga/test_update.py
@@ -22,6 +22,7 @@ from datetime import datetime
 import json
 import shutil
 
+from azurelinuxagent.common.event import *
 from azurelinuxagent.common.protocol.hostplugin import *
 from azurelinuxagent.common.protocol.metadata import *
 from azurelinuxagent.common.protocol.wire import *
@@ -912,7 +913,7 @@ class TestUpdate(UpdateTestCase):
             v = a.version
         return
 
-    def _test_ensure_no_orphans(self, invocations=3, interval=ORPHAN_WAIT_INTERVAL):
+    def _test_ensure_no_orphans(self, invocations=3, interval=ORPHAN_WAIT_INTERVAL, pid_count=0):
         with patch.object(self.update_handler, 'osutil') as mock_util:
             # Note:
             # - Python only allows mutations of objects to which a function has
@@ -927,15 +928,20 @@ class TestUpdate(UpdateTestCase):
 
             mock_util.check_pid_alive = Mock(side_effect=iterator)
 
+            pid_files = self.update_handler._get_pid_files()
+            self.assertEqual(pid_count, len(pid_files))
+
             with patch('os.getpid', return_value=42):
                 with patch('time.sleep', return_value=None) as mock_sleep:
                     self.update_handler._ensure_no_orphans(orphan_wait_interval=interval)
+                    for pid_file in pid_files:
+                        self.assertFalse(os.path.exists(pid_file))
                     return mock_util.check_pid_alive.call_count, mock_sleep.call_count
         return
 
     def test_ensure_no_orphans(self):
         fileutil.write_file(os.path.join(self.tmp_dir, "0_waagent.pid"), ustr(41))
-        calls, sleeps = self._test_ensure_no_orphans(invocations=3)
+        calls, sleeps = self._test_ensure_no_orphans(invocations=3, pid_count=1)
         self.assertEqual(3, calls)
         self.assertEqual(2, sleeps)
         return
@@ -958,7 +964,8 @@ class TestUpdate(UpdateTestCase):
         with patch('os.kill') as mock_kill:
             calls, sleeps = self._test_ensure_no_orphans(
                                         invocations=4,
-                                        interval=3*GOAL_STATE_INTERVAL)
+                                        interval=3*GOAL_STATE_INTERVAL,
+                                        pid_count=1)
             self.assertEqual(3, calls)
             self.assertEqual(2, sleeps)
             self.assertEqual(1, mock_kill.call_count)
@@ -1069,17 +1076,19 @@ class TestUpdate(UpdateTestCase):
         return
 
     def test_get_pid_files(self):
-        previous_pid_file, pid_file, = self.update_handler._get_pid_files()
-        self.assertEqual(None, previous_pid_file)
-        self.assertEqual("0_waagent.pid", os.path.basename(pid_file))
+        pid_files = self.update_handler._get_pid_files()
+        self.assertEqual(0, len(pid_files))
         return
 
     def test_get_pid_files_returns_previous(self):
         for n in range(1250):
             fileutil.write_file(os.path.join(self.tmp_dir, str(n)+"_waagent.pid"), ustr(n+1))
-        previous_pid_file, pid_file, = self.update_handler._get_pid_files()
-        self.assertEqual("1249_waagent.pid", os.path.basename(previous_pid_file))
-        self.assertEqual("1250_waagent.pid", os.path.basename(pid_file))
+        pid_files = self.update_handler._get_pid_files()
+        self.assertEqual(1250, len(pid_files))
+
+        pid_dir, pid_name, pid_re = self.update_handler._get_pid_parts()
+        for p in pid_files:
+            self.assertTrue(pid_re.match(os.path.basename(p)))
         return
 
     def test_is_clean_start_returns_true_when_no_sentinal(self):
@@ -1499,8 +1508,9 @@ class TestUpdate(UpdateTestCase):
         for n in range(1112):
             fileutil.write_file(os.path.join(self.tmp_dir, str(n)+"_waagent.pid"), ustr(n+1))
         with patch('os.getpid', return_value=1112):
-            previous_pid_file, pid_file = self.update_handler._write_pid_file()
-            self.assertEqual("1111_waagent.pid", os.path.basename(previous_pid_file))
+            pid_files, pid_file = self.update_handler._write_pid_file()
+            self.assertEqual(1112, len(pid_files))
+            self.assertEqual("1111_waagent.pid", os.path.basename(pid_files[-1]))
             self.assertEqual("1112_waagent.pid", os.path.basename(pid_file))
             self.assertEqual(fileutil.read_file(pid_file), ustr(1112))
         return
@@ -1508,8 +1518,8 @@ class TestUpdate(UpdateTestCase):
     def test_write_pid_file_ignores_exceptions(self):
         with patch('azurelinuxagent.common.utils.fileutil.write_file', side_effect=Exception):
             with patch('os.getpid', return_value=42):
-                previous_pid_file, pid_file = self.update_handler._write_pid_file()
-                self.assertEqual(None, previous_pid_file)
+                pid_files, pid_file = self.update_handler._write_pid_file()
+                self.assertEqual(0, len(pid_files))
                 self.assertEqual(None, pid_file)
         return
 
diff --git a/tests/test_agent.py b/tests/test_agent.py
index 1b359335..9b0d5f11 100644
--- a/tests/test_agent.py
+++ b/tests/test_agent.py
@@ -90,3 +90,28 @@ class TestAgent(AgentTestCase):
 
         mock_daemon.run.assert_called_once_with(child_args="-configuration-path:/foo/bar.conf")
         mock_load.assert_called_once()
+
+    @patch("azurelinuxagent.common.conf.get_ext_log_dir")
+    def test_agent_ensures_extension_log_directory(self, mock_dir):
+        ext_log_dir = os.path.join(self.tmp_dir, "FauxLogDir")
+        mock_dir.return_value = ext_log_dir
+
+        self.assertFalse(os.path.isdir(ext_log_dir))
+        agent = Agent(False,
+                    conf_file_path=os.path.join(data_dir, "test_waagent.conf"))
+        self.assertTrue(os.path.isdir(ext_log_dir))
+
+    @patch("azurelinuxagent.common.logger.error")
+    @patch("azurelinuxagent.common.conf.get_ext_log_dir")
+    def test_agent_logs_if_extension_log_directory_is_a_file(self, mock_dir, mock_log):
+        ext_log_dir = os.path.join(self.tmp_dir, "FauxLogDir")
+        mock_dir.return_value = ext_log_dir
+        fileutil.write_file(ext_log_dir, "Foo")
+
+        self.assertTrue(os.path.isfile(ext_log_dir))
+        self.assertFalse(os.path.isdir(ext_log_dir))
+        agent = Agent(False,
+                    conf_file_path=os.path.join(data_dir, "test_waagent.conf"))
+        self.assertTrue(os.path.isfile(ext_log_dir))
+        self.assertFalse(os.path.isdir(ext_log_dir))
+        mock_log.assert_called_once()
diff --git a/tests/tools.py b/tests/tools.py
index a505700c..94fab7f5 100644
--- a/tests/tools.py
+++ b/tests/tools.py
@@ -26,8 +26,10 @@ import tempfile
 import unittest
 from functools import wraps
 
+import azurelinuxagent.common.event as event
 import azurelinuxagent.common.conf as conf
 import azurelinuxagent.common.logger as logger
+
 from azurelinuxagent.common.version import PY_VERSION_MAJOR
 
 #Import mock module for Python2 and Python3
@@ -51,14 +53,21 @@ if debug:
 class AgentTestCase(unittest.TestCase):
     def setUp(self):
         prefix = "{0}_".format(self.__class__.__name__)
+
         self.tmp_dir = tempfile.mkdtemp(prefix=prefix)
         self.test_file = 'test_file'
+
         conf.get_autoupdate_enabled = Mock(return_value=True)
         conf.get_lib_dir = Mock(return_value=self.tmp_dir)
+
         ext_log_dir = os.path.join(self.tmp_dir, "azure")
         conf.get_ext_log_dir = Mock(return_value=ext_log_dir)
+
         conf.get_agent_pid_file_path = Mock(return_value=os.path.join(self.tmp_dir, "waagent.pid"))
 
+        event.init_event_status(self.tmp_dir)
+        event.init_event_logger(self.tmp_dir)
+
     def tearDown(self):
         if not debug and self.tmp_dir is not None:
             shutil.rmtree(self.tmp_dir)