add permissive cache
authorEmmanuel Garette <egarette@cadoles.com>
Thu, 13 Jul 2017 20:04:06 +0000 (22:04 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Thu, 13 Jul 2017 20:04:06 +0000 (22:04 +0200)
12 files changed:
test/test_cache.py
test/test_option_setting.py
test/test_state.py
tiramisu/config.py
tiramisu/setting.py
tiramisu/storage/__init__.py
tiramisu/storage/dictionary/__init__.py
tiramisu/storage/dictionary/setting.py
tiramisu/storage/sqlite3/__init__.py
tiramisu/storage/sqlite3/setting.py
tiramisu/storage/sqlite3/value.py
tiramisu/value.py

index e425832..493029d 100644 (file)
@@ -86,7 +86,7 @@ def test_cache_reset():
     assert 'u1' in values._p_.get_cached(c)
     assert 'u1' in settings._p_.get_cached(c)
     assert 'u2' not in values._p_.get_cached(c)
-    assert 'u2' not in settings._p_.get_cached(c)
+    assert 'u2' in settings._p_.get_cached(c)
     #when remove a value
     c.u1
     assert 'u1' in values._p_.get_cached(c)
@@ -95,7 +95,7 @@ def test_cache_reset():
     assert 'u1' in values._p_.get_cached(c)
     assert 'u1' in settings._p_.get_cached(c)
     assert 'u2' not in values._p_.get_cached(c)
-    assert 'u2' not in settings._p_.get_cached(c)
+    assert 'u2' in settings._p_.get_cached(c)
     #when add/del property
     c.u1
     assert 'u1' in values._p_.get_cached(c)
@@ -144,7 +144,7 @@ def test_cache_reset_multi():
     assert 'u1' in values._p_.get_cached(c)
     assert 'u1' in settings._p_.get_cached(c)
     assert 'u3' not in values._p_.get_cached(c)
-    assert 'u3' not in settings._p_.get_cached(c)
+    assert 'u3' in settings._p_.get_cached(c)
     #when append value
     c.u1
     c.u3
@@ -156,7 +156,7 @@ def test_cache_reset_multi():
     assert 'u1' in values._p_.get_cached(c)
     assert 'u1' in settings._p_.get_cached(c)
     assert 'u3' not in values._p_.get_cached(c)
-    assert 'u3' not in settings._p_.get_cached(c)
+    assert 'u3' in settings._p_.get_cached(c)
     #when pop value
     c.u1
     c.u3
@@ -168,7 +168,7 @@ def test_cache_reset_multi():
     assert 'u1' in values._p_.get_cached(c)
     assert 'u1' in settings._p_.get_cached(c)
     assert 'u3' not in values._p_.get_cached(c)
-    assert 'u3' not in settings._p_.get_cached(c)
+    assert 'u3' in settings._p_.get_cached(c)
     #when remove a value
     c.u1
     assert 'u1' in values._p_.get_cached(c)
@@ -177,7 +177,7 @@ def test_cache_reset_multi():
     assert 'u1' in values._p_.get_cached(c)
     assert 'u1' in settings._p_.get_cached(c)
     assert 'u3' not in values._p_.get_cached(c)
-    assert 'u3' not in settings._p_.get_cached(c)
+    assert 'u3' in settings._p_.get_cached(c)
 
 
 def test_reset_cache():
@@ -313,7 +313,8 @@ def test_force_cache():
                                                         'u2': {None: (None, None)},
                                                         'u3': {None: ([], None)},
                                                         'u4': {None: (None, None)}}
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'u1': {None: (set(['empty']), None)},
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'validator', 'warnings']), None)},
+                                                          'u1': {None: (set(['empty']), None)},
                                                           'u2': {None: (set([]), None)},
                                                           'u3': {None: (set(['empty']), None)},
                                                           'u4': {None: (set(['disabled']), None)}}
@@ -323,7 +324,8 @@ def test_force_cache():
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {'u1': {None: ([], None)},
                                                         'u2': {None: (None, None)},
                                                         'u3': {None: ([], None)}}
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'u1': {None: (set(['empty']), None)},
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'empty', 'everything_frozen', 'frozen', 'mandatory', 'validator', 'warnings']), None)},
+                                                          'u1': {None: (set(['empty']), None)},
                                                           'u2': {None: (set([]), None)},
                                                           'u3': {None: (set(['empty']), None)},
                                                           'u4': {None: (set(['disabled']), None)}}
