* 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.
parent
23d478f2fa
commit
f6251ce810
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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"]),
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue