Repository: softlayer/softlayer-python

Issue:
Whenever file volume detail is requested on slcli its reported error

**File volume detail is not displayed properly when its executed on SLCLI**


**slcli file volume-detail 609491933**


**Error Screenshots**
slcli file volume-detail 609491933
An unexpected error has occured:
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/core.py", line 183, in main
    cli.main(**kwargs)
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/decorators.py", line 84, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/file/detail.py", line 132, in cli
    env.fout(table)
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/environment.py", line 94, in fout
    self.out(self.fmt(output))
             ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/environment.py", line 84, in fmt
    return formatting.format_output(output, fmt, self.theme)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/formatting.py", line 43, in format_output
    return format_prettytable(data, fmt, theme)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/formatting.py", line 86, in format_prettytable
    ptable = table.prettytable(fmt, theme)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/formatting.py", line 308, in prettytable
    table.add_row(*row)
  File "/opt/homebrew/lib/python3.11/site-packages/rich/table.py", line 460, in add_row
    raise errors.NotRenderableError(
rich.errors.NotRenderableError: unable to render list; a string or other renderable object is required

*Tried with option as well*
slcli -vvv file volume-detail 609491933
Calling: SoftLayer_Network_Storage::getObject(id=609491933, mask='id,username,password,capacityGb,bytesUsed,snapshotCapacityGb,parentVolume.snapshotSizeBytes,storageType.keyName,serviceResource.datacenter[name],serviceResourceBackendIpAddress,fileNetworkMountAddress,storageTierLevel,provisionedIops,lunId,originalVolumeName,originalSnapshotName,originalVolumeSize,activeTransactionCount,activeTransactions.transactionStatus[friendlyName],replicationPartnerCount,replicationStatus,replicationPartners[id,username,serviceResourceBackendIpAddress,serviceResource[datacenter[name]],replicationSchedule[type[keyname]]],notes', filter='None', args=(), limit=None, offset=None))
Starting new HTTP connection (1): r25436750.application.qadal0901.softlayer.local:80
http://r25436750.application.qadal0901.softlayer.local:80 "POST /v3/sldn/xmlrpc/SoftLayer_Network_Storage HTTP/1.1" 200 None
Returned Data: 
{"capacityGb": 150, "id": 609491933, "username": "SL02SV1414935_187", "activeTransactionCount": 0, "replicationPartnerCount": 1, "fileNetworkMountAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com:/SL02SV1414935_187/data01", "originalVolumeSize": "20", "provisionedIops": "2000", "replicationStatus": "FAILOVER_COMPLETED", "serviceResourceBackendIpAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com", "snapshotCapacityGb": "5", "activeTransactions": [{"createDate": "", "elapsedSeconds": 111763, "guestId": "", "hardwareId": "", "id": "", "modifyDate": "", "statusChangeDate": "", "transactionGroup": {"name": "Volume Modification"}, "transactionStatus": {"friendlyName": "In Progress"}}], "parentVolume": {"accountId": 1414935, "capacityGb": 120, "createDate": "2024-05-16T02:28:02-05:00", "guestId": "", "hardwareId": "", "hostId": "", "id": 609491967, "nasType": "SNAPSHOT", "notes": "vol_duplicate_snapshot_2024-05-16_0228", "serviceProviderId": 1, "storageTypeId": "16", "upgradableFlag": true, "username": "SL02SV1414935_187", "serviceResourceBackendIpAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com", "serviceResourceName": "Storage Type 02 Aggregate natestdal0505-fc-d", "snapshotSizeBytes": "0"}, "replicationPartners": [{"id": 609491945, "username": "SL02SV1414935_187_REP_1", "serviceResourceBackendIpAddress": "fsf-natestdal0505-ffb-fz.service.softlayer.com", "replicationSchedule": {"active": 1, "createDate": "2024-05-16T01:20:19-05:00", "id": 666339, "modifyDate": "", "name": "SL02SV1414935_187_HOURLY_REP", "partnershipId": "", "typeId": 32, "volumeId": 609491933, "type": {"keyname": "REPLICATION_HOURLY"}}, "serviceResource": {"backendIpAddress": "fsf-natestdal0505-ffb-fz.service.softlayer.com", "id": 57365, "name": "Storage Type 02 Aggregate natestdal0505-ff-d", "datacenter": {"name": "dal10"}, "type": {"type": "NETAPP_STOR_AGGR"}}}], "serviceResource": {"backendIpAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com", "id": 52292, "name": "Storage Type 02 Aggregate natestdal0505-fc-d", "attributes": [{"value": "2", "attributeType": {"keyname": "STAAS_VERSION"}}], "datacenter": {"name": "lon02"}, "type": {"type": "NETAPP_STOR_AGGR"}}, "storageType": {"keyName": "PERFORMANCE_FILE_STORAGE"}}
An unexpected error has occured:
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/SoftLayer/CLI/core.py", line 183, in main
    cli.main(**kwargs)
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 760, in invoke

**Version**
slcli --version
Current: slcli (SoftLayer Command-line) v6.1.5
Latest:  slcli (SoftLayer Command-line) v6.2.2


Discussion:

Patch:
diff --git a/SoftLayer/CLI/block/detail.py b/SoftLayer/CLI/block/detail.py
index 7752e1b5..a4359fae 100644
--- a/SoftLayer/CLI/block/detail.py
+++ b/SoftLayer/CLI/block/detail.py
@@ -31,77 +31,52 @@ def cli(env, volume_id):
     table.add_row(['Username', block_volume['username']])
     table.add_row(['Type', storage_type])
     table.add_row(['Capacity (GB)', capacity])
-    table.add_row(['LUN Id', "%s" % block_volume['lunId']])
+    table.add_row(['LUN Id', block_volume['lunId']])
 
     if block_volume.get('provisionedIops'):
-        table.add_row(['IOPs', float(block_volume['provisionedIops'])])
+        table.add_row(['IOPs', block_volume['provisionedIops']])
 
     if block_volume.get('storageTierLevel'):