@@ -354,7 +356,7 @@ def test_cache_master_slave():
     assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None]
     assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
     cache = cfg.cfgimpl_get_settings()._p_.get_cached(cfg)
-    assert set(cache.keys()) == set(['ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
+    assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
     assert set(cache['ip_admin_eth0'].keys()) == set([None])
     assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
     assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0])
@@ -371,7 +373,7 @@ def test_cache_master_slave():
     assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
     assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None
     cache = cfg.cfgimpl_get_settings()._p_.get_cached(cfg)
-    assert set(cache.keys()) == set(['ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
+    assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
     assert set(cache['ip_admin_eth0'].keys()) == set([None])
     assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
     assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1])
@@ -393,7 +395,8 @@ def test_cache_callback():
     cfg.cfgimpl_get_settings().remove('expire')
     cfg.read_write()
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
                                                               'val4': {None: (set([]), None)},
@@ -404,12 +407,15 @@ def test_cache_callback():
                                                             'val4': {None: ('val', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.val1 = 'new'
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val3': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
+                                                              'val3': {None: (set([]), None)},
                                                               'val5': {None: (set(['empty']), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val3': {None: ('yes', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
                                                               'val4': {None: (set([]), None)},
@@ -420,8 +426,10 @@ def test_cache_callback():
                                                             'val4': {None: ('new', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.val3 = 'new2'
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
+                                                              'val3': {None: (set([]), None)},
                                                               'val4': {None: (set([]), None)},
                                                               'val5': {None: (set(['empty']), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
@@ -429,7 +437,8 @@ def test_cache_callback():
                                                             'val4': {None: ('new', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
                                                               'val4': {None: (set([]), None)},
@@ -440,16 +449,19 @@ def test_cache_callback():
                                                             'val4': {None: ('new', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.val4 = 'new3'
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
+                                                              'val4': {None: (set([]), None)},
                                                               'val5': {None: (set(['empty']), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
                                                             'val2': {None: ('new', None)},
                                                             'val3': {None: ('new2', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
                                                               'val4': {None: (set([]), None)},
@@ -460,16 +472,19 @@ def test_cache_callback():
                                                             'val4': {None: ('new3', None)},
                                                             'val5': {None: (['yes'], None)}}
     cfg.val5.append('new4')
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
-                                                              'val4': {None: (set([]), None)}}
+                                                              'val4': {None: (set([]), None)},
+                                                              'val5': {None: (set(['empty']), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
                                                             'val2': {None: ('new', None)},
                                                             'val3': {None: ('new2', None)},
                                                             'val4': {None: ('new3', None)}}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val2': {None: (set(['mandatory']), None)},
                                                               'val3': {None: (set([]), None)},
                                                               'val4': {None: (set([]), None)},
@@ -491,15 +506,19 @@ def test_cache_master_and_slaves_master():
     cfg.cfgimpl_get_settings().remove('expire')
     cfg.read_write()
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val1.val1': {None: (set(['empty']), None)},
                                                               'val1.val2': {None: (set([]), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([], None)}, 'val1.val2': {None: ([], None)}}
     cfg.val1.val1.append()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)}}
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
+                                                              'val1.val1': {None: (set(['empty']), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val1.val1': {None: (set(['empty']), None)},
                                                               'val1.val2': {None: (set([]), None), 0: (set([]), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None], None)},
@@ -507,11 +526,14 @@ def test_cache_master_and_slaves_master():
     cfg.val1.val1.append()
     cfg.cfgimpl_get_values().force_cache()
     cfg.val1.val2[1] = 'oui'
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
-                                                              'val1.val1': {None: (set(['empty']), None)}}
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
+                                                              'val1.val1': {None: (set(['empty']), None)},
+                                                              'val1.val2': {None: (set([]), None), 0: (set([]), None), 1: (set([]), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None, None], None)}}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val1.val1': {None: (set(['empty']), None)},
                                                               'val1.val2': {None: (set([]), None), 0: (set([]), None), 1: (set([]), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None, None], None)},
@@ -528,15 +550,19 @@ def test_cache_master_callback():
     cfg.cfgimpl_get_settings().remove('expire')
     cfg.read_write()
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val1.val1': {None: (set(['empty']), None)},
                                                               'val1.val2': {None: (set([]), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([], None)}, 'val1.val2': {None: ([], None)}}
     cfg.val1.val1.append()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)}}
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
+                                                              'val1.val1': {None: (set(['empty']), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {}
     cfg.cfgimpl_get_values().force_cache()
-    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
+    assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                              'val1': {None: (set([]), None)},
                                                               'val1.val1': {None: (set(['empty']), None)},
                                                               'val1.val2': {None: (set([]), None), 0: (set([]), None)}}
     assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None], None)},
@@ -554,32 +580,67 @@ def test_cache_requires():
     assert c.cfgimpl_get_settings()._p_.get_cached(c) == {}
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {}
     assert c.ip_address_service == None
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
                                                           'ip_address_service': {None: (set([]), None)}}
 
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: (None, None)}}
     c.cfgimpl_get_values().force_cache()
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
                                                           'ip_address_service': {None: (set([]), None)}}
 
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: (None, None)},
                                                         'activate_service': {None: (True, None)}}
     c.ip_address_service = '1.1.1.1'
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)}}
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
+                                                          'ip_address_service': {None: (set([]), None)}}
 
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {'activate_service': {None: (True, None)}}
     c.cfgimpl_get_values().force_cache()
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
                                                           'ip_address_service': {None: (set([]), None)}}
 
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: ('1.1.1.1', None)},
                                                         'activate_service': {None: (True, None)}}
     c.activate_service = False
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {}
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)}}
 
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {}
     c.cfgimpl_get_values().force_cache()
