24 |
24 |
import os
|
25 |
25 |
import sys
|
26 |
26 |
import unittest
|
|
27 |
import random
|
27 |
28 |
|
28 |
29 |
from ganeti import constants
|
29 |
30 |
from ganeti import compat
|
... | ... | |
469 |
470 |
(constants.RPC_ENCODING_ZLIB_BASE64, "invalid zlib data"))
|
470 |
471 |
|
471 |
472 |
|
|
473 |
class TestRpcClientBase(unittest.TestCase):
|
|
474 |
def testNoHosts(self):
|
|
475 |
cdef = ("test_call", NotImplemented, None, rpc_defs.TMO_SLOW, [],
|
|
476 |
None, None, NotImplemented)
|
|
477 |
http_proc = _FakeRequestProcessor(NotImplemented)
|
|
478 |
client = rpc._RpcClientBase(rpc._StaticResolver([]), NotImplemented,
|
|
479 |
_req_process_fn=http_proc)
|
|
480 |
self.assertEqual(client._Call(cdef, [], []), {})
|
|
481 |
|
|
482 |
# Test wrong number of arguments
|
|
483 |
self.assertRaises(errors.ProgrammerError, client._Call,
|
|
484 |
cdef, [], [0, 1, 2])
|
|
485 |
|
|
486 |
def testTimeout(self):
|
|
487 |
def _CalcTimeout((arg1, arg2)):
|
|
488 |
return arg1 + arg2
|
|
489 |
|
|
490 |
def _VerifyRequest(exp_timeout, req):
|
|
491 |
self.assertEqual(req.read_timeout, exp_timeout)
|
|
492 |
|
|
493 |
req.success = True
|
|
494 |
req.resp_status_code = http.HTTP_OK
|
|
495 |
req.resp_body = serializer.DumpJson((True, hex(req.read_timeout)))
|
|
496 |
|
|
497 |
resolver = rpc._StaticResolver([
|
|
498 |
"192.0.2.1",
|
|
499 |
"192.0.2.2",
|
|
500 |
])
|
|
501 |
|
|
502 |
nodes = [
|
|
503 |
"node1.example.com",
|
|
504 |
"node2.example.com",
|
|
505 |
]
|
|
506 |
|
|
507 |
tests = [(100, None, 100), (30, None, 30)]
|
|
508 |
tests.extend((_CalcTimeout, i, i + 300)
|
|
509 |
for i in [0, 5, 16485, 30516])
|
|
510 |
|
|
511 |
for timeout, arg1, exp_timeout in tests:
|
|
512 |
cdef = ("test_call", NotImplemented, None, timeout, [
|
|
513 |
("arg1", None, NotImplemented),
|
|
514 |
("arg2", None, NotImplemented),
|
|
515 |
], None, None, NotImplemented)
|
|
516 |
|
|
517 |
http_proc = _FakeRequestProcessor(compat.partial(_VerifyRequest,
|
|
518 |
exp_timeout))
|
|
519 |
client = rpc._RpcClientBase(resolver, NotImplemented,
|
|
520 |
_req_process_fn=http_proc)
|
|
521 |
result = client._Call(cdef, nodes, [arg1, 300])
|
|
522 |
self.assertEqual(len(result), len(nodes))
|
|
523 |
self.assertTrue(compat.all(not res.fail_msg and
|
|
524 |
res.payload == hex(exp_timeout)
|
|
525 |
for res in result.values()))
|
|
526 |
|
|
527 |
def testArgumentEncoder(self):
|
|
528 |
(AT1, AT2) = range(1, 3)
|
|
529 |
|
|
530 |
resolver = rpc._StaticResolver([
|
|
531 |
"192.0.2.5",
|
|
532 |
"192.0.2.6",
|
|
533 |
])
|
|
534 |
|
|
535 |
nodes = [
|
|
536 |
"node5.example.com",
|
|
537 |
"node6.example.com",
|
|
538 |
]
|
|
539 |
|
|
540 |
encoders = {
|
|
541 |
AT1: hex,
|
|
542 |
AT2: hash,
|
|
543 |
}
|
|
544 |
|
|
545 |
cdef = ("test_call", NotImplemented, None, rpc_defs.TMO_NORMAL, [
|
|
546 |
("arg0", None, NotImplemented),
|
|
547 |
("arg1", AT1, NotImplemented),
|
|
548 |
("arg1", AT2, NotImplemented),
|
|
549 |
], None, None, NotImplemented)
|
|
550 |
|
|
551 |
def _VerifyRequest(req):
|
|
552 |
req.success = True
|
|
553 |
req.resp_status_code = http.HTTP_OK
|
|
554 |
req.resp_body = serializer.DumpJson((True, req.post_data))
|
|
555 |
|
|
556 |
http_proc = _FakeRequestProcessor(_VerifyRequest)
|
|
557 |
|
|
558 |
for num in [0, 3796, 9032119]:
|
|
559 |
client = rpc._RpcClientBase(resolver, encoders.get,
|
|
560 |
_req_process_fn=http_proc)
|
|
561 |
result = client._Call(cdef, nodes, ["foo", num, "Hello%s" % num])
|
|
562 |
self.assertEqual(len(result), len(nodes))
|
|
563 |
for res in result.values():
|
|
564 |
self.assertFalse(res.fail_msg)
|
|
565 |
self.assertEqual(serializer.LoadJson(res.payload),
|
|
566 |
["foo", hex(num), hash("Hello%s" % num)])
|
|
567 |
|
|
568 |
def testPostProc(self):
|
|
569 |
def _VerifyRequest(nums, req):
|
|
570 |
req.success = True
|
|
571 |
req.resp_status_code = http.HTTP_OK
|
|
572 |
req.resp_body = serializer.DumpJson((True, nums))
|
|
573 |
|
|
574 |
resolver = rpc._StaticResolver([
|
|
575 |
"192.0.2.90",
|
|
576 |
"192.0.2.95",
|
|
577 |
])
|
|
578 |
|
|
579 |
nodes = [
|
|
580 |
"node90.example.com",
|
|
581 |
"node95.example.com",
|
|
582 |
]
|
|
583 |
|
|
584 |
def _PostProc(res):
|
|
585 |
self.assertFalse(res.fail_msg)
|
|
586 |
res.payload = sum(res.payload)
|
|
587 |
return res
|
|
588 |
|
|
589 |
cdef = ("test_call", NotImplemented, None, rpc_defs.TMO_NORMAL, [],
|
|
590 |
None, _PostProc, NotImplemented)
|
|
591 |
|
|
592 |
# Seeded random generator
|
|
593 |
rnd = random.Random(20299)
|
|
594 |
|
|
595 |
for i in [0, 4, 74, 1391]:
|
|
596 |
nums = [rnd.randint(0, 1000) for _ in range(i)]
|
|
597 |
http_proc = _FakeRequestProcessor(compat.partial(_VerifyRequest, nums))
|
|
598 |
client = rpc._RpcClientBase(resolver, NotImplemented,
|
|
599 |
_req_process_fn=http_proc)
|
|
600 |
result = client._Call(cdef, nodes, [])
|
|
601 |
self.assertEqual(len(result), len(nodes))
|
|
602 |
for res in result.values():
|
|
603 |
self.assertFalse(res.fail_msg)
|
|
604 |
self.assertEqual(res.payload, sum(nums))
|
|
605 |
|
|
606 |
def testPreProc(self):
|
|
607 |
def _VerifyRequest(req):
|
|
608 |
req.success = True
|
|
609 |
req.resp_status_code = http.HTTP_OK
|
|
610 |
req.resp_body = serializer.DumpJson((True, req.post_data))
|
|
611 |
|
|
612 |
resolver = rpc._StaticResolver([
|
|
613 |
"192.0.2.30",
|
|
614 |
"192.0.2.35",
|
|
615 |
])
|
|
616 |
|
|
617 |
nodes = [
|
|
618 |
"node30.example.com",
|
|
619 |
"node35.example.com",
|
|
620 |
]
|
|
621 |
|
|
622 |
def _PreProc(node, data):
|
|
623 |
self.assertEqual(len(data), 1)
|
|
624 |
return data[0] + node
|
|
625 |
|
|
626 |
cdef = ("test_call", NotImplemented, None, rpc_defs.TMO_NORMAL, [
|
|
627 |
("arg0", None, NotImplemented),
|
|
628 |
], _PreProc, None, NotImplemented)
|
|
629 |
|
|
630 |
http_proc = _FakeRequestProcessor(_VerifyRequest)
|
|
631 |
client = rpc._RpcClientBase(resolver, NotImplemented,
|
|
632 |
_req_process_fn=http_proc)
|
|
633 |
|
|
634 |
for prefix in ["foo", "bar", "baz"]:
|
|
635 |
result = client._Call(cdef, nodes, [prefix])
|
|
636 |
self.assertEqual(len(result), len(nodes))
|
|
637 |
for (idx, (node, res)) in enumerate(result.items()):
|
|
638 |
self.assertFalse(res.fail_msg)
|
|
639 |
self.assertEqual(serializer.LoadJson(res.payload), prefix + node)
|
|
640 |
|
|
641 |
def testResolverOptions(self):
|
|
642 |
def _VerifyRequest(req):
|
|
643 |
req.success = True
|
|
644 |
req.resp_status_code = http.HTTP_OK
|
|
645 |
req.resp_body = serializer.DumpJson((True, req.post_data))
|
|
646 |
|
|
647 |
nodes = [
|
|
648 |
"node30.example.com",
|
|
649 |
"node35.example.com",
|
|
650 |
]
|
|
651 |
|
|
652 |
def _Resolver(expected, hosts, options):
|
|
653 |
self.assertEqual(hosts, nodes)
|
|
654 |
self.assertEqual(options, expected)
|
|
655 |
return zip(hosts, nodes)
|
|
656 |
|
|
657 |
def _DynamicResolverOptions((arg0, )):
|
|
658 |
return sum(arg0)
|
|
659 |
|
|
660 |
tests = [
|
|
661 |
(None, None, None),
|
|
662 |
(rpc_defs.ACCEPT_OFFLINE_NODE, None, rpc_defs.ACCEPT_OFFLINE_NODE),
|
|
663 |
(False, None, False),
|
|
664 |
(True, None, True),
|
|
665 |
(0, None, 0),
|
|
666 |
(_DynamicResolverOptions, [1, 2, 3], 6),
|
|
667 |
(_DynamicResolverOptions, range(4, 19), 165),
|
|
668 |
]
|
|
669 |
|
|
670 |
for (resolver_opts, arg0, expected) in tests:
|
|
671 |
cdef = ("test_call", NotImplemented, resolver_opts, rpc_defs.TMO_NORMAL, [
|
|
672 |
("arg0", None, NotImplemented),
|
|
673 |
], None, None, NotImplemented)
|
|
674 |
|
|
675 |
http_proc = _FakeRequestProcessor(_VerifyRequest)
|
|
676 |
|
|
677 |
client = rpc._RpcClientBase(compat.partial(_Resolver, expected),
|
|
678 |
NotImplemented, _req_process_fn=http_proc)
|
|
679 |
result = client._Call(cdef, nodes, [arg0])
|
|
680 |
self.assertEqual(len(result), len(nodes))
|
|
681 |
for (idx, (node, res)) in enumerate(result.items()):
|
|
682 |
self.assertFalse(res.fail_msg)
|
|
683 |
|
|
684 |
|
|
685 |
class TestRpcRunner(unittest.TestCase):
|
|
686 |
def testUploadFile(self):
|
|
687 |
runner = rpc.RpcRunner(_req_process_fn=http_proc)
|
|
688 |
|
|
689 |
|
472 |
690 |
if __name__ == "__main__":
|
473 |
691 |
testutils.GanetiTestProgram()
|