-        table.add_row([
-            'Endurance Tier',
-            block_volume['storageTierLevel'],
-        ])
-
-    table.add_row([
-        'Data Center',
-        block_volume['serviceResource']['datacenter']['name'],
-    ])
-    table.add_row([
-        'Target IP',
-        block_volume['serviceResourceBackendIpAddress'],
-    ])
+        table.add_row(['Endurance Tier', block_volume['storageTierLevel']])
+
+    table.add_row(['Data Center', block_volume['serviceResource']['datacenter']['name']])
+    table.add_row(['Target IP', block_volume['serviceResourceBackendIpAddress']])
 
     if block_volume['snapshotCapacityGb']:
-        table.add_row([
-            'Snapshot Capacity (GB)',
-            block_volume['snapshotCapacityGb'],
-        ])
+        table.add_row(['Snapshot Capacity (GB)', block_volume['snapshotCapacityGb']])
         if 'snapshotSizeBytes' in block_volume['parentVolume']:
-            table.add_row([
-                'Snapshot Used (Bytes)',
-                block_volume['parentVolume']['snapshotSizeBytes'],
-            ])
+            table.add_row(['Snapshot Used (Bytes)', block_volume['parentVolume']['snapshotSizeBytes']])
 
-    table.add_row(['# of Active Transactions', "%i"
-                   % block_volume['activeTransactionCount']])
+    table.add_row(['# of Active Transactions', block_volume['activeTransactionCount']])
 
     if block_volume['activeTransactions']:
         for trans in block_volume['activeTransactions']:
             if 'transactionStatus' in trans and 'friendlyName' in trans['transactionStatus']:
                 table.add_row(['Ongoing Transaction', trans['transactionStatus']['friendlyName']])
 
-    table.add_row(['Replicant Count', "%u" % block_volume.get('replicationPartnerCount', 0)])
+    table.add_row(['Replicant Count', block_volume.get('replicationPartnerCount', 0)])
 
     if block_volume['replicationPartnerCount'] > 0:
         # This if/else temporarily handles a bug in which the SL API
         # returns a string or object for 'replicationStatus'; it seems that
         # the type is string for File volumes and object for Block volumes
         if 'message' in block_volume['replicationStatus']:
-            table.add_row(['Replication Status', "%s"
-                           % block_volume['replicationStatus']['message']])
+            table.add_row(['Replication Status', block_volume['replicationStatus']['message']])
         else:
-            table.add_row(['Replication Status', "%s"
-                           % block_volume['replicationStatus']])
+            table.add_row(['Replication Status', block_volume['replicationStatus']])
 
+        replicant_table = formatting.Table(['Id', 'Username', 'Target', 'Location', 'Schedule'])
+        replicant_table.align['Name'] = 'r'
+        replicant_table.align['Value'] = 'l'
         for replicant in block_volume['replicationPartners']:
-            replicant_table = formatting.Table(['Name',
-                                                'Value'])
-            replicant_table.add_row(['Replicant Id', replicant['id']])
-            replicant_table.add_row([
-                'Volume Name',
-                utils.lookup(replicant, 'username')])
             replicant_table.add_row([
-                'Target IP',
-                utils.lookup(replicant, 'serviceResourceBackendIpAddress')])
-            replicant_table.add_row([
-                'Data Center',
-                utils.lookup(replicant,
-                             'serviceResource', 'datacenter', 'name')])
-            replicant_table.add_row([
-                'Schedule',
-                utils.lookup(replicant,
-                             'replicationSchedule', 'type', 'keyname')])
-            table.add_row(['Replicant Volumes', replicant_table])
+                replicant.get('id'),
+                utils.lookup(replicant, 'username'),
+                utils.lookup(replicant, 'serviceResourceBackendIpAddress'),
+                utils.lookup(replicant, 'serviceResource', 'datacenter', 'name'),
+                utils.lookup(replicant, 'replicationSchedule', 'type', 'keyname')
+            ])
+        table.add_row(['Replicant Volumes', replicant_table])
 
     if block_volume.get('originalVolumeSize'):
         original_volume_info = formatting.Table(['Property', 'Value'])
diff --git a/SoftLayer/CLI/exceptions.py b/SoftLayer/CLI/exceptions.py
index 611d854e..55acdb60 100644
--- a/SoftLayer/CLI/exceptions.py
+++ b/SoftLayer/CLI/exceptions.py
@@ -16,9 +16,8 @@ def __init__(self, code=0, *args):
         self.code = code
 
     def __str__(self):
-        return "<CLIHalt code=%s msg=%s>" % (self.code,
-                                             getattr(self, 'message'))
-
+        message = getattr(self, 'message')
+        return f"<CLIHalt code={self.code} msg={message}>"
     __repr__ = __str__
 
 
@@ -29,6 +28,11 @@ def __init__(self, msg, *args):
         super().__init__(code=2, *args)
         self.message = msg
 
+    def __str__(self):
+        message = getattr(self, 'message')
+        return f"<CLIAbort code={self.code} msg={message}>"
+    __repr__ = __str__
+
 
 class ArgumentError(CLIAbort):
     """Halt the execution of the command because of invalid arguments."""
@@ -36,3 +40,8 @@ class ArgumentError(CLIAbort):
     def __init__(self, msg, *args):
         super().__init__(msg, *args)
         self.message = "Argument Error: %s" % msg
+
+    def __str__(self):
+        message = getattr(self, 'message')
+        return f"<ArgumentError code={self.code} msg={message}>"
+    __repr__ = __str__
diff --git a/SoftLayer/CLI/file/detail.py b/SoftLayer/CLI/file/detail.py
index cc486045..ca12e43a 100644
--- a/SoftLayer/CLI/file/detail.py
+++ b/SoftLayer/CLI/file/detail.py
@@ -37,54 +37,27 @@ def cli(env, volume_id):
     table.add_row(['Type', storage_type])
     table.add_row(['Capacity (GB)', get_capacity(file_volume)])
 
