[commit] r2002 - in trunk: GME/Mga Tests/GPyUnit
GMESRC Repository Notifications
gme-commit at list.isis.vanderbilt.edu
Tue Aug 14 09:31:32 CDT 2012
Author: ksmyth
Date: Tue Aug 14 09:31:31 2012
New Revision: 2002
Log:
Fix bug where a derived reference with CompareToBase()==true (i.e. desynched) could become an invalid ref when setting the basetype reference. This operation now throws.
Modified:
trunk/GME/Mga/MgaCheck.cpp
trunk/GME/Mga/MgaReference.cpp
trunk/Tests/GPyUnit/test_instances.py
Modified: trunk/GME/Mga/MgaCheck.cpp
==============================================================================
--- trunk/GME/Mga/MgaCheck.cpp Mon Aug 13 15:07:51 2012 (r2001)
+++ trunk/GME/Mga/MgaCheck.cpp Tue Aug 14 09:31:31 2012 (r2002)
@@ -297,6 +297,22 @@
if(!good)
COMTHROW(E_MGA_META_VIOLATION);
}
+ // inherited ref can only refer to a derived instance of the target
+ // of its base. (Derived null ref is also rejected, but null ref in archetype is accepted)
+ CoreObj basetype = self[ATTRID_DERIVED];
+ if (basetype && !(mgaproject->preferences & MGAPREF_FREEINSTANCEREFS))
+ {
+ CoreObj base_target = basetype[ATTRID_REFERENCE];
+ if (base_target)
+ {
+ for ( ; target; target = target[ATTRID_DERIVED]) {
+ if (COM_EQUAL(base_target, target))
+ break;
+ }
+ if (!target)
+ COMTHROW(E_MGA_INVALID_TARGET);
+ }
+ }
}
else if(typ == OBJTYPE_SET) {
CComQIPtr<IMgaMetaSet> setmeta = meta;
Modified: trunk/GME/Mga/MgaReference.cpp
==============================================================================
--- trunk/GME/Mga/MgaReference.cpp Mon Aug 13 15:07:51 2012 (r2001)
+++ trunk/GME/Mga/MgaReference.cpp Tue Aug 14 09:31:31 2012 (r2002)
@@ -52,32 +52,31 @@
if(t) ObjForCore(t)->SelfMark(OBJEVENT_REFERENCED);
ObjForCore(self)->SelfMark(OBJEVENT_RELATION);
COMTHROW(ObjForCore(self)->Check());
+
+ ITERATE_THROUGH(self[ATTRID_DERIVED + ATTRID_COLLECTION])
+ {
+ if (!ITER[ATTRID_MASTEROBJ])
+ {
+ COMTHROW(ObjForCore(ITER)->Check());
+ }
+ }
}
return true;
}
HRESULT FCO::put_Referred(IMgaFCO *newVal) {
+ // Inherited ref can only refer to a derived instance of the target
+ // of its base. This is checked in FCO::CheckRCS
COMTRY_IN_TRANSACTION_MAYBE {
CheckWrite();
CHECK_MYINPTRPARVALIDNULL(newVal);
std::vector<CoreObj> peer(1);
peer[0] = CoreObj(newVal);
- if(!(mgaproject->preferences & MGAPREF_FREEINSTANCEREFS)) {
- // inherited ref can only refer to a derived instance of the target
- // of its base. (Null ref is also rejected)
- CoreObj d = self[ATTRID_DERIVED];
- if(d) {
- CoreObj dt = d[ATTRID_REFERENCE];
- if(dt) {
- CoreObj t(peer[0]);
- for( ; t; t = t[ATTRID_DERIVED]) {
- if(COM_EQUAL(dt, t)) break;
- }
- if(!t) COMTHROW(E_MGA_INVALID_TARGET);
- }
- }
- }
+ CoreObj t = self[ATTRID_REFERENCE];
+
+ // FIXME: this is suspect; it makes ref.Referred = ref.Referred a mutating operation (i.e. => CompareToBase() == true)
+ // fix: if(!COM_EQUAL(t, peer[0])) {
self[ATTRID_MASTEROBJ] = NULLCOREOBJ;
putreftask(false).DoWithDeriveds(self, &peer);
} COMCATCH_IN_TRANSACTION_MAYBE(;);
Modified: trunk/Tests/GPyUnit/test_instances.py
==============================================================================
--- trunk/Tests/GPyUnit/test_instances.py Mon Aug 13 15:07:51 2012 (r2001)
+++ trunk/Tests/GPyUnit/test_instances.py Tue Aug 14 09:31:31 2012 (r2002)
@@ -9,6 +9,7 @@
return os.path.join(os.path.dirname(os.path.abspath(__file__)), file)
class TestInstances(unittest.TestCase):
+ project = None
def __init__(self, name, **kwds):
super(TestInstances, self).__init__(name, **kwds)
@@ -29,4 +30,68 @@
self.project.RootFolder.DeriveRootObject(model, True)
self.project.CommitTransaction()
-GPyUnit.util.MUGenerator(globals(), TestInstances)
+ @dec_disable_early_binding
+ def test_RedirectBaseReference(self):
+ self.project = GPyUnit.util.parse_xme(self.connstr)
+ self.project.BeginTransactionInNewTerr()
+ aspects = self.project.RootFolder.GetObjectByPathDisp("/@Aspects")
+ allproxy = self.project.RootFolder.GetObjectByPathDisp("/@Aspects/@AllRef")
+ aspects_instance = self.project.RootFolder.DeriveRootObject(aspects, True)
+ aspects_subtype = self.project.RootFolder.DeriveRootObject(aspects, False)
+ attributes = self.project.RootFolder.GetObjectByPathDisp("/@Stereotypes/@Attributes")
+ allproxy.Referred = attributes
+ for asp in (aspects_instance, aspects_subtype):
+ self.assertEqual(asp.GetObjectByPathDisp("/@AllRef").Referred.Name, attributes.Name)
+ self.assertEqual(asp.GetObjectByPathDisp("/@AllRef").Referred.ID, attributes.ID)
+ self.project.CommitTransaction()
+
+ @dec_disable_early_binding
+ def test_RedirectBaseReference2(self):
+ self.project = GPyUnit.util.parse_xme(self.connstr)
+ self.project.BeginTransactionInNewTerr()
+ aspects = self.project.RootFolder.GetObjectByPathDisp("/@Aspects")
+ allproxy = self.project.RootFolder.GetObjectByPathDisp("/@Aspects/@AllRef")
+ instances = []
+ for inst_flag in (True, False, True, False):
+ instances.append(aspects.DeriveChildObject(allproxy, allproxy.MetaRole, inst_flag))
+ attributes = self.project.RootFolder.GetObjectByPathDisp("/@Stereotypes/@Attributes")
+ allproxy.Referred = attributes
+ try:
+ instances[0].Referred = self.project.RootFolder.GetObjectByPathDisp("/@Constraints/@Constraints|kind=Aspect")
+ except Exception, e:
+ pass
+ else:
+ self.fail()
+ for asp in instances:
+ self.assertEqual(asp.Referred.Name, attributes.Name)
+ self.assertEqual(asp.Referred.ID, attributes.ID)
+ self.project.CommitTransaction()
+
+ @dec_disable_early_binding
+ def test_RedirectBaseReference3(self):
+ self.project = GPyUnit.util.parse_xme(self.connstr)
+ self.project.BeginTransactionInNewTerr()
+ aspects = self.project.RootFolder.GetObjectByPathDisp("/@Aspects")
+ allproxy = self.project.RootFolder.GetObjectByPathDisp("/@Aspects/@AllRef")
+ instances = []
+ for inst_flag in (True, False, True, False):
+ instances.append(aspects.DeriveChildObject(allproxy, allproxy.MetaRole, inst_flag))
+ self.assertFalse(instances[3].CompareToBase())
+ instances[3].Referred = instances[3].Referred
+ self.assertTrue(instances[3].CompareToBase())
+ attributes = self.project.RootFolder.GetObjectByPathDisp("/@Stereotypes/@Attributes")
+ try:
+ allproxy.Referred = attributes
+ except Exception, e:
+ pass
+ else:
+ self.fail()
+ instances[3].RevertToBase()
+ self.assertFalse(instances[3].CompareToBase())
+ allproxy.Referred = attributes
+ for asp in instances:
+ self.assertEqual(asp.Referred.Name, attributes.Name)
+ self.assertEqual(asp.Referred.ID, attributes.ID)
+ self.project.CommitTransaction()
+
+#GPyUnit.util.MUGenerator(globals(), TestInstances)
More information about the gme-commit
mailing list