|
22 | 22 | import unittest.mock
|
23 | 23 |
|
24 | 24 | import qubes.ext.core_features
|
| 25 | +import qubes.ext.custom_persist |
25 | 26 | import qubes.ext.services
|
26 | 27 | import qubes.ext.windows
|
27 | 28 | import qubes.ext.supported_features
|
@@ -1045,3 +1046,218 @@ def test_022_supported_rpc_remove(self):
|
1045 | 1046 | "supported-rpc.test2": True,
|
1046 | 1047 | },
|
1047 | 1048 | )
|
| 1049 | + |
| 1050 | + |
| 1051 | +class TC_40_CustomPersist(qubes.tests.QubesTestCase): |
| 1052 | + def setUp(self): |
| 1053 | + super().setUp() |
| 1054 | + self.ext = qubes.ext.custom_persist.CustomPersist() |
| 1055 | + self.features = {} |
| 1056 | + specs = { |
| 1057 | + "features.get.side_effect": self.features.get, |
| 1058 | + "features.items.side_effect": self.features.items, |
| 1059 | + "features.__iter__.side_effect": self.features.__iter__, |
| 1060 | + "features.__contains__.side_effect": self.features.__contains__, |
| 1061 | + "features.__setitem__.side_effect": self.features.__setitem__, |
| 1062 | + "features.__delitem__.side_effect": self.features.__delitem__, |
| 1063 | + } |
| 1064 | + |
| 1065 | + vmspecs = { |
| 1066 | + **specs, |
| 1067 | + **{ |
| 1068 | + "template": None, |
| 1069 | + }, |
| 1070 | + } |
| 1071 | + self.vm = mock.MagicMock() |
| 1072 | + self.vm.configure_mock(**vmspecs) |
| 1073 | + |
| 1074 | + def test_000_write_to_qdb(self): |
| 1075 | + self.features["custom-persist.home"] = "/home" |
| 1076 | + self.features["custom-persist.usrlocal"] = "/usr/local" |
| 1077 | + self.features["custom-persist.var_test"] = "/var/test" |
| 1078 | + |
| 1079 | + self.ext.on_domain_qdb_create(self.vm, "domain-qdb-create") |
| 1080 | + self.assertEqual( |
| 1081 | + sorted(self.vm.untrusted_qdb.mock_calls), |
| 1082 | + [ |
| 1083 | + mock.call.write("/persist/home", "/home"), |
| 1084 | + mock.call.write("/persist/usrlocal", "/usr/local"), |
| 1085 | + mock.call.write("/persist/var_test", "/var/test"), |
| 1086 | + ], |
| 1087 | + ) |
| 1088 | + |
| 1089 | + def test_001_feature_set(self): |
| 1090 | + self.ext.on_domain_feature_set( |
| 1091 | + self.vm, |
| 1092 | + "feature-set:custom-persist.test_no_oldvalue", |
| 1093 | + "custom-persist.test_no_oldvalue", |
| 1094 | + "/test_no_oldvalue", |
| 1095 | + ) |
| 1096 | + self.ext.on_domain_feature_set( |
| 1097 | + self.vm, |
| 1098 | + "feature-set:custom-persist.test_oldvalue", |
| 1099 | + "custom-persist.test_oldvalue", |
| 1100 | + "/newvalue", |
| 1101 | + "", |
| 1102 | + ) |
| 1103 | + |
| 1104 | + self.assertEqual( |
| 1105 | + sorted(self.vm.untrusted_qdb.mock_calls), |
| 1106 | + [ |
| 1107 | + mock.call.write( |
| 1108 | + "/persist/test_no_oldvalue", "/test_no_oldvalue" |
| 1109 | + ), |
| 1110 | + mock.call.write("/persist/test_oldvalue", "/newvalue"), |
| 1111 | + ], |
| 1112 | + ) |
| 1113 | + |
| 1114 | + def test_002_feature_delete(self): |
| 1115 | + self.ext.on_domain_feature_delete( |
| 1116 | + self.vm, "feature-delete:custom-persist.test", "custom-persist.test" |
| 1117 | + ) |
| 1118 | + self.vm.untrusted_qdb.rm.assert_called_with("/persist/test") |
| 1119 | + |
| 1120 | + def test_003_empty_key(self): |
| 1121 | + with self.assertRaises(qubes.exc.QubesValueError) as e: |
| 1122 | + self.ext.on_domain_feature_set( |
| 1123 | + self.vm, |
| 1124 | + "feature-set:custom-persist.", |
| 1125 | + "custom-persist.", |
| 1126 | + "/test", |
| 1127 | + "", |
| 1128 | + ) |
| 1129 | + self.assertEqual(str(e.exception), "custom-persist key cannot be empty") |
| 1130 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1131 | + |
| 1132 | + def test_004_key_too_long(self): |
| 1133 | + with self.assertRaises(qubes.exc.QubesValueError) as e: |
| 1134 | + self.ext.on_domain_feature_set( |
| 1135 | + self.vm, |
| 1136 | + "feature-set:custom-persist." + "X" * 55, |
| 1137 | + "custom-persist." + "X" * 55, |
| 1138 | + "/test", |
| 1139 | + "", |
| 1140 | + ) |
| 1141 | + |
| 1142 | + self.assertEqual( |
| 1143 | + str(e.exception), |
| 1144 | + "custom-persist key is too long (max 54), ignoring: " + "X" * 55, |
| 1145 | + ) |
| 1146 | + self.vm.untrusted_qdb.assert_not_called() |
| 1147 | + |
| 1148 | + def test_005_other_feature_deletion(self): |
| 1149 | + self.ext.on_domain_feature_delete( |
| 1150 | + self.vm, "feature-delete:otherfeature.test", "otherfeature.test" |
| 1151 | + ) |
| 1152 | + self.vm.untrusted_qdb.assert_not_called() |
| 1153 | + |
| 1154 | + def test_006_feature_set_while_vm_is_not_running(self): |
| 1155 | + self.vm.is_running.return_value = False |
| 1156 | + self.ext.on_domain_feature_set( |
| 1157 | + self.vm, |
| 1158 | + "feature-set:custom-persist.test", |
| 1159 | + "custom-persist.test", |
| 1160 | + "/test", |
| 1161 | + ) |
| 1162 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1163 | + |
| 1164 | + def test_007_feature_set_value_with_option(self): |
| 1165 | + self.ext.on_domain_feature_set( |
| 1166 | + self.vm, |
| 1167 | + "feature-set:custom-persist.test", |
| 1168 | + "custom-persist.test", |
| 1169 | + "dir:root:root:0755:/var/test", |
| 1170 | + "", |
| 1171 | + ) |
| 1172 | + self.vm.untrusted_qdb.write.assert_called_with( |
| 1173 | + "/persist/test", "dir:root:root:0755:/var/test" |
| 1174 | + ) |
| 1175 | + |
| 1176 | + def test_008_feature_set_invalid_path(self): |
| 1177 | + with self.assertRaises(qubes.exc.QubesValueError): |
| 1178 | + self.ext.on_domain_feature_set( |
| 1179 | + self.vm, |
| 1180 | + "feature-set:custom-persist.test", |
| 1181 | + "custom-persist.test", |
| 1182 | + "test", |
| 1183 | + "", |
| 1184 | + ) |
| 1185 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1186 | + |
| 1187 | + def test_009_feature_set_invalid_option_type(self): |
| 1188 | + with self.assertRaises(qubes.exc.QubesValueError): |
| 1189 | + self.ext.on_domain_feature_set( |
| 1190 | + self.vm, |
| 1191 | + "feature-set:custom-persist.test", |
| 1192 | + "custom-persist.test", |
| 1193 | + "bad:root:root:0755:/var/test", |
| 1194 | + "", |
| 1195 | + ) |
| 1196 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1197 | + |
| 1198 | + def test_010_feature_set_invalid_option_mode_too_high(self): |
| 1199 | + with self.assertRaises(qubes.exc.QubesValueError): |
| 1200 | + self.ext.on_domain_feature_set( |
| 1201 | + self.vm, |
| 1202 | + "feature-set:custom-persist.test", |
| 1203 | + "custom-persist.test", |
| 1204 | + "file:root:root:9750:/var/test", |
| 1205 | + "", |
| 1206 | + ) |
| 1207 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1208 | + |
| 1209 | + def test_011_feature_set_invalid_option_mode_negative_high(self): |
| 1210 | + with self.assertRaises(qubes.exc.QubesValueError): |
| 1211 | + self.ext.on_domain_feature_set( |
| 1212 | + self.vm, |
| 1213 | + "feature-set:custom-persist.test", |
| 1214 | + "custom-persist.test", |
| 1215 | + "file:root:root:-755:/var/test", |
| 1216 | + "", |
| 1217 | + ) |
| 1218 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1219 | + |
| 1220 | + def test_012_feature_set_option_mode_without_leading_zero(self): |
| 1221 | + self.ext.on_domain_feature_set( |
| 1222 | + self.vm, |
| 1223 | + "feature-set:custom-persist.test", |
| 1224 | + "custom-persist.test", |
| 1225 | + "file:root:root:755:/var/test", |
| 1226 | + "", |
| 1227 | + ) |
| 1228 | + self.vm.untrusted_qdb.write.assert_called_with( |
| 1229 | + "/persist/test", "file:root:root:755:/var/test" |
| 1230 | + ) |
| 1231 | + |
| 1232 | + def test_013_feature_set_invalid_path_with_option(self): |
| 1233 | + with self.assertRaises(qubes.exc.QubesValueError): |
| 1234 | + self.ext.on_domain_feature_set( |
| 1235 | + self.vm, |
| 1236 | + "feature-set:custom-persist.test", |
| 1237 | + "custom-persist.test", |
| 1238 | + "dir:root:root:0755:var/test", |
| 1239 | + "", |
| 1240 | + ) |
| 1241 | + self.vm.untrusted_qdb.write.assert_not_called() |
| 1242 | + |
| 1243 | + def test_014_feature_set_path_with_colon_with_options(self): |
| 1244 | + self.ext.on_domain_feature_set( |
| 1245 | + self.vm, |
| 1246 | + "feature-set:custom-persist.test", |
| 1247 | + "custom-persist.test", |
| 1248 | + "file:root:root:755:/var/test:dir:with:colon", |
| 1249 | + "", |
| 1250 | + ) |
| 1251 | + self.vm.untrusted_qdb.write.assert_called() |
| 1252 | + |
| 1253 | + def test_015_feature_set_path_with_colon_without_options(self): |
| 1254 | + self.ext.on_domain_feature_set( |
| 1255 | + self.vm, |
| 1256 | + "feature-set:custom-persist.test", |
| 1257 | + "custom-persist.test", |
| 1258 | + "/var/test:dir:with:colon", |
| 1259 | + "", |
| 1260 | + ) |
| 1261 | + self.vm.untrusted_qdb.write.assert_called_with( |
| 1262 | + "/persist/test", "/var/test:dir:with:colon" |
| 1263 | + ) |
0 commit comments