-    used_space = int(file_volume['bytesUsed']) \
-        if file_volume['bytesUsed'] else 0
-    if used_space < (1 << 10):
-        table.add_row(['Used Space', "%dB" % used_space])
-    elif used_space < (1 << 20):
-        table.add_row(['Used Space', "%dKB" % (used_space / (1 << 10))])
-    elif used_space < (1 << 30):
-        table.add_row(['Used Space', "%dMB" % (used_space / (1 << 20))])
-    else:
-        table.add_row(['Used Space', "%dGB" % (used_space / (1 << 30))])
+    used_space = formatting.convert_sizes(file_volume.get('bytes_used', 0), "GB", False)
+    table.add_row(['Used Space', used_space])
 
     if file_volume.get('provisionedIops'):
-        table.add_row(['IOPs', float(file_volume['provisionedIops'])])
+        table.add_row(['IOPs', file_volume['provisionedIops']])
 
     if file_volume.get('storageTierLevel'):
-        table.add_row([
-            'Endurance Tier',
-            file_volume['storageTierLevel'],
-        ])
-
-    table.add_row([
-        'Data Center',
-        file_volume['serviceResource']['datacenter']['name'],
-    ])
-    table.add_row([
-        'Target IP',
-        file_volume['serviceResourceBackendIpAddress'],
-    ])
+        table.add_row(['Endurance Tier', file_volume['storageTierLevel']])
+
+    table.add_row(['Data Center', file_volume['serviceResource']['datacenter']['name']])
+    table.add_row(['Target IP', file_volume['serviceResourceBackendIpAddress']])
 
     if file_volume['fileNetworkMountAddress']:
-        table.add_row([
-            'Mount Address',
-            file_volume['fileNetworkMountAddress'],
-        ])
+        table.add_row(['Mount Address', file_volume['fileNetworkMountAddress']])
 
     if file_volume['snapshotCapacityGb']:
-        table.add_row([
-            'Snapshot Capacity (GB)',
-            file_volume['snapshotCapacityGb'],
-        ])
+        table.add_row(['Snapshot Capacity (GB)', file_volume['snapshotCapacityGb']])
         if 'snapshotSizeBytes' in file_volume['parentVolume']:
-            table.add_row([
-                'Snapshot Used (Bytes)',
-                file_volume['parentVolume']['snapshotSizeBytes'],
-            ])
+            table.add_row(['Snapshot Used (Bytes)', file_volume['parentVolume']['snapshotSizeBytes']])
 
-    table.add_row(['# of Active Transactions', "%i"
-                   % file_volume['activeTransactionCount']])
+    table.add_row(["# of Active Transactions", file_volume['activeTransactionCount']])
 
     if file_volume['activeTransactions']:
         for trans in file_volume['activeTransactions']:
@@ -98,32 +71,22 @@ def cli(env, volume_id):
         # returns a string or object for 'replicationStatus'; it seems that
         # the type is string for File volumes and object for Block volumes
         if 'message' in file_volume['replicationStatus']:
-            table.add_row(['Replication Status', "%s"
-                           % file_volume['replicationStatus']['message']])
+            table.add_row(['Replication Status', file_volume['replicationStatus']['message']])
         else:
-            table.add_row(['Replication Status', "%s"
-                           % file_volume['replicationStatus']])
+            table.add_row(['Replication Status', file_volume['replicationStatus']])
 
-        replicant_list = []
+        replicant_table = formatting.Table(['Id', 'Username', 'Target', 'Location', 'Schedule'])
+        replicant_table.align['Name'] = 'r'
+        replicant_table.align['Value'] = 'l'
         for replicant in file_volume['replicationPartners']:
-            replicant_table = formatting.Table(['Replicant ID',
-                                                replicant['id']])
-            replicant_table.add_row([
-                'Volume Name',
-                utils.lookup(replicant, 'username')])
             replicant_table.add_row([
-                'Target IP',
-                utils.lookup(replicant, 'serviceResourceBackendIpAddress')])
-            replicant_table.add_row([
-                'Data Center',
-                utils.lookup(replicant,
-                             'serviceResource', 'datacenter', 'name')])
-            replicant_table.add_row([
-                'Schedule',
-                utils.lookup(replicant,
-                             'replicationSchedule', 'type', 'keyname')])
-            replicant_list.append(replicant_table)
-        table.add_row(['Replicant Volumes', replicant_list])
+                replicant.get('id'),
+                utils.lookup(replicant, 'username'),
+                utils.lookup(replicant, 'serviceResourceBackendIpAddress'),
+                utils.lookup(replicant, 'serviceResource', 'datacenter', 'name'),
+                utils.lookup(replicant, 'replicationSchedule', 'type', 'keyname')
+            ])
+        table.add_row(['Replicant Volumes', replicant_table])
 
     if file_volume.get('originalVolumeSize'):
         original_volume_info = formatting.Table(['Property', 'Value'])
diff --git a/SoftLayer/CLI/formatting.py b/SoftLayer/CLI/formatting.py
index b8c6e4a8..c4c28463 100644
--- a/SoftLayer/CLI/formatting.py
+++ b/SoftLayer/CLI/formatting.py
@@ -14,6 +14,7 @@
 
 import click
 from rich import box
+from rich.errors import NotRenderableError
 from rich.table import Table as rTable
 
 from SoftLayer.CLI import exceptions
@@ -392,7 +393,15 @@ def prettytable(self, fmt='table', theme=None):
             table.add_column(col, justify=justify, style=style)
 
         for row in self.rows:
-            table.add_row(*row)
+            try:
+                table.add_row(*row)
+            # Generally you will see this if one of the columns in the row is a list or dict
+            except NotRenderableError:
+                forced_row = []
+                for i in row:
+                    forced_row.append(str(i))
+                table.add_row(*forced_row)
+
         return table
 
 
diff --git a/SoftLayer/fixtures/SoftLayer_Network_Storage.py b/SoftLayer/fixtures/SoftLayer_Network_Storage.py
index 2d9cdc49..d9e927bd 100644
--- a/SoftLayer/fixtures/SoftLayer_Network_Storage.py
+++ b/SoftLayer/fixtures/SoftLayer_Network_Storage.py
@@ -334,4 +334,107 @@
     'storageType': {
         'keyName': 'ENDURANCE_BLOCK_STORAGE'
     }
