* Modified SQLite/SQLiteInventoryStore.cs to not throw if the inventory row does not exist, to match the mysql behavior. * Modified SQLite/SQLiteRegionData.cs to only persist temporary items following the same rules mysql uses. * Added another ignore to the inventory test that was missing. * Added a few more ignores to the RegionTest that the first version of my test were missing. * Added ignoring the root Folder ID, which is set by the inventory system. * Added several improvements to the PropertyCompareConstraint: Protection against infinite loops, added IComparable<T> (for UUID) and moved IComparable before the property matching. * Fixed a bug where I was saving the inside of the ignore expression instead of the outside of it.

arthursv
Kunnis 2009-08-15 06:08:36 -05:00 committed by Teravus Ovares (Dan Olivares)
parent 23d478f2fa
commit f6251ce810
6 changed files with 154 additions and 64 deletions

View File

@ -301,7 +301,8 @@ namespace OpenSim.Data.SQLite
DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString());
inventoryRow["version"] = (int)inventoryRow["version"] + 1;
if(inventoryRow != null) //MySQL doesn't throw an exception here, so sqlite shouldn't either.
inventoryRow["version"] = (int)inventoryRow["version"] + 1;
invFoldersDa.Update(ds, "inventoryfolders");
}

View File

@ -307,26 +307,21 @@ namespace OpenSim.Data.SQLite
/// <param name="regionUUID">the region UUID</param>
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
{
uint flags = obj.RootPart.GetEffectiveObjectFlags();
// Eligibility check
//
if ((flags & (uint)PrimFlags.Temporary) != 0)
return;
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
return;
lock (ds)
{
foreach (SceneObjectPart prim in obj.Children.Values)
{
if ((prim.GetEffectiveObjectFlags() & (uint)PrimFlags.Temporary) == 0
&& (prim.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) == 0)
{
m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
addPrim(prim, obj.UUID, regionUUID);
}
else if (prim.Stopped)
{
//m_log.Info("[DATASTORE]: " +
//"Adding stopped obj: " + obj.UUID + " to region: " + regionUUID);
//addPrim(prim, obj.UUID.ToString(), regionUUID.ToString());
}
else
{
// m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID);
}
m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
addPrim(prim, obj.UUID, regionUUID);
}
}
@ -1130,7 +1125,7 @@ namespace OpenSim.Data.SQLite
// explicit conversion of integers is required, which sort
// of sucks. No idea if there is a shortcut here or not.
prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
prim.Name = (String) row["Name"];
prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"];
// various text fields
prim.Text = (String) row["Text"];
prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),

View File

@ -266,6 +266,7 @@ namespace OpenSim.Data.Tests
InventoryItemBase actual = db.getInventoryItem(item1);
Assert.That(actual, Constraints.PropertyCompareConstraint(expected)
.IgnoreProperty(x=>x.InvType)
.IgnoreProperty(x=>x.CreatorIdAsUuid)
.IgnoreProperty(x=>x.Description)
.IgnoreProperty(x=>x.CreatorId));
}

View File

@ -576,8 +576,10 @@ namespace OpenSim.Data.Tests
.IgnoreProperty(x=>x.HasGroupChanged)
.IgnoreProperty(x=>x.IsSelected)
.IgnoreProperty(x=>x.RegionHandle)
.IgnoreProperty(x=>x.RegionUUID)
.IgnoreProperty(x=>x.Scene)
.IgnoreProperty(x=>x.RootPart.InventorySerial));
.IgnoreProperty(x=>x.Children)
.IgnoreProperty(x=>x.RootPart));
}
[Test]

View File

@ -403,6 +403,7 @@ namespace OpenSim.Data.Tests
Assert.That(u1a, Constraints.PropertyCompareConstraint(u)
.IgnoreProperty(x=>x.HomeRegionX)
.IgnoreProperty(x=>x.HomeRegionY)
.IgnoreProperty(x=>x.RootInventoryFolderID)
);
}

View File

@ -69,6 +69,15 @@ namespace OpenSim.Data.Tests
private bool ObjectCompare(object expected, object actual, Stack<string> propertyNames)
{
//prevent loops...
if(propertyNames.Count > 50)
{
failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
failingActual = actual;
failingExpected = expected;
return false;
}
if (actual.GetType() != expected.GetType())
{
propertyNames.Push("GetType()");
@ -122,6 +131,60 @@ namespace OpenSim.Data.Tests
return true;
}
IComparable comp = actual as IComparable;
if (comp != null)
{
if (comp.CompareTo(expected) != 0)
{
failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
failingActual = actual;
failingExpected = expected;
return false;
}
return true;
}
//Now try the much more annoying IComparable<T>
Type icomparableInterface = actual.GetType().GetInterface("IComparable`1");
if (icomparableInterface != null)
{
int result = (int)icomparableInterface.GetMethod("CompareTo").Invoke(actual, new[] { expected });
if (result != 0)
{
failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
failingActual = actual;
failingExpected = expected;
return false;
}
return true;
}
IEnumerable arr = actual as IEnumerable;
if (arr != null)
{
List<object> actualList = arr.Cast<object>().ToList();
List<object> expectedList = ((IEnumerable)expected).Cast<object>().ToList();
if (actualList.Count != expectedList.Count)
{
propertyNames.Push("Count");
failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
failingActual = actualList.Count;
failingExpected = expectedList.Count;
propertyNames.Pop();
return false;
}
//actualList and expectedList should be the same size.
for (int i = 0; i < actualList.Count; i++)
{
propertyNames.Push("[" + i + "]");
if (!ObjectCompare(expectedList[i], actualList[i], propertyNames))
return false;
propertyNames.Pop();
}
//Everything seems okay...
return true;
}
//Skip static properties. I had a nasty problem comparing colors because of all of the public static colors.
PropertyInfo[] properties = expected.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
@ -147,41 +210,6 @@ namespace OpenSim.Data.Tests
return false;
}
IComparable comp = actualValue as IComparable;
if (comp != null)
{
if (comp.CompareTo(expectedValue) != 0)
{
propertyNames.Push(property.Name);
failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
propertyNames.Pop();
failingActual = actualValue;
failingExpected = expectedValue;
return false;
}
continue;
}
IEnumerable arr = actualValue as IEnumerable;
if (arr != null)
{
List<object> actualList = arr.Cast<object>().ToList();
List<object> expectedList = ((IEnumerable)expectedValue).Cast<object>().ToList();
if (actualList.Count != expectedList.Count)
{
propertyNames.Push(property.Name);
propertyNames.Push("Count");
failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
failingActual = actualList.Count;
failingExpected = expectedList.Count;
propertyNames.Pop();
propertyNames.Pop();
}
//Todo: A value-wise comparison of all of the values.
//Everything seems okay...
continue;
}
propertyNames.Push(property.Name);
if (!ObjectCompare(expectedValue, actualValue, propertyNames))
return false;
@ -223,15 +251,7 @@ namespace OpenSim.Data.Tests
{
//If the inside of the lambda is the access to x, we've hit the end of the chain.
// We should track by the fully scoped parameter name, but this is the first rev of doing this.
if (((MemberExpression)express).Expression is ParameterExpression)
{
ignores.Add(((MemberExpression)express).Member.Name);
}
else
{
//Otherwise there could be more parameters inside...
PullApartExpression(((MemberExpression)express).Expression);
}
ignores.Add(((MemberExpression)express).Member.Name);
}
}
}
@ -270,7 +290,7 @@ namespace OpenSim.Data.Tests
{
HasInt actual = new HasInt { TheValue = 5 };
HasInt expected = new HasInt { TheValue = 4 };
var constraint = Constraints.PropertyCompareConstraint(expected).IgnoreProperty(x=>x.TheValue);
var constraint = Constraints.PropertyCompareConstraint(expected).IgnoreProperty(x => x.TheValue);
Assert.That(constraint.Matches(actual), Is.True);
}
@ -311,6 +331,28 @@ namespace OpenSim.Data.Tests
Assert.That(constraint.Matches(actual), Is.False);
}
[Test]
public void UUIDShouldMatch()
{
UUID uuid1 = UUID.Random();
UUID uuid2 = UUID.Parse(uuid1.ToString());
var constraint = Constraints.PropertyCompareConstraint(uuid1);
Assert.That(constraint.Matches(uuid2), Is.True);
}
[Test]
public void UUIDShouldNotMatch()
{
UUID uuid1 = UUID.Random();
UUID uuid2 = UUID.Random();
var constraint = Constraints.PropertyCompareConstraint(uuid1);
Assert.That(constraint.Matches(uuid2), Is.False);
}
[Test]
public void TestColors()
{
@ -321,5 +363,53 @@ namespace OpenSim.Data.Tests
Assert.That(constraint.Matches(actual), Is.True);
}
[Test]
public void ShouldCompareLists()
{
List<int> expected = new List<int> { 1, 2, 3 };
List<int> actual = new List<int> { 1, 2, 3 };
var constraint = Constraints.PropertyCompareConstraint(expected);
Assert.That(constraint.Matches(actual), Is.True);
}
[Test]
public void ShouldFailToCompareListsThatAreDifferent()
{
List<int> expected = new List<int> { 1, 2, 3 };
List<int> actual = new List<int> { 1, 2, 4 };
var constraint = Constraints.PropertyCompareConstraint(expected);
Assert.That(constraint.Matches(actual), Is.False);
}
[Test]
public void ShouldFailToCompareListsThatAreDifferentLengths()
{
List<int> expected = new List<int> { 1, 2, 3 };
List<int> actual = new List<int> { 1, 2 };
var constraint = Constraints.PropertyCompareConstraint(expected);
Assert.That(constraint.Matches(actual), Is.False);
}
public class Recursive
{
public Recursive Other { get; set; }
}
[Test]
public void ErrorsOutOnRecursive()
{
Recursive parent = new Recursive();
Recursive child = new Recursive();
parent.Other = child;
child.Other = parent;
var constraint = Constraints.PropertyCompareConstraint(child);
Assert.That(constraint.Matches(child), Is.False);
}
}
}