From f8d7951013895175f24db43a75fb3e8a9cdf1c1d Mon Sep 17 00:00:00 2001 From: Jan Synacek Date: Mon, 8 Jul 2013 10:48:47 +0200 Subject: LogicalFile: Add tests --- src/logicalfile/test/README | 28 ++++ src/logicalfile/test/__init__.py | 17 +++ src/logicalfile/test/test_base.py | 44 ++++++ src/logicalfile/test/test_basic.py | 295 +++++++++++++++++++++++++++++++++++++ 4 files changed, 384 insertions(+) create mode 100644 src/logicalfile/test/README create mode 100644 src/logicalfile/test/__init__.py create mode 100644 src/logicalfile/test/test_base.py create mode 100644 src/logicalfile/test/test_basic.py (limited to 'src') diff --git a/src/logicalfile/test/README b/src/logicalfile/test/README new file mode 100644 index 0000000..54c7c92 --- /dev/null +++ b/src/logicalfile/test/README @@ -0,0 +1,28 @@ +LogicalFile tests +================= +Basic tests for the LogicalFile provider. In the initial phase, a directory is +created and populated by various types of files (symlink, device file, fifo +file, ...). These are then used to test the provider. + +As the LogicalFile provider explicitly implements all of its +associations-related methods, they should all be tested from both sides, meaning +that the respective associations should be called twice with both of their +"arguments". + +Usage +----- +The tests must be run on the same machine as the CIMOM! + +Set following environment variables: +LMI_CIMOM_URL - URL to the CIMOM, e.g. 'https://localhost:5989'. +LMI_CIMOM_USERNAME - Name of the user on CIMOM the test will use, e.g. 'root'. +LMI_CIMOM_PASSWORD - Password of the user, e.g. 'opensesame'. +LMI_LOGICALFILE_TESTDIR - Testing directory where all the files and testing will + take place. This directory must *not* exist on the + system and will be delete after the tests are + finished. Default is '/var/tmp/logicalfile-tests'. + +Running the tests: + LMI_CIMOM_PASSWORD=opensesame \ + LMI_LOGICALFILE_TESTDIR="/home/user/my-testing-dir" \ + python test/test_basic.py \ No newline at end of file diff --git a/src/logicalfile/test/__init__.py b/src/logicalfile/test/__init__.py new file mode 100644 index 0000000..f0c659b --- /dev/null +++ b/src/logicalfile/test/__init__.py @@ -0,0 +1,17 @@ +# Copyright (C) 2013 Red Hat, Inc. All rights reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Authors: Jan Synacek diff --git a/src/logicalfile/test/test_base.py b/src/logicalfile/test/test_base.py new file mode 100644 index 0000000..80315df --- /dev/null +++ b/src/logicalfile/test/test_base.py @@ -0,0 +1,44 @@ +# Copyright (C) 2013 Red Hat, Inc. All rights reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Authors: Jan Synacek + +import pywbem +import os +import socket +import unittest + +class LogicalFileTestBase(unittest.TestCase): + """ + Base class for all LogicalFile tests. + """ + + SYSTEM_CLASS_NAME = "Linux_ComputerSystem" + SYSTEM_NAME = socket.getfqdn() + + @classmethod + def setUpClass(cls): + cls.url = os.environ.get("LMI_CIMOM_URL", "https://localhost:5989") + cls.username = os.environ.get("LMI_CIMOM_USERNAME", "root") + cls.password = os.environ.get("LMI_CIMOM_PASSWORD", "") + cls.wbemconnection = pywbem.WBEMConnection(cls.url, (cls.username, cls.password)) + cls.testdir = os.environ.get("LMI_LOGICALFILE_TESTDIR", "/var/tmp/logicalfile-tests") + + def setUp(self): + pass + + def tearDown(self): + pass diff --git a/src/logicalfile/test/test_basic.py b/src/logicalfile/test/test_basic.py new file mode 100644 index 0000000..c75bf5a --- /dev/null +++ b/src/logicalfile/test/test_basic.py @@ -0,0 +1,295 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Red Hat, Inc. All rights reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Authors: Jan Synacek + +from test_base import LogicalFileTestBase +import unittest +import pywbem +import os +import stat +import shutil + +class TestLogicalFile(LogicalFileTestBase): + """ + Exhaustive LogicalFile tests. + """ + + def setUp(self): + super(TestLogicalFile, self).setUp() + self.files = {'data':{'path' : self.testdir + "/data", + 'class': 'LMI_DataFile', + 'props': {'Readable':True, + 'Writeable':False, + 'Executable':True}}, + 'dir':{'path' : self.testdir + "/dir", + 'class': 'LMI_UnixDirectory', + 'props': {}}, + 'hardlink':{'path' : self.testdir + "/hardlink", + 'class': 'LMI_DataFile', + 'props': {'Readable':True, + 'Writeable':False, + 'Executable':True}}, + 'symlink':{'path' : self.testdir + "/symlink", + 'class': 'LMI_SymbolicLink', + 'props': {}}, + 'fifo':{'path' : self.testdir + "/fifo", + 'class': 'LMI_FIFOPipeFile', + 'props': {}}, + 'chdev':{'path' : self.testdir + "/chdev", + 'class': 'LMI_UnixDeviceFile', + 'props': {'DeviceMajor':2, 'DeviceMinor':4}}, + 'bldev':{'path' : self.testdir + "/bldev", + 'class': 'LMI_UnixDeviceFile', + 'props': {'DeviceMajor':3, 'DeviceMinor':5}}, + '..':{'path' : os.path.realpath(self.testdir + "/.."), + 'class': 'LMI_UnixDirectory', + 'props': {}}} + + self.cop = pywbem.CIMInstanceName(classname='LMI_UnixDirectory', + namespace='root/cimv2', + keybindings={ + 'CSCreationClassName':self.SYSTEM_CLASS_NAME, + 'CSName':self.SYSTEM_NAME, + 'FSCreationClassName':'LMI_LocalFileSystem', + 'FSName':'NotImportant', + 'CreationClassName':'LMI_UnixDirectory', + 'Name':self.testdir + }) + self._prepare() + + def tearDown(self): + self._cleanup() + + def _prepare(self): + try: + os.stat(self.testdir) + except OSError: + os.makedirs(self.testdir) + data_file = self.files['data']['path'] + f = open(data_file, "w+") + f.write("hello") + f.close() + os.chmod(data_file, 0550) + os.mkdir(self.files['dir']['path']) + os.link(data_file, self.files['hardlink']['path']) + os.symlink(data_file, self.files['symlink']['path']) + os.mkfifo(self.files['fifo']['path']) + chdev = self.files['chdev'] + chdev_device = os.makedev(chdev['props']['DeviceMajor'], chdev['props']['DeviceMinor']) + os.mknod(chdev['path'], 0666 | stat.S_IFCHR, chdev_device) + bldev = self.files['bldev'] + bldev_device = os.makedev(bldev['props']['DeviceMajor'], bldev['props']['DeviceMinor']) + os.mknod(bldev['path'], 0666 | stat.S_IFBLK, bldev_device) + + def _cleanup(self): + shutil.rmtree(self.testdir) + + def test_lmi_directorycontainsfile(self): + # Associators and AssociatorNames + for assoc_method in [self.wbemconnection.Associators, self.wbemconnection.AssociatorNames]: + assocs = assoc_method(self.cop, AssocClass='LMI_DirectoryContainsFile') + self.assertEquals(len(assocs), len(self.files.keys())) + for k, f in self.files.iteritems(): + # test that the files are actually there and have the correct class name + match = filter(lambda a: a['Name'] == f['path'], assocs) + self.assertEquals(len(match), 1) + self.assertEquals(match[0].classname, f['class']) + if not isinstance(match[0], pywbem.CIMInstanceName): + # test some selected properties + if k == 'data' or k == 'hardlink': + self.assertEquals(match[0]['Readable'], f['props']['Readable']) + self.assertEquals(match[0]['Writeable'], f['props']['Writeable']) + self.assertEquals(match[0]['Executable'], f['props']['Executable']) + if k == 'chdev' or k == 'bldev': + self.assertEqual(match[0]['DeviceMajor'], str(f['props']['DeviceMajor'])) + self.assertEqual(match[0]['DeviceMinor'], str(f['props']['DeviceMinor'])) + if k == 'symlink': + self.assertEqual(match[0]['TargetFile'], self.files['data']['path']) + # test the other side of LMI_DirectoryContainsFile + if k != '..': + cop_file = pywbem.CIMInstanceName(classname=f['class'], + namespace='root/cimv2', + keybindings={ + 'CSCreationClassName':self.SYSTEM_CLASS_NAME, + 'CSName':self.SYSTEM_NAME, + 'FSCreationClassName':'LMI_LocalFileSystem', + 'FSName':'NotImportant', + 'CreationClassName':f['class'], + 'Name':f['path'] + }) + assocs_file = assoc_method(cop_file, AssocClass='LMI_DirectoryContainsFile') + self.assertEquals(len(assocs_file), 1) + self.assertEquals(assocs_file[0].classname, 'LMI_UnixDirectory') + self.assertEquals(assocs_file[0]['Name'], self.testdir) + + # References and ReferenceNames + for assoc_method in [self.wbemconnection.References, self.wbemconnection.ReferenceNames]: + assocs = assoc_method(self.cop, ResultClass='LMI_DirectoryContainsFile') + self.assertEquals(len(assocs), len(self.files.keys())) + for k, f in self.files.iteritems(): + # test that the files are actually there and have the correct class name + match = filter(lambda a: a['PartComponent']['Name'] == f['path'], assocs) + self.assertEquals(len(match), 1) + match_name = match[0]['PartComponent'] + self.assertEquals(match_name.classname, f['class']) + # test the other side of LMI_DirectoryContainsFile + if k != '..' and k != 'dir': + cop_file = pywbem.CIMInstanceName(classname=f['class'], + namespace='root/cimv2', + keybindings={ + 'CSCreationClassName':self.SYSTEM_CLASS_NAME, + 'CSName':self.SYSTEM_NAME, + 'FSCreationClassName':'LMI_LocalFileSystem', + 'FSName':'NotImportant', + 'CreationClassName':f['class'], + 'Name':f['path'] + }) + assocs_file = assoc_method(cop_file, ResultClass='LMI_DirectoryContainsFile') + self.assertEquals(len(assocs_file), 1) + file_name = assocs_file[0]['GroupComponent'] + self.assertEquals(file_name.classname, 'LMI_UnixDirectory') + self.assertEquals(file_name['Name'], self.testdir) + + def test_lmi_fileidentity(self): + # Associators and AssociatorNames + for assoc_method in [self.wbemconnection.Associators, self.wbemconnection.AssociatorNames]: + assocs = assoc_method(self.cop, AssocClass='LMI_DirectoryContainsFile') + self.assertEquals(len(assocs), len(self.files.keys())) + for k, f in self.files.iteritems(): + match = filter(lambda a: a['Name'] == f['path'], assocs) + self.assertEquals(len(match), 1) + self.assertEquals(match[0].classname, f['class']) + + if isinstance(match[0], pywbem.CIMInstanceName): + match[0].path = match[0] + assocs_ident = assoc_method(match[0].path, AssocClass='LMI_FileIdentity') + self.assertEquals(len(assocs_ident), 1) + self.assertEquals(assocs_ident[0]['LFName'], f['path']) + self.assertEquals(assocs_ident[0]['LFCreationClassName'], f['class']) + + cop_ident = pywbem.CIMInstanceName(classname='LMI_UnixFile', + namespace='root/cimv2', + keybindings={ + 'CSCreationClassName':self.SYSTEM_CLASS_NAME, + 'CSName':self.SYSTEM_NAME, + 'FSCreationClassName':'LMI_LocalFileSystem', + 'FSName':'NotImportant', + 'LFCreationClassName':f['class'], + 'LFName':f['path'] + }) + assocs_ident = assoc_method(cop_ident, AssocClass='LMI_FileIdentity') + self.assertEquals(len(assocs_ident), 1) + self.assertEquals(assocs_ident[0]['Name'], f['path']) + self.assertEquals(assocs_ident[0]['CreationClassName'], f['class']) + + # References and ReferenceNames + for assoc_method in [self.wbemconnection.References, self.wbemconnection.ReferenceNames]: + assocs = assoc_method(self.cop, ResultClass='LMI_DirectoryContainsFile') + self.assertEquals(len(assocs), len(self.files.keys())) + for k, f in self.files.iteritems(): + match = filter(lambda a: a['PartComponent']['Name'] == f['path'], assocs) + self.assertEquals(len(match), 1) + match_name = match[0]['PartComponent'] + self.assertEquals(match_name['CreationClassName'], f['class']) + + assocs_ident = assoc_method(match_name, ResultClass='LMI_FileIdentity') + self.assertEquals(len(assocs_ident), 1) + ident_name = assocs_ident[0]['SameElement'] + self.assertEquals(ident_name['LFName'], f['path']) + self.assertEquals(ident_name['LFCreationClassName'], f['class']) + + cop_ident = pywbem.CIMInstanceName(classname='LMI_UnixFile', + namespace='root/cimv2', + keybindings={ + 'CSCreationClassName':self.SYSTEM_CLASS_NAME, + 'CSName':self.SYSTEM_NAME, + 'FSCreationClassName':'LMI_LocalFileSystem', + 'FSName':'NotImportant', + 'LFCreationClassName':f['class'], + 'LFName':f['path'] + }) + assocs_ident = assoc_method(cop_ident, ResultClass='LMI_FileIdentity') + self.assertEquals(len(assocs_ident), 1) + ident_name = assocs_ident[0]['SystemElement'] + self.assertEquals(ident_name['Name'], f['path']) + self.assertEquals(ident_name['CreationClassName'], f['class']) + + def test_lmi_rootdirectory(self): + # Associators and AssociatorNames + cop = self.cop.copy() + cop.keybindings['Name'] = '/' + for assoc_method in [self.wbemconnection.Associators, self.wbemconnection.AssociatorNames]: + assocs = assoc_method(cop, AssocClass='LMI_RootDirectory') + self.assertEquals(len(assocs), 1) + system = assocs[0] + self.assertEquals(system['CreationClassName'], self.SYSTEM_CLASS_NAME) + self.assertEquals(system['Name'], self.SYSTEM_NAME) + + if isinstance(system, pywbem.CIMInstanceName): + system.path = system + assocs = self.wbemconnection.Associators(system.path, AssocClass='LMI_RootDirectory') + self.assertEquals(len(assocs), 1) + self.assertEquals(assocs[0]['Name'], '/') + + # References and ReferenceNames + for assoc_method in [self.wbemconnection.References, self.wbemconnection.ReferenceNames]: + assocs = assoc_method(cop, ResultClass='LMI_RootDirectory') + self.assertEquals(len(assocs), 1) + system = assocs[0]['GroupComponent'] + self.assertEquals(system['CreationClassName'], self.SYSTEM_CLASS_NAME) + self.assertEquals(system['Name'], self.SYSTEM_NAME) + + assocs = self.wbemconnection.References(system, ResultClass='LMI_RootDirectory') + self.assertEquals(len(assocs), 1) + self.assertEquals(assocs[0]['PartComponent']['Name'], '/') + + def test_mkdir(self): + def mkdir(path): + cop = self.cop.copy() + cop['Name'] = path + inst = pywbem.CIMInstance('LMI_UnixDirectory', cop.keybindings) + self.wbemconnection.CreateInstance(inst) + + try: + mkdir(self.testdir + '/mkdir-test') + except pywbem.CIMError as pe: + self.fail(pe[1]) + + self.assertRaises(pywbem.CIMError, + mkdir, + '/cant/create/me') + + def test_rmdir(self): + def rmdir(path): + cop = self.cop.copy() + cop['Name'] = path + inst = pywbem.CIMInstance('LMI_UnixDirectory', cop.keybindings) + self.wbemconnection.DeleteInstance(cop) + + try: + rmdir(self.files['dir']['path']) + except pywbem.CIMError as pe: + self.fail(pe[1]) + + self.assertRaises(pywbem.CIMError, + rmdir, + '/cant/remove/me') + +if __name__ == '__main__': + unittest.main() -- cgit