modify tests

Change-Id: If6f79f5848306994061ae4748b636ec5025f5ba3
This commit is contained in:
takehirokaneko 2015-03-20 09:58:34 +09:00
parent 7392bbe2ed
commit 4aecf30afd
39 changed files with 657 additions and 405 deletions

View File

@ -15,7 +15,6 @@ import copy
import json
import logging
import requests
from rackclient.openstack.common.gettextutils import _
from rackclient import exceptions
from rackclient.openstack.common import importutils
@ -123,9 +122,9 @@ def get_client_class(version):
try:
client_path = version_map[str(version)]
except (KeyError, ValueError):
msg = _("Invalid client version '%(version)s'. must be one of: "
"%(keys)s") % {'version': version,
'keys': ', '.join(version_map.keys())}
msg = ("Invalid client version '%(version)s'. must be one of: "
"%(keys)s") % {'version': version,
'keys': ', '.join(version_map.keys())}
raise exceptions.UnsupportedVersion(msg)
return importutils.import_class(client_path)

View File

@ -11,6 +11,8 @@
# 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.
class UnsupportedVersion(Exception):
"""Indicates that the user is trying to use an unsupported
version of the API.
@ -107,7 +109,8 @@ def from_response(response, body, url, method=None):
class BaseError(Exception):
"""
The base exception class for all exceptions except for HTTPException based classes.
The base exception class for all exceptions except for HTTPException
based classes.
"""
pass

View File

@ -1,107 +1,21 @@
from rackclient import exceptions
from rackclient.client import Client
import cPickle
import json
import logging
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import initializing
import os
import pika
import requests
LOG = logging.getLogger(__name__)
META_URL = 'http://169.254.169.254/openstack/latest/meta_data.json'
RACK_CTX = None
def get_rack_context(proxy_port=8088, client_version="1", api_version="v1"):
global RACK_CTX
if not RACK_CTX:
try:
resp = requests.get(META_URL)
metadata = json.loads(resp.text)["meta"]
proxy_url = 'http://%s:%d/%s' % (metadata["proxy_ip"], proxy_port, api_version)
client = Client(client_version, rack_url=proxy_url)
proxy_info = client.proxy.get(metadata["gid"])
RACK_CTX = type('', (object,), metadata)
RACK_CTX.ppid = getattr(RACK_CTX, "ppid", "")
RACK_CTX.client = client
RACK_CTX.fs_endpoint = proxy_info.fs_endpoint
RACK_CTX.ipc_endpoint = proxy_info.ipc_endpoint
RACK_CTX.shm_endpoint = proxy_info.shm_endpoint
try:
# Check if this process is not recognized by RACK.
RACK_CTX.client.processes.get(RACK_CTX.gid, RACK_CTX.pid)
except exceptions.NotFound:
msg = "This process is not recognized by RACK"
raise exceptions.InvalidProcessError(msg)
if RACK_CTX.ppid:
LOG.debug("Messaging: send message to %s", RACK_CTX.ppid)
msg = _Messaging(RACK_CTX)
msg.send_msg(RACK_CTX.ppid)
while True:
receive_msg = msg.receive_msg(getattr(RACK_CTX, "msg_limit_time", 180))
if receive_msg and RACK_CTX.ppid == receive_msg.get("pid"):
LOG.debug("Messaging: receive message from %s", receive_msg.get("pid"))
break
except Exception as e:
msg = "Failed to initialize the process: %s." % e.message
raise exceptions.ProcessInitError(msg)
return RACK_CTX
class _Messaging(object):
def __init__(self, ctx):
self.ctx = ctx
connection_param = pika.ConnectionParameters(self.ctx.proxy_ip)
if self.ctx.ipc_endpoint:
connection_param = pika.ConnectionParameters(self.ctx.ipc_endpoint)
self.connection = pika.BlockingConnection(connection_param)
self.channel = self.connection.channel()
self.channel.exchange_declare(exchange=ctx.gid, type='topic')
self.channel.queue_declare(queue=ctx.pid)
self.channel.queue_bind(exchange=ctx.gid, queue=ctx.pid, routing_key=ctx.gid + '.' + ctx.pid)
def receive_msg(self, timeout_limit=180):
queue_name = self.ctx.pid
self.channel = self.connection.channel()
receive = self.Receive()
self.connection.add_timeout(deadline=int(timeout_limit), callback_method=receive.time_out)
self.channel.basic_consume(receive.get_msg, queue=queue_name, no_ack=False)
receive.channel = self.channel
self.channel.start_consuming()
return receive.message
class Receive(object):
def __init__(self):
self.channel = None
self.message = None
def get_msg(self, ch, method, properties, body):
self.message = cPickle.loads(body)
ch.basic_ack(delivery_tag=method.delivery_tag)
ch.stop_consuming()
def time_out(self):
self.channel.stop_consuming()
def send_msg(self, target):
routing_key = self.ctx.gid + '.' + target
send_dict = {'pid': self.ctx.pid}
send_msg = cPickle.dumps(send_dict)
self.channel.basic_publish(exchange=self.ctx.gid, routing_key=routing_key, body=send_msg)
if not os.environ.get("RACK_IS_TEST"):
get_rack_context()
if not RACK_CTX:
RACK_CTX = initializing.get_rack_context()

View File

@ -0,0 +1,126 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import cPickle
import json
import logging
import pika
import requests
from rackclient import exceptions
from rackclient.client import Client
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.DEBUG)
META_URL = 'http://169.254.169.254/openstack/latest/meta_data.json'
def get_rack_context(proxy_port=8088, client_version="1", api_version="v1"):
try:
resp = requests.get(META_URL)
metadata = json.loads(resp.text)["meta"]
proxy_url = 'http://%s:%d/%s' % (
metadata["proxy_ip"], proxy_port, api_version)
client = Client(client_version, rack_url=proxy_url)
proxy_info = client.proxy.get(metadata["gid"])
rack_ctx = type('', (object,), metadata)
rack_ctx.ppid = getattr(rack_ctx, "ppid", "")
rack_ctx.client = client
rack_ctx.fs_endpoint = proxy_info.fs_endpoint
rack_ctx.ipc_endpoint = proxy_info.ipc_endpoint
rack_ctx.shm_endpoint = proxy_info.shm_endpoint
try:
# Check if this process is not recognized by RACK.
rack_ctx.client.processes.get(rack_ctx.gid, rack_ctx.pid)
except exceptions.NotFound:
msg = "This process is not recognized by RACK"
raise exceptions.InvalidProcessError(msg)
if rack_ctx.ppid:
LOG.debug("Messaging: send message to %s", rack_ctx.ppid)
msg = _Messaging(rack_ctx)
msg.send_msg(rack_ctx.ppid)
while True:
receive_msg = msg.receive_msg(
getattr(rack_ctx, "msg_limit_time", 180))
if receive_msg and rack_ctx.ppid == receive_msg.get("pid"):
LOG.debug(
"Messaging: receive message from %s",
receive_msg.get("pid"))
break
except Exception as e:
msg = "Failed to initialize the process: %s." % e.message
raise exceptions.ProcessInitError(msg)
return rack_ctx
class _Messaging(object):
def __init__(self, ctx):
self.ctx = ctx
connection_param = pika.ConnectionParameters(self.ctx.proxy_ip)
if self.ctx.ipc_endpoint:
connection_param = pika.ConnectionParameters(self.ctx.ipc_endpoint)
self.connection = pika.BlockingConnection(connection_param)
self.channel = self.connection.channel()
self.channel.exchange_declare(exchange=ctx.gid, type='topic')
self.channel.queue_declare(queue=ctx.pid)
self.channel.queue_bind(
exchange=ctx.gid,
queue=ctx.pid,
routing_key=ctx.gid + '.' + ctx.pid)
def receive_msg(self, timeout_limit=180):
queue_name = self.ctx.pid
self.channel = self.connection.channel()
receive = self.Receive()
self.connection.add_timeout(
deadline=int(timeout_limit),
callback_method=receive.time_out)
self.channel.basic_consume(
receive.get_msg,
queue=queue_name,
no_ack=False)
receive.channel = self.channel
self.channel.start_consuming()
return receive.message
def send_msg(self, target):
routing_key = self.ctx.gid + '.' + target
send_dict = {'pid': self.ctx.pid}
send_msg = cPickle.dumps(send_dict)
self.channel.basic_publish(
exchange=self.ctx.gid,
routing_key=routing_key,
body=send_msg)
class Receive(object):
def __init__(self):
self.channel = None
self.message = None
def get_msg(self, ch, method, properties, body):
self.message = cPickle.loads(body)
ch.basic_ack(delivery_tag=method.delivery_tag)
ch.stop_consuming()
def time_out(self):
self.channel.stop_consuming()

View File

@ -1,3 +1,16 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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 rackclient.lib import RACK_CTX
from rackclient import exceptions
from swiftclient import client as swift_client
@ -14,7 +27,6 @@ SWIFT_PORT = 8080
def _get_swift_client():
if RACK_CTX.fs_endpoint:
try:
d = json.loads(RACK_CTX.fs_endpoint)
@ -90,7 +102,7 @@ class File(object):
try:
_, contents = swift.get_object(self.get_directory(),
self.get_name(), chunk_size)
self.get_name(), chunk_size)
if chunk_size:
for c in contents:
self.file.write(c)
@ -140,4 +152,4 @@ class File(object):
return getattr(self.file, name)
else:
raise AttributeError("%s instance has no attribute '%s'",
self.__class__.__name__, name)
self.__class__.__name__, name)

View File

@ -1,3 +1,16 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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 rackclient.lib import RACK_CTX
from rackclient import exceptions

View File

@ -1,3 +1,16 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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 datetime import datetime
from rackclient.lib import RACK_CTX
from rackclient import exceptions
@ -47,8 +60,10 @@ class Pipe:
self.name = self.r.get(parent_pipe[0])
else:
self.name = RACK_CTX.pid
read_state = self.r.hget(read_state_key(self.name), RACK_CTX.pid) or now
write_state = self.r.hget(write_state_key(self.name), RACK_CTX.pid) or now
read_state = \
self.r.hget(read_state_key(self.name), RACK_CTX.pid) or now
write_state = \
self.r.hget(write_state_key(self.name), RACK_CTX.pid) or now
if read is not None:
if read:
read_state = now
@ -125,7 +140,7 @@ class Pipe:
self.r.delete(*tuple(keys))
@classmethod
def flush_by_pid(self, pid, host=None):
def flush_by_pid(cls, pid, host=None):
if not host:
host = RACK_CTX.proxy_ip

View File

@ -1,15 +1,28 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import logging
import redis
from rackclient.lib import RACK_CTX
LOG = logging.getLogger(__name__)
FIFO = 3
PORT = 6379
def get_host():
return RACK_CTX.proxy_ip
@ -39,4 +52,3 @@ class Shm(object):
def delete(self, key):
return self.r.delete(key)

View File

@ -1,3 +1,16 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import logging
import websocket
@ -46,7 +59,8 @@ class SignalManager(object):
LOG.debug("Websocket connection %s closed" % ws.header[0])
def send(self, target_id, message):
ws = websocket.create_connection(self.url + '/send', header=['PID: ' + target_id])
ws = websocket.create_connection(self.url + '/send',
header=['PID: ' + target_id])
LOG.debug("Send a message: %s" % message)
ws.send(message)
ws.close()

View File

@ -1,3 +1,16 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import logging
import Queue
import threading
@ -42,25 +55,6 @@ def fork(opt_list, timeout_limit=180):
return return_process_list
def kill(pid):
RACK_CTX.client.processes.delete(RACK_CTX.gid, pid)
def pipe(name=None):
p = rackpipe.Pipe(name)
return p
def pipe_reader(name=None):
p = rackpipe.Pipe(name)
p.close_writer()
return p
def pipe_writer(name=None):
p = rackpipe.Pipe(name)
p.close_reader()
return p
def fopen(file_path, mode="r"):
return rackfile.File(file_path, mode)
def _bulk_fork(pid, args_list):
LOG.debug("start bulk_fork")
@ -69,8 +63,8 @@ def _bulk_fork(pid, args_list):
def _fork(pid, **kwargs):
try:
child = RACK_CTX.client.processes.create(gid=RACK_CTX.gid,
ppid=pid,
**kwargs)
ppid=pid,
**kwargs)
q.put(child)
except Exception as e:
attr = dict(args=kwargs, error=e)
@ -136,4 +130,17 @@ def _check_connection(pid, process_list, timeout):
msg = "No child process is active."
raise Exception(msg)
return actives, inactives
return actives, inactives
def kill(pid):
RACK_CTX.client.processes.delete(RACK_CTX.gid, pid)
def pipe(name=None):
p = rackpipe.Pipe(name)
return p
def fopen(file_path, mode="r"):
return rackfile.File(file_path, mode)

View File

@ -1,3 +1,16 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import logging
import os
import sys
@ -8,7 +21,7 @@ import requests
from rackclient import exceptions
VERSION='1'
VERSION = '1'
class RackShell(App):
@ -25,7 +38,7 @@ class RackShell(App):
def build_option_parser(self, description, version,
argparse_kwargs=None):
parser = super(RackShell, self).build_option_parser(
description, version, argparse_kwargs)
description, version, argparse_kwargs)
parser.add_argument(
'--rack-api-version',
@ -90,4 +103,3 @@ def main(argv=sys.argv[1:]):
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -1,67 +0,0 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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 mock import patch
import requests
from rackclient import process_context as pctxt
from rackclient.tests import utils
from rackclient.v1.proxy import ProxyManager, Proxy
from rackclient import exceptions
class ProcessContextTest(utils.TestCase):
def setUp(self):
super(ProcessContextTest, self).setUp()
patcher = patch('requests.get')
self.addCleanup(patcher.stop)
self.mock_request = patcher.start()
self.mock_request.return_value = requests.Response()
self.mock_request.return_value._content = \
('{"meta": {"gid": "11111111", '
'"pid": "22222222", "ppid": "33333333", '
'"proxy_ip": "10.0.0.2", "opt1": "value1", '
'"opt2": "value2"}}')
@patch.object(ProxyManager, 'get')
def test_init(self, mock_proxy_get):
proxy = {
'fs_endpoint': 'fs_endpoint',
'shm_endpoint': 'shm_endpoint',
'ipc_endpoint': 'ipc_endpoint'
}
mock_proxy_get.return_value = Proxy(None, proxy)
pctxt.init()
d = pctxt.PCTXT.__dict__
d.pop('client')
expected = {
'ipc_endpoint': 'ipc_endpoint',
'fs_endpoint': 'fs_endpoint',
'proxy_url': 'http://10.0.0.2:8088/v1',
'pid': '22222222',
'gid': '11111111',
'proxy_ip': '10.0.0.2',
'shm_endpoint': 'shm_endpoint',
'ppid': '33333333',
'opt1': 'value1',
'opt2': 'value2'
}
self.assertEqual(expected, d)
mock_proxy_get.assert_called_with('11111111')
def test_init_metadata_error(self):
self.mock_request.side_effect = Exception()
self.assertRaises(exceptions.MetadataAccessError, pctxt.init)

View File

@ -11,6 +11,8 @@
# 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.
class FakeClient(object):
def assert_called(self, method, url, body=None, pos=-1):

View File

@ -32,13 +32,16 @@ class MessagingTest(utils.LibTestCase):
self.mock_connection = Mock()
self.mock_channel = Mock()
self.mock_receive = Mock(spec=rack_ipc.Messaging.Receive)
self.patch_pika_blocking = patch('pika.BlockingConnection',
autospec=True)
self.addCleanup(self.patch_pika_blocking.stop)
self.patch_pika_blocking = patch('pika.BlockingConnection', autospec=True)
# self.addCleanup(self.patch_pika_blocking.stop)
self.mock_pika_blocking = self.patch_pika_blocking.start()
self.mock_pika_blocking.return_value = self.mock_connection
self.mock_connection.channel.return_value = self.mock_channel
def tearDown(self):
super(MessagingTest, self).tearDown()
self.patch_pika_blocking.stop()
def test_declare_queue(self):
queue_name = 'test_queue_name'
msg = rack_ipc.Messaging()
@ -176,39 +179,21 @@ class MessagingTest(utils.LibTestCase):
receive.time_out()
self.mock_channel.stop_consuming.assert_called_with()
#@patch('rackclient.v1.syscall.default.messaging.Messaging',
# autospec=True)
# def test_init(self, msg):
# rack_ipc.init()
# msg.assert_called_with()
#
# @patch('rackclient.v1.syscall.default.messaging.Messaging',
# autospec=True)
# def test_init_child(self, msg):
# self.mock_RACK_CTX.ppid = 'PPID'
# receive_msg = {'pid': self.mock_RACK_CTX.ppid}
# mock_messaging = Mock()
# msg.return_value = mock_messaging
# mock_messaging.receive_msg.return_value = receive_msg
# rack_ipc.init()
# mock_messaging.send_msg.asset_called_with(self.mock_RACK_CTX.ppid)
# mock_messaging.receive_msg.assert_called_onece_with()
def test_create_connection(self):
p = patch('pika.ConnectionParameters', autospec=True)
self.addCleanup(p.stop)
mock_pika_connection_param = p.start()
rack_ipc.Messaging()
mock_pika_connection_param.assert_called_with(self.mock_RACK_CTX.proxy_ip)
# @patch('pika.ConnectionParameters', autospec=True)
# def test_create_connection(self, mock_pika_connection_param):
# rack_ipc._create_connection()
# mock_pika_connection_param.assert_called_with(self.mock_RACK_CTX.proxy_ip)
#
# @patch('pika.ConnectionParameters', autospec=True)
# def test_create_connection_ipc_endpoint(self, mock_pika_connection_param):
# ipc_ip = 'ipc_ip'
# self.mock_RACK_CTX.ipc_endpoint = ipc_ip
#
# rack_ipc._create_connection()
# mock_pika_connection_param.assert_called_with(ipc_ip)
#
# def test_create_connection_amqp_connection_error(self):
# self.mock_pika_blocking.side_effect = pika.\
# exceptions.AMQPConnectionError()
# self.assertRaises(exceptions.AMQPConnectionError,
# rack_ipc._create_connection)
@patch('pika.ConnectionParameters', autospec=True)
def test_create_connection_ipc_endpoint(self, mock_pika_connection_param):
ipc_ip = 'ipc_ip'
self.mock_RACK_CTX.ipc_endpoint = ipc_ip
rack_ipc.Messaging()
mock_pika_connection_param.assert_called_with(ipc_ip)
def test_create_connection_amqp_connection_error(self):
self.mock_pika_blocking.side_effect = pika.\
exceptions.AMQPConnectionError()
self.assertRaises(exceptions.AMQPConnectionError, rack_ipc.Messaging)

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import logging
from mock import patch, Mock
from rackclient.tests import utils
@ -25,6 +26,7 @@ class SignalTest(utils.LibTestCase):
def setUp(self):
super(SignalTest, self).setUp()
logging.basicConfig(level=logging.ERROR)
@patch('websocket.WebSocketApp')
def test_receive(self, mock_websocket_websocketapp):

View File

@ -0,0 +1,215 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.
import cPickle
import json
import logging
from mock import *
from rackclient import exceptions
from rackclient.tests import utils
from rackclient.lib import initializing
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.WARN)
class InitializingTest(utils.TestCase):
def setUp(self):
super(InitializingTest, self).setUp()
p = patch("requests.get")
self.addCleanup(p.stop)
mock_request = p.start()
mock_resp = Mock()
mock_resp.text= json.dumps(dict(meta=dict(
proxy_ip="10.0.0.2",gid="gid", pid="pid", ppid="ppid")))
mock_request.return_value = mock_resp
def test_get_rack_context(self):
p = patch("rackclient.lib.initializing.Client")
self.addCleanup(p.stop)
mock_client = p.start()
mock_client = mock_client.return_value
def proxy_info(args):
info = type('', (object,), {})
info.ipc_endpoint = None
info.fs_endpoint = None
info.shm_endpoint = None
return info
mock_client.proxy = Mock()
mock_client_processes = Mock()
mock_client.proxy.get.side_effect = proxy_info
p2 = patch("rackclient.lib.initializing._Messaging")
self.addCleanup(p2.stop)
mock_messaging = p2.start()
mock_messaging = mock_messaging.return_value
mock_messaging.receive_msg.return_value=dict(pid="ppid")
actual_context = initializing.get_rack_context()
expect_context = type('', (object,), dict(
proxy_ip="10.0.0.2",
gid="gid", pid="pid",
ppid="ppid",
ipc_endpoint=None,
fs_endpoint=None,
shm_endpoint=None,
client=mock_client))
self.assertEquals(expect_context.pid, actual_context.pid)
self.assertEquals(expect_context.ppid, actual_context.ppid)
self.assertEquals(expect_context.proxy_ip, actual_context.proxy_ip)
self.assertEquals(expect_context.ipc_endpoint, actual_context.ipc_endpoint)
self.assertEquals(expect_context.fs_endpoint, actual_context.fs_endpoint)
self.assertEquals(expect_context.shm_endpoint, actual_context.shm_endpoint)
def test_get_rack_cotext_ProcessInitError_due_to_proxy(self):
self.p = patch("rackclient.lib.initializing.Client")
self.addCleanup(self.p.stop)
mock_client = self.p.start()
mock_client = mock_client.return_value
mock_client.proxy = Mock()
mock_client_processes = Mock()
mock_client.proxy.get.side_effect = Exception()
self.assertRaises(Exception, initializing.get_rack_context)
def test_get_rack_cotext_ProcessInitError_doe_to_processes(self):
self.p = patch("rackclient.lib.initializing.Client")
self.addCleanup(self.p.stop)
mock_client = self.p.start()
mock_client = mock_client.return_value
mock_client.proxy = Mock()
mock_client_processes = Mock()
mock_client.processes.get.side_effect = exceptions.NotFound("")
self.assertRaises(Exception, initializing.get_rack_context)
@patch("rackclient.lib.initializing._Messaging.Receive")
def test_messaging_receive_msg(self, mock_receive):
self.mock_connection = Mock()
self.mock_channel = Mock()
self.patch_pika_blocking = patch('pika.BlockingConnection', autospec=True)
self.addCleanup(self.patch_pika_blocking.stop)
self.mock_pika_blocking = self.patch_pika_blocking.start()
self.mock_pika_blocking.return_value = self.mock_connection
self.mock_connection.channel.return_value = self.mock_channel
context = type('', (object,), dict(
proxy_ip="10.0.0.2",
gid="gid", pid="pid",
ppid="ppid",
ipc_endpoint=None,
fs_endpoint=None,
shm_endpoint=None))
timeout_limit = 123
msg = initializing._Messaging(context)
message = msg.receive_msg(timeout_limit=timeout_limit)
self.mock_connection.add_timeout.\
assert_called_with(deadline=int(timeout_limit),
callback_method=mock_receive().time_out)
self.mock_channel.\
basic_consume.assert_called_with(mock_receive().get_msg,
queue="pid",
no_ack=False)
self.mock_channel.start_consuming.assert_called_with()
self.assertEqual(message, mock_receive().message)
def test_messaging_send_msg(self):
self.mock_connection = Mock()
self.mock_channel = Mock()
self.patch_pika_blocking = patch('pika.BlockingConnection', autospec=True)
self.addCleanup(self.patch_pika_blocking.stop)
self.mock_pika_blocking = self.patch_pika_blocking.start()
self.mock_pika_blocking.return_value = self.mock_connection
self.mock_connection.channel.return_value = self.mock_channel
context = type('', (object,), dict(
proxy_ip="10.0.0.2",
gid="gid", pid="pid",
ppid="ppid",
ipc_endpoint=None,
fs_endpoint=None,
shm_endpoint=None))
send_msg = 'test_msg'
target = 'test_pid'
msg = initializing._Messaging(context)
msg.send_msg(target)
routing_key = context.gid + '.' + target
send_dict = {'pid': context.pid}
send_msg = cPickle.dumps(send_dict)
self.mock_channel.\
basic_publish.assert_called_with(exchange=context.gid,
routing_key=routing_key,
body=send_msg)
def test_receive_get_msg(self):
self.mock_connection = Mock()
self.mock_channel = Mock()
self.patch_pika_blocking = patch('pika.BlockingConnection', autospec=True)
self.addCleanup(self.patch_pika_blocking.stop)
self.mock_pika_blocking = self.patch_pika_blocking.start()
self.mock_pika_blocking.return_value = self.mock_connection
self.mock_connection.channel.return_value = self.mock_channel
ch = Mock()
method = Mock()
properties = Mock()
receive_msg = 'receive_msg'
body = cPickle.dumps(receive_msg)
ch_object = {'delivery_tag': 'delivery_tag'}
method.configure_mock(**ch_object)
context = type('', (object,), dict(
proxy_ip="10.0.0.2",
gid="gid", pid="pid",
ppid="ppid",
ipc_endpoint=None,
fs_endpoint=None,
shm_endpoint=None))
msg = initializing._Messaging(context)
receive = msg.Receive()
receive.get_msg(ch, method, properties, body)
ch.basic_ack.assert_called_with(delivery_tag=ch_object['delivery_tag'])
ch.stop_consuming.assert_call_with()
self.assertEqual(receive.message, receive_msg)
def test_receive_timeout(self):
self.mock_connection = Mock()
self.mock_channel = Mock()
self.patch_pika_blocking = patch('pika.BlockingConnection', autospec=True)
self.addCleanup(self.patch_pika_blocking.stop)
self.mock_pika_blocking = self.patch_pika_blocking.start()
self.mock_pika_blocking.return_value = self.mock_connection
self.mock_connection.channel.return_value = self.mock_channel
context = type('', (object,), dict(
proxy_ip="10.0.0.2",
gid="gid", pid="pid",
ppid="ppid",
ipc_endpoint="data",
fs_endpoint=None,
shm_endpoint=None))
msg = initializing._Messaging(context)
receive = msg.Receive()
receive.channel = self.mock_channel
receive.time_out()
self.mock_channel.stop_consuming.assert_called_with()

View File

@ -19,6 +19,7 @@ import requests
from rackclient import client
from rackclient.tests import utils
class ClientTest(utils.TestCase):
def test_log_req(self):

View File

@ -18,61 +18,30 @@ from rackclient import client
from mock import *
# class PContextFixture(fixture.Fixture):
#
# def setUp(self):
# super(PContextFixture, self).setUp()
# self.attrs = dir(PCTXT)
# self.addCleanup(self.cleanup_pctxt)
#
# PCTXT.gid = 'gid'
# PCTXT.pid = 'pid'
# PCTXT.ppid = None
# PCTXT.proxy_ip = '10.0.0.2'
# PCTXT.proxy_url = 'http://10.0.0.2:8088/v1'
# PCTXT.fs_endpoint = None
# PCTXT.shm_endpoint = None
# PCTXT.ipc_endpoint = None
# PCTXT.client = client.Client('1', rack_url=PCTXT.proxy_url)
#
# def cleanup_pctxt(self):
# attrs = dir(PCTXT)
# for attr in attrs:
# if attr not in self.attrs: delattr(PCTXT, attr)
class TestCase(testtools.TestCase):
def setUp(self):
super(TestCase, self).setUp()
# if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or
# os.environ.get('OS_STDOUT_CAPTURE') == '1'):
# stdout = self.useFixture(fixtures.StringStream('stdout')).stream
# self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
# if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or
# os.environ.get('OS_STDERR_CAPTURE') == '1'):
# stderr = self.useFixture(fixtures.StringStream('stderr')).stream
# self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
# self.useFixture(PContextFixture())
class LibTestCase(testtools.TestCase):
def setUp(self):
super(LibTestCase, self).setUp()
patcher = patch("rackclient.lib." + self.target_context() + ".RACK_CTX")
patcher = patch(
"rackclient.lib." + self.target_context() + ".RACK_CTX")
self.addCleanup(patcher.stop)
self.mock_RACK_CTX = patcher.start()
self._init_context()
def _init_context(self):
self.mock_RACK_CTX.gid="gid"
self.mock_RACK_CTX.pid="pid"
self.mock_RACK_CTX.ppid=None
self.mock_RACK_CTX.proxy_ip="10.0.0.2"
self.mock_RACK_CTX.gid = "gid"
self.mock_RACK_CTX.pid = "pid"
self.mock_RACK_CTX.ppid = None
self.mock_RACK_CTX.proxy_ip = "10.0.0.2"
self.mock_RACK_CTX.proxy_url = 'http://10.0.0.2:8088/v1'
self.mock_RACK_CTX.client = client.Client('1', rack_url=self.mock_RACK_CTX.proxy_url)
self.mock_RACK_CTX.client = \
client.Client('1', rack_url=self.mock_RACK_CTX.proxy_url)
self.mock_RACK_CTX.fs_endpoint = None
self.mock_RACK_CTX.ipc_endpoint = None
self.mock_RACK_CTX.shm_endpoint = None
@ -80,6 +49,7 @@ class LibTestCase(testtools.TestCase):
def target_context(self):
pass
class TestResponse(requests.Response):
"""
Class used to wrap requests.Response and provide some

View File

@ -1,13 +0,0 @@
# Copyright (c) 2014 ITOCHU Techno-Solutions Corporation.
#
# 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.

View File

@ -147,7 +147,9 @@ class CreateGroup(ShowOne):
return parser
def take_action(self, parsed_args):
group = self.client.groups.create(parsed_args.name, parsed_args.description)
group = self.client.groups.create(
parsed_args.name,
parsed_args.description)
return _make_print_data(
group.gid,
group.name,
@ -184,8 +186,8 @@ class UpdateGroup(ShowOne):
def take_action(self, parsed_args):
group = self.client.groups.update(parsed_args.gid,
parsed_args.name,
parsed_args.description)
parsed_args.name,
parsed_args.description)
return _make_print_data(
group.gid,
group.name,
@ -217,7 +219,7 @@ class DeleteGroup(Command):
return parser
def take_action(self, parsed_args):
group = self.client.groups.delete(parsed_args.gid)
self.client.groups.delete(parsed_args.gid)
class InitGroup(ShowOne):
@ -238,29 +240,24 @@ class InitGroup(ShowOne):
def get_parser(self, prog_name):
parser = super(InitGroup, self).get_parser(prog_name)
parser.add_argument('config', metavar='<config-file>',
help="Configuration file including parameters of the new group")
help=("Configuration file including parameters"
" of the new group"))
return parser
def take_action(self, parsed_args):
config = ConfigParser()
config.read(parsed_args.config)
group_name = None
group_description = None
keypair_name = None
keypair_is_default = True
securitygroup_name = None
securitygroup_is_default = True
securitygroup_rules= []
network_cidr = None
network_name = None
network_is_admin = True
network_gateway_ip = None
network_dns_nameservers = []
network_ext_router_id = None
proxy_name = None
proxy_flavor = None
proxy_image = None
try:
group_name = config.get('group', 'name')
@ -275,7 +272,7 @@ class InitGroup(ShowOne):
try:
securitygroup_rules = config.get('securitygroup', 'rules').split()
securitygroup_rules = \
[utils.keyvalue_to_dict(r) for r in securitygroup_rules]
[utils.keyvalue_to_dict(r) for r in securitygroup_rules]
except argparse.ArgumentTypeError:
raise exceptions.CommandError((
"Could not create a securitygroup: "
@ -301,11 +298,15 @@ class InitGroup(ShowOne):
keypair_name = config.get('keypair', 'name')
keypair_is_default = config.get('keypair', 'is_default')
securitygroup_name = config.get('securitygroup', 'name')
securitygroup_is_default = config.get('securitygroup', 'is_default')
securitygroup_is_default = config.get(
'securitygroup',
'is_default')
network_name = config.get('network', 'name')
network_is_admin = config.get('network', 'is_admin')
network_gateway_ip = config.get('network', 'gateway_ip')
network_dns_nameservers = config.get('network', 'dns_nameservers').split()
network_dns_nameservers = config.get(
'network',
'dns_nameservers').split()
except NoOptionError:
pass
@ -313,21 +314,21 @@ class InitGroup(ShowOne):
keypair = self.client.keypairs.create(group.gid, keypair_name,
keypair_is_default)
securitygroup = self.client.securitygroups.create(
group.gid,
securitygroup_name,
securitygroup_is_default,
securitygroup_rules)
group.gid,
securitygroup_name,
securitygroup_is_default,
securitygroup_rules)
network = self.client.networks.create(
group.gid, network_cidr, network_name,
network_is_admin, network_gateway_ip,
network_dns_nameservers,
network_ext_router_id)
group.gid, network_cidr, network_name,
network_is_admin, network_gateway_ip,
network_dns_nameservers,
network_ext_router_id)
proxy = self.client.proxy.create(
group.gid, name=proxy_name,
nova_flavor_id=proxy_flavor,
glance_image_id=proxy_image,
keypair_id=keypair.keypair_id,
securitygroup_ids=[securitygroup.securitygroup_id])
group.gid, name=proxy_name,
nova_flavor_id=proxy_flavor,
glance_image_id=proxy_image,
keypair_id=keypair.keypair_id,
securitygroup_ids=[securitygroup.securitygroup_id])
columns = ['gid', 'keypair_id', 'securitygroup_id', 'network_id',
'proxy_pid', 'proxy_name']
@ -335,4 +336,3 @@ class InitGroup(ShowOne):
network.network_id, proxy.pid, proxy.name]
return columns, data

View File

@ -115,7 +115,8 @@ class CreateKeypair(ShowOne):
help="Name of the new keypair")
parser.add_argument('--is-default', metavar='<true/false>',
default=False,
help="Defaults to the default keypair of the group")
help=("Defaults to the default keypair of"
" the group"))
return parser
def take_action(self, parsed_args):
@ -195,5 +196,4 @@ class DeleteKeypair(Command):
return parser
def take_action(self, parsed_args):
keypair = self.client.keypairs.delete(self.gid, parsed_args.keypair_id)
self.client.keypairs.delete(self.gid, parsed_args.keypair_id)

View File

@ -97,4 +97,3 @@ class Montecarlo(ShowOne):
data = [process.pid, process.ppid, cmd]
return columns, data

View File

@ -125,7 +125,8 @@ class CreateNetwork(ShowOne):
help="Gateway ip address of the new network")
parser.add_argument('--dns-nameserver', metavar='<x.x.x.x>',
dest='dns_nameservers', action='append',
help="DNS server for the new network (Can be repeated)")
help=("DNS server for the new network "
"(Can be repeated)"))
parser.add_argument('--ext-router-id', metavar='<router-id>',
help="Router id the new network connects to")
@ -174,6 +175,5 @@ class DeleteNetwork(Command):
return parser
def take_action(self, parsed_args):
network = self.client.networks.delete(self.gid,
parsed_args.network_id)
self.client.networks.delete(self.gid,
parsed_args.network_id)

