summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/hashserv/tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/hashserv/tests.py')
-rw-r--r--bitbake/lib/hashserv/tests.py276
1 files changed, 267 insertions, 9 deletions
diff --git a/bitbake/lib/hashserv/tests.py b/bitbake/lib/hashserv/tests.py
index e9a361dc4b..f92f37c459 100644
--- a/bitbake/lib/hashserv/tests.py
+++ b/bitbake/lib/hashserv/tests.py
@@ -6,6 +6,8 @@
6# 6#
7 7
8from . import create_server, create_client 8from . import create_server, create_client
9from .server import DEFAULT_ANON_PERMS, ALL_PERMISSIONS
10from bb.asyncrpc import InvokeError
9import hashlib 11import hashlib
10import logging 12import logging
11import multiprocessing 13import multiprocessing
@@ -29,8 +31,9 @@ class HashEquivalenceTestSetup(object):
29 METHOD = 'TestMethod' 31 METHOD = 'TestMethod'
30 32
31 server_index = 0 33 server_index = 0
34 client_index = 0
32 35
33 def start_server(self, dbpath=None, upstream=None, read_only=False, prefunc=server_prefunc): 36 def start_server(self, dbpath=None, upstream=None, read_only=False, prefunc=server_prefunc, anon_perms=DEFAULT_ANON_PERMS, admin_username=None, admin_password=None):
34 self.server_index += 1 37 self.server_index += 1
35 if dbpath is None: 38 if dbpath is None:
36 dbpath = self.make_dbpath() 39 dbpath = self.make_dbpath()
@@ -45,7 +48,10 @@ class HashEquivalenceTestSetup(object):
45 server = create_server(self.get_server_addr(self.server_index), 48 server = create_server(self.get_server_addr(self.server_index),
46 dbpath, 49 dbpath,
47 upstream=upstream, 50 upstream=upstream,
48 read_only=read_only) 51 read_only=read_only,
52 anon_perms=anon_perms,
53 admin_username=admin_username,
54 admin_password=admin_password)
49 server.dbpath = dbpath 55 server.dbpath = dbpath
50 56
51 server.serve_as_process(prefunc=prefunc, args=(self.server_index,)) 57 server.serve_as_process(prefunc=prefunc, args=(self.server_index,))
@@ -56,18 +62,31 @@ class HashEquivalenceTestSetup(object):
56 def make_dbpath(self): 62 def make_dbpath(self):
57 return os.path.join(self.temp_dir.name, "db%d.sqlite" % self.server_index) 63 return os.path.join(self.temp_dir.name, "db%d.sqlite" % self.server_index)
58 64
59 def start_client(self, server_address): 65 def start_client(self, server_address, username=None, password=None):
60 def cleanup_client(client): 66 def cleanup_client(client):
61 client.close() 67 client.close()
62 68
63 client = create_client(server_address) 69 client = create_client(server_address, username=username, password=password)
64 self.addCleanup(cleanup_client, client) 70 self.addCleanup(cleanup_client, client)
65 71
66 return client 72 return client
67 73
68 def start_test_server(self): 74 def start_test_server(self):
69 server = self.start_server() 75 self.server = self.start_server()
70 return server.address 76 return self.server.address
77
78 def start_auth_server(self):
79 self.auth_server = self.start_server(self.server.dbpath, anon_perms=[], admin_username="admin", admin_password="password")
80 self.admin_client = self.start_client(self.auth_server.address, username="admin", password="password")
81 return self.admin_client
82
83 def auth_client(self, user):
84 return self.start_client(self.auth_server.address, user["username"], user["token"])
85
86 def auth_perms(self, *permissions):
87 self.client_index += 1
88 user = self.admin_client.new_user(f"user-{self.client_index}", permissions)
89 return self.auth_client(user)
71 90
72 def setUp(self): 91 def setUp(self):
73 if sys.version_info < (3, 5, 0): 92 if sys.version_info < (3, 5, 0):
@@ -86,18 +105,21 @@ class HashEquivalenceTestSetup(object):
86 105
87 106
88class HashEquivalenceCommonTests(object): 107class HashEquivalenceCommonTests(object):
89 def test_create_hash(self): 108 def create_test_hash(self, client):
90 # Simple test that hashes can be created 109 # Simple test that hashes can be created
91 taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9' 110 taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9'
92 outhash = '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f' 111 outhash = '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f'
93 unihash = 'f46d3fbb439bd9b921095da657a4de906510d2cd' 112 unihash = 'f46d3fbb439bd9b921095da657a4de906510d2cd'
94 113
95 self.assertClientGetHash(self.client, taskhash, None) 114 self.assertClientGetHash(client, taskhash, None)
96 115
97 result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash) 116 result = client.report_unihash(taskhash, self.METHOD, outhash, unihash)
98 self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash') 117 self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')
99 return taskhash, outhash, unihash 118 return taskhash, outhash, unihash
100 119
120 def test_create_hash(self):
121 return self.create_test_hash(self.client)
122
101 def test_create_equivalent(self): 123 def test_create_equivalent(self):
102 # Tests that a second reported task with the same outhash will be 124 # Tests that a second reported task with the same outhash will be
103 # assigned the same unihash 125 # assigned the same unihash
@@ -471,6 +493,242 @@ class HashEquivalenceCommonTests(object):
471 # shares a taskhash with Task 2 493 # shares a taskhash with Task 2
472 self.assertClientGetHash(self.client, taskhash2, unihash2) 494 self.assertClientGetHash(self.client, taskhash2, unihash2)
473 495
496 def test_auth_read_perms(self):
497 admin_client = self.start_auth_server()
498
499 # Create hashes with non-authenticated server
500 taskhash, outhash, unihash = self.test_create_hash()
501
502 # Validate hash can be retrieved using authenticated client
503 with self.auth_perms("@read") as client:
504 self.assertClientGetHash(client, taskhash, unihash)
505
506 with self.auth_perms() as client, self.assertRaises(InvokeError):
507 self.assertClientGetHash(client, taskhash, unihash)
508
509 def test_auth_report_perms(self):
510 admin_client = self.start_auth_server()
511
512 # Without read permission, the user is completely denied
513 with self.auth_perms() as client, self.assertRaises(InvokeError):
514 self.create_test_hash(client)
515
516 # Read permission allows the call to succeed, but it doesn't record
517 # anythin in the database
518 with self.auth_perms("@read") as client:
519 taskhash, outhash, unihash = self.create_test_hash(client)
520 self.assertClientGetHash(client, taskhash, None)
521
522 # Report permission alone is insufficient
523 with self.auth_perms("@report") as client, self.assertRaises(InvokeError):
524 self.create_test_hash(client)
525
526 # Read and report permission actually modify the database
527 with self.auth_perms("@read", "@report") as client:
528 taskhash, outhash, unihash = self.create_test_hash(client)
529 self.assertClientGetHash(client, taskhash, unihash)
530
531 def test_auth_no_token_refresh_from_anon_user(self):
532 self.start_auth_server()
533
534 with self.start_client(self.auth_server.address) as client, self.assertRaises(InvokeError):
535 client.refresh_token()
536
537 def assertUserCanAuth(self, user):
538 with self.start_client(self.auth_server.address) as client:
539 client.auth(user["username"], user["token"])
540
541 def assertUserCannotAuth(self, user):
542 with self.start_client(self.auth_server.address) as client, self.assertRaises(InvokeError):
543 client.auth(user["username"], user["token"])
544
545 def test_auth_self_token_refresh(self):
546 admin_client = self.start_auth_server()
547
548 # Create a new user with no permissions
549 user = admin_client.new_user("test-user", [])
550
551 with self.auth_client(user) as client:
552 new_user = client.refresh_token()
553
554 self.assertEqual(user["username"], new_user["username"])
555 self.assertNotEqual(user["token"], new_user["token"])
556 self.assertUserCanAuth(new_user)
557 self.assertUserCannotAuth(user)
558
559 # Explicitly specifying with your own username is fine also
560 with self.auth_client(new_user) as client:
561 new_user2 = client.refresh_token(user["username"])
562
563 self.assertEqual(user["username"], new_user2["username"])
564 self.assertNotEqual(user["token"], new_user2["token"])
565 self.assertUserCanAuth(new_user2)
566 self.assertUserCannotAuth(new_user)
567 self.assertUserCannotAuth(user)
568
569 def test_auth_token_refresh(self):
570 admin_client = self.start_auth_server()
571
572 user = admin_client.new_user("test-user", [])
573
574 with self.auth_perms() as client, self.assertRaises(InvokeError):
575 client.refresh_token(user["username"])
576
577 with self.auth_perms("@user-admin") as client:
578 new_user = client.refresh_token(user["username"])
579
580 self.assertEqual(user["username"], new_user["username"])
581 self.assertNotEqual(user["token"], new_user["token"])
582 self.assertUserCanAuth(new_user)
583 self.assertUserCannotAuth(user)
584
585 def test_auth_self_get_user(self):
586 admin_client = self.start_auth_server()
587
588 user = admin_client.new_user("test-user", [])
589 user_info = user.copy()
590 del user_info["token"]
591
592 with self.auth_client(user) as client:
593 info = client.get_user()
594 self.assertEqual(info, user_info)
595
596 # Explicitly asking for your own username is fine also
597 info = client.get_user(user["username"])
598 self.assertEqual(info, user_info)
599
600 def test_auth_get_user(self):
601 admin_client = self.start_auth_server()
602
603 user = admin_client.new_user("test-user", [])
604 user_info = user.copy()
605 del user_info["token"]
606
607 with self.auth_perms() as client, self.assertRaises(InvokeError):
608 client.get_user(user["username"])
609
610 with self.auth_perms("@user-admin") as client:
611 info = client.get_user(user["username"])
612 self.assertEqual(info, user_info)
613
614 info = client.get_user("nonexist-user")
615 self.assertIsNone(info)
616
617 def test_auth_reconnect(self):
618 admin_client = self.start_auth_server()
619
620 user = admin_client.new_user("test-user", [])
621 user_info = user.copy()
622 del user_info["token"]
623
624 with self.auth_client(user) as client:
625 info = client.get_user()
626 self.assertEqual(info, user_info)
627
628 client.disconnect()
629
630 info = client.get_user()
631 self.assertEqual(info, user_info)
632
633 def test_auth_delete_user(self):
634 admin_client = self.start_auth_server()
635
636 user = admin_client.new_user("test-user", [])
637
638 # No self service
639 with self.auth_client(user) as client, self.assertRaises(InvokeError):
640 client.delete_user(user["username"])
641
642 with self.auth_perms() as client, self.assertRaises(InvokeError):
643 client.delete_user(user["username"])
644
645 with self.auth_perms("@user-admin") as client:
646 client.delete_user(user["username"])
647
648 # User doesn't exist, so even though the permission is correct, it's an
649 # error
650 with self.auth_perms("@user-admin") as client, self.assertRaises(InvokeError):
651 client.delete_user(user["username"])
652
653 def assertUserPerms(self, user, permissions):
654 with self.auth_client(user) as client:
655 info = client.get_user()
656 self.assertEqual(info, {
657 "username": user["username"],
658 "permissions": permissions,
659 })
660
661 def test_auth_set_user_perms(self):
662 admin_client = self.start_auth_server()
663
664 user = admin_client.new_user("test-user", [])
665
666 self.assertUserPerms(user, [])
667
668 # No self service to change permissions
669 with self.auth_client(user) as client, self.assertRaises(InvokeError):
670 client.set_user_perms(user["username"], ["@all"])
671 self.assertUserPerms(user, [])
672
673 with self.auth_perms() as client, self.assertRaises(InvokeError):
674 client.set_user_perms(user["username"], ["@all"])
675 self.assertUserPerms(user, [])
676
677 with self.auth_perms("@user-admin") as client:
678 client.set_user_perms(user["username"], ["@all"])
679 self.assertUserPerms(user, sorted(list(ALL_PERMISSIONS)))
680
681 # Bad permissions
682 with self.auth_perms("@user-admin") as client, self.assertRaises(InvokeError):
683 client.set_user_perms(user["username"], ["@this-is-not-a-permission"])
684 self.assertUserPerms(user, sorted(list(ALL_PERMISSIONS)))
685
686 def test_auth_get_all_users(self):
687 admin_client = self.start_auth_server()
688
689 user = admin_client.new_user("test-user", [])
690
691 with self.auth_client(user) as client, self.assertRaises(InvokeError):
692 client.get_all_users()
693
694 # Give the test user the correct permission
695 admin_client.set_user_perms(user["username"], ["@user-admin"])
696
697 with self.auth_client(user) as client:
698 all_users = client.get_all_users()
699
700 # Convert to a dictionary for easier comparison
701 all_users = {u["username"]: u for u in all_users}
702
703 self.assertEqual(all_users,
704 {
705 "admin": {
706 "username": "admin",
707 "permissions": sorted(list(ALL_PERMISSIONS)),
708 },
709 "test-user": {
710 "username": "test-user",
711 "permissions": ["@user-admin"],
712 }
713 }
714 )
715
716 def test_auth_new_user(self):
717 self.start_auth_server()
718
719 permissions = ["@read", "@report", "@db-admin", "@user-admin"]
720 permissions.sort()
721
722 with self.auth_perms() as client, self.assertRaises(InvokeError):
723 client.new_user("test-user", permissions)
724
725 with self.auth_perms("@user-admin") as client:
726 user = client.new_user("test-user", permissions)
727 self.assertIn("token", user)
728 self.assertEqual(user["username"], "test-user")
729 self.assertEqual(user["permissions"], permissions)
730
731
474class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase): 732class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase):
475 def get_server_addr(self, server_idx): 733 def get_server_addr(self, server_idx):
476 return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx) 734 return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx)