зеркало из https://github.com/microsoft/InQRy.git
Merged PR 43599: Merge pybar to master
This code is not yet ready for production. However, it should be reviewed regularly during the development process. Please verify the code "builds" successfully using `python3 setup.py install` and that all tests pass using `pytest` Any and all feedback is appreciated! Related work items: #1409731
This commit is contained in:
Родитель
f2a5eb93b7
Коммит
8cfbed127e
|
@ -1,20 +1,11 @@
|
|||
test-scripts/
|
||||
*.cache/
|
||||
*.egg-info/
|
||||
*.eggs/
|
||||
|
||||
*.pyc
|
||||
*.pdf
|
||||
*.cache
|
||||
*.cre.js
|
||||
*.default.js
|
||||
*.settings.js
|
||||
|
||||
dist/
|
||||
.eggs/
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/libraries/
|
||||
.idea/dictionaries/
|
||||
.cache/
|
||||
*.iml
|
||||
*.egg-info
|
||||
build/
|
||||
|
||||
.installed.cfg
|
||||
.DS_Store
|
||||
|
||||
cr8000.js
|
||||
translate.xml
|
||||
dist/
|
||||
**/__pycache__/
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6.0 (~/.pyenv/versions/3.6.0/bin/python)" project-jdk-type="Python SDK" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/lab_inventory.iml" filepath="$PROJECT_DIR$/.idea/lab_inventory.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,5 +1,5 @@
|
|||
# PyBar
|
||||
Generate asset QR codes for a physical inventory procedure
|
||||
Generate a QR code for a physical inventory procedure based on an individual asset's hardware specifications
|
||||
|
||||
### Install
|
||||
|
||||
|
@ -8,4 +8,4 @@ Generate asset QR codes for a physical inventory procedure
|
|||
|
||||
### Test
|
||||
|
||||
`python3 setup.py pytest`
|
||||
`python3 setup.py test`
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
class Asset:
|
||||
"""The current machine and it's associated specs"""
|
||||
def __init__(self):
|
||||
pass
|
||||
class Asset(object):
|
||||
"""
|
||||
Represents the object to be entered into a Snipe-IT inventory database.
|
||||
|
||||
def is_valid(self):
|
||||
An Asset object is built from a SystemProfile object and it's
|
||||
attributes, which is then used to assemble the QR code.
|
||||
"""
|
||||
|
||||
def __init__(self, systemprofile):
|
||||
"""
|
||||
Instantiates an Asset object with several attributes,
|
||||
all which can be used to build a QR code.
|
||||
"""
|
||||
self.systemprofile = systemprofile
|
||||
self.cpu_name = systemprofile.cpu_name
|
||||
self.cpu_processors = systemprofile.cpu_processors
|
||||
self.cpu_speed = systemprofile.cpu_speed
|
||||
self.cpu_cores = systemprofile.cpu_cores
|
||||
self.memory = systemprofile.memory
|
||||
self.serial = systemprofile.serial
|
||||
self.model = systemprofile.model
|
||||
self.name = systemprofile.name
|
||||
|
||||
@staticmethod
|
||||
def is_valid():
|
||||
"""TODO"""
|
||||
return None
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
BASE_COMMAND = '/usr/sbin/diskutil'
|
||||
|
||||
|
||||
def get_physical_disk_identifiers(diskutil_list_output=None):
|
||||
diskutil_list_output = diskutil_list_output or list_all()
|
||||
physical_disk_id_pattern = re.compile(r'(/dev/disk\d+) \(\w+, physical\).*')
|
||||
|
||||
return re.findall(physical_disk_id_pattern, diskutil_list_output)
|
||||
|
||||
|
||||
def get_disk_info(disk_identifier):
|
||||
return _get_output_of_diskutil_command(arguments=f'info {disk_identifier}')
|
||||
|
||||
|
||||
def list_all():
|
||||
return _get_output_of_diskutil_command(arguments='list')
|
||||
|
||||
|
||||
def _get_output_of_diskutil_command(arguments=None):
|
||||
arguments = arguments or ''
|
||||
full_command = shlex.split(' '.join([BASE_COMMAND, arguments]))
|
||||
|
||||
return subprocess.check_output(full_command).decode('utf-8')
|
|
@ -0,0 +1,18 @@
|
|||
import tkinter as tk
|
||||
|
||||
win = tk.Tk()
|
||||
win.title("PyBar")
|
||||
# tk.Label()(win, text="Label").grid(column=0, row=0)
|
||||
label = tk.Label(win, text="Hello")
|
||||
label.grid(column=0, row=0)
|
||||
|
||||
|
||||
def click():
|
||||
action.configure()
|
||||
label.configure(foreground="red")
|
||||
|
||||
|
||||
action = tk.Button(win, text="Generate QR Code", command=click)
|
||||
action.grid(column=1, row=0)
|
||||
|
||||
win.mainloop()
|
|
@ -0,0 +1,6 @@
|
|||
class Instructions:
|
||||
"""Create Instructions object"""
|
||||
|
||||
def __init__(self):
|
||||
"""TODO"""
|
||||
pass
|
|
@ -0,0 +1,52 @@
|
|||
import re
|
||||
import yaml
|
||||
from pybar import diskutil
|
||||
|
||||
|
||||
def create_from_diskutil_info_output(output):
|
||||
return Disk(yaml.load(output))
|
||||
|
||||
|
||||
def get_all_physical_disks():
|
||||
return [
|
||||
create_from_diskutil_info_output(diskutil.get_disk_info(disk_identifier))
|
||||
for disk_identifier in diskutil.get_physical_disk_identifiers()
|
||||
]
|
||||
|
||||
|
||||
class Disk:
|
||||
|
||||
def __init__(self, attributes=None):
|
||||
self.attributes = attributes or {}
|
||||
|
||||
@property
|
||||
def device_location(self):
|
||||
return self.attributes.get('Device Location')
|
||||
|
||||
@property
|
||||
def is_internal(self):
|
||||
return self.device_location == 'Internal'
|
||||
|
||||
@property
|
||||
def is_external(self):
|
||||
return self.device_location == 'External'
|
||||
|
||||
@property
|
||||
def device_name(self):
|
||||
return self.attributes.get('Device / Media Name')
|
||||
|
||||
@property
|
||||
def is_ssd(self):
|
||||
return self.attributes.get('Solid State')
|
||||
|
||||
@property
|
||||
def verbose_disk_size(self):
|
||||
return self.attributes.get('Disk Size') or self.attributes.get('Total Size')
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
disk_size_pattern = re.compile(r'(?P<disk_size>\d+\.?\d* [MGT]?B) .*$')
|
||||
disk_size_match = re.match(disk_size_pattern, self.verbose_disk_size)
|
||||
|
||||
if disk_size_match:
|
||||
return disk_size_match.group('disk_size')
|
|
@ -1,6 +1,9 @@
|
|||
import instructions
|
||||
from qrcode import QRCode
|
||||
|
||||
fieldset = {'trashcan': instructions.trashcan}
|
||||
|
||||
for fieldset in fieldsets:
|
||||
class AssetQRCode(QRCode):
|
||||
"""TODO"""
|
||||
|
||||
def __init__(self):
|
||||
"""TODO"""
|
||||
pass
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
class SystemProfile:
|
||||
def __init__(self):
|
||||
pass
|
|
@ -0,0 +1,116 @@
|
|||
import platform
|
||||
import subprocess
|
||||
import yaml
|
||||
|
||||
|
||||
class SystemProfile(object):
|
||||
"""Represents the machine's "system profile" before it is parsed and
|
||||
converted into an Asset object.
|
||||
|
||||
A SystemProfile object should be able to be used to access several system
|
||||
profile specs, even if they are not used by the Asset class.
|
||||
|
||||
A SystemProfile object should also be able to be used the same way,
|
||||
regardless of which operating system the specs were generated from"""
|
||||
|
||||
def __init__(self):
|
||||
"""TODO"""
|
||||
self.os_type = platform.system()
|
||||
|
||||
def operating_system(self):
|
||||
if self.os_type == 'Darwin':
|
||||
mac_hardware()
|
||||
elif self.os_type == 'Windows':
|
||||
windows()
|
||||
else:
|
||||
raise OSError(
|
||||
'{os}: Unknown operating system'.format(os=self.os_type))
|
||||
|
||||
def storage(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def serial(self):
|
||||
serial = mac_hardware().get('Serial Number (system)')
|
||||
assert isinstance(serial, str)
|
||||
return serial
|
||||
|
||||
@property
|
||||
def cpu_name(self):
|
||||
name = mac_hardware().get('Processor Name')
|
||||
assert isinstance(name, str)
|
||||
return name
|
||||
|
||||
@property
|
||||
def cpu_processors(self):
|
||||
processors = mac_hardware().get('Number of Processors')
|
||||
assert isinstance(processors, int)
|
||||
return processors
|
||||
|
||||
@property
|
||||
def cpu_cores(self):
|
||||
cores = mac_hardware().get('Total Number of Cores')
|
||||
assert isinstance(cores, int)
|
||||
return cores
|
||||
|
||||
@property
|
||||
def cpu_speed(self):
|
||||
speed = mac_hardware().get('Processor Speed')
|
||||
assert isinstance(speed, str)
|
||||
return speed
|
||||
|
||||
@property
|
||||
def memory(self):
|
||||
memory = mac_hardware().get('Memory')
|
||||
return memory
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
model = mac_hardware().get('Model Identifier')
|
||||
return model
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
name = mac_hardware().get('Model Name')
|
||||
return name
|
||||
|
||||
|
||||
def _mac_system_profiler(data_type):
|
||||
"""
|
||||
This function is passed one of several strings that is then parsed using
|
||||
the yaml module and can then be utilized in other mac_data_type functions.
|
||||
|
||||
Used only for '/usr/sbin/system_profiler' argument 'SPHardwareDataType'
|
||||
:param data_type:
|
||||
:return: data
|
||||
"""
|
||||
command = [
|
||||
'/usr/sbin/system_profiler', 'SP' + str.title(data_type) + 'DataType']
|
||||
data = yaml.load(subprocess.check_output(command))
|
||||
return data
|
||||
|
||||
|
||||
def mac_hardware():
|
||||
"""
|
||||
This function is used as the primary means of obtaining basic Mac
|
||||
hardware components.
|
||||
"""
|
||||
system_profiler_hardware = _mac_system_profiler('hardware')
|
||||
hardware_components = system_profiler_hardware['Hardware']['Hardware Overview']
|
||||
return hardware_components
|
||||
|
||||
|
||||
def mac_storage():
|
||||
"""
|
||||
This function will be used as the primary means of obtaining data about
|
||||
the a Mac's storage specifications.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def windows():
|
||||
"""
|
||||
This function is used as the primary means of obtaining basic Windows
|
||||
machine hardware components.
|
||||
"""
|
||||
pass
|
|
@ -0,0 +1,2 @@
|
|||
[aliases]
|
||||
test=pytest
|
17
setup.py
17
setup.py
|
@ -1,16 +1,21 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from setuptools import setup
|
||||
try:
|
||||
from setuptools import setup
|
||||
except ImportError:
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name='PyBar',
|
||||
version='0.0.1',
|
||||
version='0.0.2',
|
||||
license='MIT',
|
||||
description='Generate QRCodes for a Physical Inventory',
|
||||
description='Generate QRCodes for a physical inventory',
|
||||
author='Eric Hanko',
|
||||
author_email='v-erhank@microsoft.com',
|
||||
packages=['pybar'],
|
||||
long_description=open('README.md').read(),
|
||||
install_requires=["qrcode >= 5.3.0"],
|
||||
install_requires=[
|
||||
"qrcode >= 5.3.0",
|
||||
"PyYAML >= 3.12",
|
||||
"pytest-runner",
|
||||
"pytest"],
|
||||
setup_requires=['pytest-runner'],
|
||||
tests_require=['pytest'],
|
||||
)
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import pytest
|
||||
from pybar.asset import Asset
|
||||
|
||||
test_data = {
|
||||
'owner': 'Hanko',
|
||||
'serial': 'HZ1KF3L90',
|
||||
'cpu': ('Intel', 'Core i7', '2.9GHz')
|
||||
}
|
||||
|
||||
|
||||
class TestAsset:
|
||||
def test_empty_asset_instantiation_works(self):
|
||||
Asset()
|
||||
|
||||
def test_empty_asset_is_not_valid(self):
|
||||
asset = Asset()
|
||||
assert not asset.is_valid()
|
||||
|
||||
def test_asset_is_valid_with_known_good_test_data(self):
|
||||
pass
|
|
@ -1,7 +0,0 @@
|
|||
import pytest
|
||||
from pybar.system_profile import SystemProfile
|
||||
|
||||
|
||||
class TestSystemProfile:
|
||||
def test_empty_profile_instantiation_works(self):
|
||||
SystemProfile()
|
|
@ -0,0 +1,88 @@
|
|||
import pytest
|
||||
from pybar.asset import Asset
|
||||
from pybar.systemprofile import SystemProfile
|
||||
|
||||
|
||||
sp = SystemProfile()
|
||||
asset = Asset(sp)
|
||||
|
||||
|
||||
def test_empty_asset_instantiation_works():
|
||||
Asset(sp)
|
||||
|
||||
|
||||
def test_empty_asset_is_not_valid():
|
||||
assert not asset.is_valid()
|
||||
|
||||
|
||||
def test_presence_of_cpu_name_attribute():
|
||||
assert hasattr(asset, 'cpu_name')
|
||||
|
||||
|
||||
def test_cpu_attribute_is_tuple():
|
||||
assert isinstance(asset.cpu_name, str)
|
||||
|
||||
|
||||
def test_presence_of_cpu_speed_attribute():
|
||||
assert hasattr(asset, 'cpu_speed')
|
||||
|
||||
|
||||
def test_cpu_speed_is_integer():
|
||||
assert isinstance(asset.cpu_speed, str)
|
||||
|
||||
|
||||
def test_presence_of_cpu_processors_attribute():
|
||||
assert hasattr(asset, 'cpu_processors')
|
||||
|
||||
|
||||
def test_cpu_processor_is_string():
|
||||
assert isinstance(asset.cpu_processors, int)
|
||||
|
||||
|
||||
def test_presence_of_cpu_cores_attribute():
|
||||
assert hasattr(asset, 'cpu_cores')
|
||||
|
||||
|
||||
def test_cpu_cores_is_integer():
|
||||
assert isinstance(asset.cpu_cores, int)
|
||||
|
||||
|
||||
def test_presence_of_memory_attribute():
|
||||
assert hasattr(asset, 'memory')
|
||||
|
||||
|
||||
def test_memory_attribute_is_string():
|
||||
assert isinstance(asset.memory, str)
|
||||
|
||||
|
||||
def test_presence_of_serial_attribute():
|
||||
assert hasattr(asset, 'serial')
|
||||
|
||||
|
||||
def test_serial_attribute_is_string():
|
||||
assert isinstance(asset.serial, str)
|
||||
|
||||
|
||||
def test_presence_of_name_attribute():
|
||||
assert hasattr(asset, 'name')
|
||||
|
||||
|
||||
def test_name_attribute_is_string():
|
||||
assert isinstance(asset.model, str)
|
||||
|
||||
|
||||
def test_presence_of_model_attribute():
|
||||
assert hasattr(asset, 'model')
|
||||
|
||||
|
||||
def test_model_attribute_is_string():
|
||||
assert isinstance(asset.model, str)
|
||||
|
||||
|
||||
def test_serial_is_correct_length():
|
||||
assert len(asset.serial) == 12
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_asset_is_valid_with_known_good_test_data():
|
||||
pass
|
|
@ -0,0 +1,58 @@
|
|||
from pybar import diskutil
|
||||
|
||||
diskutil_list_output = '''/dev/disk0 (internal, physical):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: GUID_partition_scheme *751.3 GB disk0
|
||||
1: EFI EFI 209.7 MB disk0s1
|
||||
2: Apple_CoreStorage Macintosh HD 750.4 GB disk0s2
|
||||
3: Apple_Boot Recovery HD 650.1 MB disk0s3
|
||||
/dev/disk1 (internal, virtual):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: Apple_HFS Macintosh HD +750.1 GB disk1
|
||||
Logical Volume on disk0s2
|
||||
2F555A8B-D884-485F-985A-3B7ADF7BFCB5
|
||||
Unlocked Encrypted
|
||||
/dev/disk2 (disk image):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: Apple_partition_scheme +19.8 MB disk2
|
||||
1: Apple_partition_map 32.3 KB disk2s1
|
||||
2: Apple_HFS Flash Player 19.7 MB disk2s2
|
||||
/dev/disk3 (disk image):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: GUID_partition_scheme +35.8 MB disk3
|
||||
1: Apple_HFS Synergy 35.8 MB disk3s1
|
||||
/dev/disk4 (external, physical):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: FDisk_partition_scheme *2.0 TB disk4
|
||||
1: Windows_NTFS My Passport 2.0 TB disk4s1
|
||||
/dev/disk5 (external, physical):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: GUID_partition_scheme *2.0 TB disk5
|
||||
1: EFI EFI 209.7 MB disk5s1
|
||||
2: Apple_HFS Builds 1.5 TB disk5s2
|
||||
3: Apple_HFS Source 499.7 GB disk5s3
|
||||
/dev/disk6 (external, physical):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: GUID_partition_scheme *1.0 TB disk6
|
||||
1: EFI EFI 209.7 MB disk6s1
|
||||
2: Apple_RAID 999.9 GB disk6s2
|
||||
3: Apple_Boot Boot OS X 134.2 MB disk6s3
|
||||
/dev/disk7 (external, physical):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: GUID_partition_scheme *1.0 TB disk7
|
||||
1: EFI EFI 209.7 MB disk7s1
|
||||
2: Apple_RAID 999.9 GB disk7s2
|
||||
3: Apple_Boot Boot OS X 134.2 MB disk7s3
|
||||
/dev/disk8 (external, virtual):
|
||||
#: TYPE NAME SIZE IDENTIFIER
|
||||
0: Apple_HFS RedBackup +2.0 TB disk8
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def test_only_physical_drives_included():
|
||||
expected_physical_disks = [
|
||||
'/dev/disk0', '/dev/disk4', '/dev/disk5', '/dev/disk6', '/dev/disk7']
|
||||
|
||||
assert expected_physical_disks == diskutil.get_physical_disk_identifiers(
|
||||
diskutil_list_output)
|
|
@ -0,0 +1,10 @@
|
|||
from pybar.qr_builder import AssetQRCode
|
||||
|
||||
|
||||
def test_empty_asset_qr_code_can_be_instantiated():
|
||||
AssetQRCode()
|
||||
|
||||
|
||||
def test_asset_qr_code_as_attributes_of_inherited_class():
|
||||
qr = AssetQRCode()
|
||||
assert hasattr(qr, 'add_data')
|
|
@ -0,0 +1,54 @@
|
|||
from pybar import macdisk
|
||||
|
||||
diskutil_output = ''' Device Identifier: disk5
|
||||
Device Node: /dev/disk5
|
||||
Whole: Yes
|
||||
Part of Whole: disk2
|
||||
Device / Media Name: G-DRIVE PRO Thunderbolt
|
||||
|
||||
Volume Name: Not applicable (no file system)
|
||||
Mounted: Not applicable (no file system)
|
||||
File System: None
|
||||
|
||||
Content (IOContent): GUID_partition_scheme
|
||||
OS Can Be Installed: No
|
||||
Media Type: Generic
|
||||
Protocol: SATA
|
||||
SMART Status: Verified
|
||||
|
||||
Disk Size: 2.0 TB (2000179691520 Bytes) (exactly 3906600960 512-Byte-Units)
|
||||
Device Block Size: 512 Bytes
|
||||
|
||||
Read-Only Media: No
|
||||
Read-Only Volume: Not applicable (no file system)
|
||||
|
||||
Device Location: External
|
||||
Removable Media: Fixed
|
||||
|
||||
Solid State: No
|
||||
Virtual: No
|
||||
OS 9 Drivers: No
|
||||
Low Level Format: Not supported
|
||||
'''
|
||||
|
||||
test_disk = macdisk.create_from_diskutil_info_output(diskutil_output)
|
||||
|
||||
|
||||
def test_disk_is_not_internal():
|
||||
assert test_disk.is_internal is False
|
||||
|
||||
|
||||
def test_disk_is_external():
|
||||
assert test_disk.is_external
|
||||
|
||||
|
||||
def test_device_name_is_correct():
|
||||
assert test_disk.device_name == 'G-DRIVE PRO Thunderbolt'
|
||||
|
||||
|
||||
def test_disk_is_not_ssd():
|
||||
assert test_disk.is_ssd is False
|
||||
|
||||
|
||||
def test_size_is_correct():
|
||||
assert test_disk.size == '2.0 TB'
|
|
@ -0,0 +1,58 @@
|
|||
from pybar import macdisk
|
||||
|
||||
diskutil_output = ''' Device Identifier: disk0
|
||||
Device Node: /dev/disk0
|
||||
Whole: Yes
|
||||
Part of Whole: disk0
|
||||
Device / Media Name: APPLE SSD SM768E
|
||||
|
||||
Volume Name: Not applicable (no file system)
|
||||
|
||||
Mounted: Not applicable (no file system)
|
||||
|
||||
File System: None
|
||||
|
||||
Content (IOContent): GUID_partition_scheme
|
||||
OS Can Be Installed: No
|
||||
Media Type: Generic
|
||||
Protocol: SATA
|
||||
SMART Status: Verified
|
||||
|
||||
Total Size: 751.3 GB (751277983744 Bytes) (exactly 1467339812 512-Byte-Units)
|
||||
Volume Free Space: Not applicable (no file system)
|
||||
Device Block Size: 512 Bytes
|
||||
|
||||
Read-Only Media: No
|
||||
Read-Only Volume: Not applicable (no file system)
|
||||
|
||||
Device Location: Internal
|
||||
Removable Media: No
|
||||
|
||||
Solid State: Yes
|
||||
Virtual: No
|
||||
OS 9 Drivers: No
|
||||
Low Level Format: Not supported
|
||||
|
||||
'''
|
||||
|
||||
test_disk = macdisk.create_from_diskutil_info_output(diskutil_output)
|
||||
|
||||
|
||||
def test_disk_is_internal():
|
||||
assert test_disk.is_internal
|
||||
|
||||
|
||||
def test_disk_is_not_external():
|
||||
assert test_disk.is_external is False
|
||||
|
||||
|
||||
def test_device_name_is_correct():
|
||||
assert test_disk.device_name == 'APPLE SSD SM768E'
|
||||
|
||||
|
||||
def test_disk_is_ssd():
|
||||
assert test_disk.is_ssd
|
||||
|
||||
|
||||
def test_size_is_correct():
|
||||
assert test_disk.size == '751.3 GB'
|
|
@ -0,0 +1,120 @@
|
|||
import pytest
|
||||
from pybar.systemprofile import SystemProfile, mac_hardware
|
||||
|
||||
hardware_test_data_as_dict = {
|
||||
'Hardware':
|
||||
{
|
||||
'Hardware Overview':
|
||||
{
|
||||
'Model Name': 'MacBook Pro',
|
||||
'Model Identifier': 'MacBookPro11,2',
|
||||
'Processor Name': 'Intel Core i7',
|
||||
'Processor Speed': '2.2 GHz',
|
||||
'Number of Processors': 1,
|
||||
'Total Number of Cores': 4,
|
||||
'L2 Cache (per Core)': '256 KB',
|
||||
'L3 Cache': '6 MB', 'Memory': '16 GB',
|
||||
'Boot ROM Version': 'MBP112.0138.B21',
|
||||
'SMC Version (system)': '2.18f15',
|
||||
'Serial Number (system)': 'C02NT9WJG3QC',
|
||||
'Hardware UUID': '7BE2608D-6373-52C7-B5FB-442C261A71A4'}}}
|
||||
|
||||
hardware_test_data_as_yaml = """
|
||||
Hardware:
|
||||
|
||||
Hardware Overview:
|
||||
|
||||
Model Name: Mac Pro
|
||||
Model Identifier: MacPro6,1
|
||||
Processor Name: Quad-Core Intel Xeon E5
|
||||
Processor Speed: 3.7 GHz
|
||||
Number of Processors: 1
|
||||
Total Number of Cores: 4
|
||||
L2 Cache (per Core): 256 KB
|
||||
L3 Cache: 10 MB
|
||||
Memory: 32 GB
|
||||
Boot ROM Version: MP61.0116.B21
|
||||
SMC Version (system): 2.20f18
|
||||
Illumination Version: 1.4a6
|
||||
Serial Number (system): F5KQH0P9F9VN
|
||||
Hardware UUID: 4D4C19C7-19C4-5678-A936-A419C4609AFD"""
|
||||
|
||||
|
||||
def test_empty_profile_instantiation_works():
|
||||
SystemProfile()
|
||||
|
||||
|
||||
def test_that_system_profile_object_operating_system_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "operating_system")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_storage_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "storage")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_serial_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "serial")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_cpu_name_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "cpu_name")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_cpu_speed_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "cpu_speed")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_cpu_processors_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "cpu_processors")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_cpu_cores_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "cpu_cores")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_model_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "model")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_name_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "name")
|
||||
|
||||
|
||||
def test_that_system_profile_object_has_memory_attribute():
|
||||
sp = SystemProfile()
|
||||
assert hasattr(sp, "memory")
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_when_ios_device_is_connected():
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_ability_to_get_components_from_system_profile_object():
|
||||
pass
|
||||
|
||||
|
||||
def test_mac_hardware_method_output_data_type_is_dictionary():
|
||||
assert isinstance(mac_hardware(), dict)
|
||||
|
||||
|
||||
def test_system_profiler_has_os_type_attribute():
|
||||
sp = SystemProfile()
|
||||
assert sp.os_type
|
||||
|
||||
|
||||
def test_operating_system_method_fails_when_operating_system_is_not_darwin_or_windows():
|
||||
sp = SystemProfile()
|
||||
sp.os_type = 'Linux'
|
||||
with pytest.raises(OSError):
|
||||
sp.operating_system()
|
Загрузка…
Ссылка в новой задаче