View File

@ -62,10 +62,12 @@ class PS(Lister):
def _make_print_data(pid, ppid, name, nova_instance_id, nova_flavor_id,
glance_image_id, keypair_id, securitygroup_ids, networks,
userdata, args, app_status, gid, user_id, project_id, status=None):
userdata, args, app_status, gid, user_id, project_id,
status=None):
columns = ['pid', 'ppid', 'name', 'nova_instance_id', 'nova_flavor_id',
'glance_image_id', 'keypair_id', 'securitygroup_ids', 'networks',
'userdata', 'args', 'app_status', 'gid', 'user_id', 'project_id']
'glance_image_id', 'keypair_id', 'securitygroup_ids',
'networks', 'userdata', 'args', 'app_status', 'gid', 'user_id',
'project_id']
data = [pid, ppid, name, nova_instance_id, nova_flavor_id,
glance_image_id, keypair_id, securitygroup_ids, networks,
userdata, args, app_status, gid, user_id, project_id]
@ -169,7 +171,8 @@ class Boot(ShowOne):
help="Userdata file path")
parser.add_argument('--args', metavar='<key1=value1,key2=value2,...>',
type=utils.keyvalue_to_dict,
help="Key-value pairs to be passed to metadata server")
help=("Key-value pairs to be passed to "
"metadata server"))
return parser
@ -183,15 +186,15 @@ class Boot(ShowOne):
"Can't open '%s'" % parsed_args.userdata)
process = self.client.processes.create(
gid=self.gid,
ppid=parsed_args.ppid,
name=parsed_args.name,
nova_flavor_id=parsed_args.flavor,
glance_image_id=parsed_args.image,
keypair_id=parsed_args.keypair,
securitygroup_ids=parsed_args.securitygroup_ids,
userdata=userdata,
args=parsed_args.args)
gid=self.gid,
ppid=parsed_args.ppid,
name=parsed_args.name,
nova_flavor_id=parsed_args.flavor,
glance_image_id=parsed_args.image,
keypair_id=parsed_args.keypair,
securitygroup_ids=parsed_args.securitygroup_ids,
userdata=userdata,
args=parsed_args.args)
sg_ids = process.securitygroup_ids
if sg_ids:
@ -245,5 +248,4 @@ class Kill(Command):
return parser
def take_action(self, parsed_args):
process = self.client.processes.delete(self.gid, parsed_args.pid)
self.client.processes.delete(self.gid, parsed_args.pid)

