Fixed some tests
This commit is contained in:
Родитель
76bcf03f00
Коммит
75855cea9b
|
@ -36,6 +36,7 @@ import pkgutil
|
|||
import inspect
|
||||
import importlib
|
||||
import tempfile
|
||||
import pathlib
|
||||
from Queue import Queue
|
||||
|
||||
from api import MayaAPI as maya
|
||||
|
@ -74,8 +75,8 @@ class AzureBatchAssets(object):
|
|||
self.ui = AssetsUI(self, frame)
|
||||
self.frame = frame
|
||||
|
||||
callback.after_new(self._callback_refresh)
|
||||
callback.after_read(self._callback_refresh)
|
||||
#callback.after_new(self._callback_refresh)
|
||||
#callback.after_read(self._callback_refresh)
|
||||
|
||||
def _callback_refresh(self, *args):
|
||||
"""Called by Maya when a new scene file is loaded, so we reset
|
||||
|
@ -131,6 +132,7 @@ class AzureBatchAssets(object):
|
|||
SYS_SEARCHPATHS.append(maya.workspace(query=True, directory=True))
|
||||
SYS_SEARCHPATHS.append(os.getcwd())
|
||||
SYS_SEARCHPATHS = list(set(SYS_SEARCHPATHS))
|
||||
return SYS_SEARCHPATHS
|
||||
|
||||
def _configure_renderer(self):
|
||||
"""Configure the renderer-specific asset collection according
|
||||
|
@ -624,7 +626,7 @@ class Asset(object):
|
|||
"""Check whether this file is already represented in the current
|
||||
asset list.
|
||||
"""
|
||||
return any(f.path == self.path for f in files) #TODO: Check if this is accurate
|
||||
return any(pathlib.Path(f.path) == pathlib.Path(self.path) for f in files)
|
||||
|
||||
def restore_label(self):
|
||||
"""Restore the original UI display label after the file has been
|
||||
|
|
|
@ -44,7 +44,15 @@ MAYA_IMAGES = {
|
|||
'offer': 'autodesk-maya-arnold-win2016-preview',
|
||||
'sku': 'maya2017',
|
||||
'version': 'latest'
|
||||
}
|
||||
},
|
||||
'Batch CentOS Preview':
|
||||
{
|
||||
'node_sku_id': 'batch.node.centos 7',
|
||||
'publisher': 'batch',
|
||||
'offer': 'autodesk-maya-arnold-centos73-preview',
|
||||
'sku': 'maya2017',
|
||||
'version': 'latest'
|
||||
},
|
||||
}
|
||||
LICENSES = [
|
||||
{'label': 'Maya', 'id': 'maya', 'plugin': None },
|
||||
|
@ -71,8 +79,8 @@ class AzureBatchEnvironment(object):
|
|||
self.skus = self._load_skus()
|
||||
self.ui = EnvironmentUI(self, frame, MAYA_IMAGES.keys(), self.skus, self.licenses)
|
||||
self.refresh()
|
||||
callback.after_new(self.ui.refresh)
|
||||
callback.after_read(self.ui.refresh)
|
||||
#callback.after_new(self.ui.refresh)
|
||||
#callback.after_read(self.ui.refresh)
|
||||
|
||||
def _load_skus(self):
|
||||
"""Populate the list of availablke hardware SKUs."""
|
||||
|
|
|
@ -67,8 +67,8 @@ class AzureBatchSubmission(object):
|
|||
self.env_manager = None
|
||||
self.batch = None
|
||||
|
||||
callback.after_new(self.ui.refresh)
|
||||
callback.after_open(self.ui.refresh)
|
||||
#callback.after_new(self.ui.refresh)
|
||||
#callback.after_open(self.ui.refresh)
|
||||
|
||||
def _collect_modules(self):
|
||||
"""Collect the renderer-specific submission modules. This is where
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# coding=utf-8
|
||||
# --------------------------------------------------------------------------
|
||||
#!/usr/bin/env python
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for
|
||||
# license information.
|
||||
# --------------------------------------------------------------------------
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -15,8 +15,6 @@ import re
|
|||
|
||||
batch_client = None
|
||||
storage_client = None
|
||||
is_thumnail = re.compile("framethumb_[\d\-]+.png")
|
||||
is_log = re.compile("frame_[\d\-]+.log")
|
||||
|
||||
|
||||
def header(header):
|
||||
|
@ -40,6 +38,7 @@ def _check_valid_dir(directory):
|
|||
except (TypeError, EnvironmentError) as exp:
|
||||
raise RuntimeError(exp)
|
||||
|
||||
|
||||
def _download_output(container, blob_name, output_path, size):
|
||||
def progress(data, total):
|
||||
try:
|
||||
|
@ -54,73 +53,61 @@ def _download_output(container, blob_name, output_path, size):
|
|||
storage_client.get_blob_to_path(container, blob_name, output_path, progress_callback=progress)
|
||||
print(" Output download successful.\n")
|
||||
|
||||
def _track_completed_tasks(container, dwnld_dir):
|
||||
try:
|
||||
job_outputs = storage_client.list_blobs(container)
|
||||
for output in job_outputs:
|
||||
if output.name.startswith('thumbs/'):
|
||||
continue
|
||||
elif is_log.match(output.name):
|
||||
output_file = os.path.join(dwnld_dir, "logs", output.name)
|
||||
else:
|
||||
output_file = os.path.join(dwnld_dir, output.name)
|
||||
|
||||
if not os.path.isfile(output_file):
|
||||
_download_output(container, output.name, output_file, output.properties.content_length)
|
||||
|
||||
except (TypeError, AttributeError, KeyError) as exp:
|
||||
raise RuntimeError("Failed {0}".format(exp))
|
||||
def _track_completed_outputs(container, dwnld_dir):
|
||||
job_outputs = storage_client.list_blobs(container)
|
||||
for output in job_outputs:
|
||||
if output.name.startswith('thumbs/'):
|
||||
continue
|
||||
else:
|
||||
output_file = os.path.normpath(os.path.join(dwnld_dir, output.name))
|
||||
if not os.path.isfile(output_file):
|
||||
if not os.path.isdir(os.path.dirname(output_file)):
|
||||
os.makedirs(os.path.dirname(output_file))
|
||||
_download_output(container, output.name, output_file, output.properties.content_length)
|
||||
|
||||
|
||||
def _check_job_stopped(job):
|
||||
"""Checks job for failure or completion.
|
||||
:returns: A boolean indicating True if the job completed, or False if still in
|
||||
progress.
|
||||
:raises: RuntimeError if the job has failed, or been cancelled.
|
||||
"""
|
||||
Checks job for failure or completion.
|
||||
|
||||
:Args:
|
||||
- job (:class:`batchapps.SubmittedJob`): an instance of the current
|
||||
SubmittedJob object.
|
||||
|
||||
:Returns:
|
||||
- A boolean indicating True if the job completed, or False if still in
|
||||
progress.
|
||||
:Raises:
|
||||
- RuntimeError if the job has failed, or been cancelled.
|
||||
"""
|
||||
|
||||
from azure.batch.models import JobState
|
||||
stopped_status = [
|
||||
batch.models.JobState.disabling,
|
||||
batch.models.JobState.disabled,
|
||||
batch.models.JobState.terminating,
|
||||
batch.models.JobState.deleting
|
||||
]
|
||||
JobState.disabling,
|
||||
JobState.disabled,
|
||||
JobState.terminating,
|
||||
JobState.deleting
|
||||
]
|
||||
running_status = [
|
||||
batch.models.JobState.active,
|
||||
batch.models.JobState.enabling
|
||||
]
|
||||
|
||||
JobState.active,
|
||||
JobState.enabling
|
||||
]
|
||||
try:
|
||||
if job.state in stopped_status:
|
||||
print(header("Job has stopped"))
|
||||
print("Job status: {0}".format(job.state))
|
||||
raise RuntimeError("Job is no longer running. Status: {0}".format(job.state))
|
||||
|
||||
elif job.state == batch.models.JobState.completed:
|
||||
elif job.state == JobState.completed:
|
||||
print(header("Job has completed"))
|
||||
return True
|
||||
|
||||
elif job.state in running_status:
|
||||
return False
|
||||
|
||||
else:
|
||||
raise RuntimeError("Job state invalid: {}".format(job.state))
|
||||
except AttributeError as exp:
|
||||
raise RuntimeError(exp)
|
||||
|
||||
|
||||
def track_job_progress(id, container, dwnld_dir):
|
||||
from azure.batch.models import TaskState
|
||||
print("Tracking job with ID: {0}".format(id))
|
||||
try:
|
||||
job = batch_client.job.get(id)
|
||||
tasks = [t for t in batch_client.task.list(id)]
|
||||
while True:
|
||||
completed_tasks = [t for t in tasks if t.state == batch.models.TaskState.completed]
|
||||
completed_tasks = [t for t in tasks if t.state == TaskState.completed]
|
||||
errored_tasks = [t for t in completed_tasks if t.execution_info.exit_code != 0]
|
||||
if len(tasks) == 0:
|
||||
percentage = 0
|
||||
|
@ -130,19 +117,17 @@ def track_job_progress(id, container, dwnld_dir):
|
|||
if errored_tasks:
|
||||
print(" - Warning: some tasks have completed with a non-zero exit code.")
|
||||
|
||||
_track_completed_tasks(container, dwnld_dir)
|
||||
_track_completed_outputs(container, dwnld_dir)
|
||||
if _check_job_stopped(job):
|
||||
return # Job complete
|
||||
|
||||
time.sleep(10)
|
||||
job = batch_client.job.get(id)
|
||||
tasks = [t for t in batch_client.task.list(id)]
|
||||
|
||||
except (TypeError, AttributeError) as exp:
|
||||
raise RuntimeError("Error occured: {0}".format(exp))
|
||||
except KeyboardInterrupt:
|
||||
raise RuntimeError("Monitoring aborted.")
|
||||
|
||||
|
||||
def _authenticate(cfg_path):
|
||||
global batch_client, storage_client
|
||||
cfg = ConfigParser.ConfigParser()
|
||||
|
@ -160,6 +145,7 @@ def _authenticate(cfg_path):
|
|||
except (EnvironmentError, ConfigParser.NoOptionError, ConfigParser.NoSectionError) as exp:
|
||||
raise ValueError("Failed to authenticate using Maya configuration {0}".format(cfg_path))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
sys.path.append(sys.argv[5])
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
"description": "The SAS URL to a pre-render asset path redirection script"
|
||||
}
|
||||
},
|
||||
"thumbScript": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The SAS URL to the thumbnail generation script"
|
||||
}
|
||||
},
|
||||
"frameStart": {
|
||||
"type": "int",
|
||||
"metadata": {
|
||||
|
@ -72,6 +78,10 @@
|
|||
{
|
||||
"blobSource": "[parameters('assetScript')]",
|
||||
"filePath": "scripts/renderPrep.mel"
|
||||
},
|
||||
{
|
||||
"blobSource": "[parameters('thumbScript')]",
|
||||
"filePath": "thumbnail.py"
|
||||
}
|
||||
],
|
||||
"commandLine": "dir"
|
||||
|
@ -87,7 +97,7 @@
|
|||
],
|
||||
"repeatTask": {
|
||||
"displayName": "Frame {0}",
|
||||
"commandLine": "mkdir /X;mount -rbind $AZ_BATCH_JOB_PREP_WORKING_DIR/assets /X;render -renderer \"[parameters('renderer')]\" -verb -preRender \"renderPrep\" -rd \"$AZ_BATCH_TASK_WORKING_DIR/images\" -s {0} -e {0} \"[parameters('sceneFile')]\"",
|
||||
"commandLine": "mkdir /X;mount -rbind $AZ_BATCH_JOB_PREP_WORKING_DIR/assets /X;render -renderer [parameters('renderer')] -verb -preRender renderPrep -rd \"$AZ_BATCH_TASK_WORKING_DIR/images\" -s {0} -e {0} \"[parameters('sceneFile')]\";err=$?;$AZ_BATCH_JOB_PREP_WORKING_DIR/thumbnail.py $err;exit $err",
|
||||
"environmentSettings": [
|
||||
{
|
||||
"name": "MAYA_SCRIPT_PATH",
|
||||
|
@ -110,6 +120,18 @@
|
|||
"uploadCondition": "taskSuccess"
|
||||
}
|
||||
},
|
||||
{
|
||||
"filePattern": "thumbs/*.png",
|
||||
"destination": {
|
||||
"autoStorage": {
|
||||
"fileGroup": "[parameters('outputs')]",
|
||||
"path": "thumbs"
|
||||
}
|
||||
},
|
||||
"uploadOptions": {
|
||||
"uploadCondition": "taskSuccess"
|
||||
}
|
||||
},
|
||||
{
|
||||
"filePattern": "../stdout.txt",
|
||||
"destination": {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pathlib==1.0.1
|
||||
azure-mgmt-batch==4.0.0
|
||||
azure-mgmt-batch==3.0.0
|
||||
azure-mgmt-storage==1.0.0rc1
|
||||
azure-batch==3.0.0
|
||||
azure-batch==2.0.1
|
||||
azure-storage==0.32.0
|
||||
mock=2.0.0
|
|
@ -1,6 +1,6 @@
|
|||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Batch Apps Maya Plugin
|
||||
# Azure Batch Maya Plugin
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Batch Apps Maya Plugin
|
||||
# Azure Batch Maya Plugin
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#
|
||||
|
@ -31,6 +31,7 @@ import sys
|
|||
import os
|
||||
import logging
|
||||
import json
|
||||
from Queue import Queue
|
||||
|
||||
try:
|
||||
import unittest2 as unittest
|
||||
|
@ -41,6 +42,8 @@ try:
|
|||
except ImportError:
|
||||
import mock
|
||||
|
||||
import batch_extensions
|
||||
|
||||
from ui_assets import AssetsUI
|
||||
from assets import Asset, Assets, AzureBatchAssets
|
||||
from exception import FileUploadException
|
||||
|
@ -50,53 +53,53 @@ class TestAsset(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(Asset)
|
||||
self.mock_file = mock.create_autospec(UserFile)
|
||||
self.mock_file.path = "/my/test_path"
|
||||
self.mock_file = "/my/local/test_path"
|
||||
self.mock_self.batch = mock.create_autospec(batch_extensions.BatchExtensionsClient)
|
||||
self.mock_self.batch.file = mock.create_autospec(batch_extensions.operations.ExtendedFileOperations)
|
||||
self.mock_self.log = logging.getLogger('batch-maya-asset-tests')
|
||||
return super(TestAsset, self).setUp()
|
||||
|
||||
def test_create_asset(self):
|
||||
|
||||
self.mock_file._exist = True
|
||||
self.mock_file.__bool__.return_value = True
|
||||
|
||||
test_asset = Asset(self.mock_file, None)
|
||||
def test_asset_create(self):
|
||||
test_asset = Asset(self.mock_file, "parent", "batch")
|
||||
self.assertEqual(test_asset.label, " test_path")
|
||||
self.assertEqual(test_asset.path, "/my/test_path")
|
||||
self.assertEqual(test_asset.note, "Can't find /my/test_path")
|
||||
self.assertEqual(test_asset.path, "\\my\\local\\test_path")
|
||||
self.assertEqual(test_asset.note, "Can't find \\my\\local\\test_path")
|
||||
self.assertFalse(test_asset.exists)
|
||||
|
||||
self.mock_file.__bool__.return_value = True
|
||||
test_asset = Asset(self.mock_file, None)
|
||||
#self.assertEqual(test_asset.note, "/test_path")
|
||||
with mock.patch.object(os.path, 'exists') as exist:
|
||||
with mock.patch.object(os.path, 'getmtime') as mod:
|
||||
with mock.patch.object(os.path, 'getsize'):
|
||||
exist.return_value = True
|
||||
mod.return_value = 1453766301
|
||||
test_asset = Asset(self.mock_file, "parent", "batch")
|
||||
self.assertEqual(test_asset.note, "\\my\\local\\test_path")
|
||||
self.assertTrue(test_asset.exists)
|
||||
self.assertEqual(test_asset.pathmap['\\my\\local']('Linux'), 'my/local')
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_display(self, mock_api):
|
||||
|
||||
self.mock_self.file = self.mock_file
|
||||
def test_asset_display(self, mock_api):
|
||||
self.mock_self.path = "\\my\\local\\test_path"
|
||||
self.mock_self.label = "label"
|
||||
self.mock_self.note = "note"
|
||||
self.mock_self.exists = False
|
||||
|
||||
Asset.display(self.mock_self, "ui", "layout", "scroll")
|
||||
mock_api.symbol_button.assert_called_with(image="fpe_someBrokenPaths.png",
|
||||
parent="layout",
|
||||
command=mock.ANY,
|
||||
height=17,
|
||||
annotation="Add search path")
|
||||
mock_api.symbol_button.assert_called_with(
|
||||
image="fpe_someBrokenPaths.png", parent="layout", command=mock.ANY,
|
||||
height=17, annotation="Add search path")
|
||||
mock_api.text.assert_called_with("label", parent="layout", enable=False, annotation="note", align="left")
|
||||
self.assertEqual(self.mock_self.scroll_layout, "scroll")
|
||||
self.assertEqual(self.mock_self.frame, "ui")
|
||||
|
||||
self.mock_self.file = None
|
||||
self.mock_self.exists = True
|
||||
Asset.display(self.mock_self, "ui", "layout", "scroll")
|
||||
mock_api.symbol_button.assert_called_with(image='fpe_someBrokenPaths.png',
|
||||
parent="layout",
|
||||
command=mock.ANY,
|
||||
height=17,
|
||||
annotation="Add search path")
|
||||
mock_api.symbol_check_box.assert_called_with(
|
||||
annotation='Click to remove asset from submission', offCommand=mock.ANY,
|
||||
onCommand=mock.ANY, parent='layout', value=True)
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_included(self, mock_api):
|
||||
|
||||
self.mock_self.file = self.mock_file
|
||||
def test_asset_included(self, mock_api):
|
||||
self.mock_self.exists = False
|
||||
self.mock_self.check_box = None
|
||||
|
||||
val = Asset.included(self.mock_self)
|
||||
|
@ -106,13 +109,12 @@ class TestAsset(unittest.TestCase):
|
|||
val = Asset.included(self.mock_self)
|
||||
self.assertFalse(val)
|
||||
|
||||
self.mock_self.file = "True"
|
||||
self.mock_self.exists = True
|
||||
val = Asset.included(self.mock_self)
|
||||
mock_api.symbol_check_box.assert_called_with(1, query=True, value=True)
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_include(self, mock_api):
|
||||
|
||||
def test_asset_include(self, mock_api):
|
||||
self.mock_self.check_box = 1
|
||||
self.mock_self.parent_list = []
|
||||
Asset.include(self.mock_self)
|
||||
|
@ -124,9 +126,8 @@ class TestAsset(unittest.TestCase):
|
|||
mock_api.symbol_check_box.assert_called_with(1, edit=True, annotation="Click to remove asset from submission")
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_search(self, mock_api):
|
||||
def test_asset_search(self, mock_api):
|
||||
from assets import USR_SEARCHPATHS
|
||||
|
||||
self.mock_self.frame = mock.create_autospec(AssetsUI)
|
||||
mock_api.file_select.return_value = None
|
||||
Asset.search(self.mock_self)
|
||||
|
@ -144,8 +145,7 @@ class TestAsset(unittest.TestCase):
|
|||
self.mock_self.frame.refresh.assert_called_with()
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_exclude(self, mock_api):
|
||||
|
||||
def test_asset_exclude(self, mock_api):
|
||||
self.mock_self.check_box = 1
|
||||
self.mock_self.parent_list = []
|
||||
Asset.exclude(self.mock_self)
|
||||
|
@ -163,8 +163,7 @@ class TestAsset(unittest.TestCase):
|
|||
mock_api.symbol_check_box.assert_called_with(1, edit=True, annotation="Click to include asset in submission")
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_delete(self, mock_api):
|
||||
|
||||
def test_asset_delete(self, mock_api):
|
||||
self.mock_self.parent_list = []
|
||||
self.mock_self.check_box = 1
|
||||
|
||||
|
@ -177,9 +176,8 @@ class TestAsset(unittest.TestCase):
|
|||
mock_api.delete_ui.assert_called_with(1, control=True)
|
||||
self.assertEqual(self.mock_self.parent_list, [])
|
||||
|
||||
def test_check(self):
|
||||
|
||||
new_file = mock.create_autospec(UserFile)
|
||||
def test_asset_check(self):
|
||||
new_file = mock.create_autospec(Asset)
|
||||
new_file.path = "C:\\TEST_file\\WeiRD_path"
|
||||
self.mock_self.path = "c:\\test_file\\Weird_path"
|
||||
|
||||
|
@ -191,8 +189,7 @@ class TestAsset(unittest.TestCase):
|
|||
self.assertFalse(check)
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_make_visible(self, mock_maya):
|
||||
|
||||
def test_asset_make_visible(self, mock_maya):
|
||||
mock_maya.text.return_value = 17
|
||||
self.mock_self.scroll_layout = "layout"
|
||||
self.mock_self.display_text = "text"
|
||||
|
@ -202,10 +199,8 @@ class TestAsset(unittest.TestCase):
|
|||
self.called += 1
|
||||
if kwargs.get("query") and self.mock_self.scroll_layout == "layout":
|
||||
return [4,0]
|
||||
|
||||
elif kwargs.get("query"):
|
||||
return [0,0]
|
||||
|
||||
else:
|
||||
self.assertEqual(kwargs.get("scrollPage"), "up")
|
||||
self.mock_self.scroll_layout = "scrolled"
|
||||
|
@ -223,29 +218,29 @@ class TestAsset(unittest.TestCase):
|
|||
self.assertEqual(self.called, 4)
|
||||
|
||||
@mock.patch("assets.maya")
|
||||
def test_upload(self, mock_maya):
|
||||
def test_asset_upload(self, mock_maya):
|
||||
|
||||
queue = Queue()
|
||||
self.mock_self.path = "/my/test/path/file.txt"
|
||||
self.mock_self.display_text = "display"
|
||||
self.mock_self.file = mock.create_autospec(UserFile)
|
||||
self.mock_self.file.upload.return_value = mock.Mock(success=True)
|
||||
self.mock_self.included.return_value = False
|
||||
self.mock_self.storage_path = "my/test/path/file.txt"
|
||||
self.mock_self.size = 10
|
||||
prog = mock.create_autospec(ProgressBar)
|
||||
prog.done = False
|
||||
|
||||
Asset.upload(self.mock_self, 0, prog, True)
|
||||
self.mock_self.file.upload.assert_called_with(force=True, callback=mock.ANY, block=100000)
|
||||
self.assertEqual(mock_maya.text.call_count, 0)
|
||||
Asset.upload(self.mock_self, 0, prog, queue, "container")
|
||||
self.mock_self.batch.file.upload.assert_called_with(
|
||||
"/my/test/path/file.txt", "container", "my/test/path/file.txt", progress_callback=mock.ANY)
|
||||
self.assertEqual(queue.qsize(), 7)
|
||||
|
||||
self.mock_self.file.upload.return_value = mock.Mock(success=False)
|
||||
with self.assertRaises(FileUploadException):
|
||||
Asset.upload(self.mock_self, 0, prog, True)
|
||||
self.mock_self.batch.file.upload.side_effect = ValueError('boom')
|
||||
Asset.upload(self.mock_self, 0, prog, queue, "container")
|
||||
self.assertEqual(queue.qsize(), 13)
|
||||
|
||||
Asset.upload(self.mock_self, 0, prog, False)
|
||||
mock_maya.text.assert_called_with("display", edit=True, label=" Skipped file.txt")
|
||||
|
||||
self.mock_self.included.return_value = True
|
||||
Asset.upload(self.mock_self, 0, prog, False)
|
||||
mock_maya.text.assert_called_with("display", edit=True, label=" Already uploaded file.txt")
|
||||
prog.done = True
|
||||
Asset.upload(self.mock_self, 0, prog, queue, "container")
|
||||
self.assertEqual(queue.qsize(), 14)
|
||||
|
||||
|
||||
class TestAssets(unittest.TestCase):
|
||||
|
@ -253,111 +248,102 @@ class TestAssets(unittest.TestCase):
|
|||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(Assets)
|
||||
self.mock_self._log = logging.getLogger("TestAssets")
|
||||
self.mock_self.batch = mock.create_autospec(batch_extensions.BatchExtensionsClient)
|
||||
return super(TestAssets, self).setUp()
|
||||
|
||||
def test_create_assets(self):
|
||||
|
||||
test_assets = Assets()
|
||||
self.assertIsNone(test_assets.manager)
|
||||
self.assertEqual(test_assets.refs, {'Additional':[]})
|
||||
def test_assets_create(self):
|
||||
test_assets = Assets('batch')
|
||||
self.assertEqual(test_assets.batch, 'batch')
|
||||
self.assertEqual(test_assets.refs, [])
|
||||
|
||||
@mock.patch("assets.SYS_SEARCHPATHS")
|
||||
@mock.patch("assets.USR_SEARCHPATHS")
|
||||
@mock.patch("assets.glob")
|
||||
@mock.patch("assets.os.path.exists")
|
||||
def test_search_path(self, mock_exists, mock_glob, mock_sys, mock_usr):
|
||||
|
||||
def test_assets_search_path(self, mock_exists, mock_glob, mock_sys, mock_usr):
|
||||
mock_sys = []
|
||||
mock_usr = []
|
||||
self.mock_self.pathmaps = []
|
||||
self.mock_self.pathmaps = {}
|
||||
mock_exists.return_value = True
|
||||
|
||||
path = Assets.search_path(self.mock_self, "testpath\\testfile")
|
||||
path = Assets._search_path(self.mock_self, "testpath\\testfile")
|
||||
self.assertEqual(path, ["testpath\\testfile"])
|
||||
mock_exists.assert_called_once_with("testpath\\testfile")
|
||||
mock_exists.call_count = 0
|
||||
self.assertEqual(mock_glob.glob.call_count, 0)
|
||||
|
||||
mock_exists.return_value = False
|
||||
path = Assets.search_path(self.mock_self, "testpath\\testfile")
|
||||
path = Assets._search_path(self.mock_self, "testpath\\testfile")
|
||||
self.assertEqual(path, ["testpath\\testfile"])
|
||||
mock_exists.assert_called_once_with("testpath\\testfile")
|
||||
self.assertEqual(mock_glob.glob.call_count, 0)
|
||||
|
||||
mock_glob.glob.return_value = [1,2,3]
|
||||
path = Assets.search_path(self.mock_self, "testpath\\*\\testfile")
|
||||
path = Assets._search_path(self.mock_self, "testpath\\*\\testfile")
|
||||
mock_glob.glob.assert_called_with("testpath\\*\\testfile")
|
||||
self.assertEqual(path, [1,2,3])
|
||||
|
||||
mock_glob.glob.return_value = []
|
||||
path = Assets.search_path(self.mock_self, "testpath\\[0-9]testfile")
|
||||
path = Assets._search_path(self.mock_self, "testpath\\[0-9]testfile")
|
||||
mock_glob.glob.assert_any_call("testpath\\[0-9]testfile")
|
||||
self.assertEqual(path, ["testpath\\[0-9]testfile"])
|
||||
|
||||
def test_assets_gather(self):
|
||||
self.mock_self.refs = []
|
||||
self.mock_self._get_textures.return_value = ['a']
|
||||
self.mock_self._get_caches.return_value = ['b']
|
||||
self.mock_self._get_references.return_value = ['c']
|
||||
|
||||
def test_gather(self):
|
||||
|
||||
self.mock_self.refs = {}
|
||||
self.mock_self.get_textures.return_value = {'a':1}
|
||||
self.mock_self.get_caches.return_value = {'b':2}
|
||||
self.mock_self.get_references.return_value = {'c':3}
|
||||
|
||||
Assets.gather(self.mock_self, "manager")
|
||||
self.assertEqual(self.mock_self.refs, {'a':1, 'b':2, 'c':3, 'Additional':[]})
|
||||
self.assertEqual(self.mock_self.manager, "manager")
|
||||
|
||||
self.assertEqual(self.mock_self.get_textures.call_count, 1)
|
||||
self.assertEqual(self.mock_self.get_caches.call_count, 1)
|
||||
self.assertEqual(self.mock_self.get_references.call_count, 1)
|
||||
Assets.gather(self.mock_self)
|
||||
self.assertEqual(self.mock_self.refs, ['a', 'b', 'c'])
|
||||
self.assertEqual(self.mock_self._get_textures.call_count, 1)
|
||||
self.assertEqual(self.mock_self._get_caches.call_count, 1)
|
||||
self.assertEqual(self.mock_self._get_references.call_count, 1)
|
||||
|
||||
@mock.patch("assets.Asset")
|
||||
def test_extend(self, mock_asset):
|
||||
|
||||
self.mock_self.refs = {}
|
||||
|
||||
self.mock_self.manager = mock.create_autospec(FileManager)
|
||||
def test_assets_extend(self, mock_asset):
|
||||
self.mock_self.refs = []
|
||||
mock_asset.return_value = mock.create_autospec(Asset)
|
||||
mock_asset.return_value.is_duplicate.return_value = True
|
||||
self.mock_self.manager.file_from_path.return_value = "UserFile"
|
||||
self.mock_self.search_path.return_value = ["a"]
|
||||
self.mock_self._search_path.return_value = ["a"]
|
||||
|
||||
Assets.extend(self.mock_self, {"new_path":["/test_path/test_file"]})
|
||||
mock_asset.assert_called_with("UserFile", [])
|
||||
self.assertEqual(self.mock_self.refs, {"new_path": []})
|
||||
Assets.extend(self.mock_self, ["/test_path/test_file"])
|
||||
mock_asset.assert_called_with("a", [], self.mock_self.batch, self.mock_self._log)
|
||||
self.assertEqual(self.mock_self.refs, [])
|
||||
|
||||
mock_asset.return_value.is_duplicate.return_value = False
|
||||
Assets.extend(self.mock_self, {"new_path":["/test_path/test_file"]})
|
||||
self.assertEqual(self.mock_self.refs, {"new_path": [mock.ANY]})
|
||||
Assets.extend(self.mock_self, ["/test_path/test_file"])
|
||||
self.assertEqual(self.mock_self.refs, [mock.ANY])
|
||||
|
||||
self.mock_self.refs = []
|
||||
mock_asset.side_effect = Exception("error!")
|
||||
Assets.extend(self.mock_self, {"new_path":["/test_path/test_file"]})
|
||||
self.assertEqual(self.mock_self.refs, {"new_path": []})
|
||||
Assets.extend(self.mock_self, ["/test_path/test_file"])
|
||||
self.assertEqual(self.mock_self.refs, [])
|
||||
|
||||
def test_collect(self):
|
||||
|
||||
self.mock_self.refs = {}
|
||||
def test_assets_collect(self):
|
||||
self.mock_self.refs = []
|
||||
files = Assets.collect(self.mock_self)
|
||||
self.assertEqual(files, [])
|
||||
|
||||
test_file = mock.create_autospec(Asset)
|
||||
test_file.file = "my_test_file"
|
||||
self.mock_self.refs["Test1"] = [test_file]
|
||||
test_file.included.return_value = True
|
||||
self.mock_self.refs = [test_file]
|
||||
files = Assets.collect(self.mock_self)
|
||||
test_file.included.assert_called_once_with()
|
||||
self.assertEqual(files, ["my_test_file"])
|
||||
self.assertEqual(files, [test_file])
|
||||
|
||||
test_file.included.return_value = False
|
||||
files = Assets.collect(self.mock_self)
|
||||
self.assertEqual(files, [])
|
||||
|
||||
@mock.patch("assets.Asset")
|
||||
@mock.patch("assets.maya")
|
||||
def test_get_textures(self, mock_maya, mock_asset):
|
||||
|
||||
self.mock_self.manager = mock.create_autospec(FileManager)
|
||||
def test_assets_get_textures(self, mock_maya, mock_asset):
|
||||
mock_asset.return_value = mock.create_autospec(Asset)
|
||||
mock_asset.return_value.is_duplicate.return_value = True
|
||||
self.mock_self.manager.file_from_path.return_value = "UserFile"
|
||||
self.mock_self.search_path.return_value = ["a"]
|
||||
self.mock_self._search_path.return_value = ["a"]
|
||||
|
||||
class TestIter(object):
|
||||
|
||||
def __init__(self):
|
||||
self.current = None
|
||||
self.itr = iter(range(0,5))
|
||||
|
@ -373,364 +359,194 @@ class TestAssets(unittest.TestCase):
|
|||
return ["dir1/1", "dir2/2", "dir3/3"]
|
||||
|
||||
mock_maya.dependency_nodes.return_value = TestIter()
|
||||
tex = Assets.get_textures(self.mock_self)
|
||||
self.assertEqual(tex, {'Files': []})
|
||||
tex = Assets._get_textures(self.mock_self)
|
||||
self.assertEqual(tex, [])
|
||||
self.assertEqual(mock_asset.call_count, 15)
|
||||
mock_asset.assert_called_with("UserFile", [])
|
||||
mock_asset.assert_called_with("a", [], self.mock_self.batch, self.mock_self._log)
|
||||
|
||||
mock_asset.return_value.is_duplicate.return_value = False
|
||||
mock_maya.dependency_nodes.return_value = TestIter()
|
||||
tex = Assets.get_textures(self.mock_self)
|
||||
self.assertEqual(len(tex['Files']), 15)
|
||||
tex = Assets._get_textures(self.mock_self)
|
||||
self.assertEqual(len(tex), 15)
|
||||
|
||||
@mock.patch("assets.Asset")
|
||||
@mock.patch("assets.maya")
|
||||
def test_get_references(self, mock_maya, mock_asset):
|
||||
|
||||
self.mock_self.manager = mock.create_autospec(FileManager)
|
||||
def test_assets_get_references(self, mock_maya, mock_asset):
|
||||
mock_asset.return_value = mock.create_autospec(Asset)
|
||||
mock_asset.return_value.is_duplicate.return_value = True
|
||||
self.mock_self.manager.file_from_path.return_value = "UserFile"
|
||||
self.mock_self.pathmaps = []
|
||||
self.mock_self.refs = {'Files':[]}
|
||||
self.mock_self.refs = []
|
||||
|
||||
refs = Assets.get_references(self.mock_self)
|
||||
self.assertEqual(refs, {'References':[]})
|
||||
refs = Assets._get_references(self.mock_self)
|
||||
self.assertEqual(refs, [])
|
||||
|
||||
mock_maya.get_list.return_value = ["1", "2", "3"]
|
||||
mock_maya.reference.return_value = "c:\\file\\ref"
|
||||
refs = Assets.get_references(self.mock_self)
|
||||
self.assertEqual(refs, {'References':[]})
|
||||
self.assertEqual(set(self.mock_self.pathmaps), set(["c:\\file"]))
|
||||
refs = Assets._get_references(self.mock_self)
|
||||
self.assertEqual(refs, [])
|
||||
|
||||
mock_asset.return_value.is_duplicate.return_value = False
|
||||
refs = Assets.get_references(self.mock_self)
|
||||
self.assertEqual(refs, {'References':[mock.ANY]})
|
||||
refs = Assets._get_references(self.mock_self)
|
||||
self.assertEqual(refs, [mock.ANY])
|
||||
|
||||
@mock.patch("assets.Asset")
|
||||
@mock.patch("assets.maya")
|
||||
@mock.patch("assets.glob")
|
||||
def test_get_caches(self, mock_glob, mock_maya, mock_asset):
|
||||
|
||||
def test_assets_get_caches(self, mock_glob, mock_maya, mock_asset):
|
||||
def get_attr(node):
|
||||
if node.endswith("cachePath"):
|
||||
return "/test_path"
|
||||
else:
|
||||
return "test_file"
|
||||
|
||||
self.mock_self.pathmaps = []
|
||||
self.mock_self.manager = mock.create_autospec(FileManager)
|
||||
mock_asset.return_value = mock.create_autospec(Asset)
|
||||
mock_maya.get_list.return_value = ["1", "2", "3"]
|
||||
mock_maya.get_attr = get_attr
|
||||
mock_glob.glob.return_value = ["pathA"]
|
||||
self.mock_self.manager.file_from_path.return_value = "UserFile"
|
||||
|
||||
caches = Assets.get_caches(self.mock_self)
|
||||
self.assertEqual(caches, {'Caches': [mock.ANY, mock.ANY, mock.ANY]})
|
||||
self.assertEqual(set(self.mock_self.pathmaps), set(["/test_path"]))
|
||||
caches = Assets._get_caches(self.mock_self)
|
||||
self.assertEqual(caches, [mock.ANY, mock.ANY, mock.ANY])
|
||||
|
||||
@mock.patch("assets.Asset")
|
||||
def test_add_asset(self, mock_asset):
|
||||
|
||||
self.mock_self.pathmaps = []
|
||||
self.mock_self.refs = {'Additional':[]}
|
||||
self.mock_self.manager = mock.create_autospec(FileManager)
|
||||
def test_assets_add_asset(self, mock_asset):
|
||||
self.mock_self.refs = []
|
||||
mock_asset.return_value = mock.create_autospec(Asset)
|
||||
mock_asset.return_value.is_duplicate.return_value = True
|
||||
self.mock_self.manager.file_from_path.return_value = "UserFile"
|
||||
|
||||
Assets.add_asset(self.mock_self, "/test_path/my_asset", "ui", ("layout", "scroll"))
|
||||
self.assertEqual(self.mock_self.pathmaps, ["/test_path"])
|
||||
self.assertEqual(self.mock_self.refs, {'Additional':[]})
|
||||
Assets.add_asset(self.mock_self, "/test_path/my_asset", "ui", "layout", "scroll")
|
||||
self.assertEqual(self.mock_self.refs, [])
|
||||
mock_asset.return_value.is_duplicate.assert_called_once_with([])
|
||||
mock_asset.assert_called_once_with("UserFile", [])
|
||||
mock_asset.assert_called_once_with("/test_path/my_asset", [], self.mock_self.batch, self.mock_self._log)
|
||||
|
||||
mock_asset.return_value.is_duplicate.return_value = False
|
||||
Assets.add_asset(self.mock_self, "/test_path/my_asset", "ui", ("layout", "scroll"))
|
||||
self.assertEqual(self.mock_self.refs, {'Additional':[mock.ANY]})
|
||||
Assets.add_asset(self.mock_self, "/test_path/my_asset", "ui", "layout", "scroll")
|
||||
self.assertEqual(self.mock_self.refs, [mock.ANY])
|
||||
mock_asset.return_value.display.assert_called_with("ui", "layout", "scroll")
|
||||
|
||||
def test_get_pathmaps(self):
|
||||
|
||||
self.mock_self.pathmaps = []
|
||||
maps = Assets.get_pathmaps(self.mock_self)
|
||||
self.assertEqual(maps, {"PathMaps": []})
|
||||
|
||||
self.mock_self.pathmaps = ["test", "", "test", None, 0, 5, "", "test"]
|
||||
maps = Assets.get_pathmaps(self.mock_self)
|
||||
self.assertEqual(maps, {"PathMaps": ["test", "5"]})
|
||||
|
||||
|
||||
class TestBatchAppsAssets(unittest.TestCase):
|
||||
class TestAzureBatchAssets(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(BatchAppsAssets)
|
||||
self.mock_self = mock.create_autospec(AzureBatchAssets)
|
||||
self.mock_self._log = logging.getLogger("TestAssets")
|
||||
return super(TestBatchAppsAssets, self).setUp()
|
||||
self.mock_self.batch = mock.create_autospec(batch_extensions.BatchExtensionsClient)
|
||||
test_dir = os.path.dirname(__file__)
|
||||
top_dir = os.path.dirname(test_dir)
|
||||
src_dir = os.path.join(top_dir, 'azure_batch_maya', 'scripts')
|
||||
mod_dir = os.path.join(test_dir, 'data', 'modules')
|
||||
ui_dir = os.path.join(src_dir, 'ui')
|
||||
tools_dir = os.path.join(src_dir, 'tools')
|
||||
os.environ["AZUREBATCH_ICONS"] = os.path.join(top_dir, 'azure_batch_maya', 'icons')
|
||||
os.environ["AZUREBATCH_TEMPLATES"] = os.path.join(top_dir, 'azure_batch_maya', 'templates')
|
||||
os.environ["AZUREBATCH_MODULES"] = mod_dir
|
||||
os.environ["AZUREBATCH_SCRIPTS"] = "{0};{1};{2}".format(src_dir, ui_dir, tools_dir)
|
||||
return super(TestAzureBatchAssets, self).setUp()
|
||||
|
||||
|
||||
@mock.patch.object(BatchAppsAssets, "collect_modules")
|
||||
@mock.patch.object(AzureBatchAssets, "_collect_modules")
|
||||
@mock.patch("assets.callback")
|
||||
@mock.patch("assets.AssetsUI")
|
||||
def test_create_batchappsassets(self, mock_ui, mock_call, mock_collect):
|
||||
|
||||
assets = BatchAppsAssets("frame", "call")
|
||||
def test_batchassets_create(self, mock_ui, mock_call, mock_collect):
|
||||
assets = AzureBatchAssets("frame", "call")
|
||||
mock_ui.assert_called_with(assets, "frame")
|
||||
mock_collect.assert_called_with()
|
||||
mock_call.after_new.assert_called_with(assets.callback_refresh)
|
||||
mock_call.after_read.assert_called_with(assets.callback_refresh)
|
||||
|
||||
def test_callback_refresh(self):
|
||||
#mock_call.after_new.assert_called_with(assets.callback_refresh)
|
||||
#mock_call.after_read.assert_called_with(assets.callback_refresh)
|
||||
|
||||
def test_batchassets_callback_refresh(self):
|
||||
self.mock_self.ui = mock.create_autospec(AssetsUI)
|
||||
self.mock_self.frame = mock.Mock()
|
||||
self.mock_self.frame.selected_tab = lambda: 1
|
||||
self.mock_self.ui.ready = False
|
||||
|
||||
BatchAppsAssets.callback_refresh(self.mock_self)
|
||||
AzureBatchAssets._callback_refresh(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 0)
|
||||
self.assertFalse(self.mock_self.ui.ready)
|
||||
|
||||
self.mock_self.ui.ready = True
|
||||
BatchAppsAssets.callback_refresh(self.mock_self)
|
||||
AzureBatchAssets._callback_refresh(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 0)
|
||||
self.assertFalse(self.mock_self.ui.ready)
|
||||
|
||||
self.mock_self.frame.selected_tab = lambda: 3
|
||||
BatchAppsAssets.callback_refresh(self.mock_self)
|
||||
AzureBatchAssets._callback_refresh(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 1)
|
||||
|
||||
@mock.patch("assets.Assets")
|
||||
@mock.patch("assets.FileManager")
|
||||
def test_configure(self, mock_mgr, mock_assets):
|
||||
def test_batchassets_configure(self, mock_assets):
|
||||
session = mock.Mock(batch="batch")
|
||||
AzureBatchAssets.configure(self.mock_self, session)
|
||||
mock_assets.assert_called_with("batch")
|
||||
self.assertEqual(self.mock_self._set_searchpaths.call_count, 1)
|
||||
|
||||
session = mock.Mock(credentials="creds", config="conf")
|
||||
BatchAppsAssets.configure(self.mock_self, session)
|
||||
|
||||
mock_mgr.assert_called_with("creds", "conf")
|
||||
mock_assets.assert_called_with()
|
||||
self.assertEqual(self.mock_self.set_searchpaths.call_count, 1)
|
||||
|
||||
def test_collect_modules(self):
|
||||
|
||||
mods = BatchAppsAssets.collect_modules(self.mock_self)
|
||||
def test_batchassets_collect_modules(self):
|
||||
mods = AzureBatchAssets._collect_modules(self.mock_self)
|
||||
self.assertEqual(len(mods), 4)
|
||||
|
||||
@mock.patch("assets.BatchAppsRenderAssets")
|
||||
@mock.patch("assets.AzureBatchRenderAssets")
|
||||
@mock.patch("assets.maya")
|
||||
def test_configure_renderer(self, mock_maya, mock_default):
|
||||
|
||||
def test_batchassets_configure_renderer(self, mock_maya, mock_default):
|
||||
mock_default.return_value = mock.Mock(render_engine = "default")
|
||||
mock_maya.mel.return_value = "test_renderer"
|
||||
mock_maya.get_attr.return_value = "test_renderer"
|
||||
|
||||
renderer = mock.Mock(render_engine = "my_renderer")
|
||||
self.mock_self.modules = [renderer, "test", None]
|
||||
|
||||
BatchAppsAssets.configure_renderer(self.mock_self)
|
||||
AzureBatchAssets._configure_renderer(self.mock_self)
|
||||
self.assertEqual(self.mock_self.renderer, mock_default.return_value)
|
||||
|
||||
renderer = mock.Mock(render_engine = "test_renderer")
|
||||
self.mock_self.modules.append(renderer)
|
||||
|
||||
BatchAppsAssets.configure_renderer(self.mock_self)
|
||||
AzureBatchAssets._configure_renderer(self.mock_self)
|
||||
self.assertEqual(self.mock_self.renderer, renderer)
|
||||
|
||||
def test_set_assets(self):
|
||||
|
||||
self.mock_self.manager = "manager"
|
||||
def test_batchassets_set_assets(self):
|
||||
self.mock_self.renderer = mock.Mock()
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
BatchAppsAssets.set_assets(self.mock_self)
|
||||
self.mock_self._assets = mock.create_autospec(Assets)
|
||||
AzureBatchAssets.set_assets(self.mock_self)
|
||||
self.mock_self._configure_renderer.assert_called_with()
|
||||
self.mock_self._assets.gather.assert_called_with()
|
||||
self.mock_self._assets.extend.assert_called_with(mock.ANY)
|
||||
|
||||
self.mock_self.configure_renderer.assert_called_with()
|
||||
self.mock_self.assets.gather.assert_called_with("manager")
|
||||
|
||||
def test_asset_categories(self):
|
||||
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
self.mock_self.assets.refs = {'Additional':[], 'Caches':[], 'Textures':[]}
|
||||
cats = BatchAppsAssets.asset_categories(self.mock_self)
|
||||
self.assertEqual(sorted(cats), ['Caches', 'Textures'])
|
||||
|
||||
self.mock_self.assets.refs = {'Caches':[], 'Textures':[]}
|
||||
cats = BatchAppsAssets.asset_categories(self.mock_self)
|
||||
self.assertEqual(sorted(cats), ['Caches', 'Textures'])
|
||||
|
||||
def test_collect_assets(self):
|
||||
|
||||
self.mock_self.ui = mock.create_autospec(AssetsUI)
|
||||
self.mock_self.ui.ready = True
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
self.mock_self.manager = mock.create_autospec(FileManager)
|
||||
|
||||
self.mock_self.assets.refs = {'Additional':[]}
|
||||
self.mock_self.assets.get_pathmaps.return_value = ['/test_path', "c:\\test_path"]
|
||||
self.mock_self.manager.file_from_path.return_value = mock.create_autospec(UserFile)
|
||||
self.mock_self.manager.create_file_set.return_value = mock.create_autospec(FileCollection)
|
||||
|
||||
collection = BatchAppsAssets.collect_assets(self.mock_self, ['/test_path/file1', "c:\\test_path\\file2"])
|
||||
self.assertTrue('pathmaps' in collection)
|
||||
self.assertTrue('assets' in collection)
|
||||
self.mock_self.assets.collect.assert_called_with()
|
||||
self.assertEqual(self.mock_self.ui.prepare.call_count, 0)
|
||||
|
||||
self.mock_self.ui.ready = False
|
||||
collection = BatchAppsAssets.collect_assets(self.mock_self, ['/test_path/file1', "c:\\test_path\\file2"])
|
||||
self.mock_self.ui.prepare.assert_called_with()
|
||||
|
||||
def test_get_assets(self):
|
||||
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
self.mock_self.assets.refs = {'Test':["file1", "file2"]}
|
||||
|
||||
assets = BatchAppsAssets.get_assets(self.mock_self, "Nothing")
|
||||
self.assertEqual(assets, [])
|
||||
|
||||
assets = BatchAppsAssets.get_assets(self.mock_self, "Test")
|
||||
def test_batchassets_get_assets(self):
|
||||
self.mock_self._assets = mock.create_autospec(Assets)
|
||||
self.mock_self._assets.refs = ["file1", "file2"]
|
||||
assets = AzureBatchAssets.get_assets(self.mock_self)
|
||||
self.assertEqual(assets, ["file1", "file2"])
|
||||
|
||||
@mock.patch("assets.SYS_SEARCHPATHS")
|
||||
@mock.patch("assets.maya")
|
||||
def test_set_searchpaths(self, mock_maya, mock_syspaths):
|
||||
|
||||
def test_batchassets_set_searchpaths(self, mock_maya, mock_syspaths):
|
||||
mock_maya.file.return_value = "testscene.mb"
|
||||
mock_maya.workspace.return_value = "/test/directory"
|
||||
mock_syspaths = ["a", "b", "c"]
|
||||
|
||||
paths = BatchAppsAssets.set_searchpaths(self.mock_self)
|
||||
paths = AzureBatchAssets._set_searchpaths(self.mock_self)
|
||||
self.assertEqual(sorted(paths), ["/test/directory", "/test/directory\\sourceimages", os.getcwd()])
|
||||
|
||||
|
||||
def test_add_files(self):
|
||||
|
||||
def test_batchassets_add_files(self):
|
||||
self.mock_self.ui = mock.Mock()
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
BatchAppsAssets.add_files(self.mock_self, ["a", "b"], "layout")
|
||||
self.mock_self.assets.add_asset.assert_any_call("a", self.mock_self.ui, "layout")
|
||||
self.mock_self.assets.add_asset.assert_any_call("b", self.mock_self.ui, "layout")
|
||||
|
||||
def test_add_dir(self):
|
||||
self.mock_self._assets = mock.create_autospec(Assets)
|
||||
AzureBatchAssets.add_files(self.mock_self, ["a", "b"], "layout", "scroll")
|
||||
self.mock_self._assets.add_asset.assert_any_call("a", self.mock_self.ui, "layout", "scroll")
|
||||
self.mock_self._assets.add_asset.assert_any_call("b", self.mock_self.ui, "layout", "scroll")
|
||||
|
||||
def test_batchassets_add_dir(self):
|
||||
test_dir = os.path.join(os.path.dirname(__file__), "data")
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
self.mock_self._assets = mock.create_autospec(Assets)
|
||||
self.mock_self.ui = mock.Mock()
|
||||
AzureBatchAssets.add_dir(self.mock_self, [test_dir], "layout", "scroll")
|
||||
self.mock_self._assets.add_asset.assert_any_call(os.path.join(test_dir, "modules", "default.py"),
|
||||
self.mock_self.ui, "layout", "scroll")
|
||||
self.assertTrue(self.mock_self._assets.add_asset.call_count >= 4)
|
||||
|
||||
BatchAppsAssets.add_dir(self.mock_self, [test_dir], "layout")
|
||||
self.mock_self.assets.add_asset.assert_any_call(os.path.join(test_dir, "modules", "default.py"), self.mock_self.ui, "layout")
|
||||
self.assertTrue(self.mock_self.assets.add_asset.call_count >= 4)
|
||||
|
||||
def test_upload_items(self):
|
||||
|
||||
mock_file1 = mock.Mock()
|
||||
mock_file2 = mock.Mock()
|
||||
to_upload = [mock_file1]
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
self.mock_self.assets.refs = {'Test':[mock_file1, mock_file2]}
|
||||
prog = mock.create_autospec(ProgressBar)
|
||||
prog.is_cancelled.return_value = False
|
||||
|
||||
c = BatchAppsAssets.upload_items(self.mock_self, to_upload, prog, 1234)
|
||||
self.assertFalse(c)
|
||||
|
||||
prog.is_cancelled.return_value = True
|
||||
c = BatchAppsAssets.upload_items(self.mock_self, to_upload, prog, 1234)
|
||||
self.assertTrue(c)
|
||||
|
||||
@mock.patch("assets.Asset")
|
||||
@mock.patch("assets.ProgressBar")
|
||||
@mock.patch("assets.maya")
|
||||
def test_upload(self, mock_maya, mock_prog):
|
||||
|
||||
def test_batchassets_upload(self, mock_maya, mock_prog, mock_asset):
|
||||
# TODO
|
||||
self.mock_self.ui = mock.create_autospec(AssetsUI)
|
||||
self.mock_self.ui.upload_button = mock.create_autospec(ProcButton)
|
||||
self.mock_self.assets = mock.create_autospec(Assets)
|
||||
BatchAppsAssets.upload(self.mock_self)
|
||||
|
||||
|
||||
class TestAssetsCombined(unittest.TestCase):
|
||||
|
||||
@mock.patch("assets.callback")
|
||||
@mock.patch("ui_assets.utils")
|
||||
@mock.patch("ui_assets.maya")
|
||||
@mock.patch("assets.maya")
|
||||
def test_assets(self, *args):
|
||||
|
||||
mock_maya = args[0]
|
||||
mock_maya.file.return_value = "/test_path/test_scene.mb"
|
||||
mock_maya.workspace.return_value = "/test/project"
|
||||
|
||||
mock_uimaya = args[1]
|
||||
mock_uimaya.file_select.return_value = [os.path.join(os.path.dirname(__file__), "data", "star.png")]
|
||||
|
||||
def add_tab(tab):
|
||||
self.assertFalse(tab.ready)
|
||||
|
||||
def call(func, *args, **kwargs):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func()
|
||||
|
||||
layout = mock.Mock(add_tab=add_tab)
|
||||
assets = BatchAppsAssets(layout, call)
|
||||
|
||||
self.assertEqual(len(assets.modules), 4)
|
||||
|
||||
creds = mock.create_autospec(Credentials)
|
||||
conf = mock.create_autospec(Configuration)
|
||||
session = mock.Mock(credentials=creds, config=conf)
|
||||
|
||||
assets.configure(session)
|
||||
#self.assertEqual(assets.scene, "")
|
||||
|
||||
mock_maya.file.return_value = os.path.join(os.path.dirname(__file__), "data", "empty.mb")
|
||||
assets.configure(session)
|
||||
#self.assertTrue(assets.scene.endswith("empty.mb"))
|
||||
|
||||
assets.ui.prepare()
|
||||
self.assertTrue(assets.ui.ready)
|
||||
self.assertEqual(assets.assets.refs, {'Additional':[],
|
||||
'Caches':[],
|
||||
'Files':[],
|
||||
'References':[]})
|
||||
|
||||
files = assets.get_assets("Caches")
|
||||
self.assertEqual(files, [])
|
||||
|
||||
assets.ui.add_asset()
|
||||
files = assets.get_assets("Additional")
|
||||
self.assertEqual(len(files), 1)
|
||||
|
||||
asset = files[0]
|
||||
self.assertTrue(asset.included())
|
||||
self.assertTrue(asset in asset.parent_list)
|
||||
asset.exclude()
|
||||
self.assertFalse(asset in asset.parent_list)
|
||||
|
||||
check_path = mock.Mock(path=mock_uimaya.file_select.return_value[0])
|
||||
self.assertTrue(asset.is_duplicate([check_path]))
|
||||
check_path.path = "/test_file"
|
||||
self.assertFalse(asset.is_duplicate([check_path]))
|
||||
|
||||
asset.delete()
|
||||
|
||||
files = assets.get_assets("Additional")
|
||||
self.assertEqual(len(files), 0)
|
||||
self.assertEqual(len(assets.assets.pathmaps), 1)
|
||||
|
||||
assets.ui.add_asset()
|
||||
files = assets.get_assets("Additional")
|
||||
self.assertEqual(len(files), 1)
|
||||
self.assertEqual(len(assets.assets.pathmaps), 2)
|
||||
|
||||
collected = assets.collect_assets([])
|
||||
self.assertTrue(collected.get('assets'))
|
||||
self.assertTrue(collected.get('pathmaps'))
|
||||
decoded = collected.get('pathmaps')['PathMaps']
|
||||
self.assertEqual(len(decoded), 1)
|
||||
|
||||
assets.ui.refresh()
|
||||
files = assets.get_assets("Additional")
|
||||
self.assertEqual(len(files), 0)
|
||||
self.assertEqual(len(assets.assets.pathmaps), 0)
|
||||
self.mock_self._assets = mock.create_autospec(Assets)
|
||||
AzureBatchAssets.upload(self.mock_self)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,337 +0,0 @@
|
|||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Batch Apps Maya Plugin
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the ""Software""), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import json
|
||||
|
||||
try:
|
||||
import unittest2 as unittest
|
||||
except ImportError:
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from ui_environment import EnvironmentUI
|
||||
from environment import BatchAppsEnvironment, BatchPlugin
|
||||
|
||||
|
||||
class TestPlugin(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(BatchPlugin)
|
||||
return super(TestPlugin, self).setUp()
|
||||
|
||||
@mock.patch.object(BatchPlugin, "create_checkbox")
|
||||
def test_create(self, mock_checkbox):
|
||||
|
||||
plugin = BatchPlugin("base", "plugin", "False", [])
|
||||
mock_checkbox.assert_called_with()
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
v = plugin.license_var
|
||||
|
||||
self.assertEqual(plugin.label, "plugin")
|
||||
self.assertFalse(plugin.license)
|
||||
self.assertFalse(plugin.supported)
|
||||
|
||||
plugin = BatchPlugin("base", "plugin", "False", [{"name":"My Plugin", "license":False}])
|
||||
self.assertEqual(plugin.label, "My Plugin")
|
||||
self.assertFalse(plugin.license)
|
||||
self.assertTrue(plugin.supported)
|
||||
self.assertEqual(plugin.license_var, {})
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_create_checkbox(self, mock_maya):
|
||||
self.mock_self.license = False
|
||||
self.mock_self.base = mock.create_autospec(BatchAppsEnvironment)
|
||||
self.mock_self.base.ui = mock.create_autospec(EnvironmentUI)
|
||||
self.mock_self.base.ui.plugin_layout = "layout"
|
||||
self.mock_self.supported = False
|
||||
self.mock_self.label = "plugin"
|
||||
self.mock_self.contents = []
|
||||
|
||||
BatchPlugin.create_checkbox(self.mock_self)
|
||||
self.assertEqual(len(self.mock_self.contents), 2)
|
||||
mock_maya.check_box.assert_called_with(label="Unsupported: plugin", value=False, onCommand=self.mock_self.include,
|
||||
offCommand=self.mock_self.exclude, parent="layout", enable=False)
|
||||
mock_maya.text.assert_called_with(label="", parent="layout")
|
||||
|
||||
self.mock_self.license = True
|
||||
self.mock_self.contents = []
|
||||
BatchPlugin.create_checkbox(self.mock_self)
|
||||
self.assertEqual(len(self.mock_self.contents), 4)
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_is_used(self, mock_maya):
|
||||
|
||||
used = ["plugin_A", "plugin_B"]
|
||||
self.mock_self.base = mock.create_autospec(BatchAppsEnvironment)
|
||||
self.mock_self.base.plugins = []
|
||||
self.mock_self.base.warnings = []
|
||||
self.mock_self.plugin = "plugin_C.py"
|
||||
self.mock_self.label = "plugin"
|
||||
self.mock_self.supported = False
|
||||
self.mock_self.loaded = False
|
||||
self.mock_self.license = False
|
||||
self.mock_self.checkbox = "checkbox"
|
||||
self.mock_self.license_check = "license"
|
||||
BatchPlugin.is_used(self.mock_self, used)
|
||||
self.assertFalse(self.mock_self.used)
|
||||
self.assertEqual(self.mock_self.base.plugins, [])
|
||||
self.assertEqual(self.mock_self.base.warnings, [])
|
||||
|
||||
self.mock_self.loaded = True
|
||||
BatchPlugin.is_used(self.mock_self, used)
|
||||
self.assertFalse(self.mock_self.used)
|
||||
self.assertEqual(self.mock_self.base.plugins, [])
|
||||
self.assertEqual(self.mock_self.base.warnings, [])
|
||||
|
||||
self.mock_self.plugin = "plugin_A.py"
|
||||
BatchPlugin.is_used(self.mock_self, used)
|
||||
self.assertTrue(self.mock_self.used)
|
||||
self.assertEqual(mock_maya.check_box.call_count, 0)
|
||||
self.assertEqual(self.mock_self.base.plugins, [])
|
||||
self.assertEqual(self.mock_self.base.warnings, ["plugin_A.py"])
|
||||
|
||||
self.mock_self.supported = True
|
||||
self.mock_self.base.warnings = []
|
||||
BatchPlugin.is_used(self.mock_self, used)
|
||||
self.assertTrue(self.mock_self.used)
|
||||
mock_maya.check_box.assert_called_with("checkbox", edit=True, value=True)
|
||||
self.assertEqual(self.mock_self.base.plugins, ["plugin"])
|
||||
self.assertEqual(self.mock_self.base.warnings, [])
|
||||
|
||||
self.mock_self.license = True
|
||||
BatchPlugin.is_used(self.mock_self, used)
|
||||
mock_maya.check_box.assert_called_with("license", edit=True, enable=True)
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_use_license(self, mock_maya):
|
||||
|
||||
self.mock_self.license = False
|
||||
self.mock_self.custom_license_endp = "endp"
|
||||
self.mock_self.custom_license_port = "port"
|
||||
BatchPlugin.use_license(self.mock_self, True)
|
||||
self.assertEqual(mock_maya.text_field.call_count, 0)
|
||||
|
||||
self.mock_self.license = True
|
||||
BatchPlugin.use_license(self.mock_self, True)
|
||||
self.assertEqual(mock_maya.text_field.call_count, 2)
|
||||
mock_maya.text_field.assert_called_with("port", edit=True, enable=True)
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_include(self, mock_maya):
|
||||
|
||||
self.mock_self.base = mock.create_autospec(BatchAppsEnvironment)
|
||||
self.mock_self.base.plugins = []
|
||||
self.mock_self.label = "My Plugin"
|
||||
self.mock_self.license = False
|
||||
self.mock_self.license_check = "check"
|
||||
BatchPlugin.include(self.mock_self)
|
||||
self.assertEqual(self.mock_self.base.plugins, ["My Plugin"])
|
||||
self.assertEqual(mock_maya.check_box.call_count, 0)
|
||||
|
||||
self.mock_self.license = True
|
||||
BatchPlugin.include(self.mock_self)
|
||||
self.assertEqual(self.mock_self.base.plugins, ["My Plugin", "My Plugin"])
|
||||
mock_maya.check_box.assert_called_with("check", edit=True, enable=True)
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_exclude(self, mock_maya):
|
||||
|
||||
self.mock_self.base = mock.create_autospec(BatchAppsEnvironment)
|
||||
self.mock_self.base.plugins = ["My Plugin"]
|
||||
self.mock_self.label = "My Plugin"
|
||||
self.mock_self.license = False
|
||||
self.mock_self.license_check = "check"
|
||||
self.mock_self.used = False
|
||||
|
||||
BatchPlugin.exclude(self.mock_self)
|
||||
self.assertEqual(mock_maya.warning.call_count, 0)
|
||||
self.assertEqual(mock_maya.check_box.call_count, 0)
|
||||
self.assertEqual(self.mock_self.base.plugins, [])
|
||||
|
||||
self.mock_self.license = True
|
||||
BatchPlugin.exclude(self.mock_self)
|
||||
self.assertEqual(mock_maya.warning.call_count, 0)
|
||||
mock_maya.check_box.assert_called_with("check", edit=True, enable=False)
|
||||
self.assertEqual(self.mock_self.base.plugins, [])
|
||||
|
||||
self.mock_self.used = True
|
||||
BatchPlugin.exclude(self.mock_self)
|
||||
mock_maya.warning.assert_called_with(mock.ANY)
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_delete(self, mock_maya):
|
||||
|
||||
self.mock_self.contents = ["a"]
|
||||
BatchPlugin.delete(self.mock_self)
|
||||
mock_maya.delete_ui.assert_called_with("a", control=True)
|
||||
|
||||
@mock.patch("environment.maya")
|
||||
def test_get_vaiables(self, mock_maya):
|
||||
|
||||
mock_maya.check_box.return_value = True
|
||||
self.mock_self.license = False
|
||||
self.mock_self.license_check = "check"
|
||||
self.mock_self.license_var = {"key":"solidangle_LICENSE", "value":"{port}@{host}"}
|
||||
self.mock_self.custom_license_endp = "host"
|
||||
self.mock_self.custom_license_port = "port"
|
||||
vars = BatchPlugin.get_variables(self.mock_self)
|
||||
self.assertEqual(vars, {})
|
||||
self.assertEqual(mock_maya.text_field.call_count, 0)
|
||||
|
||||
self.mock_self.license = True
|
||||
mock_maya.text_field.return_value = "blah"
|
||||
vars = BatchPlugin.get_variables(self.mock_self)
|
||||
self.assertEqual(vars, {"solidangle_LICENSE":"blah@blah"})
|
||||
self.assertEqual(mock_maya.text_field.call_count, 2)
|
||||
|
||||
|
||||
class TestBatchAppsEnvironment(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(BatchAppsEnvironment)
|
||||
self.mock_self._log = logging.getLogger("TestEnvironment")
|
||||
self.mock_self._server_plugins = []
|
||||
self.mock_self.warnings = []
|
||||
self.mock_self._plugins = []
|
||||
self.mock_self._version = "2017"
|
||||
return super(TestBatchAppsEnvironment, self).setUp()
|
||||
|
||||
@mock.patch.object(BatchAppsEnvironment, "refresh")
|
||||
@mock.patch("environment.EnvironmentUI")
|
||||
@mock.patch("environment.callback")
|
||||
def test_create(self, mock_call, mock_ui, mock_refresh):
|
||||
|
||||
env = BatchAppsEnvironment("frame", "call")
|
||||
mock_ui.assert_called_with(env, "frame", ["Maya I/O PR55"])
|
||||
mock_call.after_new.assert_called_with(mock.ANY)
|
||||
mock_call.after_read.assert_called_with(mock.ANY)
|
||||
mock_refresh.assert_called_with()
|
||||
|
||||
self.assertEqual(env.plugins, [])
|
||||
self.assertEqual(env.version, "2017")
|
||||
lic = env.license
|
||||
env.ui.get_license_server.assert_called_with()
|
||||
vars = env.environment_variables
|
||||
env.ui.get_env_vars.assert_called_with()
|
||||
|
||||
def test_configure(self):
|
||||
|
||||
BatchAppsEnvironment.configure(self.mock_self, "session")
|
||||
self.assertEqual(self.mock_self._session, "session")
|
||||
|
||||
@mock.patch("environment.BatchPlugin")
|
||||
@mock.patch("environment.maya")
|
||||
def test_get_plugins(self, mock_maya, mock_plugin):
|
||||
|
||||
mock_maya.plugins.return_value = ["mtoa.mll", "b", "c"]
|
||||
self.mock_self.search_for_plugins.return_value = ["Mayatomr.mll", "mtoa.mll", "c", "d", "e"]
|
||||
mock_plugin.return_value = mock.create_autospec(BatchPlugin)
|
||||
plugins = BatchAppsEnvironment.get_plugins(self.mock_self)
|
||||
|
||||
mock_maya.plugins.assert_any_call('e', query=True, loaded=True)
|
||||
self.mock_self.search_for_plugins.assert_called_with()
|
||||
|
||||
mock_plugin.assert_any_call(mock.ANY, "mtoa.mll", ["mtoa.mll", "b", "c"],
|
||||
[{"name": "Arnold", "plugin": "mtoa.", "license": True, "license_var": {"key":"solidangle_LICENSE", "value":"{port}@{host}"}}])
|
||||
mock_plugin.assert_any_call(mock.ANY, "e", ["mtoa.mll", "b", "c"], [])
|
||||
mock_plugin.assert_any_call(mock.ANY, "Mayatomr.mll", ["mtoa.mll", "b", "c"],
|
||||
[{"name": "MentalRay", "plugin": "Mayatomr.", "license": False}])
|
||||
mock_plugin.return_value.is_used.assert_called_with(["mtoa.mll", "b", "c"])
|
||||
self.assertEqual(len(plugins), 5)
|
||||
|
||||
self.mock_self.warnings = ["a","b","c"]
|
||||
plugins = BatchAppsEnvironment.get_plugins(self.mock_self)
|
||||
mock_maya.warning.assert_called_with("The following plug-ins are used in the scene, but not yet supported.\nRendering may be affected.\na\nb\nc\n")
|
||||
|
||||
@mock.patch("environment.os")
|
||||
def test_search_for_plugins(self, mock_os):
|
||||
|
||||
self.mock_self.is_default = lambda a: BatchAppsEnvironment.is_default(self.mock_self, a)
|
||||
mock_os.path.splitext = os.path.splitext
|
||||
mock_os.environ = {"MAYA_PLUG_IN_PATH":"dir1;dir2;dir3"}
|
||||
mock_os.pathsep = ';'
|
||||
mock_os.path.isdir.return_value = True
|
||||
mock_os.listdir.return_value = ["a","b","test.mll","test.mll","plugin.py", "xgenMR.py", "fbxmaya.mll"]
|
||||
plugins = BatchAppsEnvironment.search_for_plugins(self.mock_self)
|
||||
self.assertEqual(sorted(plugins), sorted(["test.mll", "plugin.py"]))
|
||||
|
||||
def test_set_version(self):
|
||||
|
||||
BatchAppsEnvironment.set_version(self.mock_self, "Maya 2015")
|
||||
self.assertEqual(self.mock_self._version, "2017")
|
||||
BatchAppsEnvironment.set_version(self.mock_self, "test")
|
||||
self.assertEqual(self.mock_self._version, "2017")
|
||||
|
||||
def test_refresh(self):
|
||||
self.mock_self._server_plugins = [1,2,3]
|
||||
self.mock_self.warnings = [4,5,6]
|
||||
mock_plugin = mock.create_autospec(BatchPlugin)
|
||||
self.mock_self._plugins = [mock_plugin]
|
||||
|
||||
BatchAppsEnvironment.refresh(self.mock_self)
|
||||
self.assertEqual(self.mock_self._server_plugins, [])
|
||||
self.assertEqual(self.mock_self.warnings, [])
|
||||
self.mock_self.get_plugins.assert_called_with()
|
||||
mock_plugin.delete.assert_called_with()
|
||||
|
||||
|
||||
class TestEnvironmentCombined(unittest.TestCase):
|
||||
|
||||
@mock.patch("ui_environment.utils")
|
||||
@mock.patch("ui_environment.maya")
|
||||
@mock.patch("environment.callback")
|
||||
@mock.patch("environment.maya")
|
||||
def test_environment(self, *args):
|
||||
|
||||
os.environ["MAYA_PLUG_IN_PATH"] = os.path.join(os.path.dirname(__file__), "data", "modules")
|
||||
|
||||
def add_tab(tab):
|
||||
self.assertFalse(tab.ready)
|
||||
|
||||
def call(func, *args, **kwargs):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func(*args, **kwargs)
|
||||
|
||||
layout = mock.Mock(add_tab=add_tab)
|
||||
env = BatchAppsEnvironment(layout, call)
|
||||
|
||||
env.configure("session")
|
||||
self.assertEqual(env.plugins, [])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,510 +0,0 @@
|
|||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Batch Apps Maya Plugin
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the ""Software""), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import datetime
|
||||
|
||||
try:
|
||||
import unittest2 as unittest
|
||||
except ImportError:
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from ui_history import HistoryUI, BatchAppsJobInfo
|
||||
from history import BatchAppsHistory
|
||||
from batchapps import JobManager, Configuration, Credentials
|
||||
from batchapps.job import SubmittedJob, JobSubmission, Task
|
||||
from batchapps.exceptions import FileDownloadException
|
||||
from utils import ProcButton
|
||||
|
||||
class TestBatchAppsHistory(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(BatchAppsHistory)
|
||||
self.mock_self._log = logging.getLogger("TestHistory")
|
||||
self.mock_self.index = 0
|
||||
self.mock_self.per_call = 5
|
||||
self.mock_self.min = True
|
||||
self.mock_self.max = False
|
||||
return super(TestBatchAppsHistory, self).setUp()
|
||||
|
||||
@mock.patch("history.HistoryUI")
|
||||
def test_create_batchappshistory(self, mock_ui):
|
||||
|
||||
history = BatchAppsHistory("frame", "call")
|
||||
mock_ui.assert_called_with(history, "frame")
|
||||
|
||||
@mock.patch("history.JobManager")
|
||||
def test_configure(self, mock_mgr):
|
||||
|
||||
session = mock.Mock(credentials="creds", config="conf")
|
||||
BatchAppsHistory.configure(self.mock_self, session)
|
||||
|
||||
mock_mgr.assert_called_with("creds", "conf")
|
||||
self.assertEqual(session, self.mock_self._session)
|
||||
|
||||
def test_get_history(self):
|
||||
|
||||
mgr = mock.create_autospec(JobManager)
|
||||
mgr.get_jobs.return_value = [mock.Mock(name="test_job")]
|
||||
mgr.__len__.return_value = 1
|
||||
|
||||
def call(func, arg_a, arg_b):
|
||||
self.assertEqual(func, mgr.get_jobs)
|
||||
self.assertEqual(arg_a, 0)
|
||||
self.assertEqual(arg_b, 5)
|
||||
return func()
|
||||
|
||||
self.mock_self.manager = mgr
|
||||
self.mock_self._call = call
|
||||
self.mock_self.ui = mock.create_autospec(HistoryUI)
|
||||
self.mock_self.ui.create_job_entry.return_value = "job_entry"
|
||||
|
||||
displayed = BatchAppsHistory.get_history(self.mock_self)
|
||||
self.assertEqual(displayed, ["job_entry"])
|
||||
self.assertEqual(len(self.mock_self.jobs), 1)
|
||||
|
||||
def test_set_num_jobs(self):
|
||||
|
||||
self.mock_self.ui = mock.create_autospec(HistoryUI)
|
||||
self.mock_self.count = 8
|
||||
|
||||
BatchAppsHistory.set_num_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.num_jobs, "1 - 5 of 8")
|
||||
|
||||
self.mock_self.count = 3
|
||||
BatchAppsHistory.set_num_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.num_jobs, "1 - 3 of 3")
|
||||
|
||||
self.mock_self.index = 5
|
||||
BatchAppsHistory.set_num_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.num_jobs, "3 - 3 of 3")
|
||||
|
||||
self.mock_self.count = 20
|
||||
BatchAppsHistory.set_num_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.num_jobs, "6 - 10 of 20")
|
||||
|
||||
def test_set_min_max(self):
|
||||
|
||||
self.mock_self.ui = mock.create_autospec(HistoryUI)
|
||||
self.mock_self.count = 4
|
||||
BatchAppsHistory.set_min_max(self.mock_self)
|
||||
self.assertTrue(self.mock_self.min)
|
||||
self.assertTrue(self.mock_self.max)
|
||||
|
||||
self.mock_self.index = 2
|
||||
BatchAppsHistory.set_min_max(self.mock_self)
|
||||
self.assertTrue(self.mock_self.max)
|
||||
self.assertFalse(self.mock_self.min)
|
||||
|
||||
self.mock_self.count = 20
|
||||
BatchAppsHistory.set_min_max(self.mock_self)
|
||||
self.assertFalse(self.mock_self.max)
|
||||
self.assertFalse(self.mock_self.min)
|
||||
|
||||
self.mock_self.count = 5
|
||||
BatchAppsHistory.set_min_max(self.mock_self)
|
||||
self.assertTrue(self.mock_self.max)
|
||||
self.assertFalse(self.mock_self.min)
|
||||
|
||||
self.mock_self.count = 6
|
||||
BatchAppsHistory.set_min_max(self.mock_self)
|
||||
self.assertFalse(self.mock_self.max)
|
||||
self.assertFalse(self.mock_self.min)
|
||||
|
||||
def test_next_jobs(self):
|
||||
|
||||
self.mock_self.count = 12
|
||||
BatchAppsHistory.show_next_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 5)
|
||||
|
||||
BatchAppsHistory.show_next_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 10)
|
||||
|
||||
BatchAppsHistory.show_next_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 12)
|
||||
|
||||
def test_prev_jobs(self):
|
||||
|
||||
self.mock_self.count = 9
|
||||
BatchAppsHistory.show_prev_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 0)
|
||||
|
||||
self.mock_self.index = 4
|
||||
BatchAppsHistory.show_prev_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 0)
|
||||
|
||||
self.mock_self.index = 8
|
||||
BatchAppsHistory.show_prev_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 3)
|
||||
|
||||
def test_first_jobs(self):
|
||||
|
||||
BatchAppsHistory.show_first_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 0)
|
||||
|
||||
self.mock_self.index = 8
|
||||
BatchAppsHistory.show_first_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 0)
|
||||
|
||||
def test_last_jobs(self):
|
||||
|
||||
self.mock_self.count = 11
|
||||
BatchAppsHistory.show_last_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 10)
|
||||
|
||||
self.mock_self.count = 15
|
||||
BatchAppsHistory.show_last_jobs(self.mock_self)
|
||||
self.assertEqual(self.mock_self.index, 10)
|
||||
|
||||
def test_job_selected(self):
|
||||
|
||||
ui_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
ui_job.index = 0
|
||||
|
||||
self.mock_self.selected_job = None
|
||||
BatchAppsHistory.job_selected(self.mock_self, None)
|
||||
|
||||
BatchAppsHistory.job_selected(self.mock_self, ui_job)
|
||||
self.assertEqual(self.mock_self.selected_job, ui_job)
|
||||
self.mock_self.update_job.assert_called_with(0)
|
||||
|
||||
BatchAppsHistory.job_selected(self.mock_self, ui_job)
|
||||
ui_job.collapse.assert_called_with()
|
||||
|
||||
self.mock_self.selected_job = None
|
||||
self.mock_self.jobs = []
|
||||
BatchAppsHistory.job_selected(self.mock_self, ui_job)
|
||||
ui_job.collapse.assert_called_with()
|
||||
|
||||
@mock.patch("history.maya")
|
||||
def test_update_job(self, mock_maya):
|
||||
|
||||
job = mock.create_autospec(SubmittedJob)
|
||||
job.status = "Running"
|
||||
job.percentage = "10%"
|
||||
job.time_submitted = "today"
|
||||
job.number_tasks = "500"
|
||||
job.id = "12345"
|
||||
job.pool_id = "67890"
|
||||
job.name = "Test Job"
|
||||
self.mock_self.jobs = [job]
|
||||
|
||||
ui_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
ui_job.index = 0
|
||||
self.mock_self.selected_job = ui_job
|
||||
|
||||
def call(func):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
|
||||
self.mock_self._call = call
|
||||
|
||||
BatchAppsHistory.update_job(self.mock_self, 0)
|
||||
ui_job.set_thumbnail.assert_called_with(os.path.join(
|
||||
os.environ["BATCHAPPS_ICONS"], "loading_preview.png"), 24)
|
||||
ui_job.set_status.assert_called_with("Running")
|
||||
|
||||
def test_get_thumb(self):
|
||||
|
||||
job = mock.create_autospec(SubmittedJob)
|
||||
job.status = "Running"
|
||||
job.get_tasks.return_value = [1,2,3]
|
||||
self.mock_self.jobs = [job]
|
||||
|
||||
ui_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
ui_job.index = 0
|
||||
|
||||
def call(func):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func()
|
||||
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_job = ui_job
|
||||
|
||||
BatchAppsHistory.get_thumb(self.mock_self)
|
||||
self.mock_self.get_task_thumb.assert_called_with(job, [1,2,3])
|
||||
|
||||
job.status = "Complete"
|
||||
BatchAppsHistory.get_thumb(self.mock_self)
|
||||
self.mock_self.get_job_thumb.assert_called_with(job)
|
||||
|
||||
self.mock_self.jobs = []
|
||||
BatchAppsHistory.get_thumb(self.mock_self)
|
||||
ui_job.set_thumbnail.assert_called_with(os.path.join(os.environ["BATCHAPPS_ICONS"], "no_preview.png"), 24)
|
||||
|
||||
self.mock_self.selected_job = None
|
||||
BatchAppsHistory.get_thumb(self.mock_self)
|
||||
|
||||
@mock.patch("history.glob")
|
||||
@mock.patch("history.maya")
|
||||
def test_task_thumb(self, mock_maya, mock_glob):
|
||||
|
||||
star = os.path.join(os.path.dirname(__file__), "data", "star.png")
|
||||
mock_glob.glob.return_value = []
|
||||
job = mock.create_autospec(SubmittedJob)
|
||||
job.id = "12345"
|
||||
|
||||
task1 = mock.create_autospec(Task)
|
||||
task1.id = "abc"
|
||||
task1.get_thumbnail.side_effect = FileDownloadException("Broken!")
|
||||
|
||||
task2 = mock.create_autospec(Task)
|
||||
task2.id = "abc"
|
||||
task2.get_thumbnail.return_value = star
|
||||
|
||||
def call(func, dir, thumb, over):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
self.assertTrue(over)
|
||||
self.assertTrue(thumb.startswith("12345.abc"))
|
||||
return func()
|
||||
|
||||
self.mock_self.temp_name = lambda a: BatchAppsHistory.temp_name(self.mock_self, a)
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
BatchAppsHistory.get_task_thumb(self.mock_self, job, [task2, task1])
|
||||
self.mock_self.selected_job.set_thumbnail.assert_called_with(star, mock.ANY)
|
||||
mock_glob.glob.assert_called_with(mock.ANY)
|
||||
self.assertEqual(task2.get_thumbnail.call_count, 1)
|
||||
task2.get_thumbnail.call_count = 0
|
||||
|
||||
mock_glob.glob.return_value = [star]
|
||||
BatchAppsHistory.get_task_thumb(self.mock_self, job, [task2, task1])
|
||||
self.assertEqual(task2.get_thumbnail.call_count, 0)
|
||||
|
||||
mock_glob.glob.return_value = []
|
||||
task2.get_thumbnail.side_effect = FileDownloadException("Broken!")
|
||||
BatchAppsHistory.get_task_thumb(self.mock_self, job, [task2, task1])
|
||||
self.mock_self.selected_job.set_thumbnail.assert_called_with(
|
||||
os.path.join(os.environ["BATCHAPPS_ICONS"], "no_preview.png"), mock.ANY)
|
||||
|
||||
@mock.patch("history.glob")
|
||||
@mock.patch("history.maya")
|
||||
def test_job_thumb(self, mock_maya, mock_glob):
|
||||
|
||||
star = os.path.join(os.path.dirname(__file__), "data", "star.png")
|
||||
mock_glob.glob.return_value = []
|
||||
job = mock.create_autospec(SubmittedJob)
|
||||
job.id = "12345"
|
||||
job.get_thumbnail.side_effect = FileDownloadException("Broken!")
|
||||
|
||||
def call(func, dir, thumb, over):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
self.assertTrue(over)
|
||||
self.assertTrue(thumb.startswith("12345.job."))
|
||||
return func()
|
||||
|
||||
self.mock_self.temp_name = lambda a: BatchAppsHistory.temp_name(self.mock_self, a)
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
BatchAppsHistory.get_job_thumb(self.mock_self, job)
|
||||
self.mock_self.selected_job.set_thumbnail.assert_called_with(
|
||||
os.path.join(os.environ["BATCHAPPS_ICONS"], "no_preview.png"), mock.ANY)
|
||||
job.get_thumbnail.call_count = 0
|
||||
|
||||
mock_glob.glob.return_value = [star]
|
||||
BatchAppsHistory.get_job_thumb(self.mock_self, job)
|
||||
self.mock_self.selected_job.set_thumbnail.assert_called_with(star, mock.ANY)
|
||||
self.assertEqual(job.get_thumbnail.call_count, 0)
|
||||
|
||||
mock_glob.glob.return_value = []
|
||||
job.get_thumbnail.side_effect = None
|
||||
job.get_thumbnail.return_value = star
|
||||
BatchAppsHistory.get_job_thumb(self.mock_self, job)
|
||||
self.mock_self.selected_job.set_thumbnail.assert_called_with(star, mock.ANY)
|
||||
self.assertEqual(job.get_thumbnail.call_count, 1)
|
||||
|
||||
def test_cancel_job(self):
|
||||
|
||||
job = mock.create_autospec(SubmittedJob)
|
||||
job.cancel.return_value = True
|
||||
|
||||
def call(func):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func()
|
||||
|
||||
self.mock_self.jobs = [job]
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
self.mock_self.selected_job.index = 0
|
||||
|
||||
BatchAppsHistory.cancel_job(self.mock_self)
|
||||
job.cancel.assert_called_with()
|
||||
job.cancel.call_count = 0
|
||||
|
||||
self.mock_self.jobs = []
|
||||
BatchAppsHistory.cancel_job(self.mock_self)
|
||||
self.assertEqual(job.cancel.call_count, 0)
|
||||
|
||||
@mock.patch("history.os")
|
||||
@mock.patch("history.tempfile")
|
||||
@mock.patch("history.shutil")
|
||||
@mock.patch("history.maya")
|
||||
def test_download_output(self, mock_maya, mock_util, mock_temp, mock_os):
|
||||
|
||||
data_dir = os.path.join(os.path.dirname(__file__), "data")
|
||||
mock_temp.mkdtemp.return_value = data_dir
|
||||
mock_os.path.exists.return_value = False
|
||||
|
||||
selected_file = os.path.join(os.path.dirname(__file__), "my_output.zip")
|
||||
job = mock.create_autospec(SubmittedJob)
|
||||
|
||||
def call(func, dir, overwrite):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
self.assertEqual(dir, data_dir)
|
||||
self.assertTrue(overwrite)
|
||||
func(dir, overwrite)
|
||||
return os.path.join(data_dir, "output.zip")
|
||||
|
||||
self.mock_self.ui = mock.create_autospec(HistoryUI)
|
||||
self.mock_self.ui.refresh_button = mock.create_autospec(ProcButton)
|
||||
self.mock_self.jobs = [job]
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_job = mock.create_autospec(BatchAppsJobInfo)
|
||||
self.mock_self.selected_job.index = 0
|
||||
|
||||
BatchAppsHistory.download_output(self.mock_self, selected_file)
|
||||
job.get_output.assert_called_with(data_dir, overwrite=True, callback=mock.ANY, block=100000)
|
||||
|
||||
job.get_output.side_effect = FileDownloadException("Failed!")
|
||||
BatchAppsHistory.download_output(self.mock_self, selected_file)
|
||||
self.mock_self.ui.refresh_button.finish.assert_called_with()
|
||||
|
||||
job.get_output.call_count = 0
|
||||
job.get_output.side_effect = None
|
||||
mock_os.path.exists.return_value = True
|
||||
|
||||
BatchAppsHistory.download_output(self.mock_self, selected_file)
|
||||
mock_os.remove.assert_called_with(selected_file)
|
||||
mock_util.move_assert_called_with(os.path.join(data_dir, "output.zip"), selected_file)
|
||||
mock_util.rmtree.assert_called_with(data_dir)
|
||||
|
||||
mock_os.remove.side_effect = EnvironmentError("Couldn't delete...")
|
||||
BatchAppsHistory.download_output(self.mock_self, selected_file)
|
||||
self.mock_self.ui.refresh_button.finish.assert_called_with()
|
||||
self.assertEqual(job.get_output.call_count, 1)
|
||||
|
||||
mock_util.rmtree.side_effect = Exception("Couldn't move to new location")
|
||||
BatchAppsHistory.download_output(self.mock_self, selected_file)
|
||||
self.mock_self.ui.refresh_button.finish.assert_called_with()
|
||||
mock_util.rmtree.assert_called_with(data_dir)
|
||||
|
||||
def test_image_height(self):
|
||||
|
||||
image = os.path.join(os.path.dirname(__file__), "data", "star.png")
|
||||
height = BatchAppsHistory.get_image_height(self.mock_self, image)
|
||||
self.assertEqual(height, 405)
|
||||
|
||||
|
||||
class TestHistoryCombined(unittest.TestCase):
|
||||
|
||||
@mock.patch("ui_history.utils")
|
||||
@mock.patch("ui_history.maya")
|
||||
@mock.patch("history.maya")
|
||||
def test_history(self, *args):
|
||||
|
||||
def add_tab(tab):
|
||||
self.assertFalse(tab.ready)
|
||||
|
||||
def call(func, *args, **kwargs):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func(*args, **kwargs)
|
||||
|
||||
layout = mock.Mock(add_tab=add_tab)
|
||||
history = BatchAppsHistory(layout, call)
|
||||
|
||||
creds = mock.create_autospec(Credentials)
|
||||
conf = mock.create_autospec(Configuration)
|
||||
session = mock.Mock(credentials=creds, config=conf)
|
||||
|
||||
history.configure(session)
|
||||
|
||||
history.manager = mock.create_autospec(JobManager)
|
||||
job1 = mock.create_autospec(SubmittedJob)
|
||||
job1.name = "Job1"
|
||||
job1.status = "Complete"
|
||||
job1.percentage = "100%"
|
||||
job1.time_submitted = str(datetime.datetime.now()).replace(' ', 'T')
|
||||
job1.number_tasks = "10"
|
||||
job1.id = "12345"
|
||||
job1.pool_id = "pool"
|
||||
|
||||
job2 = mock.create_autospec(SubmittedJob)
|
||||
job2.name = "Job2"
|
||||
|
||||
history.manager.get_jobs.return_value = [job1, job2]
|
||||
history.manager.__len__.return_value = 2
|
||||
|
||||
history.ui.prepare()
|
||||
self.assertTrue(history.ui.ready)
|
||||
self.assertTrue(history.min)
|
||||
self.assertTrue(history.max)
|
||||
|
||||
history.ui.show_next_jobs()
|
||||
self.assertEqual(history.index, 2)
|
||||
self.assertFalse(history.min)
|
||||
self.assertTrue(history.max)
|
||||
|
||||
history.ui.show_last_jobs()
|
||||
self.assertEqual(history.index, 0)
|
||||
self.assertTrue(history.min)
|
||||
self.assertTrue(history.max)
|
||||
|
||||
history.ui.show_prev_jobs()
|
||||
self.assertEqual(history.index, 0)
|
||||
self.assertTrue(history.min)
|
||||
self.assertTrue(history.max)
|
||||
|
||||
history.ui.show_first_jobs()
|
||||
self.assertEqual(history.index, 0)
|
||||
self.assertTrue(history.min)
|
||||
self.assertTrue(history.max)
|
||||
|
||||
history.ui.jobs_displayed[0].on_expand()
|
||||
self.assertEqual(history.ui.jobs_displayed[0], history.selected_job)
|
||||
|
||||
history.selected_job.collapse()
|
||||
self.assertIsNone(history.selected_job)
|
||||
|
||||
history.ui.jobs_displayed[1].on_expand()
|
||||
self.assertIsNone(history.selected_job)
|
||||
|
||||
mock_maya = args[1]
|
||||
mock_maya.file_select.return_value = os.path.join(os.path.dirname(__file__), "data", "my_output.zip")
|
||||
history.ui.jobs_displayed[0].download_output()
|
||||
self.assertEqual(job1.get_output.call_count, 0)
|
||||
|
||||
history.ui.jobs_displayed[0].on_expand()
|
||||
history.ui.jobs_displayed[0].download_output()
|
||||
self.assertEqual(job1.get_output.call_count, 1)
|
|
@ -8,223 +8,70 @@ try:
|
|||
except ImportError:
|
||||
import mock
|
||||
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from batch_extensions import models
|
||||
|
||||
from batchapps import (
|
||||
JobManager,
|
||||
Configuration)
|
||||
|
||||
from batchapps.job import (
|
||||
SubmittedJob,
|
||||
Task,
|
||||
JobSubmission)
|
||||
|
||||
from batchapps.exceptions import (
|
||||
RestCallException,
|
||||
AuthenticationException,
|
||||
InvalidConfigException)
|
||||
CWD = os.path.dirname(os.path.abspath(__file__))
|
||||
top_dir = os.path.dirname(CWD)
|
||||
src_dir = os.path.join(top_dir, 'azure_batch_maya', 'scripts')
|
||||
tools_dir = os.path.join(src_dir, 'tools')
|
||||
sys.path.extend([src_dir, tools_dir])
|
||||
|
||||
with mock.patch.object(sys, "argv"):
|
||||
import job_watcher as client
|
||||
|
||||
class TestBlob(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.properties = object
|
||||
|
||||
|
||||
class TestJobWatcher(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.cwd = os.path.dirname(os.path.abspath(__file__))
|
||||
return super(TestJobWatcher, self).setUp()
|
||||
|
||||
def test_check_valid_dir(self):
|
||||
|
||||
def test_watcher_check_valid_dir(self):
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._check_valid_dir(None)
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._check_valid_dir("test")
|
||||
|
||||
client._check_valid_dir("//test")
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._check_valid_dir(1)
|
||||
self.assertEqual(client._check_valid_dir(CWD), CWD)
|
||||
|
||||
self.assertEqual(client._check_valid_dir(self.cwd), self.cwd)
|
||||
@mock.patch.object(client, 'storage_client')
|
||||
@mock.patch.object(client, '_download_output')
|
||||
def test_watcher_track_completed_outputs(self, mock_download, mock_storage):
|
||||
blob = namedtuple("Blob", "name, properties")
|
||||
mock_storage.list_blobs.return_value = [
|
||||
blob("job_output.exr", mock.Mock(content_length=1)),
|
||||
blob("subdir/job_output.png", mock.Mock(content_length=1)),
|
||||
blob("thumbs/0.png", mock.Mock(content_length=1)),
|
||||
blob("logs/frame_0.log", mock.Mock(content_length=1)),
|
||||
blob("logs/frame_0_error.log", mock.Mock(content_length=1))]
|
||||
|
||||
@mock.patch.object(client, "_check_valid_dir")
|
||||
@mock.patch('job_watcher.os')
|
||||
def test_download_tasks_outputs(self, mock_os, mock_check_valid_dir):
|
||||
|
||||
client._download_task_outputs(None, [], None)
|
||||
self.assertFalse(mock_os.path.join.called, "Output list is empty")
|
||||
|
||||
mock_task = mock.create_autospec(Task)
|
||||
mock_outputs = [{'type': 'TaskOutput', 'name': 'test.png'}]
|
||||
mock_check_valid_dir.return_value = "test_dir"
|
||||
mock_os.path.isfile.return_value = False
|
||||
|
||||
client._download_task_outputs(mock_task, mock_outputs, "test_dir")
|
||||
mock_os.path.join.assert_called_with("test_dir", "test.png")
|
||||
mock_task.get_output.assert_called_with({'type': 'TaskOutput', 'name': 'test.png'}, "test_dir",
|
||||
callback=mock.ANY, block=100000)
|
||||
|
||||
@mock.patch.object(client, '_download_task_outputs')
|
||||
def test_track_completed_tasks(self, mock_download_task_outputs):
|
||||
|
||||
mock_job = mock.create_autospec(SubmittedJob)
|
||||
|
||||
mock_job.get_tasks.side_effect = RestCallException("RestCallException", "RestCallExceptionRaised", None)
|
||||
client._track_completed_outputs("container", "\\test_dir")
|
||||
mock_storage.list_blobs.assert_called_with("container")
|
||||
self.assertEqual(mock_download.call_count, 4)
|
||||
mock_download.assert_any_call('container', 'job_output.exr', '\\test_dir\\job_output.exr', 1)
|
||||
mock_download.assert_any_call('container', 'subdir/job_output.png', '\\test_dir\\subdir\\job_output.png', 1)
|
||||
mock_download.assert_any_call('container', 'logs/frame_0.log', '\\test_dir\\logs\\frame_0.log', 1)
|
||||
mock_download.assert_any_call('container', 'logs/frame_0_error.log', '\\test_dir\\logs\\frame_0_error.log', 1)
|
||||
|
||||
def test_watcher_check_job_stopped(self):
|
||||
mock_job = mock.create_autospec(models.CloudJob)
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._track_completed_tasks(mock_job, "test_dir")
|
||||
|
||||
mock_job.get_tasks.side_effect = None
|
||||
mock_job.get_tasks.return_value = [1, 2, 3]
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._track_completed_tasks(mock_job, "test_dir")
|
||||
|
||||
mock_task1 = mock.create_autospec(Task)
|
||||
mock_task1.status = "Complete"
|
||||
mock_task1.id = 1
|
||||
mock_task1.outputs = []
|
||||
mock_task2 = mock.create_autospec(Task)
|
||||
mock_task2.status = "Complete"
|
||||
mock_task2.id = 2
|
||||
mock_task2.outputs = []
|
||||
|
||||
mock_job.number_tasks = 3
|
||||
|
||||
mock_job.get_tasks.return_value = [mock_task1, mock_task2]
|
||||
|
||||
client._track_completed_tasks(mock_job, "test_dir")
|
||||
|
||||
def test_retrieve_logs(self):
|
||||
|
||||
mock_job = mock.create_autospec(SubmittedJob)
|
||||
|
||||
client._retrieve_logs(mock_job)
|
||||
|
||||
mock_job.get_logs.side_effect = RestCallException("RestCallException", "RestCalleExceptionRaised", None)
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._retrieve_logs(mock_job)
|
||||
|
||||
mock_job.get_logs.side_effect = None
|
||||
mock_job.get_logs.return_value = {}
|
||||
|
||||
self.assertIsNone(client._retrieve_logs(mock_job))
|
||||
|
||||
mock_job.get_logs.return_value = {'upTo': None}
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._retrieve_logs(mock_job)
|
||||
|
||||
mock_job.get_logs.return_value = {'upTo': None,
|
||||
'messages': [{'timestamp': '1800-09-23bla',
|
||||
'text': 'This is a test message',
|
||||
'taskId': 2}]}
|
||||
self.assertTrue(mock_job.get_logs()['messages'])
|
||||
|
||||
@mock.patch.object(client, "_retrieve_logs")
|
||||
def test_check_job_stopped(self, mock_retrieve_logs):
|
||||
|
||||
mock_job = mock.create_autospec(SubmittedJob)
|
||||
|
||||
client._check_job_stopped(mock_job)
|
||||
mock_job.state = "test"
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._check_job_stopped(mock_job)
|
||||
|
||||
mock_job.status = "test"
|
||||
client._check_job_stopped(mock_job)
|
||||
|
||||
mock_job.status = "Error"
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._check_job_stopped(mock_job)
|
||||
self.assertTrue(mock_retrieve_logs.called)
|
||||
|
||||
mock_job.status = "OnHold"
|
||||
mock_job.state = models.JobState.disabled
|
||||
with self.assertRaises(RuntimeError):
|
||||
client._check_job_stopped(mock_job)
|
||||
|
||||
mock_job.status = "Complete"
|
||||
mock_job.state = models.JobState.completed
|
||||
self.assertTrue(client._check_job_stopped(mock_job))
|
||||
|
||||
mock_job.status = "NotStarted"
|
||||
mock_job.state = models.JobState.active
|
||||
self.assertFalse(client._check_job_stopped(mock_job))
|
||||
|
||||
mock_job.status = "InProgress"
|
||||
self.assertFalse(client._check_job_stopped(mock_job))
|
||||
|
||||
@mock.patch.object(client, "_check_job_stopped")
|
||||
@mock.patch.object(client, "_track_completed_tasks")
|
||||
def test_track_job_progress(self, mock_track_completed_tasks, mock_check_job_stopped):
|
||||
|
||||
mock_job_manager = mock.create_autospec(JobManager)
|
||||
mock_id = "test_id"
|
||||
mock_dwnld_dir = "test_dir"
|
||||
mock_job = mock.create_autospec(SubmittedJob)
|
||||
mock_job.status = "test"
|
||||
mock_job_manager.get_job.return_value = mock_job
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client.track_job_progress(mock_job_manager, mock_id, mock_dwnld_dir)
|
||||
|
||||
mock_job.status = "Error"
|
||||
mock_job.percentage = "30"
|
||||
mock_check_job_stopped.side_effect = RuntimeError("RuntimeError", "RuntimeError raised", None)
|
||||
with self.assertRaises(RuntimeError):
|
||||
client.track_job_progress(mock_job_manager, mock_id, mock_dwnld_dir)
|
||||
|
||||
mock_job.status = "InProgress"
|
||||
mock_check_job_stopped.side_effect = [False, True]
|
||||
self.assertFalse(client.track_job_progress(mock_job_manager, mock_id, mock_dwnld_dir))
|
||||
self.assertEqual(mock_job.update.call_count, 1)
|
||||
|
||||
mock_job.status = "Complete"
|
||||
mock_check_job_stopped.side_effect = None
|
||||
self.assertIsNone(client.track_job_progress(mock_job_manager, mock_id, mock_dwnld_dir), "track_job_progress returned None unexpectedly.")
|
||||
|
||||
@mock.patch("job_watcher.webbrowser")
|
||||
@mock.patch("job_watcher.AzureOAuth")
|
||||
def test_authentication(self, mock_azureoauth, mock_webbrowser):
|
||||
|
||||
|
||||
mock_azureoauth.get_unattended_session.return_value = "Auth"
|
||||
auth = client.authentication("test")
|
||||
self.assertEqual("Auth", auth)
|
||||
self.assertFalse(mock_azureoauth.get_session.called)
|
||||
|
||||
mock_azureoauth.get_unattended_session.side_effect = InvalidConfigException("InvalidConfigException", "InvalidConfigException raised", None)
|
||||
|
||||
client.authentication("test")
|
||||
self.assertTrue(mock_azureoauth.get_session.called)
|
||||
|
||||
mock_azureoauth.get_session.return_value = "Done!"
|
||||
auth = client.authentication("test")
|
||||
self.assertEqual("Done!", auth)
|
||||
mock_azureoauth.get_session.called_with(config="test")
|
||||
|
||||
mock_azureoauth.get_session.side_effect = InvalidConfigException("InvalidConfigException", "InvalidConfigException raised", None)
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client.authentication("test")
|
||||
|
||||
mock_azureoauth.get_authorization_token.side_effect = InvalidConfigException("InvalidConfigException", "InvalidConfigExceptio Raised", None)
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
client.authentication("test")
|
||||
|
||||
mock_azureoauth.get_session.side_effect = AuthenticationException("AuthenticationException", "AuthenticationException raised", None)
|
||||
|
||||
@mock.patch("job_watcher.Configuration")
|
||||
def test_generate_config(self, mock_cfg):
|
||||
|
||||
mock_data_path = "test"
|
||||
with self.assertRaises(EnvironmentError):
|
||||
client.generate_config(mock_data_path)
|
||||
|
||||
mock_cfg.side_effect = InvalidConfigException("InvalidConfigException", "InvalidConfigException Raised", None)
|
||||
|
||||
mock_data_path = os.path.dirname(os.path.normpath(__file__))
|
||||
with self.assertRaises(ValueError):
|
||||
client.generate_config(mock_data_path)
|
||||
|
||||
mock_cfg.side_effect = None
|
||||
self.assertEqual(client.generate_config(mock_data_path), mock_cfg())
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Batch Apps Maya Plugin
|
||||
# Azure Batch Maya Plugin
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#
|
||||
|
@ -44,6 +44,7 @@ except ImportError:
|
|||
|
||||
from ui_pools import PoolsUI, AzureBatchPoolInfo
|
||||
from pools import AzureBatchPools
|
||||
from environment import AzureBatchEnvironment
|
||||
import batch_extensions as batch
|
||||
from batch_extensions import models
|
||||
|
||||
|
@ -53,6 +54,9 @@ class AzureTestBatchPools(unittest.TestCase):
|
|||
def setUp(self):
|
||||
self.mock_self = mock.create_autospec(AzureBatchPools)
|
||||
self.mock_self._log = logging.getLogger("TestPools")
|
||||
self.mock_self.batch = mock.create_autospec(batch.BatchExtensionsClient)
|
||||
self.mock_self.batch.pool = mock.create_autospec(batch.operations.ExtendedPoolOperations)
|
||||
self.mock_self.environment = mock.create_autospec(AzureBatchEnvironment)
|
||||
return super(AzureTestBatchPools, self).setUp()
|
||||
|
||||
@mock.patch("pools.PoolsUI")
|
||||
|
@ -62,7 +66,7 @@ class AzureTestBatchPools(unittest.TestCase):
|
|||
|
||||
def test_pools_configure(self):
|
||||
session = mock.Mock(batch="batch")
|
||||
AzureBatchPools.configure(self.mock_self, session)
|
||||
AzureBatchPools.configure(self.mock_self, session, "env_manager")
|
||||
self.assertEqual("batch", self.mock_self.batch)
|
||||
|
||||
def test_pools_list_pools(self):
|
||||
|
@ -77,7 +81,13 @@ class AzureTestBatchPools(unittest.TestCase):
|
|||
self.mock_self._call = lambda x: [pool1, pool2]
|
||||
|
||||
ids = AzureBatchPools.list_pools(self.mock_self)
|
||||
self.assertEqual(ids, ['67890', '12345'])
|
||||
self.assertEqual(ids, [])
|
||||
self.assertEqual(len(self.mock_self.pools), 0)
|
||||
|
||||
pool1.id = "Maya_Pool_A"
|
||||
pool2.id = "Maya_Auto_Pool_B"
|
||||
ids = AzureBatchPools.list_pools(self.mock_self)
|
||||
self.assertEqual(ids, ["Maya_Pool_A"])
|
||||
self.assertEqual(len(self.mock_self.pools), 2)
|
||||
|
||||
def test_pools_get_pools(self):
|
||||
|
@ -111,6 +121,7 @@ class AzureTestBatchPools(unittest.TestCase):
|
|||
self.mock_self.batch.pool = mock.Mock(get="get")
|
||||
self.mock_self.batch.compute_node = mock.Mock(list="list")
|
||||
pool = mock.create_autospec(models.CloudPool)
|
||||
pool.application_licenses = ["maya", "arnold"]
|
||||
pool.display_name = "name"
|
||||
pool.current_dedicated_nodes = 3
|
||||
pool.target_dedicated_nodes = 5
|
||||
|
@ -119,6 +130,7 @@ class AzureTestBatchPools(unittest.TestCase):
|
|||
pool.max_tasks_per_node = 1
|
||||
pool.allocation_state = mock.Mock(value="allocating")
|
||||
pool.creation_time = datetime.datetime.now()
|
||||
pool.vm_size = "Standard_A1"
|
||||
self.mock_self.pools = [pool]
|
||||
pool_ui = mock.create_autospec(AzureBatchPoolInfo)
|
||||
pool_ui.index = 0
|
||||
|
@ -144,177 +156,99 @@ class AzureTestBatchPools(unittest.TestCase):
|
|||
|
||||
def test_pools_auto_pool(self):
|
||||
self.mock_self.pools = [mock.Mock(id='Maya_Pool_123'), mock.Mock(id='Maya_Auto_Pool_123')]
|
||||
self.mock_self.selected_pool = mock.Mock(index=0)
|
||||
self.mock_self.selected_pool = mock.Mock(index=1)
|
||||
self.assertTrue(AzureBatchPools.is_auto_pool(self.mock_self))
|
||||
self.mock_self.selected_pool = mock.Mock(index=1)
|
||||
self.mock_self.selected_pool = mock.Mock(index=0)
|
||||
self.assertFalse(AzureBatchPools.is_auto_pool(self.mock_self))
|
||||
self.mock_self.selected_pool = mock.Mock(index=2)
|
||||
self.assertFalse(AzureBatchPools.is_auto_pool(self.mock_self))
|
||||
|
||||
def test_get_pool_size(self):
|
||||
def test_pools_get_size(self):
|
||||
|
||||
self.mock_self.pools = [mock.Mock(target_size=5),
|
||||
mock.Mock(target_size="8"),
|
||||
mock.Mock(target_size=None)]
|
||||
self.mock_self.pools = [mock.Mock(target_dedicated_nodes=5),
|
||||
mock.Mock(target_dedicated_nodes="8"),
|
||||
mock.Mock(target_dedicated_nodes=None)]
|
||||
|
||||
self.mock_self.selected_pool = mock.Mock(index=0)
|
||||
self.assertEqual(BatchAppsPools.get_pool_size(self.mock_self), 5)
|
||||
self.assertEqual(AzureBatchPools.get_pool_size(self.mock_self), 5)
|
||||
|
||||
self.mock_self.selected_pool = mock.Mock(index=1)
|
||||
self.assertEqual(BatchAppsPools.get_pool_size(self.mock_self), 8)
|
||||
self.assertEqual(AzureBatchPools.get_pool_size(self.mock_self), 8)
|
||||
|
||||
self.mock_self.selected_pool = mock.Mock(index=2)
|
||||
self.assertEqual(BatchAppsPools.get_pool_size(self.mock_self), 0)
|
||||
self.assertEqual(AzureBatchPools.get_pool_size(self.mock_self), 0)
|
||||
|
||||
self.mock_self.selected_pool = mock.Mock(index=3)
|
||||
self.assertEqual(BatchAppsPools.get_pool_size(self.mock_self), 0)
|
||||
self.assertEqual(AzureBatchPools.get_pool_size(self.mock_self), 0)
|
||||
|
||||
def test_delete_pool(self):
|
||||
def test_pools_delete(self):
|
||||
|
||||
mock_pool = mock.create_autospec(Pool)
|
||||
mock_pool.delete.return_value = None
|
||||
mock_pool = mock.create_autospec(models.CloudPool)
|
||||
mock_pool.id = "pool id"
|
||||
self.mock_self.pools = [mock_pool]
|
||||
|
||||
def call(func):
|
||||
self.assertTrue(hasattr(func, "__call__"))
|
||||
return func()
|
||||
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_pool = mock.Mock(index=0)
|
||||
self.mock_self.ui = mock.create_autospec(PoolsUI)
|
||||
|
||||
BatchAppsPools.delete_pool(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 1)
|
||||
|
||||
mock_pool.delete.return_value = 1
|
||||
BatchAppsPools.delete_pool(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 2)
|
||||
|
||||
self.mock_self.selected_pool.index = 1
|
||||
BatchAppsPools.delete_pool(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 2)
|
||||
|
||||
def test_create_pool(self):
|
||||
|
||||
def call(func, **kwargs):
|
||||
self.assertTrue(hasattr(func, "__call__"))
|
||||
self.assertEqual(kwargs.get("target_size"), 5)
|
||||
return func(**kwargs)
|
||||
|
||||
self.mock_self._call = call
|
||||
self.mock_self.manager = mock.create_autospec(PoolManager)
|
||||
|
||||
BatchAppsPools.create_pool(self.mock_self, 5)
|
||||
self.mock_self.manager.create.assert_called_with(target_size=5)
|
||||
|
||||
@mock.patch("pools.maya")
|
||||
def test_resize_pool(self, mock_maya):
|
||||
|
||||
def call(func, *args):
|
||||
self.assertTrue(hasattr(func, "__call__"))
|
||||
self.assertEqual(args[0], 5)
|
||||
self.assertTrue(callable(func))
|
||||
return func(*args)
|
||||
|
||||
mock_pool = mock.create_autospec(Pool)
|
||||
mock_pool.delete.return_value = None
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_pool = mock.Mock(index=0)
|
||||
self.mock_self.ui = mock.create_autospec(PoolsUI)
|
||||
|
||||
AzureBatchPools.delete_pool(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 1)
|
||||
self.mock_self.batch.pool.delete.assert_called_with("pool id")
|
||||
|
||||
self.mock_self.batch.pool.delete.side_effect = AttributeError("boom")
|
||||
AzureBatchPools.delete_pool(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 2)
|
||||
self.mock_self.batch.pool.delete.assert_called_with("pool id")
|
||||
|
||||
self.mock_self.selected_pool.index = 1
|
||||
AzureBatchPools.delete_pool(self.mock_self)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 3)
|
||||
self.assertEqual(self.mock_self.batch.pool.delete.call_count, 2)
|
||||
|
||||
def test_pools_create(self):
|
||||
pool_obj = None
|
||||
def call(func, new_pool):
|
||||
self.assertTrue(callable(func))
|
||||
pool_obj = new_pool
|
||||
self.assertEqual(new_pool.target_dedicated_nodes, 5)
|
||||
self.assertEqual(new_pool.display_name, "Maya Pool for test job")
|
||||
self.assertEqual(new_pool.application_licenses, ['maya'])
|
||||
self.assertEqual(new_pool.virtual_machine_configuration.node_agent_sku_id, 'sku_id')
|
||||
self.assertEqual(new_pool.virtual_machine_configuration.image_reference.publisher, 'foo')
|
||||
return func(new_pool)
|
||||
|
||||
self.mock_self._call = call
|
||||
self.mock_self.environment.get_application_licenses.return_value = ['maya']
|
||||
self.mock_self.environment.get_image.return_value = {
|
||||
'publisher': 'foo', 'sku': 'bar', 'offer': 'baz', 'node_sku_id':'sku_id'}
|
||||
AzureBatchPools.create_pool(self.mock_self, 5, "test job")
|
||||
self.mock_self.batch.pool.add.assert_called_with(pool_obj)
|
||||
|
||||
@mock.patch("pools.maya")
|
||||
def test_pools_resize(self, mock_maya):
|
||||
|
||||
def call(func, *args):
|
||||
self.assertTrue(callable(func))
|
||||
self.assertEqual(args[1]['target_dedicated_nodes'], 5)
|
||||
return func(*args)
|
||||
|
||||
mock_pool = mock.create_autospec(models.CloudPool)
|
||||
mock_pool.id = "pool id"
|
||||
self.mock_self.pools = [mock_pool]
|
||||
|
||||
self.mock_self._call = call
|
||||
self.mock_self.selected_pool = mock.Mock(index=0)
|
||||
self.mock_self.ui = mock.create_autospec(PoolsUI)
|
||||
|
||||
BatchAppsPools.resize_pool(self.mock_self, 5)
|
||||
AzureBatchPools.resize_pool(self.mock_self, 5)
|
||||
self.assertFalse(self.mock_self.ui.refresh.call_count)
|
||||
|
||||
BatchAppsPools.resize_pool(self.mock_self, "5")
|
||||
AzureBatchPools.resize_pool(self.mock_self, "5")
|
||||
self.assertFalse(self.mock_self.ui.refresh.call_count)
|
||||
|
||||
BatchAppsPools.resize_pool(self.mock_self, None)
|
||||
AzureBatchPools.resize_pool(self.mock_self, None)
|
||||
self.assertEqual(self.mock_self.ui.refresh.call_count, 1)
|
||||
|
||||
|
||||
class TestPoolsCombined(unittest.TestCase):
|
||||
|
||||
@mock.patch("ui_pools.utils")
|
||||
@mock.patch("ui_pools.maya")
|
||||
@mock.patch("pools.maya")
|
||||
def test_pools(self, *args):
|
||||
|
||||
def add_tab(tab):
|
||||
self.assertFalse(tab.ready)
|
||||
|
||||
def call(func, *args, **kwargs):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func(*args, **kwargs)
|
||||
|
||||
layout = mock.Mock(add_tab=add_tab)
|
||||
pools = BatchAppsPools(layout, call)
|
||||
|
||||
creds = mock.create_autospec(Credentials)
|
||||
conf = mock.create_autospec(Configuration)
|
||||
session = mock.Mock(credentials=creds, config=conf)
|
||||
|
||||
pools.configure(session)
|
||||
|
||||
pools.manager = mock.create_autospec(PoolManager)
|
||||
|
||||
pool1 = mock.create_autospec(Pool)
|
||||
pool1.current_size = "3"
|
||||
pool1.target_size = "5"
|
||||
pool1.auto = False
|
||||
pool1.state = "500"
|
||||
pool1.id = "12345"
|
||||
pool1.max_tasks = "2"
|
||||
pool1.allocation_state = "allocating"
|
||||
pool1.created = "now"
|
||||
|
||||
pool2 = mock.create_autospec(Pool)
|
||||
pool2.id = "67890"
|
||||
pool2.auto = True
|
||||
|
||||
pools.manager.get_pools.return_value = []
|
||||
pools.manager.__len__.return_value = 0
|
||||
|
||||
pools.ui.prepare()
|
||||
self.assertIsNone(pools.selected_pool)
|
||||
self.assertEqual(pools.pools, [])
|
||||
self.assertTrue(pools.ui.ready)
|
||||
|
||||
pools.manager.get_pools.return_value = [pool1, pool2]
|
||||
pools.manager.__len__.return_value = 2
|
||||
|
||||
pools.ui.refresh()
|
||||
self.assertIsNone(pools.selected_pool)
|
||||
self.assertEqual(pools.pools, [pool1, pool2])
|
||||
self.assertEqual(len(pools.ui.pools_displayed), 2)
|
||||
self.assertEqual(pools.ui.pools_displayed[0].index, 0)
|
||||
|
||||
pools.ui.pools_displayed[0].on_expand()
|
||||
self.assertIsNone(pools.selected_pool)
|
||||
|
||||
pool1.created = str(datetime.datetime.now()).replace(' ', 'T')
|
||||
pools.ui.pools_displayed[0].on_expand()
|
||||
self.assertEqual(pools.ui.pools_displayed[0], pools.selected_pool)
|
||||
|
||||
pools.ui.pools_displayed[1].on_expand()
|
||||
self.assertIsNone(pools.selected_pool)
|
||||
|
||||
pools.ui.pools_displayed[0].on_expand()
|
||||
self.assertEqual(pools.get_pool_size(), 5)
|
||||
self.assertFalse(pools.is_auto_pool())
|
||||
|
||||
pools.resize_pool(10)
|
||||
pool1.resize.assert_called_with(10)
|
||||
pool1.resize.side_effect = Exception("failed!")
|
||||
|
||||
pools.resize_pool(8)
|
||||
self.assertIsNone(pools.selected_pool)
|
||||
|
||||
pools.ui.pools_displayed[0].on_expand()
|
||||
pools.ui.pools_displayed[0].collapse()
|
||||
self.assertIsNone(pools.selected_pool)
|
||||
|
||||
pools.ui.pools_displayed[0].on_expand()
|
||||
pools.delete_pool()
|
||||
pool1.delete.assert_called_with()
|
||||
self.assertIsNone(pools.selected_pool)
|
|
@ -46,11 +46,18 @@ from submission import AzureBatchSubmission, AzureBatchRenderJob
|
|||
from assets import AzureBatchAssets
|
||||
from pools import AzureBatchPools
|
||||
from environment import AzureBatchEnvironment
|
||||
from shared import AzureBatchSettings
|
||||
from exception import CancellationException
|
||||
|
||||
from batch_extensions import BatchExtensionsClient
|
||||
from batch_extensions.batch_auth import SharedKeyCredentials
|
||||
from batch_extensions import operations
|
||||
from batch_extensions import models
|
||||
|
||||
from azure.storage.blob import BlockBlobService
|
||||
|
||||
LIVE = True
|
||||
|
||||
def print_status(status):
|
||||
print(status)
|
||||
|
||||
|
@ -88,8 +95,8 @@ class TestBatchSubmission(unittest.TestCase):
|
|||
submission = AzureBatchSubmission("frame", "call")
|
||||
mock_mods.assert_called_with()
|
||||
mock_ui.assert_called_with(submission, "frame")
|
||||
mock_call.after_new.assert_called_with(mock.ANY)
|
||||
mock_call.after_open.assert_called_with(mock.ANY)
|
||||
#mock_call.after_new.assert_called_with(mock.ANY)
|
||||
#mock_call.after_open.assert_called_with(mock.ANY)
|
||||
|
||||
@mock.patch("submission.maya")
|
||||
def test_submission_start(self, mock_maya):
|
||||
|
@ -97,7 +104,7 @@ class TestBatchSubmission(unittest.TestCase):
|
|||
self.mock_self.ui = mock.create_autospec(SubmissionUI)
|
||||
self.mock_self.ui.render_module = "module"
|
||||
self.mock_self.renderer = mock.Mock()
|
||||
AzureBatchSubmission.start(self.mock_self, session, "assets", "pools")
|
||||
AzureBatchSubmission.start(self.mock_self, session, "assets", "pools", "env")
|
||||
self.mock_self.renderer.delete.assert_called_with()
|
||||
self.mock_self._configure_renderer.assert_called_with()
|
||||
self.mock_self.renderer.display.assert_called_with("module")
|
||||
|
@ -143,17 +150,17 @@ class TestBatchSubmission(unittest.TestCase):
|
|||
@mock.patch("submission.utils")
|
||||
@mock.patch("submission.maya")
|
||||
def test_submission_submit(self, mock_maya, mock_utils):
|
||||
def call(func):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func()
|
||||
def call(func, *args, **kwargs):
|
||||
self.assertTrue(callable(func))
|
||||
return func(*args, **kwargs)
|
||||
|
||||
mock_prog = mock.create_autospec(ProgressBar)
|
||||
mock_prog.is_cancelled.return_value = False
|
||||
mock_utils.ProgressBar.return_value = mock_prog
|
||||
self.mock_self._configure_pool = AzureBatchSubmission._configure_pool
|
||||
self.mock_self._check_outputs = AzureBatchSubmission._check_outputs
|
||||
mock_utils.format_scene_path.return_value = "test_file_path"
|
||||
self.mock_self._configure_pool = lambda t: AzureBatchSubmission._configure_pool(self.mock_self, t)
|
||||
self.mock_self._check_plugins.return_value = []
|
||||
self.mock_self.asset_manager.upload.return_value = ("a", "b", mock_prog)
|
||||
self.mock_self._get_os_flavor.return_value = 'Windows'
|
||||
self.mock_self.pool_manager.create_auto_pool.return_value = {'autoPool': 'auto-pool'}
|
||||
self.mock_self.pool_manager.create_pool.return_value = {'poolId': 'new-pool'}
|
||||
self.mock_self.renderer = mock.Mock()
|
||||
|
@ -161,154 +168,76 @@ class TestBatchSubmission(unittest.TestCase):
|
|||
self.mock_self.renderer.get_params.return_value = {"foo": "bar"}
|
||||
self.mock_self.renderer.get_title.return_value = "job name"
|
||||
self.mock_self._call = call
|
||||
mock_job = mock.create_autospec(models.ExtendedJobParameter)
|
||||
self.mock_self.batch.job.jobparameter_from_json.return_value = mock_job
|
||||
|
||||
self.mock_self.ui.get_pool.return_value = {1:"pool"}
|
||||
self.mock_self.asset_manager.upload.return_value = ("files", "maps", mock_prog)
|
||||
self.mock_self.asset_manager.upload.return_value = ("files", "maps", "thumbs", mock_prog)
|
||||
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 1)
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
|
||||
self.mock_self.ui.get_pool.return_value = {1:4}
|
||||
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 1)
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
self.mock_self.pool_manager.create_auto_pool.assert_called_with(4, "job name")
|
||||
self.mock_self.batch.job.add.assert_called_with(mock_job)
|
||||
self.mock_self.batch.job.jobparameter_from_json.assert_called_with(
|
||||
{'poolInfo': {'autoPool': 'auto-pool'},
|
||||
'displayName': 'job name',
|
||||
'id': mock.ANY,
|
||||
'applicationTemplateInfo': {
|
||||
'parameters': {'sceneFile': 'test_file_path', 'outputs': mock.ANY, 'assetScript': 'maps', 'foo': 'bar', 'projectData': 'files', 'thumbScript': 'thumbs'},
|
||||
'filePath': os.path.join(os.environ['AZUREBATCH_TEMPLATES'], 'arnold-basic-windows.json')},
|
||||
'metadata': [{'name': 'JobType', 'value': 'Maya'}]})
|
||||
|
||||
job.submit.assert_called_with()
|
||||
self.assertEqual(job.instances, 4)
|
||||
|
||||
self.mock_self.ui.get_pool.return_value = {2:4}
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 1)
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
self.mock_self.batch.job.add.assert_called_with(mock_job)
|
||||
self.mock_self.batch.job.jobparameter_from_json.assert_called_with(
|
||||
{'poolInfo': {'poolId': '4'},
|
||||
'displayName': 'job name',
|
||||
'id': mock.ANY,
|
||||
'applicationTemplateInfo': {
|
||||
'parameters': {'sceneFile': 'test_file_path', 'outputs': mock.ANY, 'assetScript': 'maps', 'foo': 'bar', 'projectData': 'files', 'thumbScript': 'thumbs'},
|
||||
'filePath': os.path.join(os.environ['AZUREBATCH_TEMPLATES'], 'arnold-basic-windows.json')},
|
||||
'metadata': [{'name': 'JobType', 'value': 'Maya'}]})
|
||||
|
||||
job.submit.assert_called_with()
|
||||
self.assertEqual(job.pool, '4')
|
||||
|
||||
self.mock_self.check_outputs.side_effect = ValueError("No camera")
|
||||
self.mock_self._check_outputs.side_effect = ValueError("No camera")
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 2)
|
||||
self.mock_self.check_outputs.side_effect = None
|
||||
self.mock_self._check_outputs.side_effect = None
|
||||
|
||||
self.mock_self.ui.get_pool.return_value = {3: 4}
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 2)
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
|
||||
job.submit.assert_called_with()
|
||||
job.submit.call_count = 0
|
||||
self.mock_self.pool_manager.create_pool.assert_called_with(4)
|
||||
self.mock_self.batch.job.add.assert_called_with(mock_job)
|
||||
self.mock_self.batch.job.add.call_count = 0
|
||||
self.mock_self.pool_manager.create_pool.assert_called_with(4, 'job name')
|
||||
|
||||
mock_prog.is_cancelled.return_value = True
|
||||
mock_prog.is_cancelled.side_effect = CancellationException("cancelled")
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.info.call_count, 4)
|
||||
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
self.assertEqual(job.submit.call_count, 0)
|
||||
self.assertEqual(self.mock_self.batch.job.add.call_count, 0)
|
||||
|
||||
mock_prog.is_cancelled.return_value = False
|
||||
mock_prog.is_cancelled.side_effect = None
|
||||
self.mock_self.pool_manager.create_pool.side_effect = Exception("Logged out!")
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 2)
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
self.assertEqual(self.mock_self.batch.job.add.call_count, 0)
|
||||
|
||||
self.mock_self.pool_manager.create_pool.side_effect = ValueError("Bad data")
|
||||
AzureBatchSubmission.submit(self.mock_self)
|
||||
self.assertEqual(mock_maya.error.call_count, 3)
|
||||
self.mock_self.renderer.disable.assert_called_with(True)
|
||||
self.assertEqual(job.submit.call_count, 0)
|
||||
|
||||
|
||||
class TestSubmissionCombined(unittest.TestCase):
|
||||
|
||||
@mock.patch("submission.utils")
|
||||
@mock.patch("ui_submission.utils")
|
||||
@mock.patch("ui_submission.maya")
|
||||
@mock.patch("submission.callback")
|
||||
@mock.patch("submission.maya")
|
||||
def test_submission(self, *args):
|
||||
|
||||
mock_callback = args[1]
|
||||
mock_maya = args[0]
|
||||
mock_maya.mel.return_value = "Renderer"
|
||||
mock_maya.get_list.return_value = ["1","2","3"]
|
||||
mock_maya.get_attr.return_value = True
|
||||
|
||||
ui_maya = args[2]
|
||||
ui_maya.radio_group.return_value = 2
|
||||
ui_maya.menu.return_value = "12345"
|
||||
ui_maya.int_slider.return_value = 6
|
||||
|
||||
def add_tab(tab):
|
||||
pass
|
||||
|
||||
def call(func, *args, **kwargs):
|
||||
self.assertTrue(hasattr(func, '__call__'))
|
||||
return func()
|
||||
|
||||
mock_utils = args[4]
|
||||
mock_prog = mock.create_autospec(ProgressBar)
|
||||
mock_prog.is_cancelled.return_value = False
|
||||
mock_utils.ProgressBar.return_value = mock_prog
|
||||
|
||||
layout = mock.Mock(add_tab=add_tab)
|
||||
sub = AzureBatchSubmission(layout, call)
|
||||
self.assertEqual(len(sub.modules), 4)
|
||||
self.assertTrue(mock_callback.after_new.called)
|
||||
self.assertTrue(mock_callback.after_open.called)
|
||||
|
||||
creds = mock.create_autospec(Credentials)
|
||||
conf = mock.create_autospec(Configuration)
|
||||
session = mock.Mock(credentials=creds, config=conf)
|
||||
assets = mock.create_autospec(BatchAppsAssets)
|
||||
pools = mock.create_autospec(BatchAppsPools)
|
||||
env = mock.create_autospec(BatchAppsEnvironment)
|
||||
env.license = {"license":"test"}
|
||||
env.environment_variables = {"env":"val"}
|
||||
env.plugins = {"plugins":"test"}
|
||||
|
||||
sub.start(session, assets, pools, env)
|
||||
|
||||
mock_maya.mel.return_value = "Renderer_A"
|
||||
sub.ui.refresh()
|
||||
|
||||
sub.asset_manager.upload.return_value = (["abc"], {}, mock_prog)
|
||||
sub.asset_manager.collect_assets.return_value = {'assets':['abc'],
|
||||
'pathmaps':'mapping'}
|
||||
sub.job_manager = mock.create_autospec(JobManager)
|
||||
job = mock.create_autospec(JobSubmission)
|
||||
job.required_files = mock.Mock()
|
||||
job.required_files.upload.return_value = []
|
||||
sub.job_manager.create_job.return_value = job
|
||||
|
||||
sub.submit()
|
||||
self.assertEqual(mock_maya.error.call_count, 0)
|
||||
self.assertEqual(sub.pool_manager.create_pool.call_count, 0)
|
||||
job.submit.assert_called_with()
|
||||
self.assertEqual(job.params, {"setting_A":1, "setting_B":2})
|
||||
job.add_file_collection.assert_called_with(["abc"])
|
||||
self.assertEqual(job.pool, "12345")
|
||||
|
||||
mock_maya.get_attr.return_value = False
|
||||
sub.submit()
|
||||
mock_maya.error.assert_called_with(mock.ANY)
|
||||
mock_maya.error.call_count = 0
|
||||
mock_maya.get_attr.return_value = True
|
||||
|
||||
ui_maya.menu.return_value = None
|
||||
sub.submit()
|
||||
mock_maya.error.assert_called_with("No pool selected.")
|
||||
mock_maya.error.call_count = 0
|
||||
|
||||
ui_maya.radio_group.return_value = 1
|
||||
sub.submit()
|
||||
self.assertEqual(mock_maya.error.call_count, 0)
|
||||
self.assertEqual(sub.pool_manager.create_pool.call_count, 0)
|
||||
job.submit.assert_called_with()
|
||||
self.assertEqual(job.instances, 6)
|
||||
|
||||
ui_maya.radio_group.return_value = 3
|
||||
sub.submit()
|
||||
self.assertEqual(mock_maya.error.call_count, 0)
|
||||
sub.pool_manager.create_pool.assert_called_with(6)
|
||||
job.submit.assert_called_with()
|
||||
|
||||
sub.asset_manager.upload.return_value = [("failed", Exception("boom"))]
|
||||
sub.submit()
|
||||
self.assertEqual(mock_maya.error.call_count, 1)
|
||||
self.assertEqual(self.mock_self.batch.job.add.call_count, 0)
|
||||
|
|
Загрузка…
Ссылка в новой задаче