-    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
                                                           'ip_address_service': {None: (set(['disabled']), None)}}
 
     assert c.cfgimpl_get_values()._p_.get_cached(c) == {'activate_service': {None: (False, None)}}
+
+
+def test_cache_global_properties():
+    a = BoolOption('activate_service', '', True)
+    b = IPOption('ip_address_service', '',
+                 requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
+    od = OptionDescription('service', '', [a, b])
+    c = Config(od)
+    c.cfgimpl_get_settings().remove('expire')
+    c.read_write()
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {}
+    assert c.cfgimpl_get_values()._p_.get_cached(c) == {}
+    assert c.ip_address_service == None
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
+                                                          'ip_address_service': {None: (set([]), None)}}
+
+    assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: (None, None)}}
+    c.cfgimpl_get_settings().remove('disabled')
+    assert c.ip_address_service == None
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings']), None)},
+                                                          'activate_service': {None: (set([]), None)},
+                                                          'ip_address_service': {None: (set([]), None)}}
+    c.cfgimpl_get_settings().append('test')
+    assert c.ip_address_service == None
+    assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test']), None)},
+                                                          'activate_service': {None: (set([]), None)},
+                                                          'ip_address_service': {None: (set([]), None)}}
index 4e67308..55a6dbd 100644 (file)
@@ -536,6 +536,18 @@ def test_reset_properties_force_store_value():
     raises(ValueError, 'setting.reset(all_properties=True, opt=option)')
 
 
+def test_set_modified_value():
+    gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('force_store_value',))
+    gcgroup = OptionDescription('gc', '', [gcdummy])
+    descr = OptionDescription('tiramisu', '', [gcgroup])
+    cfg = Config(descr)
+    setting = cfg.cfgimpl_get_settings()
+    option = cfg.cfgimpl_get_description().gc.dummy
+    assert setting._p_.get_modified_properties() == {}
+    setting._p_.set_modified_properties({None: set(('frozen', 'expire', 'cache', 'validator', 'warnings'))})
+    assert setting._p_.get_modified_properties() == {None: set(('frozen', 'expire', 'cache', 'validator', 'warnings'))}
+
+
 def test_pprint():
     msg_error = _("cannot access to {0} \"{1}\" because has {2} {3}")
     msg_is = _('the value of "{0}" is "{1}"')
index cc22408..fbf0280 100644 (file)
@@ -536,47 +536,47 @@ def test_state_groupconfig():
         pass
 
 