View File

@ -25,9 +25,9 @@ def _make_print_data(pid, ppid, name, nova_instance_id, nova_flavor_id,
userdata, args, app_status, fs_endpoint, ipc_endpoint,
shm_endpoint, gid, user_id, project_id, status=None):
columns = ['pid', 'ppid', 'name', 'nova_instance_id', 'nova_flavor_id',
'glance_image_id', 'keypair_id', 'securitygroup_ids', 'networks',
'userdata', 'args', 'app_status', 'fs_endpoint', 'ipc_endpoint',
'shm_endpoint', 'gid', 'user_id', 'project_id']
'glance_image_id', 'keypair_id', 'securitygroup_ids',
'networks', 'userdata', 'args', 'app_status', 'fs_endpoint',
'ipc_endpoint', 'shm_endpoint', 'gid', 'user_id', 'project_id']
data = [pid, ppid, name, nova_instance_id, nova_flavor_id,
glance_image_id, keypair_id, securitygroup_ids, networks,
userdata, args, app_status, fs_endpoint, ipc_endpoint,
@ -117,23 +117,27 @@ class CreateProxy(ShowOne):
parser.add_argument('--securitygroup', metavar='<securitygroup-id>',
dest='securitygroup', action='append',
default=[],
help="Securitygroup id the rack-proxy process belongs to (Can be repeated)")
help=("Securitygroup id the rack-proxy process "
"belongs to (Can be repeated)"))
parser.add_argument('--flavor', metavar='<nova-flavor-id>',
required=True,
help="(Required) Flavor id of the rack-proxy process")
help=("(Required) Flavor id of "
"the rack-proxy process"))
parser.add_argument('--image', metavar='<glance-image-id>',
required=True,
help="(Required) Image id that registered on Glance of the rack-proxy process")
help=("(Required) Image id that registered "
"on Glance of the rack-proxy process"))
return parser
def take_action(self, parsed_args):
proxy = self.client.proxy.create(self.gid,
name=parsed_args.name,
nova_flavor_id=parsed_args.flavor,
glance_image_id=parsed_args.image,
keypair_id=parsed_args.keypair,
securitygroup_ids=parsed_args.securitygroup)
proxy = self.client.proxy.create(
self.gid,
ame=parsed_args.name,
ova_flavor_id=parsed_args.flavor,
lance_image_id=parsed_args.image,
eypair_id=parsed_args.keypair,
ecuritygroup_ids=parsed_args.securitygroup)
sg_ids = proxy.securitygroup_ids
if sg_ids:
@ -236,4 +240,3 @@ class UpdateProxy(ShowOne):
proxy.user_id,
proxy.project_id
)

