172 |
172 |
|
173 |
173 |
|
174 |
174 |
class TenantContentTypeTest(TenantTransactionTestCase):
|
|
175 |
@classmethod
|
|
176 |
def setUpClass(cls):
|
|
177 |
super(TenantContentTypeTest, cls).setUpClass()
|
|
178 |
settings.SHARED_APPS = ('tenant_schemas', )
|
|
179 |
settings.TENANT_APPS = ('dts_test_app',
|
|
180 |
'django.contrib.contenttypes',
|
|
181 |
'django.contrib.auth', )
|
|
182 |
settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
|
|
183 |
cls.sync_shared()
|
|
184 |
|
175 |
185 |
def test_content_type_cache(self):
|
176 |
186 |
import threading
|
177 |
187 |
from django.apps import apps
|
178 |
188 |
from django.contrib.contenttypes.models import ContentType
|
|
189 |
try:
|
|
190 |
from django.contrib.contenttypes.management import create_contenttypes
|
|
191 |
except ImportError:
|
|
192 |
from django.contrib.contenttypes.management import update_contenttypes as create_contenttypes
|
179 |
193 |
|
180 |
194 |
connection.set_schema_to_public()
|
181 |
195 |
tenant1 = Tenant(domain_url='something.test.com',
|
... | ... | |
186 |
200 |
tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
|
187 |
201 |
tenant2.save(verbosity=BaseTestCase.get_verbosity())
|
188 |
202 |
|
189 |
|
# go to tenant1's path
|
190 |
|
connection.set_tenant(tenant1)
|
|
203 |
with tenant_context(tenant2):
|
|
204 |
# recreate contenttypes to change primary key
|
|
205 |
ContentType.objects.all().delete()
|
|
206 |
assert ContentType.objects.count() == 0
|
|
207 |
for app_config in apps.get_app_configs():
|
|
208 |
create_contenttypes(app_config)
|
|
209 |
assert ContentType.objects.count() != 0
|
191 |
210 |
|
|
211 |
# go to tenant1's path
|
192 |
212 |
def collects_cts(d):
|
193 |
213 |
for app in apps.get_app_configs():
|
194 |
214 |
for model in app.get_models():
|
... | ... | |
196 |
216 |
|
197 |
217 |
# check cache is thread and tenant local
|
198 |
218 |
tenant1_cts = {}
|
199 |
|
collects_cts(tenant1_cts)
|
|
219 |
with tenant_context(tenant1):
|
|
220 |
collects_cts(tenant1_cts)
|
200 |
221 |
|
201 |
222 |
# switch temporarily to tenant2's path
|
202 |
223 |
tenant2_cts = {}
|
203 |
224 |
with tenant_context(tenant2):
|
204 |
225 |
collects_cts(tenant2_cts)
|
205 |
|
tenant1_thread_cts = {}
|
206 |
226 |
|
207 |
227 |
class T(threading.Thread):
|
208 |
228 |
def run(self):
|
... | ... | |
210 |
230 |
from django.db import connection
|
211 |
231 |
collects_cts(tenant1_thread_cts)
|
212 |
232 |
connection.close()
|
|
233 |
tenant1_thread_cts = {}
|
213 |
234 |
|
214 |
235 |
t = T()
|
215 |
236 |
t.start()
|
... | ... | |
220 |
241 |
assert tenant1_cts[model] is not tenant2_cts[model]
|
221 |
242 |
assert tenant2_cts[model] is not tenant1_thread_cts[model]
|
222 |
243 |
assert tenant1_cts[model] is not tenant1_thread_cts[model]
|
|
244 |
# check pk differs between tenants, as we recreated them
|
|
245 |
assert tenant1_cts[model].pk is not tenant2_cts[model].pk
|
|
246 |
assert tenant2_cts[model].pk is not tenant1_thread_cts[model].pk
|
223 |
247 |
|
224 |
248 |
# check cache is effective
|
225 |
249 |
tenant12_cts = {}
|
226 |
250 |
with tenant_context(tenant1):
|
|
251 |
for key in tenant1_cts:
|
|
252 |
assert ContentType.objects.get(pk=tenant1_cts[key].pk).model == tenant1_cts[key].model
|
227 |
253 |
collects_cts(tenant12_cts)
|
228 |
254 |
|
229 |
255 |
tenant22_cts = {}
|
230 |
256 |
with tenant_context(tenant2):
|
|
257 |
for key in tenant2_cts:
|
|
258 |
assert ContentType.objects.get(pk=tenant2_cts[key].pk).model == tenant2_cts[key].model
|
231 |
259 |
collects_cts(tenant22_cts)
|
232 |
260 |
|
233 |
261 |
for app in apps.get_app_configs():
|
234 |
262 |
for model in app.get_models():
|
|
263 |
assert tenant22_cts[model].pk is tenant2_cts[model].pk
|
|
264 |
assert tenant12_cts[model].pk is tenant1_cts[model].pk
|
235 |
265 |
assert tenant12_cts[model] is tenant1_cts[model]
|
236 |
266 |
assert tenant22_cts[model] is tenant2_cts[model]
|
237 |
267 |
|
238 |
|
-
|