-def test_state_unkown_setting_owner():
-    """load an unknow _owner, should create it"""
-    assert not 'supernewuser' in owners.__dict__
-    val = """ccopy_reg
-_reconstructor
-p0
-(ctiramisu.setting
-Settings
-p1
-c__builtin__
-object
-p2
-Ntp3
-Rp4
-(dp5
-S'_owner'
-p6
-S'supernewuser'
-p7
-sS'_p_'
-p8
-g0
-(ctiramisu.storage.dictionary.setting
-Settings
-p9
-g2
-Ntp10
-Rp11
-(dp12
-S'_cache'
-p13
-(dp14
-sS'_permissives'
-p15
-(dp16
-sS'_properties'
-p17
-(dp18
-sbsb.
-."""
-    if sys.version_info[0] >= 3:  # pragma: optional cover
-        val = bytes(val, "UTF-8")
-    loads(val)
-    assert 'supernewuser' in owners.__dict__
+#def test_state_unkown_setting_owner():
+#    """load an unknow _owner, should create it"""
+#    assert not 'supernewuser' in owners.__dict__
+#    val = """ccopy_reg
+#_reconstructor
+#p0
+#(ctiramisu.setting
+#Settings
+#p1
+#c__builtin__
+#object
+#p2
+#Ntp3
+#Rp4
+#(dp5
+#S'_owner'
+#p6
+#S'supernewuser'
+#p7
+#sS'_p_'
+#p8
+#g0
+#(ctiramisu.storage.dictionary.setting
+#Properties
+#p9
+#g2
+#Ntp10
+#Rp11
+#(dp12
+#S'_cache'
+#p13
+#(dp14
+#sS'_permissives'
+#p15
+#(dp16
+#sS'_properties'
+#p17
+#(dp18
+#sbsb.
+#."""
+#    if sys.version_info[0] >= 3:  # pragma: optional cover
+#        val = bytes(val, "UTF-8")
+#    loads(val)
+#    assert 'supernewuser' in owners.__dict__
index ce96f39..46310b4 100644 (file)
@@ -73,7 +73,7 @@ class SubConfig(object):
 
     def cfgimpl_reset_cache(self,
                             only_expired=False,
-                            only=('values', 'settings'),
+                            only=('values', 'properties', 'permissives', 'settings'),
                             opt=None,
                             path=None):
         """reset all settings in cache
@@ -84,13 +84,15 @@ class SubConfig(object):
         context = self._cfgimpl_get_context()
         if 'values' in only:
             values = context.cfgimpl_get_values()
-        if 'settings' in only:
+        if 'settings' in only or 'properties' in only or 'permissives' in only:
             settings = context.cfgimpl_get_settings()
         if only_expired:
             if 'values' in only:
                 values._p_.reset_expired_cache(int(time()))
-            if 'settings' in only:
+            if 'settings' in only or 'properties' in only:
                 settings._p_.reset_expired_cache(int(time()))
+            if 'settings' in only or 'permissives' in only:
+                settings._pp_.reset_expired_cache(int(time()))
         elif not None in (opt, path):
             if opt.__class__.__name__ == 'DynOptionDescription':
                 descr = context.cfgimpl_get_description()
@@ -102,8 +104,10 @@ class SubConfig(object):
                     path = subpath + '.' + spath[-1] + suffix
                     if 'values' in only:
                         values._p_.delcache(path)
-                    if 'settings' in only:
+                    if 'settings' in only or 'properties' in only:
                         settings._p_.delcache(path)
+                    if 'settings' in only or 'permissives' in only:
+                        settings._pp_.delcache(path)
             elif not isinstance(opt, DynSymLinkOption) and opt._is_subdyn():
                 descr = context.cfgimpl_get_description()
                 spath = path.split('.')
@@ -126,23 +130,33 @@ class SubConfig(object):
                         path += '.' + spath3 + suffix
                     if 'values' in only:
                         values._p_.delcache(path)
-                    if 'settings' in only:
+                    if 'settings' in only or 'properties' in only:
                         settings._p_.delcache(path)
+                    if 'settings' in only or 'permissives' in only:
+                        settings._pp_.delcache(path)
             else:
                 if 'values' in only:
                     values._p_.delcache(path)
-                if 'settings' in only:
+                if 'settings' in only or 'permissives' in only:
                     settings._p_.delcache(path)
+                if 'settings' in only or 'permissives' in only:
+                    settings._pp_.delcache(path)
             for option in getattr(opt, '_dependencies', []):
                 if 'values' in only:
                     option.reset_cache(opt, values, 'values')
                 if 'settings' in only:
                     option.reset_cache(opt, settings, 'settings')
+                else:
+                    if 'properties' in only:
+                        option.reset_cache(opt, settings, 'properties')
+                    if 'permissives' in only:
+                        option.reset_cache(opt, settings, 'permissives')
         else:
             if 'values' in only:
                 values._p_.reset_all_cache()
             if 'settings' in only:
                 settings._p_.reset_all_cache()
+                settings._pp_.reset_all_cache()
 
     def cfgimpl_get_home_by_path(self, path, force_permissive=False,
                                  returns_raise=False, _setting_properties=undefined):
@@ -752,8 +766,8 @@ class _CommonConfig(SubConfig):
             session))
         config.cfgimpl_get_settings()._p_.set_modified_properties(self.cfgimpl_get_settings(
             )._p_.get_modified_properties())
-        config.cfgimpl_get_settings()._p_.set_modified_permissives(self.cfgimpl_get_settings(
-            )._p_.get_modified_permissives())
+        config.cfgimpl_get_settings()._pp_.set_modified_permissives(self.cfgimpl_get_settings(
+            )._pp_.get_modified_permissives())
         return config
 
 
@@ -781,7 +795,7 @@ class Config(_CommonConfig):
             self._impl_settings = force_settings
             self._impl_values = Values(self, force_values)
         else:
-            settings, values = get_storages(self, session_id, persistent)
+            properties, permissives, values = get_storages(self, session_id, persistent)
             if name is undefined:
                 name = 'config'
                 if session_id is not None:
@@ -790,7 +804,7 @@ class Config(_CommonConfig):
                 raise ValueError(_("name is mandatory for the config").format(name))
             if name is not None and not valid_name(name):  # pragma: optional cover
                 raise ValueError(_("invalid name: {0} for config").format(name))
-            self._impl_settings = Settings(self, settings)
+            self._impl_settings = Settings(self, properties, permissives)
             self._impl_values = Values(self, values)
         super(Config, self).__init__(descr, weakref.ref(self))
         self._impl_meta = None
@@ -829,8 +843,8 @@ class GroupConfig(_CommonConfig):
                     raise ConflictError(_('config name must be uniq in '
                                           'groupconfig for {0}').format(name))
         self._impl_children = children
-        settings, values = get_storages(self, session_id, persistent)
-        self._impl_settings = Settings(self, settings)
+        properties, permissives, values = get_storages(self, session_id, persistent)
+        self._impl_settings = Settings(self, properties, permissives)
         self._impl_values = Values(self, values)
         super(GroupConfig, self).__init__(_descr, weakref.ref(self))
         self._impl_meta = None
index 7a1cc90..81bc02f 100644 (file)
@@ -310,9 +310,9 @@ class Property(object):
 #____________________________________________________________
 class Settings(object):
     "``config.Config()``'s configuration options settings"
-    __slots__ = ('context', '_owner', '_p_', '__weakref__')
+    __slots__ = ('context', '_owner', '_p_', '_pp_', '__weakref__')
 
-    def __init__(self, context, storage):
+    def __init__(self, context, properties, permissives):
         """
         initializer
 
@@ -325,7 +325,8 @@ class Settings(object):
         # generic owner
         self._owner = owners.user
         self.context = weakref.ref(context)
-        self._p_ = storage
+        self._p_ = properties
+        self._pp_ = permissives
 
     def _getcontext(self):
         """context could be None, we need to test it
@@ -370,7 +371,7 @@ class Settings(object):
             if opt is not None and _path is None:
                 _path = opt.impl_getpath(self._getcontext())
             self._p_.delproperties(_path)
-        self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path)
+        self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path, only=('settings',))
 
     def _getproperties(self, opt=None, path=None,
                        setting_properties=undefined, read_write=True,
@@ -378,14 +379,27 @@ class Settings(object):
         """
         """
         if opt is None:
-            props = self._p_.getproperties(path, default_properties)
+            ntime = int(time())
+            if self._p_.hascache(path, index):
+                is_cached, props = self._p_.getcache(path, ntime, index)
+            else:
+                is_cached = False
+            if not is_cached or 'cache' not in props:
+                props = self._p_.getproperties(path, default_properties)
+            if 'cache' in props:
+                if 'expire' in props:
+                    ntime = ntime + expires_time
+                else:
+                    ntime = None
+                self._p_.setcache(path, props, ntime, index)
         else:
-            if setting_properties is undefined:
-                setting_properties = self._getproperties(read_write=False)
             if path is None:  # pragma: optional cover
                 raise ValueError(_('if opt is not None, path should not be'
                                    ' None in _getproperties'))
+            if setting_properties is undefined:
+                setting_properties = self._getproperties(read_write=False)
             is_cached = False
+
             if apply_requires:
                 if 'cache' in setting_properties and 'expire' in setting_properties:
                     ntime = int(time())
@@ -440,6 +454,26 @@ class Settings(object):
         self._p_.setproperties(path, properties)
         self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
 
+    def getpermissive(self, setting_properties, path=None):
+        if 'cache' in setting_properties and 'expire' in setting_properties:
+            ntime = int(time())
+        else:
+            ntime = None
+        if 'cache' in setting_properties and self._pp_.hascache(path, None):
+            is_cached, perm = self._pp_.getcache(path, ntime, None)
+        else:
+            is_cached = False
+        if not is_cached:
+            if path is not None:
+                perm = self._pp_.getpermissive(path)
+            else:
+                perm = self._pp_.getpermissive()
+            if 'cache' in setting_properties:
+                if 'expire' in setting_properties:
+                    ntime = ntime + expires_time
+                self._pp_.setcache(path, perm, ntime, None)
+        return perm
+
     #____________________________________________________________
     def validate_properties(self, opt_or_descr, is_descr, check_frozen, path,
                             value=None, force_permissive=False,
@@ -472,10 +506,10 @@ class Settings(object):
         # remove opt permissive
         # permissive affect option's permission with or without permissive
         # global property
-        properties -= self._p_.getpermissive(path)
+        properties -= self.getpermissive(setting_properties, path)
         # remove global permissive if need
         if force_permissive is True or 'permissive' in setting_properties:
-            properties -= self._p_.getpermissive()
+            properties -= self.getpermissive(setting_properties)
 
         # calc properties
         properties &= setting_properties
@@ -540,8 +574,15 @@ class Settings(object):
             path = opt.impl_getpath(self._getcontext())
         if not isinstance(permissive, tuple):  # pragma: optional cover
             raise TypeError(_('permissive must be a tuple'))
-        self._p_.setpermissive(path, permissive)
-        self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
+        self._pp_.setpermissive(path, permissive)
+        setting_properties = self._getproperties(read_write=False)
+        self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('values',))
+        if 'cache' in setting_properties:
+            if 'expire' in setting_properties:
+                ntime = int(time()) + expires_time
+            else:
+                ntime = None
+            self._pp_.setcache(path, set(permissive), ntime, None)
 
     #____________________________________________________________
     def setowner(self, owner):
@@ -549,6 +590,7 @@ class Settings(object):
         if not isinstance(owner, owners.Owner):  # pragma: optional cover
             raise TypeError(_("invalid generic owner {0}").format(str(owner)))
         self._owner = owner
+        #FIXME qu'est ce qui se passe si pas de owner ??
 
     def getowner(self):
         return self._owner
@@ -718,16 +760,17 @@ class Settings(object):
         return self._p_.get_modified_properties()
 
     def get_modified_permissives(self):
-        return self._p_.get_modified_permissives()
+        return self._pp_.get_modified_permissives()
 
     def __getstate__(self):
-        return {'_p_': self._p_, '_owner': str(self._owner)}
+        return {'_p_': self._p_, '_pp_': self._pp_, '_owner': str(self._owner)}
 
     def _impl_setstate(self, storage):
         self._p_._storage = storage
 
     def __setstate__(self, states):
         self._p_ = states['_p_']
+        self._pp_ = states['_pp_']
         try:
             self._owner = getattr(owners, states['_owner'])
         except AttributeError:
index ff74d79..58c68ab 100644 (file)
@@ -133,9 +133,10 @@ def get_storages(context, session_id, persistent):
         session_id = gen_id(context)
     imp = storage_type.get()
     storage = imp.Storage(session_id, persistent)
-    settings = imp.Settings(storage)
+    properties = imp.Properties(storage)
+    permissives = imp.Permissives(storage)
     values = imp.Values(storage)
-    return settings, values
+    return properties, permissives, values
 
 
 def get_storages_option(type_):
index 9ff39ef..312f8ef 100644 (file)
@@ -23,9 +23,9 @@ The advantage of this solution is that you can easily create a Config and
 use it. But if something goes wrong, you will lost your modifications.
 """
 from .value import Values
-from .setting import Settings
+from .setting import Properties, Permissives
 from .storage import setting, Storage, list_sessions, delete_session
 from .option import StorageBase, StorageOptionDescription, StorageMasterSlaves
 
-__all__ = (setting, Values, Settings, Storage, list_sessions, delete_session,
-           StorageBase, StorageOptionDescription, StorageMasterSlaves)
+__all__ = ('setting', 'Values', 'Properties', 'Permissives', 'Storage', 'list_sessions',
+           'delete_session', 'StorageBase', 'StorageOptionDescription', 'StorageMasterSlaves')
index 9022bc1..07f6787 100644 (file)
@@ -19,16 +19,15 @@ from copy import copy
 from ..util import Cache
 
 
-class Settings(Cache):
-    __slots__ = ('_properties', '_permissives')
+class Properties(Cache):
+    __slots__ = ('_properties',)
 
     def __init__(self, storage):
         # properties attribute: the name of a property enables this property
         # key is None for global properties
         self._properties = {}
         # permissive properties
-        self._permissives = {}
-        super(Settings, self).__init__(storage)
+        super(Properties, self).__init__(storage)
 
     # properties
     def setproperties(self, path, properties):
@@ -47,12 +46,6 @@ class Settings(Cache):
         if path in self._properties:
             del(self._properties[path])
 
-    def setpermissive(self, path, permissive):
-        self._permissives[path] = frozenset(permissive)
-
-    def getpermissive(self, path=None):
-        return self._permissives.get(path, frozenset())
-
     def get_modified_properties(self):
         """return all modified settings in a dictionary
         example: {'path1': set(['prop1', 'prop2'])}
@@ -62,6 +55,21 @@ class Settings(Cache):
     def set_modified_properties(self, properties):
         self._properties = properties
 
+
+class Permissives(Cache):
+    __slots__ = ('_permissives',)
+
+    def __init__(self, storage):
+        # permissive properties
+        self._permissives = {}
+        super(Permissives, self).__init__(storage)
+
+    def setpermissive(self, path, permissive):
+        self._permissives[path] = frozenset(permissive)
+
+    def getpermissive(self, path=None):
+        return self._permissives.get(path, frozenset())
+
     def get_modified_permissives(self):
         """return all modified permissives in a dictionary
         example: {'path1': set(['perm1', 'perm2'])}
@@ -70,3 +78,4 @@ class Settings(Cache):
 
     def set_modified_permissives(self, permissives):
         self._permissives = permissives
+
index 3bd8e0c..b377610 100644 (file)
@@ -21,7 +21,7 @@ You should not configure differents Configs with same session_id.
 
 """
 from .value import Values
-from .setting import Settings
+from .setting import Properties, Permissives
 from .storage import Storage, list_sessions, delete_session
 
-__all__ = ('Values', 'Settings', 'Storage', 'list_sessions', 'delete_session')
+__all__ = ('Values', 'Properties', 'Permissives', 'Storage', 'list_sessions', 'delete_session')
index 6aab6dc..2923538 100644 (file)
 from .sqlite3db import Sqlite3DB
 
 
-class Settings(Sqlite3DB):
+class Properties(Sqlite3DB):
     __slots__ = tuple()
 
     def __init__(self, storage):
-        super(Settings, self).__init__(storage)
+        super(Properties, self).__init__(storage)
 
     # properties
     def setproperties(self, path, properties):
@@ -63,26 +63,6 @@ class Settings(Sqlite3DB):
         self._storage.execute("DELETE FROM property WHERE path = ? AND session_id = ?",
                               (path, self._session_id))
 
-    # permissive
-    def setpermissive(self, path, permissive):
-        path = self._sqlite_encode_path(path)
-        self._storage.execute("DELETE FROM permissive WHERE path = ? AND session_id = ?",
-                              (path, self._session_id),
-                              False)
-        self._storage.execute("INSERT INTO permissive(path, permissives, session_id) "
-                              "VALUES (?, ?, ?)", (path,
-                                                   self._sqlite_encode(permissive),
-                                                   self._session_id))
-
-    def getpermissive(self, path='_none'):
-        permissives = self._storage.select("SELECT permissives FROM "
-                                           "permissive WHERE path = ? AND session_id = ? LIMIT 1",
-                                           (path, self._session_id))
-        if permissives is None:
-            return frozenset()
-        else:
-            return frozenset(self._sqlite_decode(permissives[0]))
-
     def get_modified_properties(self):
         """return all modified settings in a dictionary
         example: {'path1': set(['prop1', 'prop2'])}
