136 lines
4.9 KiB
Python
136 lines
4.9 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright 2013 The Plaso Project Authors.
|
|
# Please see the AUTHORS file for details on individual authors.
|
|
#
|
|
# Licensed 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.
|
|
"""Tests for the plist plugin interface."""
|
|
|
|
import unittest
|
|
|
|
from plaso.events import plist_event
|
|
from plaso.lib import errors
|
|
from plaso.parsers import plist
|
|
from plaso.parsers.plist_plugins import interface
|
|
from plaso.parsers.plist_plugins import test_lib
|
|
|
|
|
|
class MockPlugin(interface.PlistPlugin):
|
|
"""Mock plugin."""
|
|
|
|
NAME = 'mock_plist_plugin'
|
|
DESCRIPTION = u'Parser for testing parsing plist files.'
|
|
|
|
PLIST_PATH = 'plist_binary'
|
|
PLIST_KEYS = frozenset(['DeviceCache', 'PairedDevices'])
|
|
|
|
def GetEntries(self, parser_context, **unused_kwargs):
|
|
event_object = plist_event.PlistEvent(
|
|
u'/DeviceCache/44-00-00-00-00-00', u'LastInquiryUpdate',
|
|
1351827808261762)
|
|
parser_context.ProduceEvent(event_object, parser_chain=self.NAME)
|
|
|
|
|
|
class TestPlistPlugin(test_lib.PlistPluginTestCase):
|
|
"""Tests for the plist plugin interface."""
|
|
|
|
def setUp(self):
|
|
"""Sets up the needed objects used throughout the test."""
|
|
self._top_level_dict = {
|
|
'DeviceCache': {
|
|
'44-00-00-00-00-04': {
|
|
'Name': 'Apple Magic Trackpad 2', 'LMPSubversion': 796,
|
|
'Services': '', 'BatteryPercent': 0.61},
|
|
'44-00-00-00-00-02': {
|
|
'Name': 'test-macpro', 'ClockOffset': 28180,
|
|
'PageScanPeriod': 2, 'PageScanRepetitionMode': 1}}}
|
|
|
|
def testGetPluginNames(self):
|
|
"""Tests the GetPluginNames function."""
|
|
plugin_names = plist.PlistParser.GetPluginNames()
|
|
|
|
self.assertNotEquals(plugin_names, [])
|
|
|
|
self.assertTrue('plist_default' in plugin_names)
|
|
|
|
def testProcess(self):
|
|
"""Tests the Process function."""
|
|
# Ensure the plugin only processes if both filename and keys exist.
|
|
plugin_object = MockPlugin()
|
|
|
|
# Test correct filename and keys.
|
|
top_level = {'DeviceCache': 1, 'PairedDevices': 1}
|
|
event_object_generator = self._ParsePlistWithPlugin(
|
|
plugin_object, 'plist_binary', top_level)
|
|
event_objects = self._GetEventObjectsFromQueue(event_object_generator)
|
|
|
|
self.assertEquals(len(event_objects), 1)
|
|
|
|
# Correct filename with odd filename cAsinG. Adding an extra useless key.
|
|
top_level = {'DeviceCache': 1, 'PairedDevices': 1, 'R@ndomExtraKey': 1}
|
|
event_object_generator = self._ParsePlistWithPlugin(
|
|
plugin_object, 'pLiSt_BinAry', top_level)
|
|
event_objects = self._GetEventObjectsFromQueue(event_object_generator)
|
|
|
|
self.assertEquals(len(event_objects), 1)
|
|
|
|
# Test wrong filename.
|
|
top_level = {'DeviceCache': 1, 'PairedDevices': 1}
|
|
with self.assertRaises(errors.WrongPlistPlugin):
|
|
_ = self._ParsePlistWithPlugin(
|
|
plugin_object, 'wrong_file.plist', top_level)
|
|
|
|
# Test not enough required keys.
|
|
top_level = {'Useless_Key': 0, 'PairedDevices': 1}
|
|
with self.assertRaises(errors.WrongPlistPlugin):
|
|
_ = self._ParsePlistWithPlugin(
|
|
plugin_object, 'plist_binary.plist', top_level)
|
|
|
|
def testRecurseKey(self):
|
|
"""Tests the RecurseKey function."""
|
|
# Ensure with a depth of 1 we only return the root key.
|
|
result = list(interface.RecurseKey(self._top_level_dict, depth=1))
|
|
self.assertEquals(len(result), 1)
|
|
|
|
# Trying again with depth limit of 2 this time.
|
|
result = list(interface.RecurseKey(self._top_level_dict, depth=2))
|
|
self.assertEquals(len(result), 3)
|
|
|
|
# A depth of two should gives us root plus the two devices. Let's check.
|
|
my_keys = []
|
|
for unused_root, key, unused_value in result:
|
|
my_keys.append(key)
|
|
expected = set(['DeviceCache', '44-00-00-00-00-04', '44-00-00-00-00-02'])
|
|
self.assertTrue(expected == set(my_keys))
|
|
|
|
def testGetKeys(self):
|
|
"""Tests the GetKeys function."""
|
|
# Match DeviceCache from the root level.
|
|
key = ['DeviceCache']
|
|
result = interface.GetKeys(self._top_level_dict, key)
|
|
self.assertEquals(len(result), 1)
|
|
|
|
# Look for a key nested a layer beneath DeviceCache from root level.
|
|
# Note: overriding the default depth to look deeper.
|
|
key = ['44-00-00-00-00-02']
|
|
result = interface.GetKeys(self._top_level_dict, key, depth=2)
|
|
self.assertEquals(len(result), 1)
|
|
|
|
# Check the value of the result was extracted as expected.
|
|
self.assertTrue('test-macpro' == result[key[0]]['Name'])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|