View File

@ -55,7 +55,8 @@ class ListSecuritygroups(Lister):
securitygroups = self.client.securitygroups.list(self.gid)
return (
('securitygroup_id', 'name', 'is_default', 'status'),
((s.securitygroup_id, s.name, s.is_default, s.status) for s in securitygroups)
((s.securitygroup_id, s.name, s.is_default, s.status)
for s in securitygroups)
)
@ -81,8 +82,9 @@ class ShowSecuritygroup(ShowOne):
return parser
def take_action(self, parsed_args):
securitygroup = self.client.securitygroups.get(self.gid,
parsed_args.securitygroup_id)
securitygroup = self.client.securitygroups.get(
self.gid,
parsed_args.securitygroup_id)
return _make_print_data(
securitygroup.securitygroup_id,
securitygroup.name,
@ -116,11 +118,15 @@ class CreateSecuritygroup(ShowOne):
help="Name of the new securitygroup")
parser.add_argument('--is-default', metavar='<true/false>',
default=False,
help="Defaults to the default securitygroup of the group")
help=("Defaults to the default securitygroup "
"of the group"))
parser.add_argument('--rule',
metavar=("<protocol=tcp|udp|icmp,port_range_max=integer,"
"port_range_min=integer,remote_ip_prefix=cidr,"
"remote_securitygroup_id=securitygroup_uuid>"),
metavar=("<protocol=tcp|udp|icmp,"
"port_range_max=integer,"
"port_range_min=integer,"
"remote_ip_prefix=cidr,"
"remote_securitygroup_id="
"securitygroup_uuid>"),
action='append',
type=utils.keyvalue_to_dict,
dest='rules',
@ -130,16 +136,18 @@ class CreateSecuritygroup(ShowOne):
"port_range_max: Starting port range, "
"port_range_min: Ending port range, "
"remote_ip_prefix: CIDR to match on, "
"remote_securitygroup_id: Remote securitygroup id "
"remote_securitygroup_id: "
"Remote securitygroup id "
"to apply rule. (Can be repeated)"))
return parser
def take_action(self, parsed_args):
securitygroup = self.client.securitygroups.create(self.gid,
parsed_args.name,
parsed_args.is_default,
parsed_args.rules)
securitygroup = self.client.securitygroups.create(
self.gid,
parsed_args.name,
parsed_args.is_default,
parsed_args.rules)
return _make_print_data(
securitygroup.securitygroup_id,
@ -173,13 +181,15 @@ class UpdateSecuritygroup(ShowOne):
help="Securitygroup ID")
parser.add_argument('--is-default', metavar='<true/false>',
required=True,
help="Defaults to the default securitygroup of the group")
help=("Defaults to the default securitygroup "
"of the group"))
return parser
def take_action(self, parsed_args):
securitygroup = self.client.securitygroups.update(self.gid,
parsed_args.securitygroup_id,
parsed_args.is_default)
securitygroup = self.client.securitygroups.update(
self.gid,
parsed_args.securitygroup_id,
parsed_args.is_default)
return _make_print_data(
securitygroup.securitygroup_id,
securitygroup.name,
@ -213,6 +223,6 @@ class DeleteSecuritygroup(Command):
return parser
def take_action(self, parsed_args):
securitygroup = self.client.securitygroups.delete(self.gid,
parsed_args.securitygroup_id)
self.client.securitygroups.delete(
self.gid,
parsed_args.securitygroup_id)

View File

@ -43,7 +43,8 @@ class KeypairManager(base.Manager):
:param keypair_id: ID of the keypair to get.
:rtype: Keypair.
"""
return self._get("/groups/%s/keypairs/%s" % (gid, keypair_id), "keypair")
return self._get("/groups/%s/keypairs/%s" %
(gid, keypair_id), "keypair")
def create(self, gid, name=None, is_default=False):
"""
@ -84,7 +85,8 @@ class KeypairManager(base.Manager):
"is_default": is_default
}
}
return self._update("/groups/%s/keypairs/%s" % (gid, keypair_id), body, "keypair")
return self._update("/groups/%s/keypairs/%s" %
(gid, keypair_id), body, "keypair")
def delete(self, gid, keypair_id):
"""

View File

@ -44,9 +44,11 @@ class NetworkManager(base.Manager):
:param network_id: ID of the network to get.
:rtype: Network.
"""
return self._get("/groups/%s/networks/%s" % (gid, network_id), "network")
return self._get("/groups/%s/networks/%s" %
(gid, network_id), "network")
def create(self, gid, cidr, name=None, is_admin=False, gateway=None, dns_nameservers=None, ext_router_id=None):
def create(self, gid, cidr, name=None, is_admin=False,
gateway=None, dns_nameservers=None, ext_router_id=None):
"""
Create a network.
@ -72,7 +74,7 @@ class NetworkManager(base.Manager):
return True
if not _is_valid_cidr(cidr):
raise exceptions.CommandError("cidr must be a CIDR.")
raise exceptions.CommandError("cidr must be a CIDR.")
if is_admin:
try:
@ -83,7 +85,8 @@ class NetworkManager(base.Manager):
if gateway and not netaddr.valid_ipv4(gateway):
raise exceptions.CommandError("gateway must be a IP address")
if dns_nameservers is not None and not isinstance(dns_nameservers, list):
if dns_nameservers is not None and not isinstance(
dns_nameservers, list):
raise exceptions.CommandError("dns_nameservers must be a list")
body = {
@ -101,7 +104,7 @@ class NetworkManager(base.Manager):
def delete(self, gid, network_id):
"""
Delete a network.
:param gid: ID of the group.
:param network_id: ID of the network to delete.
"""

View File

@ -46,7 +46,7 @@ class ProcessManager(base.Manager):
return self._get("/groups/%s/processes/%s" % (gid, pid), "process")
def create(self, gid, ppid=None, **kwargs):
'''
"""
Create a process.
If you give a ppid(Parent process ID),
@ -62,10 +62,11 @@ class ProcessManager(base.Manager):
:param list securitygroup_ids: List of IDs of securitygroups
:param userdata: file type object or string of script
:param dict args: Dict of key-value pairs to be stored as metadata
'''
"""
securitygroup_ids = kwargs.get('securitygroup_ids')
if securitygroup_ids is not None and not isinstance(securitygroup_ids, list):
if securitygroup_ids is not None and not isinstance(
securitygroup_ids, list):
raise exceptions.CommandError("securitygroup_ids must be a list")
userdata = kwargs.get('userdata')
@ -105,12 +106,13 @@ class ProcessManager(base.Manager):
"app_status": app_status
}
}
return self._update("/groups/%s/processes/%s" % (gid, pid), body, "process")
return self._update("/groups/%s/processes/%s" %
(gid, pid), body, "process")
def delete(self, gid, pid):
"""
Delete a process.
:param gid: ID of the group.
:param pid: ID of the process to delete.
"""

View File

@ -33,10 +33,11 @@ class ProxyManager(base.Manager):
:param gid: ID of the group.
:rtype: Process
"""
return self._get("/groups/%s/proxy" % (gid), "proxy")
return self._get("/groups/%s/proxy" % gid, "proxy")
def create(self, gid, name=None, nova_flavor_id=None, glance_image_id=None, keypair_id=None,
securitygroup_ids=None, userdata=None, args=None):
def create(self, gid, name=None, nova_flavor_id=None, glance_image_id=None,
keypair_id=None, securitygroup_ids=None, userdata=None,
args=None):
"""
Create a rack-proxy process.
@ -50,7 +51,8 @@ class ProxyManager(base.Manager):
:param dict args: Dict of key-value pairs to be stored as metadata
"""
if securitygroup_ids is not None and not isinstance(securitygroup_ids, list):
if securitygroup_ids is not None and not isinstance(
securitygroup_ids, list):
raise exceptions.CommandError("securitygroup_ids must be a list")
if userdata:
@ -74,12 +76,14 @@ class ProxyManager(base.Manager):
}
return self._create("/groups/%s/proxy" % gid, body, "proxy")
def update(self, gid, shm_endpoint=None, ipc_endpoint=None, fs_endpoint=None, app_status=None):
def update(self, gid, shm_endpoint=None, ipc_endpoint=None,
fs_endpoint=None, app_status=None):
"""
Update parameters of a rack-proxy process.
:param gid: ID of a group
:param shm_endpoint: An endpoint of Shared memory. Arbitrary string value.
:param shm_endpoint: An endpoint of Shared memory.
Arbitrary string value.
:param ipc_endpoint: An endpoint of IPC. Arbitrary string value.
:param fs_endpoint: An endpoint of File System. Arbitrary string value.
:param app_status: Application layer status of a rack-proxy process.

View File

@ -43,9 +43,11 @@ class SecuritygroupManager(base.Manager):
:param securitygroup_id: ID of the securitygroup to get.
:rtype: Securitygroup.
"""
return self._get("/groups/%s/securitygroups/%s" % (gid, securitygroup_id), "securitygroup")
return self._get("/groups/%s/securitygroups/%s" %
(gid, securitygroup_id), "securitygroup")
def create(self, gid, name=None, is_default=False, securitygroup_rules=None):
def create(self, gid, name=None, is_default=False,
securitygroup_rules=None):
"""
Create a securitygroup.
@ -61,7 +63,8 @@ class SecuritygroupManager(base.Manager):
if securitygroup_rules is not None:
if not isinstance(securitygroup_rules, list):
raise exceptions.CommandError("securitygroup_rules must be a list")
raise exceptions.CommandError(
"securitygroup_rules must be a list")
body = {
"securitygroup": {
@ -70,7 +73,8 @@ class SecuritygroupManager(base.Manager):
"securitygrouprules": securitygroup_rules
}
}
return self._create("/groups/%s/securitygroups" % gid, body, "securitygroup")
return self._create("/groups/%s/securitygroups" %
gid, body, "securitygroup")
def update(self, gid, securitygroup_id, is_default=False):
"""
@ -90,7 +94,8 @@ class SecuritygroupManager(base.Manager):
"is_default": is_default,
}
}
return self._update("/groups/%s/securitygroups/%s" % (gid, securitygroup_id), body, "securitygroup")
return self._update("/groups/%s/securitygroups/%s" %
(gid, securitygroup_id), body, "securitygroup")
def delete(self, gid, securitygroup_id):
"""

View File

@ -11,7 +11,7 @@ setenv = VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
find . -type f -name "*.pyc" -delete
/usr/bin/find . -type f -name "*.pyc" -delete
python setup.py testr --testr-args='{posargs}'
[testenv:pep8]