+}
+
+
+FILE_DETAIL_ISSUE2154 = {
+    "capacityGb": 150,
+    "id": 609491933,
+    "username": "SL02SV1414935_187",
+    "activeTransactionCount": 0,
+    "replicationPartnerCount": 1,
+    "fileNetworkMountAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com:/SL02SV1414935_187/data01",
+    "originalVolumeSize": "20",
+    "provisionedIops": "2000",
+    "replicationStatus": "FAILOVER_COMPLETED",
+    "serviceResourceBackendIpAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com",
+    "snapshotCapacityGb": "5",
+    "activeTransactions": [
+        {
+            "createDate": "",
+            "elapsedSeconds": 111763,
+            "guestId": "",
+            "hardwareId": "",
+            "id": "",
+            "modifyDate": "",
+            "statusChangeDate": "",
+            "transactionGroup": {
+                "name": "Volume Modification"
+            },
+            "transactionStatus": {
+                "friendlyName": "In Progress"
+            }
+        }
+    ],
+    "parentVolume": {
+        "accountId": 1414935,
+        "capacityGb": 120,
+        "createDate": "2024-05-16T02:28:02-05:00",
+        "guestId": "",
+        "hardwareId": "",
+        "hostId": "",
+        "id": 609491967,
+        "nasType": "SNAPSHOT",
+        "notes": "vol_duplicate_snapshot_2024-05-16_0228",
+        "serviceProviderId": 1,
+        "storageTypeId": "16",
+        "upgradableFlag": True,
+        "username": "SL02SV1414935_187",
+        "serviceResourceBackendIpAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com",
+        "serviceResourceName": "Storage Type 02 Aggregate natestdal0505-fc-d",
+        "snapshotSizeBytes": "0"
+    },
+    "replicationPartners": [
+        {
+            "id": 609491945,
+            "username": "SL02SV1414935_187_REP_1",
+            "serviceResourceBackendIpAddress": "fsf-natestdal0505-ffb-fz.service.softlayer.com",
+            "replicationSchedule": {
+                "active": 1,
+                "createDate": "2024-05-16T01:20:19-05:00",
+                "id": 666339,
+                "modifyDate": "",
+                "name": "SL02SV1414935_187_HOURLY_REP",
+                "partnershipId": "",
+                "typeId": 32,
+                "volumeId": 609491933,
+                "type": {
+                    "keyname": "REPLICATION_HOURLY"
+                }
+            },
+            "serviceResource": {
+                "backendIpAddress": "fsf-natestdal0505-ffb-fz.service.softlayer.com",
+                "id": 57365,
+                "name": "Storage Type 02 Aggregate natestdal0505-ff-d",
+                "datacenter": {
+                    "name": "dal10"
+                },
+                "type": {
+                    "type": "NETAPP_STOR_AGGR"
+                }
+            }
+        }
+    ],
+    "serviceResource": {
+        "backendIpAddress": "fsf-natestdal0505-fcb-fz.service.softlayer.com",
+        "id": 52292,
+        "name": "Storage Type 02 Aggregate natestdal0505-fc-d",
+        "attributes": [
+            {
+                "value": "2",
+                "attributeType": {
+                    "keyname": "STAAS_VERSION"
+                }
+            }
+        ],
+        "datacenter": {
+            "name": "lon02"
+        },
+        "type": {
+            "type": "NETAPP_STOR_AGGR"
+        }
+    },
+    "storageType": {
+        "keyName": "PERFORMANCE_FILE_STORAGE"
     }
+}


Test patch:
diff --git a/SoftLayer/testing/__init__.py b/SoftLayer/testing/__init__.py
index 6eff9851..b55ea2e8 100644
--- a/SoftLayer/testing/__init__.py
+++ b/SoftLayer/testing/__init__.py
@@ -111,6 +111,7 @@ def setUp(self):  # NOQA
         self.env = environment.Environment()
         self.env.client = self.client
         self.set_up()
+        self.maxDiff = None
 
     def tearDown(self):  # NOQA
         super().tearDown()
diff --git a/tests/CLI/formatting_table_tests.py b/tests/CLI/formatting_table_tests.py
index 11766707..4d62a742 100644
--- a/tests/CLI/formatting_table_tests.py
+++ b/tests/CLI/formatting_table_tests.py
@@ -4,6 +4,8 @@
 
     :license: MIT, see LICENSE for more details.
 """
+from rich.console import Console
+
 
 from SoftLayer.CLI import exceptions
 from SoftLayer.CLI import formatting
@@ -21,6 +23,48 @@ def test_boolean_table(self):
         table.add_row(["entry1"])
         self.assertTrue(table)
 
+    def test_key_value_table(self):
+        expected = """┌───────────┬─────────────────────────┐
+│    Key    │          Value          │
+├───────────┼─────────────────────────┤
+│   First   │           One           │
+│ Sub Table │ ┌─────────┬───────────┐ │
+│           │ │ Sub Key │ Sub Value │ │
+│           │ ├─────────┼───────────┤ │
+│           │ │ Second  │    Two    │ │
+│           │ └─────────┴───────────┘ │
+└───────────┴─────────────────────────┘
+"""
+        table = formatting.KeyValueTable(["Key", "Value"])
+        table.add_row(["First", "One"])
+        sub_table = formatting.KeyValueTable(["Sub Key", "Sub Value"])
+        sub_table.add_row(["Second", "Two"])
+        table.add_row(["Sub Table", sub_table])
+        console = Console()
+
+        with console.capture() as capture:
+            to_print = formatting.format_output(table)
+            console.print(to_print)
+        result = capture.get()
+        self.assertEqual(expected, result)
+
+    def test_unrenderable_recovery_table(self):
+        expected = """│ Sub Table │ [<rich.table.Table object at"""
+        table = formatting.KeyValueTable(["Key", "Value"])
+        table.add_row(["First", "One"])
+        sub_table = formatting.KeyValueTable(["Sub Key", "Sub Value"])
+        sub_table.add_row(["Second", "Two"])
+        # You can't have a list of tables, that isn't handled very well.
+        listable = [sub_table]
+        table.add_row(["Sub Table", listable])
+        console = Console()
+        with console.capture() as capture:
+            to_print = formatting.format_output(table)
+            console.print(to_print)
+        result = capture.get()
+        print(result)
+        self.assertIn(expected, result)
+
 
 class IterToTableTests(testing.TestCase):
 
diff --git a/tests/CLI/modules/block_tests.py b/tests/CLI/modules/block_tests.py
index 5a7cd7c8..d21c8dec 100644
--- a/tests/CLI/modules/block_tests.py
+++ b/tests/CLI/modules/block_tests.py
@@ -65,10 +65,9 @@ def test_volume_detail(self):
         self.assert_called_with('SoftLayer_Network_Storage', 'getObject', identifier=1234)
         self.assertEqual({
             'Username': 'username',
-            'LUN Id': '2',
-            'Notes': "{'status': 'available'}",
             'Endurance Tier': 'READHEAVY_TIER',
-            'IOPs': 1000.0,
+            'IOPs': "1000",
+            'LUN Id': 2,
             'Snapshot Capacity (GB)': '10',
             'Snapshot Used (Bytes)': 1024,
             'Capacity (GB)': '20GB',
@@ -76,24 +75,31 @@ def test_volume_detail(self):
             'Data Center': 'dal05',
             'Type': 'ENDURANCE',
             'ID': 100,
-            '# of Active Transactions': '1',
+            'Notes': "{'status': 'available'}",
+            '# of Active Transactions': 1,
             'Ongoing Transaction': 'This is a buffer time in which the customer may cancel the server',
-            'Replicant Count': '1',
-            'Replication Status': 'Replicant Volume Provisioning '
-                                  'has completed.',
-            'Replicant Volumes': [
-                {'Name': 'Replicant Id', 'Value': 1785},
-                {'Name': 'Volume Name', 'Value': 'TEST_REP_2'},
-                {'Name': 'Target IP', 'Value': '10.3.177.84'},
-                {'Name': 'Data Center', 'Value': 'dal01'},
-                {'Name': 'Schedule', 'Value': 'REPLICATION_DAILY'}],
+            'Replicant Count': 1,
+            'Replication Status': 'Replicant Volume Provisioning has completed.',
+            "Replicant Volumes": [
+                {
+                    "Id": 1784,
+                    "Username": "TEST_REP_1",
+                    "Target": "10.3.174.79",
+                    "Location": "wdc01",
+                    "Schedule": "REPLICATION_HOURLY"
+                },
+                {
+                    "Id": 1785,
+                    "Username": "TEST_REP_2",
+                    "Target": "10.3.177.84",
+                    "Location": "dal01",
+                    "Schedule": "REPLICATION_DAILY"
+                }
+            ],
             'Original Volume Properties': [
-                {'Property': 'Original Volume Size',
-                 'Value': '20'},
-                {'Property': 'Original Volume Name',
-                 'Value': 'test-original-volume-name'},
-                {'Property': 'Original Snapshot Name',
-                 'Value': 'test-original-snapshot-name'}
+                {'Property': 'Original Volume Size', 'Value': '20'},
+                {'Property': 'Original Volume Name', 'Value': 'test-original-volume-name'},
+                {'Property': 'Original Snapshot Name', 'Value': 'test-original-snapshot-name'}
             ]
         }, json.loads(result.output))
 
@@ -102,10 +108,10 @@ def test_block_detail_issue1732(self):
         lun_mock.return_value = SoftLayer_Network_Storage.BLOCK_LIST_ISSUES_1732
         result = self.run_command(['--format=table',  'block', 'volume-detail', '1234'])
         self.assert_no_fail(result)
-        self.assertIn('│                 Username │ SL02SEL307608-60                          │', result.output)
-        self.assertIn('│            Capacity (GB) │ 16000GB                                   │', result.output)
-        self.assertIn('│       Replication Status │ FAILBACK_COMPLETED                        │', result.output)
-        self.assertIn('│                    Notes │ test                                      │', result.output)
+        self.assertIn('Username │ SL02SEL307608-60', result.output)
+        self.assertIn('Capacity (GB) │ 16000GB', result.output)
+        self.assertIn('Replication Status │ FAILBACK_COMPLETED', result.output)
+        self.assertIn('Notes │ test', result.output)
 
     def test_volume_detail_name_identifier(self):
         result = self.run_command(['block', 'volume-detail', 'SL-12345'])
diff --git a/tests/CLI/modules/file_tests.py b/tests/CLI/modules/file_tests.py
index 5aafbbee..c68ac7a0 100644
--- a/tests/CLI/modules/file_tests.py
+++ b/tests/CLI/modules/file_tests.py
@@ -5,6 +5,7 @@
     :license: MIT, see LICENSE for more details.
 """
 from SoftLayer.CLI import exceptions
+from SoftLayer.fixtures import SoftLayer_Network_Storage
 from SoftLayer import SoftLayerError
 from SoftLayer import testing
 
@@ -162,11 +163,12 @@ def test_volume_detail(self):
         result = self.run_command(['file', 'volume-detail', '1234'])
 
         self.assert_no_fail(result)
+        print(result.output)
         self.assertEqual({
             'Username': 'username',
-            'Used Space': '0B',
+            'Used Space': '0.00 MB',
             'Endurance Tier': 'READHEAVY_TIER',
-            'IOPs': 1000,
+            'IOPs': "1000",
             'Mount Address': '127.0.0.1:/TEST',
             'Snapshot Capacity (GB)': '10',
             'Snapshot Used (Bytes)': 1024,
@@ -176,29 +178,30 @@ def test_volume_detail(self):
             'Type': 'ENDURANCE',
             'ID': 100,
             'Notes': "{'status': 'available'}",
-            '# of Active Transactions': '1',
+            '# of Active Transactions': 1,
             'Ongoing Transaction': 'This is a buffer time in which the customer may cancel the server',
             'Replicant Count': '1',
-            'Replication Status': 'Replicant Volume Provisioning '
-                                  'has completed.',
-            'Replicant Volumes': [[
-                {'Replicant ID': 'Volume Name', '1784': 'TEST_REP_1'},
-                {'Replicant ID': 'Target IP', '1784': '10.3.174.79'},
-                {'Replicant ID': 'Data Center', '1784': 'wdc01'},
-                {'Replicant ID': 'Schedule', '1784': 'REPLICATION_HOURLY'},
-            ], [
-                {'Replicant ID': 'Volume Name', '1785': 'TEST_REP_2'},
-                {'Replicant ID': 'Target IP', '1785': '10.3.177.84'},
-                {'Replicant ID': 'Data Center', '1785': 'dal01'},
-                {'Replicant ID': 'Schedule', '1785': 'REPLICATION_DAILY'},
-            ]],
+            'Replication Status': 'Replicant Volume Provisioning has completed.',
+            "Replicant Volumes": [
+                {
+                    "Id": 1784,
+                    "Username": "TEST_REP_1",
+                    "Target": "10.3.174.79",
+                    "Location": "wdc01",
+                    "Schedule": "REPLICATION_HOURLY"
+                },
+                {
+                    "Id": 1785,
+                    "Username": "TEST_REP_2",
+                    "Target": "10.3.177.84",
+                    "Location": "dal01",
+                    "Schedule": "REPLICATION_DAILY"
+                }
+            ],
             'Original Volume Properties': [
-                {'Property': 'Original Volume Size',
-                 'Value': '20'},
-                {'Property': 'Original Volume Name',
-                 'Value': 'test-original-volume-name'},
-                {'Property': 'Original Snapshot Name',
-                 'Value': 'test-original-snapshot-name'}
+                {'Property': 'Original Volume Size', 'Value': '20'},
+                {'Property': 'Original Volume Name', 'Value': 'test-original-volume-name'},
+                {'Property': 'Original Snapshot Name', 'Value': 'test-original-snapshot-name'}
             ]
         }, json.loads(result.output))
 
@@ -220,18 +223,22 @@ def test_volume_detail_name_identifier(self):
         self.assert_called_with('SoftLayer_Network_Storage', 'getObject', identifier=1)
         self.assert_no_fail(result)
 
+    def test_volume_detail_issues2154(self):
+        lun_mock = self.set_mock('SoftLayer_Network_Storage', 'getObject')
+        lun_mock.return_value = SoftLayer_Network_Storage.FILE_DETAIL_ISSUE2154
+        result = self.run_command(['--format=table', 'file', 'volume-detail', '1234'])
+        self.assert_no_fail(result)
+        self.assertIn("SL02SV1414935_187", result.output)
+
     def test_volume_order_performance_iops_not_given(self):
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=performance', '--size=20',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=performance', '--size=20',
                                    '--location=dal05'])
 
         self.assertEqual(2, result.exit_code)
 
     def test_volume_order_performance_snapshot_error(self):
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=performance', '--size=20',
-                                   '--iops=100', '--location=dal05',
-                                   '--snapshot-size=10',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=performance', '--size=20',
+                                   '--iops=100', '--location=dal05', '--snapshot-size=10',
                                    '--service-offering=performance'])
 
         self.assertEqual(2, result.exit_code)