@@ -99,19 +79,43 @@ class Settings(Sqlite3DB):
     def set_modified_properties(self, properties):
         self._storage.execute("DELETE FROM property", commit=False)
         for path, property_ in properties.items():
-            self._storage.execute("INSERT INTO property(path, property, session_id) "
+            self._storage.execute("INSERT INTO property(path, properties, session_id) "
                                   "VALUES (?, ?, ?)", (path,
                                                        self._sqlite_encode(property_),
                                                        self._session_id,
                                                       ), False)
         self._storage._conn.commit()
 
+
+class Permissives(Sqlite3DB):
+    __slots__ = tuple()
+
+    # permissive
+    def setpermissive(self, path, permissive):
+        path = self._sqlite_encode_path(path)
+        self._storage.execute("DELETE FROM permissive WHERE path = ? AND session_id = ?",
+                              (path, self._session_id),
+                              False)
+        self._storage.execute("INSERT INTO permissive(path, permissives, session_id) "
+                              "VALUES (?, ?, ?)", (path,
+                                                   self._sqlite_encode(permissive),
+                                                   self._session_id))
+
+    def getpermissive(self, path='_none'):
+        permissives = self._storage.select("SELECT permissives FROM "
+                                           "permissive WHERE path = ? AND session_id = ? LIMIT 1",
+                                           (path, self._session_id))
+        if permissives is None:
+            return frozenset()
+        else:
+            return frozenset(self._sqlite_decode(permissives[0]))
+
     def get_modified_permissives(self):
         """return all modified permissives in a dictionary
         example: {'path1': set(['perm1', 'perm2'])}
         """
         ret = {}
-        for path, permissives in self._storage.select("SELECT * FROM permissive "
+        for path, permissives in self._storage.select("SELECT path, permissives FROM permissive "
                                                       "WHERE session_id = ?",
                                                       (self._session_id,),
                                                       only_one=False):
@@ -122,7 +126,7 @@ class Settings(Sqlite3DB):
     def set_modified_permissives(self, permissives):
         self._storage.execute("DELETE FROM permissive", commit=False)
         for path, permissive in permissives.items():
-            self._storage.execute("INSERT INTO permissive(path, permissive, session_id) "
+            self._storage.execute("INSERT INTO permissive(path, permissives, session_id) "
                                   "VALUES (?, ?, ?)", (path,
                                                        self._sqlite_encode(permissive),
                                                        self._session_id,
index eb1b8b4..034293d 100644 (file)
@@ -231,10 +231,19 @@ class Values(Sqlite3DB):
             index = export[1][idx]
             value = export[2][idx]
             owner = export[3][idx]
-            self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
-                                  "(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value),
-                                                      str(owner), index,
-                                                      self._session_id))
+            if index is None:
+                self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
+                                      "(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value),
+                                                          str(owner), index,
+                                                          self._session_id), commit=False)
+            else:
+                for val in zip(index, value, owner):
+                    self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id)"
+                                          "VALUES (?, ?, ?, ?, ?)", (path,
+                                                                     self._sqlite_encode(val[1]),
+                                                                     str(val[2]), val[0],
+                                                                     self._session_id),
+                                          commit=False)
         self._storage._conn.commit()
 
     def get_max_length(self, path, session):
index fa28747..fe6e267 100644 (file)
@@ -199,7 +199,7 @@ class Values(object):
                 self._setvalue(opt, path, value, force_owner=owners.forced)
             else:
                 self._p_.resetvalue(path, session)
-            context.cfgimpl_reset_cache(opt=opt, path=path)
+            context.cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties'))
 
     def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
         "convenience method to know if an option is empty"
@@ -430,7 +430,7 @@ class Values(object):
 
     def _setvalue(self, opt, path, value, force_owner=undefined, index=None):
         context = self._getcontext()
-        context.cfgimpl_reset_cache(opt=opt, path=path)
+        context.cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties'))
         if force_owner is undefined:
             owner = context.cfgimpl_get_settings().getowner()
         else: