diff options
author | Joshua Watt <JPEWhacker@gmail.com> | 2023-11-03 08:26:35 -0600 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-11-09 17:33:03 +0000 |
commit | 92a9d6d55ddb64a12be4ad38e2ed4280ce59ba8e (patch) | |
tree | d2f52f6c5be0237a7bb120dccfec0f3a031b2332 /bitbake | |
parent | c1574ae46f7a5701d79f2c1d333094a5d5919a46 (diff) | |
download | poky-92a9d6d55ddb64a12be4ad38e2ed4280ce59ba8e.tar.gz |
bitbake: hashserv: test: Add bitbake-hashclient tests
The bitbake-hashclient command-line tool now has a lot more features
which should be tested, so add some tests for them.
(Bitbake rev: 178cf99673d7ddf8e0bb63a5a43331a18f3286d5)
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/hashserv/tests.py | 300 |
1 files changed, 277 insertions, 23 deletions
diff --git a/bitbake/lib/hashserv/tests.py b/bitbake/lib/hashserv/tests.py index fc69acaf7c..a80ccd57e1 100644 --- a/bitbake/lib/hashserv/tests.py +++ b/bitbake/lib/hashserv/tests.py | |||
@@ -19,6 +19,14 @@ import unittest | |||
19 | import socket | 19 | import socket |
20 | import time | 20 | import time |
21 | import signal | 21 | import signal |
22 | import subprocess | ||
23 | import json | ||
24 | import re | ||
25 | from pathlib import Path | ||
26 | |||
27 | |||
28 | THIS_DIR = Path(__file__).parent | ||
29 | BIN_DIR = THIS_DIR.parent.parent / "bin" | ||
22 | 30 | ||
23 | def server_prefunc(server, idx): | 31 | def server_prefunc(server, idx): |
24 | logging.basicConfig(level=logging.DEBUG, filename='bbhashserv-%d.log' % idx, filemode='w', | 32 | logging.basicConfig(level=logging.DEBUG, filename='bbhashserv-%d.log' % idx, filemode='w', |
@@ -103,8 +111,22 @@ class HashEquivalenceTestSetup(object): | |||
103 | result = client.get_unihash(self.METHOD, taskhash) | 111 | result = client.get_unihash(self.METHOD, taskhash) |
104 | self.assertEqual(result, unihash) | 112 | self.assertEqual(result, unihash) |
105 | 113 | ||
114 | def assertUserPerms(self, user, permissions): | ||
115 | with self.auth_client(user) as client: | ||
116 | info = client.get_user() | ||
117 | self.assertEqual(info, { | ||
118 | "username": user["username"], | ||
119 | "permissions": permissions, | ||
120 | }) | ||
121 | |||
122 | def assertUserCanAuth(self, user): | ||
123 | with self.start_client(self.auth_server.address) as client: | ||
124 | client.auth(user["username"], user["token"]) | ||
125 | |||
126 | def assertUserCannotAuth(self, user): | ||
127 | with self.start_client(self.auth_server.address) as client, self.assertRaises(InvokeError): | ||
128 | client.auth(user["username"], user["token"]) | ||
106 | 129 | ||
107 | class HashEquivalenceCommonTests(object): | ||
108 | def create_test_hash(self, client): | 130 | def create_test_hash(self, client): |
109 | # Simple test that hashes can be created | 131 | # Simple test that hashes can be created |
110 | taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9' | 132 | taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9' |
@@ -117,6 +139,24 @@ class HashEquivalenceCommonTests(object): | |||
117 | self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash') | 139 | self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash') |
118 | return taskhash, outhash, unihash | 140 | return taskhash, outhash, unihash |
119 | 141 | ||
142 | def run_hashclient(self, args, **kwargs): | ||
143 | try: | ||
144 | p = subprocess.run( | ||
145 | [BIN_DIR / "bitbake-hashclient"] + args, | ||
146 | stdout=subprocess.PIPE, | ||
147 | stderr=subprocess.STDOUT, | ||
148 | encoding="utf-8", | ||
149 | **kwargs | ||
150 | ) | ||
151 | except subprocess.CalledProcessError as e: | ||
152 | print(e.output) | ||
153 | raise e | ||
154 | |||
155 | print(p.stdout) | ||
156 | return p | ||
157 | |||
158 | |||
159 | class HashEquivalenceCommonTests(object): | ||
120 | def test_create_hash(self): | 160 | def test_create_hash(self): |
121 | return self.create_test_hash(self.client) | 161 | return self.create_test_hash(self.client) |
122 | 162 | ||
@@ -161,7 +201,7 @@ class HashEquivalenceCommonTests(object): | |||
161 | self.assertClientGetHash(self.client, taskhash, unihash) | 201 | self.assertClientGetHash(self.client, taskhash, unihash) |
162 | 202 | ||
163 | def test_remove_taskhash(self): | 203 | def test_remove_taskhash(self): |
164 | taskhash, outhash, unihash = self.test_create_hash() | 204 | taskhash, outhash, unihash = self.create_test_hash(self.client) |
165 | result = self.client.remove({"taskhash": taskhash}) | 205 | result = self.client.remove({"taskhash": taskhash}) |
166 | self.assertGreater(result["count"], 0) | 206 | self.assertGreater(result["count"], 0) |
167 | self.assertClientGetHash(self.client, taskhash, None) | 207 | self.assertClientGetHash(self.client, taskhash, None) |
@@ -170,13 +210,13 @@ class HashEquivalenceCommonTests(object): | |||
170 | self.assertIsNone(result_outhash) | 210 | self.assertIsNone(result_outhash) |
171 | 211 | ||
172 | def test_remove_unihash(self): | 212 | def test_remove_unihash(self): |
173 | taskhash, outhash, unihash = self.test_create_hash() | 213 | taskhash, outhash, unihash = self.create_test_hash(self.client) |
174 | result = self.client.remove({"unihash": unihash}) | 214 | result = self.client.remove({"unihash": unihash}) |
175 | self.assertGreater(result["count"], 0) | 215 | self.assertGreater(result["count"], 0) |
176 | self.assertClientGetHash(self.client, taskhash, None) | 216 | self.assertClientGetHash(self.client, taskhash, None) |
177 | 217 | ||
178 | def test_remove_outhash(self): | 218 | def test_remove_outhash(self): |
179 | taskhash, outhash, unihash = self.test_create_hash() | 219 | taskhash, outhash, unihash = self.create_test_hash(self.client) |
180 | result = self.client.remove({"outhash": outhash}) | 220 | result = self.client.remove({"outhash": outhash}) |
181 | self.assertGreater(result["count"], 0) | 221 | self.assertGreater(result["count"], 0) |
182 | 222 | ||
@@ -184,7 +224,7 @@ class HashEquivalenceCommonTests(object): | |||
184 | self.assertIsNone(result_outhash) | 224 | self.assertIsNone(result_outhash) |
185 | 225 | ||
186 | def test_remove_method(self): | 226 | def test_remove_method(self): |
187 | taskhash, outhash, unihash = self.test_create_hash() | 227 | taskhash, outhash, unihash = self.create_test_hash(self.client) |
188 | result = self.client.remove({"method": self.METHOD}) | 228 | result = self.client.remove({"method": self.METHOD}) |
189 | self.assertGreater(result["count"], 0) | 229 | self.assertGreater(result["count"], 0) |
190 | self.assertClientGetHash(self.client, taskhash, None) | 230 | self.assertClientGetHash(self.client, taskhash, None) |
@@ -193,7 +233,7 @@ class HashEquivalenceCommonTests(object): | |||
193 | self.assertIsNone(result_outhash) | 233 | self.assertIsNone(result_outhash) |
194 | 234 | ||
195 | def test_clean_unused(self): | 235 | def test_clean_unused(self): |
196 | taskhash, outhash, unihash = self.test_create_hash() | 236 | taskhash, outhash, unihash = self.create_test_hash(self.client) |
197 | 237 | ||
198 | # Clean the database, which should not remove anything because all hashes an in-use | 238 | # Clean the database, which should not remove anything because all hashes an in-use |
199 | result = self.client.clean_unused(0) | 239 | result = self.client.clean_unused(0) |
@@ -497,7 +537,7 @@ class HashEquivalenceCommonTests(object): | |||
497 | admin_client = self.start_auth_server() | 537 | admin_client = self.start_auth_server() |
498 | 538 | ||
499 | # Create hashes with non-authenticated server | 539 | # Create hashes with non-authenticated server |
500 | taskhash, outhash, unihash = self.test_create_hash() | 540 | taskhash, outhash, unihash = self.create_test_hash(self.client) |
501 | 541 | ||
502 | # Validate hash can be retrieved using authenticated client | 542 | # Validate hash can be retrieved using authenticated client |
503 | with self.auth_perms("@read") as client: | 543 | with self.auth_perms("@read") as client: |
@@ -534,14 +574,6 @@ class HashEquivalenceCommonTests(object): | |||
534 | with self.start_client(self.auth_server.address) as client, self.assertRaises(InvokeError): | 574 | with self.start_client(self.auth_server.address) as client, self.assertRaises(InvokeError): |
535 | client.refresh_token() | 575 | client.refresh_token() |
536 | 576 | ||
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): | 577 | def test_auth_self_token_refresh(self): |
546 | admin_client = self.start_auth_server() | 578 | admin_client = self.start_auth_server() |
547 | 579 | ||
@@ -650,14 +682,6 @@ class HashEquivalenceCommonTests(object): | |||
650 | with self.auth_perms("@user-admin") as client, self.assertRaises(InvokeError): | 682 | with self.auth_perms("@user-admin") as client, self.assertRaises(InvokeError): |
651 | client.delete_user(user["username"]) | 683 | client.delete_user(user["username"]) |
652 | 684 | ||
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): | 685 | def test_auth_set_user_perms(self): |
662 | admin_client = self.start_auth_server() | 686 | admin_client = self.start_auth_server() |
663 | 687 | ||
@@ -785,6 +809,236 @@ class HashEquivalenceCommonTests(object): | |||
785 | for col in columns: | 809 | for col in columns: |
786 | self.client.remove({col: ""}) | 810 | self.client.remove({col: ""}) |
787 | 811 | ||
812 | |||
813 | class TestHashEquivalenceClient(HashEquivalenceTestSetup, unittest.TestCase): | ||
814 | def get_server_addr(self, server_idx): | ||
815 | return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx) | ||
816 | |||
817 | def test_stats(self): | ||
818 | self.run_hashclient(["--address", self.server_address, "stats"], check=True) | ||
819 | |||
820 | def test_stress(self): | ||
821 | self.run_hashclient(["--address", self.server_address, "stress"], check=True) | ||
822 | |||
823 | def test_remove_taskhash(self): | ||
824 | taskhash, outhash, unihash = self.create_test_hash(self.client) | ||
825 | self.run_hashclient([ | ||
826 | "--address", self.server_address, | ||
827 | "remove", | ||
828 | "--where", "taskhash", taskhash, | ||
829 | ], check=True) | ||
830 | self.assertClientGetHash(self.client, taskhash, None) | ||
831 | |||
832 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash) | ||
833 | self.assertIsNone(result_outhash) | ||
834 | |||
835 | def test_remove_unihash(self): | ||
836 | taskhash, outhash, unihash = self.create_test_hash(self.client) | ||
837 | self.run_hashclient([ | ||
838 | "--address", self.server_address, | ||
839 | "remove", | ||
840 | "--where", "unihash", unihash, | ||
841 | ], check=True) | ||
842 | self.assertClientGetHash(self.client, taskhash, None) | ||
843 | |||
844 | def test_remove_outhash(self): | ||
845 | taskhash, outhash, unihash = self.create_test_hash(self.client) | ||
846 | self.run_hashclient([ | ||
847 | "--address", self.server_address, | ||
848 | "remove", | ||
849 | "--where", "outhash", outhash, | ||
850 | ], check=True) | ||
851 | |||
852 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash) | ||
853 | self.assertIsNone(result_outhash) | ||
854 | |||
855 | def test_remove_method(self): | ||
856 | taskhash, outhash, unihash = self.create_test_hash(self.client) | ||
857 | self.run_hashclient([ | ||
858 | "--address", self.server_address, | ||
859 | "remove", | ||
860 | "--where", "method", self.METHOD, | ||
861 | ], check=True) | ||
862 | self.assertClientGetHash(self.client, taskhash, None) | ||
863 | |||
864 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash) | ||
865 | self.assertIsNone(result_outhash) | ||
866 | |||
867 | def test_clean_unused(self): | ||
868 | taskhash, outhash, unihash = self.create_test_hash(self.client) | ||
869 | |||
870 | # Clean the database, which should not remove anything because all hashes an in-use | ||
871 | self.run_hashclient([ | ||
872 | "--address", self.server_address, | ||
873 | "clean-unused", "0", | ||
874 | ], check=True) | ||
875 | self.assertClientGetHash(self.client, taskhash, unihash) | ||
876 | |||
877 | # Remove the unihash. The row in the outhash table should still be present | ||
878 | self.run_hashclient([ | ||
879 | "--address", self.server_address, | ||
880 | "remove", | ||
881 | "--where", "unihash", unihash, | ||
882 | ], check=True) | ||
883 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False) | ||
884 | self.assertIsNotNone(result_outhash) | ||
885 | |||
886 | # Now clean with no minimum age which will remove the outhash | ||
887 | self.run_hashclient([ | ||
888 | "--address", self.server_address, | ||
889 | "clean-unused", "0", | ||
890 | ], check=True) | ||
891 | result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False) | ||
892 | self.assertIsNone(result_outhash) | ||
893 | |||
894 | def test_refresh_token(self): | ||
895 | admin_client = self.start_auth_server() | ||
896 | |||
897 | user = admin_client.new_user("test-user", ["@read", "@report"]) | ||
898 | |||
899 | p = self.run_hashclient([ | ||
900 | "--address", self.auth_server.address, | ||
901 | "--login", user["username"], | ||
902 | "--password", user["token"], | ||
903 | "refresh-token" | ||
904 | ], check=True) | ||
905 | |||
906 | new_token = None | ||
907 | for l in p.stdout.splitlines(): | ||
908 | l = l.rstrip() | ||
909 | m = re.match(r'Token: +(.*)$', l) | ||
910 | if m is not None: | ||
911 | new_token = m.group(1) | ||
912 | |||
913 | self.assertTrue(new_token) | ||
914 | |||
915 | print("New token is %r" % new_token) | ||
916 | |||
917 | self.run_hashclient([ | ||
918 | "--address", self.auth_server.address, | ||
919 | "--login", user["username"], | ||
920 | "--password", new_token, | ||
921 | "get-user" | ||
922 | ], check=True) | ||
923 | |||
924 | def test_set_user_perms(self): | ||
925 | admin_client = self.start_auth_server() | ||
926 | |||
927 | user = admin_client.new_user("test-user", ["@read"]) | ||
928 | |||
929 | self.run_hashclient([ | ||
930 | "--address", self.auth_server.address, | ||
931 | "--login", admin_client.username, | ||
932 | "--password", admin_client.password, | ||
933 | "set-user-perms", | ||
934 | "-u", user["username"], | ||
935 | "@read", "@report", | ||
936 | ], check=True) | ||
937 | |||
938 | new_user = admin_client.get_user(user["username"]) | ||
939 | |||
940 | self.assertEqual(set(new_user["permissions"]), {"@read", "@report"}) | ||
941 | |||
942 | def test_get_user(self): | ||
943 | admin_client = self.start_auth_server() | ||
944 | |||
945 | user = admin_client.new_user("test-user", ["@read"]) | ||
946 | |||
947 | p = self.run_hashclient([ | ||
948 | "--address", self.auth_server.address, | ||
949 | "--login", admin_client.username, | ||
950 | "--password", admin_client.password, | ||
951 | "get-user", | ||
952 | "-u", user["username"], | ||
953 | ], check=True) | ||
954 | |||
955 | self.assertIn("Username:", p.stdout) | ||
956 | self.assertIn("Permissions:", p.stdout) | ||
957 | |||
958 | p = self.run_hashclient([ | ||
959 | "--address", self.auth_server.address, | ||
960 | "--login", user["username"], | ||
961 | "--password", user["token"], | ||
962 | "get-user", | ||
963 | ], check=True) | ||
964 | |||
965 | self.assertIn("Username:", p.stdout) | ||
966 | self.assertIn("Permissions:", p.stdout) | ||
967 | |||
968 | def test_get_all_users(self): | ||
969 | admin_client = self.start_auth_server() | ||
970 | |||
971 | admin_client.new_user("test-user1", ["@read"]) | ||
972 | admin_client.new_user("test-user2", ["@read"]) | ||
973 | |||
974 | p = self.run_hashclient([ | ||
975 | "--address", self.auth_server.address, | ||
976 | "--login", admin_client.username, | ||
977 | "--password", admin_client.password, | ||
978 | "get-all-users", | ||
979 | ], check=True) | ||
980 | |||
981 | self.assertIn("admin", p.stdout) | ||
982 | self.assertIn("test-user1", p.stdout) | ||
983 | self.assertIn("test-user2", p.stdout) | ||
984 | |||
985 | def test_new_user(self): | ||
986 | admin_client = self.start_auth_server() | ||
987 | |||
988 | p = self.run_hashclient([ | ||
989 | "--address", self.auth_server.address, | ||
990 | "--login", admin_client.username, | ||
991 | "--password", admin_client.password, | ||
992 | "new-user", | ||
993 | "-u", "test-user", | ||
994 | "@read", "@report", | ||
995 | ], check=True) | ||
996 | |||
997 | new_token = None | ||
998 | for l in p.stdout.splitlines(): | ||
999 | l = l.rstrip() | ||
1000 | m = re.match(r'Token: +(.*)$', l) | ||
1001 | if m is not None: | ||
1002 | new_token = m.group(1) | ||
1003 | |||
1004 | self.assertTrue(new_token) | ||
1005 | |||
1006 | user = { | ||
1007 | "username": "test-user", | ||
1008 | "token": new_token, | ||
1009 | } | ||
1010 | |||
1011 | self.assertUserPerms(user, ["@read", "@report"]) | ||
1012 | |||
1013 | def test_delete_user(self): | ||
1014 | admin_client = self.start_auth_server() | ||
1015 | |||
1016 | user = admin_client.new_user("test-user", ["@read"]) | ||
1017 | |||
1018 | p = self.run_hashclient([ | ||
1019 | "--address", self.auth_server.address, | ||
1020 | "--login", admin_client.username, | ||
1021 | "--password", admin_client.password, | ||
1022 | "delete-user", | ||
1023 | "-u", user["username"], | ||
1024 | ], check=True) | ||
1025 | |||
1026 | |||
1027 | self.assertIsNone(admin_client.get_user(user["username"])) | ||
1028 | |||
1029 | def test_get_db_usage(self): | ||
1030 | p = self.run_hashclient([ | ||
1031 | "--address", self.server_address, | ||
1032 | "get-db-usage", | ||
1033 | ], check=True) | ||
1034 | |||
1035 | def test_get_db_query_columns(self): | ||
1036 | p = self.run_hashclient([ | ||
1037 | "--address", self.server_address, | ||
1038 | "get-db-query-columns", | ||
1039 | ], check=True) | ||
1040 | |||
1041 | |||
788 | class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase): | 1042 | class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase): |
789 | def get_server_addr(self, server_idx): | 1043 | def get_server_addr(self, server_idx): |
790 | return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx) | 1044 | return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx) |