@@ -250,10 +257,8 @@ def test_volume_order_performance(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=performance', '--size=20',
-                                   '--iops=100', '--location=dal05',
-                                   '--snapshot-size=10'])
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=performance', '--size=20',
+                                   '--iops=100', '--location=dal05',  '--snapshot-size=10'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
@@ -265,8 +270,7 @@ def test_volume_order_performance(self, order_mock):
                          'ready.\n')
 
     def test_volume_order_endurance_tier_not_given(self):
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=endurance', '--size=20',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=endurance', '--size=20',
                                    '--location=dal05'])
 
         self.assertEqual(2, result.exit_code)
@@ -285,10 +289,8 @@ def test_volume_order_endurance(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=endurance', '--size=20',
-                                   '--tier=0.25', '--location=dal05',
-                                   '--snapshot-size=10'])
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=endurance', '--size=20',
+                                   '--tier=0.25', '--location=dal05', '--snapshot-size=10'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
@@ -303,20 +305,17 @@ def test_volume_order_endurance(self, order_mock):
     def test_volume_order_order_not_placed(self, order_mock):
         order_mock.return_value = {}
 
-        result = self.run_command(['file', 'volume-order',
+        result = self.run_command(['--really', 'file', 'volume-order',
                                    '--storage-type=endurance', '--size=20',
                                    '--tier=0.25', '--location=dal05'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
-                         'Order could not be placed! Please verify '
-                         'your options and try again.\n')
+                         'Order could not be placed! Please verify your options and try again.\n')
 
     def test_volume_order_hourly_billing_not_available(self):
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=endurance', '--size=20',
-                                   '--tier=0.25', '--location=dal10',
-                                   '--billing=hourly',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=endurance', '--size=20',
+                                   '--tier=0.25', '--location=dal10', '--billing=hourly',
                                    '--service-offering=enterprise'])
 
         self.assertEqual(2, result.exit_code)
@@ -335,10 +334,8 @@ def test_volume_order_hourly_billing(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=endurance', '--size=20',
-                                   '--tier=0.25', '--location=dal05',
-                                   '--service-offering=storage_as_a_service',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=endurance', '--size=20',
+                                   '--tier=0.25', '--location=dal05', '--service-offering=storage_as_a_service',
                                    '--billing=hourly', '--snapshot-size=10'])
 
         self.assert_no_fail(result)
@@ -356,39 +353,35 @@ def test_volume_order_hourly_billing(self, order_mock):
     def test_volume_order_performance_manager_error(self, order_mock):
         order_mock.side_effect = ValueError('failure!')
 
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=performance', '--size=20',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=performance', '--size=20',
                                    '--iops=100', '--location=dal05'])
 
         self.assertEqual(2, result.exit_code)
+        print(result.output)
         self.assertEqual('Argument Error: failure!', result.exception.message)
 
     @mock.patch('SoftLayer.FileStorageManager.order_file_volume')
     def test_volume_order_endurance_manager_error(self, order_mock):
         order_mock.side_effect = ValueError('failure!')
 
-        result = self.run_command(['file', 'volume-order',
-                                   '--storage-type=endurance', '--size=20',
+        result = self.run_command(['--really', 'file', 'volume-order', '--storage-type=endurance', '--size=20',
                                    '--tier=0.25', '--location=dal05'])
 
         self.assertEqual(2, result.exit_code)
         self.assertEqual('Argument Error: failure!', result.exception.message)
 
     def test_enable_snapshots(self):
-        result = self.run_command(['file', 'snapshot-enable', '12345678',
-                                   '--schedule-type=HOURLY', '--minute=10',
+        result = self.run_command(['file', 'snapshot-enable', '12345678', '--schedule-type=HOURLY', '--minute=10',
                                    '--retention-count=5'])
 
         self.assert_no_fail(result)
 
     def test_disable_snapshots(self):
-        result = self.run_command(['file', 'snapshot-disable', '12345678',
-                                   '--schedule-type=HOURLY'])
+        result = self.run_command(['file', 'snapshot-disable', '12345678', '--schedule-type=HOURLY'])
         self.assert_no_fail(result)
 
     def test_list_volume_schedules(self):
-        result = self.run_command([
-            'file', 'snapshot-schedule-list', '12345678'])
+        result = self.run_command(['file', 'snapshot-schedule-list', '12345678'])
         self.assert_no_fail(result)
         self.assertEqual([
             {
@@ -457,20 +450,17 @@ def test_delete_snapshot(self):
     def test_snapshot_order_order_not_placed(self, order_mock):
         order_mock.return_value = {}
 
-        result = self.run_command(['file', 'snapshot-order', '1234',
-                                   '--capacity=10', '--tier=0.25'])
+        result = self.run_command(['--really', 'file', 'snapshot-order', '1234', '--capacity=10', '--tier=0.25'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
-                         'Order could not be placed! Please verify '
-                         'your options and try again.\n')
+                         'Order could not be placed! Please verify your options and try again.\n')
 
     @mock.patch('SoftLayer.FileStorageManager.order_snapshot_space')
     def test_snapshot_order_performance_manager_error(self, order_mock):
         order_mock.side_effect = ValueError('failure!')
 
-        result = self.run_command(['file', 'snapshot-order', '1234',
-                                   '--capacity=10', '--tier=0.25'])
+        result = self.run_command(['--really', 'file', 'snapshot-order', '1234', '--capacity=10', '--tier=0.25'])
 
         self.assertEqual(2, result.exit_code)
         self.assertEqual('Argument Error: failure!', result.exception.message)
@@ -486,8 +476,7 @@ def test_snapshot_order(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'snapshot-order', '1234',
-                                   '--capacity=10', '--tier=0.25'])
+        result = self.run_command(['--really', 'file', 'snapshot-order', '1234', '--capacity=10', '--tier=0.25'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
@@ -496,32 +485,25 @@ def test_snapshot_order(self, order_mock):
                          ' > Order status: PENDING_APPROVAL\n')
 
     def test_snapshot_cancel(self):
-        result = self.run_command(['--really',
-                                   'file', 'snapshot-cancel', '1234'])
+        result = self.run_command(['--really', 'file', 'snapshot-cancel', '1234'])
 
         self.assert_no_fail(result)
-        self.assertEqual('File volume with id 1234 has been marked'
-                         ' for snapshot cancellation\n', result.output)
-        self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
-                                args=(False, True, None))
+        self.assertEqual('File volume with id 1234 has been marked for snapshot cancellation\n', result.output)
+        self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem', args=(False, True, None))
 
     def test_replicant_failover(self):
-        result = self.run_command(['file', 'replica-failover', '12345678',
-                                   '--replicant-id=5678'])
+        result = self.run_command(['file', 'replica-failover', '12345678', '--replicant-id=5678'])
 
         self.assert_no_fail(result)
-        self.assertEqual('Failover to replicant is now in progress.\n',
-                         result.output)
+        self.assertEqual('Failover to replicant is now in progress.\n', result.output)
 
     @mock.patch('SoftLayer.FileStorageManager.failover_to_replicant')
     def test_replicant_failover_unsuccessful(self, failover_mock):
         failover_mock.return_value = False
 
-        result = self.run_command(['file', 'replica-failover', '12345678',
-                                   '--replicant-id=5678'])
+        result = self.run_command(['file', 'replica-failover', '12345678', '--replicant-id=5678'])
 
-        self.assertEqual('Failover operation could not be initiated.\n',
-                         result.output)
+        self.assertEqual('Failover operation could not be initiated.\n', result.output)
 
     @mock.patch('SoftLayer.CLI.formatting.confirm')
     @mock.patch('SoftLayer.FileStorageManager.disaster_recovery_failover_to_replicant')
@@ -537,8 +519,7 @@ def test_disaster_recovery_failover(self, disaster_recovery_failover_mock, confi
     def test_disaster_recovery_failover_aborted(self, confirm_mock):
         confirm_mock.return_value = False
 
-        result = self.run_command(['file', 'disaster-recovery-failover', '12345678',
-                                   '--replicant-id=5678'])
+        result = self.run_command(['file', 'disaster-recovery-failover', '12345678', '--replicant-id=5678'])
 
         self.assertEqual(result.exit_code, 2)
         self.assertIsInstance(result.exception, exceptions.CLIAbort)
@@ -547,8 +528,7 @@ def test_replicant_failback(self):
         result = self.run_command(['file', 'replica-failback', '12345678'])
 
         self.assert_no_fail(result)
-        self.assertEqual('Failback from replicant is now in progress.\n',
-                         result.output)
+        self.assertEqual('Failback from replicant is now in progress.\n', result.output)
 
     @mock.patch('SoftLayer.FileStorageManager.failback_from_replicant')
     def test_replicant_failback_unsuccessful(self, failback_mock):
@@ -556,21 +536,18 @@ def test_replicant_failback_unsuccessful(self, failback_mock):
 
         result = self.run_command(['file', 'replica-failback', '12345678'])
 
-        self.assertEqual('Failback operation could not be initiated.\n',
-                         result.output)
+        self.assertEqual('Failback operation could not be initiated.\n', result.output)
 
     @mock.patch('SoftLayer.FileStorageManager.order_replicant_volume')
     def test_replicant_order_order_not_placed(self, order_mock):
         order_mock.return_value = {}
 
-        result = self.run_command(['file', 'replica-order', '100',
-                                   '--snapshot-schedule=DAILY',
+        result = self.run_command(['--really', 'file', 'replica-order', '100', '--snapshot-schedule=DAILY',
                                    '--location=dal05'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
-                         'Order could not be placed! Please verify '
-                         'your options and try again.\n')
+                         'Order could not be placed! Please verify your options and try again.\n')
 
     @mock.patch('SoftLayer.FileStorageManager.order_replicant_volume')
     def test_replicant_order(self, order_mock):
@@ -588,9 +565,8 @@ def test_replicant_order(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'replica-order', '100',
-                                   '--snapshot-schedule=DAILY',
-                                   '--location=dal05', '--tier=2'])
+        result = self.run_command(['--really', 'file', 'replica-order', '100',
+                                   '--snapshot-schedule=DAILY', '--location=dal05', '--tier=2'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
@@ -605,19 +581,14 @@ def test_replicant_order(self, order_mock):
     def test_replication_locations(self):
         result = self.run_command(['file', 'replica-locations', '1234'])
         self.assert_no_fail(result)
-        self.assertEqual(
-            {
-                '12345': 'Dallas 05',
-            },
-            json.loads(result.output))
+        self.assertEqual({'12345': 'Dallas 05'}, json.loads(result.output))
 
     @mock.patch('SoftLayer.FileStorageManager.get_replication_locations')
     def test_replication_locations_unsuccessful(self, locations_mock):
         locations_mock.return_value = False
         result = self.run_command(['file', 'replica-locations', '1234'])
         self.assert_no_fail(result)
-        self.assertEqual('No data centers compatible for replication.\n',
-                         result.output)
+        self.assertEqual('No data centers compatible for replication.\n',  result.output)
 
     def test_replication_partners(self):
         result = self.run_command(['file', 'replica-partners', '1234'])
@@ -655,23 +626,19 @@ def test_replication_partners_unsuccessful(self, partners_mock):
     def test_duplicate_order_exception_caught(self, order_mock):
         order_mock.side_effect = ValueError('order attempt failed, oh noooo!')
 
-        result = self.run_command(['file', 'volume-duplicate', '100'])
+        result = self.run_command(['--really', 'file', 'volume-duplicate', '100'])
 
         self.assertEqual(2, result.exit_code)
-        self.assertEqual('Argument Error: order attempt failed, oh noooo!',
-                         result.exception.message)
+        self.assertEqual('Argument Error: order attempt failed, oh noooo!', result.exception.message)
 
     @mock.patch('SoftLayer.FileStorageManager.order_duplicate_volume')
     def test_duplicate_order_order_not_placed(self, order_mock):
         order_mock.return_value = {}
 
-        result = self.run_command(['file', 'volume-duplicate', '100',
-                                   '--duplicate-iops=1400'])
+        result = self.run_command(['--really', 'file', 'volume-duplicate', '100', '--duplicate-iops=1400'])
 
         self.assert_no_fail(result)
-        self.assertEqual(result.output,
-                         'Order could not be placed! Please verify '
-                         'your options and try again.\n')
+        self.assertEqual(result.output, 'Order could not be placed! Please verify your options and try again.\n')
 
     @mock.patch('SoftLayer.FileStorageManager.order_duplicate_volume')
     def test_duplicate_order(self, order_mock):
@@ -682,11 +649,9 @@ def test_duplicate_order(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'volume-duplicate', '100',
-                                   '--origin-snapshot-id=470',
-                                   '--duplicate-size=250',
-                                   '--duplicate-tier=2',
-                                   '--duplicate-snapshot-size=20'])
+        result = self.run_command(['--really', 'file', 'volume-duplicate', '100',
+                                   '--origin-snapshot-id=470', '--duplicate-size=250',
+                                   '--duplicate-tier=2', '--duplicate-snapshot-size=20'])
 
         self.assert_no_fail(result)
         self.assertEqual(result.output,
@@ -702,10 +667,8 @@ def test_duplicate_order_hourly_billing(self, order_mock):
             }
         }
 
-        result = self.run_command(['file', 'volume-duplicate', '100',
-                                   '--origin-snapshot-id=470',
-                                   '--duplicate-size=250',
-                                   '--duplicate-tier=2', '--billing=hourly',
+        result = self.run_command(['--really', 'file', 'volume-duplicate', '100', '--origin-snapshot-id=470',
+                                   '--duplicate-size=250', '--duplicate-tier=2', '--billing=hourly',
                                    '--duplicate-snapshot-size=20'])
 
         order_mock.assert_called_with('100', origin_snapshot_id=470,
@@ -723,7 +686,7 @@ def test_duplicate_order_hourly_billing(self, order_mock):
     def test_modify_order_exception_caught(self, order_mock):
         order_mock.side_effect = ValueError('order attempt failed, noooo!')
 
-        result = self.run_command(['file', 'volume-modify', '102', '--new-size=1000'])
+        result = self.run_command(['--really', 'file', 'volume-modify', '102', '--new-size=1000'])
 
         self.assertEqual(2, result.exit_code)
         self.assertEqual('Argument Error: order attempt failed, noooo!', result.exception.message)
@@ -732,7 +695,7 @@ def test_modify_order_exception_caught(self, order_mock):
     def test_modify_order_order_not_placed(self, order_mock):
         order_mock.return_value = {}
 
-        result = self.run_command(['file', 'volume-modify', '102', '--new-iops=1400'])
+        result = self.run_command(['--really', 'file', 'volume-modify', '102', '--new-iops=1400'])
 
         self.assert_no_fail(result)
         self.assertEqual('Order could not be placed! Please verify your options and try again.\n', result.output)
@@ -743,7 +706,7 @@ def test_modify_order(self, order_mock):
                                                                           {'description': '1000 GBs'},
                                                                           {'description': '4 IOPS per GB'}]}}
 
-        result = self.run_command(['file', 'volume-modify', '102', '--new-size=1000', '--new-tier=4'])
+        result = self.run_command(['--really', 'file', 'volume-modify', '102', '--new-size=1000', '--new-tier=4'])
 
         order_mock.assert_called_with('102', new_size=1000, new_iops=None, new_tier_level=4)
         self.assert_no_fail(result)