From ff418654a5bcc76d054e91ee1bd9ee5201c19178 Mon Sep 17 00:00:00 2001 From: Greg Denton Date: Mon, 1 Jul 2019 14:59:33 -0700 Subject: [PATCH 1/3] Adding owner and deed wrappers (#362) * adding owner and deed wrappers. api.getOwner now returns an owner wrapper. * adding owner tests --- pycue/opencue/api.py | 5 +- pycue/opencue/wrappers/deed.py | 93 ++++++++++++++++++++++ pycue/opencue/wrappers/owner.py | 86 ++++++++++++++++++++ pycue/tests/api_test.py | 2 +- pycue/tests/wrappers/deed_test.py | 105 ++++++++++++++++++++++++ pycue/tests/wrappers/owner_test.py | 123 +++++++++++++++++++++++++++++ 6 files changed, 411 insertions(+), 3 deletions(-) create mode 100644 pycue/opencue/wrappers/deed.py create mode 100644 pycue/opencue/wrappers/owner.py create mode 100644 pycue/tests/wrappers/deed_test.py create mode 100644 pycue/tests/wrappers/owner_test.py diff --git a/pycue/opencue/api.py b/pycue/opencue/api.py index 43560120e..2c05a0c10 100644 --- a/pycue/opencue/api.py +++ b/pycue/opencue/api.py @@ -50,6 +50,7 @@ from .wrappers.host import Host, NestedHost from .wrappers.job import Job from .wrappers.layer import Layer +from .wrappers.owner import Owner from .wrappers.proc import Proc from .wrappers.service import Service from .wrappers.show import Show @@ -500,8 +501,8 @@ def getHost(uniq): @util.grpcExceptionParser def getOwner(id): """Return an Owner object from the id or name.""" - return Cuebot.getStub('owner').GetOwner( - host_pb2.OwnerGetOwnerRequest(name=id), timeout=Cuebot.Timeout).owner + return Owner(Cuebot.getStub('owner').GetOwner( + host_pb2.OwnerGetOwnerRequest(name=id), timeout=Cuebot.Timeout).owner) # # Filters diff --git a/pycue/opencue/wrappers/deed.py b/pycue/opencue/wrappers/deed.py new file mode 100644 index 000000000..dd1120677 --- /dev/null +++ b/pycue/opencue/wrappers/deed.py @@ -0,0 +1,93 @@ +# Copyright (c) 2018 Sony Pictures Imageworks Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + +""" +Project: opencue + +Module: deed.py - deed object + +""" + +import opencue.wrappers.host +from opencue.compiled_proto import host_pb2 +from opencue.cuebot import Cuebot + + +class Deed(object): + + def __init__(self, comment=None): + self.data = comment + self.stub = Cuebot.getStub('comment') + + def delete(self): + """Delete this comment""" + self.stub.Delete(host_pb2.DeedDeleteRequest(deed=self.data), timeout=Cuebot.Timeout) + + def getHost(self): + """Return the host for this deed + @rtype: Host Wrapper + @return: Host associated with this deed""" + return opencue.wrappers.host.Host( + self.stub.GetHost(host_pb2.DeedGetHostRequest(deed=self.data), + timeout=Cuebot.Timeout).host) + + def getOwner(self): + """Returns the owner for these settings.""" + return opencue.wrappers.owner.Owner( + self.stub.GetOwner(host_pb2.DeedGetOwnerRequest(deed=self.data), + timeout=Cuebot.Timeout).owner) + + def setBlackoutTime(self, startTime, stopTime): + """Sets a blackout time for the host. + @type startTime: int + @param startTime: blackout start time + @type stopTime: int + @param stopTime: blackout stop time""" + self.stub.SetBlackoutTime( + host_pb2.DeedSetBlackoutTimeRequest(deed=self.data, + start_time=startTime, + stop_time=stopTime), + timeout=Cuebot.Timeout) + + def setBlackoutTimeEnabled(self, enabled): + """Enable/Disable blackout time without changing the times. + @type enabled: bool + @param enabled: enable/disable blackout time""" + self.stub.SetBlackoutTimeEnabled( + host_pb2.DeedSetBlackoutTimeEnabledRequest(deed=self.data, + enabled=enabled), + timeout=Cuebot.Timeout) + + def id(self): + return self.data.id + + def host(self): + return self.data.host + + def owner(self): + return self.data.owner + + def show(self): + return self.data.show + + def blackout(self): + return self.data.blackout + + def blackoutStartTime(self): + return self.data.blackout_start_time + + def blackoutStopTime(self): + return self.data.blackout_stop_time diff --git a/pycue/opencue/wrappers/owner.py b/pycue/opencue/wrappers/owner.py new file mode 100644 index 000000000..5318e39f9 --- /dev/null +++ b/pycue/opencue/wrappers/owner.py @@ -0,0 +1,86 @@ +# Copyright (c) 2018 Sony Pictures Imageworks Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +""" +Project: opencue Library + +Module: owner.py - opencue Library implementation of a owner + +""" + +import opencue.wrappers.deed +import opencue.wrappers.host +from opencue import Cuebot +from opencue.compiled_proto import host_pb2 + + +class Owner(object): + def __init__(self, owner=None): + """Host class initialization""" + self.data = owner + self.stub = Cuebot.getStub('owner') + + def delete(self): + """Delete the owner record""" + self.stub.Delete(host_pb2.OwnerDeleteRequest(owner=self.data), timeout=Cuebot.Timeout) + + def getDeeds(self): + """Return the list of deeds for the owner + @rtype: List + @return: The list of deeds associated with this owner.""" + response = self.stub.GetDeeds(host_pb2.OwnerGetDeedsRequest(owner=self.data), + timeout=Cuebot.Timeout) + return [opencue.wrappers.deed.Deed(deed) for deed in response.deeds.deeds] + + def getHosts(self): + """Get a list of all hosts this owner is responsible for. + @rtype: List + @return: List of hosts the owned by this owner.""" + response = self.stub.GetHosts(host_pb2.OwnerGetHostsRequest(owner=self.data), + timeout=Cuebot.Timeout) + return [opencue.wrappers.host.Host(host) for host in response.hosts.hosts] + + def getOwner(self, name): + """Return an owner by name. + @type: str + @param: Name of the owner + @rtype: Owner + @return: Owner that matches the specified name""" + return Owner(self.stub.GetOwner(host_pb2.OwnerGetOwnerRequest(name=name), + timeout=Cuebot.Timeout).owner) + + def setShow(self, show): + """Set the show for the owner. + @type: str + @param: name of the show""" + self.stub.SetShow(host_pb2.OwnerSetShowRequest(owner=self.data, show=show), + timeout=Cuebot.Timeout) + + def takeOwnership(self, host): + """Set the hosts new owner settings.""" + self.stub.TakeOwnership(host_pb2.OwnerTakeOwnershipRequest(owner=self.data, host=host), + timeout=Cuebot.Timeout) + + def hostCount(self): + return self.data.host_count + + def id(self): + return self.data.id + + def name(self): + return self.data.name + + def show(self): + return self.data.show diff --git a/pycue/tests/api_test.py b/pycue/tests/api_test.py index bf04b978f..9aecf421c 100644 --- a/pycue/tests/api_test.py +++ b/pycue/tests/api_test.py @@ -624,7 +624,7 @@ def testGetOwner(self, getStubMock): stubMock.GetOwner.assert_called_with( host_pb2.OwnerGetOwnerRequest(name=ownerName), timeout=mock.ANY) - self.assertEqual(ownerName, owner.name) + self.assertEqual(ownerName, owner.name()) class FilterTests(unittest.TestCase): diff --git a/pycue/tests/wrappers/deed_test.py b/pycue/tests/wrappers/deed_test.py new file mode 100644 index 000000000..d366589e7 --- /dev/null +++ b/pycue/tests/wrappers/deed_test.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +# Copyright (c) 2018 Sony Pictures Imageworks Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import +import mock +import unittest + +import opencue +from opencue.compiled_proto import host_pb2 + + +TEST_DEED_ID = 'ddd-dd-dddd' +TEST_DEED_OWNER = 'testDeedOwner' +TEST_HOST_ID = 'hhh-hh-hhhh' + + +@mock.patch('opencue.cuebot.Cuebot.getStub') +class DeedTests(unittest.TestCase): + + def testDelete(self, getStubMock): + stubMock = mock.Mock() + stubMock.Delete.return_value = host_pb2.DeedDeleteResponse() + getStubMock.return_value = stubMock + + deed = opencue.wrappers.deed.Deed(host_pb2.Deed(id=TEST_DEED_ID)) + deed.delete() + + stubMock.Delete.assert_called_with( + host_pb2.DeedDeleteRequest(deed=deed.data), timeout=mock.ANY) + + def testGetHost(self, getStubMock): + stubMock = mock.Mock() + stubMock.GetHost.return_value = host_pb2.DeedGetHostResponse( + host=host_pb2.Host(id=TEST_HOST_ID)) + getStubMock.return_value = stubMock + + deed = opencue.wrappers.deed.Deed(host_pb2.Deed(id=TEST_DEED_ID)) + host = deed.getHost() + + stubMock.GetHost.assert_called_with( + host_pb2.DeedGetHostRequest(deed=deed.data), timeout=mock.ANY) + self.assertEqual(host.id(), TEST_HOST_ID) + + def testGetOwner(self, getStubMock): + stubMock = mock.Mock() + stubMock.GetOwner.return_value = host_pb2.DeedGetOwnerResponse( + owner=host_pb2.Owner(name=TEST_DEED_OWNER)) + getStubMock.return_value = stubMock + + deed = opencue.wrappers.deed.Deed(host_pb2.Deed(id=TEST_DEED_ID)) + owner = deed.getOwner() + + stubMock.GetOwner.assert_called_with( + host_pb2.DeedGetOwnerRequest(deed=deed.data), timeout=mock.ANY) + self.assertEqual(owner.name(), TEST_DEED_OWNER) + + def testSetBlackoutTime(self, getStubMock): + stubMock = mock.Mock() + stubMock.SetBlackoutTime.return_value = host_pb2.DeedSetBlackoutTimeResponse() + getStubMock.return_value = stubMock + + testStartTime = 100 + testStopTime = 200 + deed = opencue.wrappers.deed.Deed(host_pb2.Deed(id=TEST_DEED_ID)) + deed.setBlackoutTime(testStartTime, testStopTime) + + stubMock.SetBlackoutTime.assert_called_with( + host_pb2.DeedSetBlackoutTimeRequest(deed=deed.data, + start_time=testStartTime, + stop_time=testStopTime), + timeout=mock.ANY) + + def testSetBlackoutTimeEnabled(self, getStubMock): + stubMock = mock.Mock() + stubMock.SetBlackoutTimeEnabled.return_value = host_pb2.DeedSetBlackoutTimeEnabledResponse() + getStubMock.return_value = stubMock + + testBlackoutEnabled = True + deed = opencue.wrappers.deed.Deed(host_pb2.Deed(id=TEST_DEED_ID)) + deed.setBlackoutTimeEnabled(testBlackoutEnabled) + + stubMock.SetBlackoutTimeEnabled.assert_called_with( + host_pb2.DeedSetBlackoutTimeEnabledRequest(deed=deed.data, + enabled=testBlackoutEnabled), + timeout=mock.ANY) + + +if __name__ == '__main__': + unittest.main() diff --git a/pycue/tests/wrappers/owner_test.py b/pycue/tests/wrappers/owner_test.py new file mode 100644 index 000000000..a2d750eaf --- /dev/null +++ b/pycue/tests/wrappers/owner_test.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +# Copyright (c) 2018 Sony Pictures Imageworks Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import +import mock +import unittest + +import opencue +from opencue.compiled_proto import host_pb2 + + +TEST_DEED_ID = 'ddd-dd-dddd' +TEST_HOST_ID = 'hhh-hh-hhhh' +TEST_OWNER_ID = 'ooo-oo-oooo' +TEST_OWNER_NAME = 'testOwner' +TEST_SHOW_NAME = 'testShow' + + + +@mock.patch('opencue.cuebot.Cuebot.getStub') +class OwnerTests(unittest.TestCase): + + def testDelete(self, getStubMock): + stubMock = mock.Mock() + stubMock.Delete.return_value = host_pb2.OwnerDeleteResponse() + getStubMock.return_value = stubMock + + owner = opencue.wrappers.owner.Owner( + host_pb2.Owner(id=TEST_OWNER_ID, name=TEST_OWNER_NAME)) + owner.delete() + + stubMock.Delete.assert_called_with( + host_pb2.OwnerDeleteRequest(owner=owner.data), timeout=mock.ANY) + + def testGetDeeds(self, getStubMock): + stubMock = mock.Mock() + stubMock.GetDeeds.return_value = host_pb2.OwnerGetDeedsResponse( + deeds=host_pb2.DeedSeq(deeds=[host_pb2.Deed(id=TEST_DEED_ID)])) + getStubMock.return_value = stubMock + + owner = opencue.wrappers.owner.Owner( + host_pb2.Owner(id=TEST_OWNER_ID, name=TEST_OWNER_NAME)) + deeds = owner.getDeeds() + + stubMock.GetDeeds.assert_called_with( + host_pb2.OwnerGetDeedsRequest(owner=owner.data), timeout=mock.ANY) + self.assertEqual(len(deeds), 1) + self.assertEqual(deeds[0].id(), TEST_DEED_ID) + + def testGetHosts(self, getStubMock): + stubMock = mock.Mock() + stubMock.GetHosts.return_value = host_pb2.OwnerGetHostsResponse( + hosts=host_pb2.HostSeq(hosts=[host_pb2.Host(id=TEST_HOST_ID)])) + getStubMock.return_value = stubMock + + owner = opencue.wrappers.owner.Owner( + host_pb2.Owner(id=TEST_OWNER_ID, name=TEST_OWNER_NAME)) + hosts = owner.getHosts() + + stubMock.GetHosts.assert_called_with( + host_pb2.OwnerGetHostsRequest(owner=owner.data), timeout=mock.ANY) + self.assertEqual(len(hosts), 1) + self.assertEqual(hosts[0].id(), TEST_HOST_ID) + + def testGetOwner(self, getStubMock): + stubMock = mock.Mock() + stubMock.GetOwner.return_value = host_pb2.OwnerGetOwnerResponse( + owner=host_pb2.Owner(id=TEST_OWNER_ID, name=TEST_OWNER_NAME)) + getStubMock.return_value = stubMock + + owner = opencue.wrappers.owner.Owner() + response = owner.getOwner(TEST_OWNER_NAME) + + stubMock.GetOwner.assert_called_with( + host_pb2.OwnerGetOwnerRequest(name=TEST_OWNER_NAME), timeout=mock.ANY) + self.assertEqual(response.id(), TEST_OWNER_ID) + self.assertEqual(response.name(), TEST_OWNER_NAME) + + def testSetShow(self, getStubMock): + stubMock = mock.Mock() + stubMock.SetShow.return_value = host_pb2.OwnerSetShowResponse() + getStubMock.return_value = stubMock + + owner = opencue.wrappers.owner.Owner( + host_pb2.Owner(id=TEST_OWNER_ID, name=TEST_OWNER_NAME)) + owner.setShow(TEST_SHOW_NAME) + + stubMock.SetShow.assert_called_with( + host_pb2.OwnerSetShowRequest(owner=owner.data, show=TEST_SHOW_NAME), + timeout=mock.ANY) + + def testTakeOwnership(self, getStubMock): + stubMock = mock.Mock() + stubMock.TakeOwnership.return_value = host_pb2.OwnerTakeOwnershipResponse() + getStubMock.return_value = stubMock + + owner = opencue.wrappers.owner.Owner( + host_pb2.Owner(id=TEST_OWNER_ID, name=TEST_OWNER_NAME)) + owner.takeOwnership(TEST_HOST_ID) + + stubMock.TakeOwnership.assert_called_with( + host_pb2.OwnerTakeOwnershipRequest(owner=owner.data, host=TEST_HOST_ID), + timeout=mock.ANY) + + +if __name__ == '__main__': + unittest.main() From d5c84801e90b35f3b597313a9c98ecef11948ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal=20McMullan?= Date: Mon, 1 Jul 2019 23:00:11 +0100 Subject: [PATCH 2/3] honor the user-specified 'Chunk Size' value #365 (#366) --- cuesubmit/cuesubmit/ui/Submit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuesubmit/cuesubmit/ui/Submit.py b/cuesubmit/cuesubmit/ui/Submit.py index a7800d91f..a2aa792a7 100644 --- a/cuesubmit/cuesubmit/ui/Submit.py +++ b/cuesubmit/cuesubmit/ui/Submit.py @@ -257,7 +257,7 @@ def jobDataChanged(self): layerType=self.jobTypeSelector.text(), cmd=self.settingsWidget.getCommandData(), layerRange=self.frameBox.frameSpecInput.text(), - chunk=None, + chunk=self.chunkInput.text(), cores=self.coresInput.text(), env=None, services=[i.strip() for i in self.servicesSelector.text().split(',')], From 388399d46394266b05da59410406f577b3f0eb52 Mon Sep 17 00:00:00 2001 From: Greg Denton Date: Mon, 1 Jul 2019 15:14:19 -0700 Subject: [PATCH 3/3] Adding missing wrapper function for RegisterOutputPath (#363) * adding missing wrapper function for RegisterOutputPath * removed unnecessary line from readme. --- cuebot/README.md | 1 - pycue/opencue/wrappers/layer.py | 9 +++++++++ pycue/tests/wrappers/layer_test.py | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cuebot/README.md b/cuebot/README.md index 6b66efe75..0e956f3b0 100644 --- a/cuebot/README.md +++ b/cuebot/README.md @@ -41,4 +41,3 @@ NOTE: Only OpenCue developers will need to do this setup. If you just want to us View > Tool Windows > Gradle. Refresh the Gradle project and run the build task, which will run compilation and tests. - diff --git a/pycue/opencue/wrappers/layer.py b/pycue/opencue/wrappers/layer.py index 6763f8b3e..82531c34b 100644 --- a/pycue/opencue/wrappers/layer.py +++ b/pycue/opencue/wrappers/layer.py @@ -204,6 +204,15 @@ def createFrameByFrameDependency(self, layer): # @param kill: wheather or not to kill the frames as well""" # self.proxy.unbookProcs([a.proxy for a in subs], number, kill) + def registerOutputPath(self, outputPath): + """Register an output with the given layer. The output paths are sent in the opencue email. + @type outputPath: str + @param outputPath: Output path to register + """ + self.stub.RegisterOutputPath( + job_pb2.LayerRegisterOutputPathRequest(layer=self.data, spec=outputPath), + timeout=Cuebot.Timeout) + def reorderFrames(self, range, order): """Reorders the specified frame range on this layer. @type range: string diff --git a/pycue/tests/wrappers/layer_test.py b/pycue/tests/wrappers/layer_test.py index 116a64a03..7607a9455 100644 --- a/pycue/tests/wrappers/layer_test.py +++ b/pycue/tests/wrappers/layer_test.py @@ -317,6 +317,20 @@ def testCreateFrameByFrameDependency(self, getStubMock): timeout=mock.ANY) self.assertEqual(depend.id(), dependId) + def testRegisterOutputPath(self, getStubMock): + stubMock = mock.Mock() + stubMock.RegisterOutputPath.return_value = job_pb2.LayerRegisterOutputPathResponse() + getStubMock.return_value = stubMock + + outputPath = '/test/output/path' + layer = opencue.wrappers.layer.Layer( + job_pb2.Layer(name=TEST_LAYER_NAME)) + layer.registerOutputPath(outputPath) + + stubMock.RegisterOutputPath.assert_called_with( + job_pb2.LayerRegisterOutputPathRequest(layer=layer.data, spec=outputPath), + timeout=mock.ANY) + def testReorderFrames(self, getStubMock): stubMock = mock.Mock() stubMock.ReorderFrames.return_value = job_pb2.LayerReorderFramesResponse()