* 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"];
|
DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
|
||||||
|
|
||||||
inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString());
|
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");
|
invFoldersDa.Update(ds, "inventoryfolders");
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,26 +307,21 @@ namespace OpenSim.Data.SQLite
|
||||||
/// <param name="regionUUID">the region UUID</param>
|
/// <param name="regionUUID">the region UUID</param>
|
||||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
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)
|
lock (ds)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||||
{
|
{
|
||||||
if ((prim.GetEffectiveObjectFlags() & (uint)PrimFlags.Temporary) == 0
|
m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||||
&& (prim.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) == 0)
|
addPrim(prim, obj.UUID, regionUUID);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1130,7 +1125,7 @@ namespace OpenSim.Data.SQLite
|
||||||
// explicit conversion of integers is required, which sort
|
// explicit conversion of integers is required, which sort
|
||||||
// of sucks. No idea if there is a shortcut here or not.
|
// of sucks. No idea if there is a shortcut here or not.
|
||||||
prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
|
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
|
// various text fields
|
||||||
prim.Text = (String) row["Text"];
|
prim.Text = (String) row["Text"];
|
||||||
prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
|
prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
|
||||||
|
|
|
@ -266,6 +266,7 @@ namespace OpenSim.Data.Tests
|
||||||
InventoryItemBase actual = db.getInventoryItem(item1);
|
InventoryItemBase actual = db.getInventoryItem(item1);
|
||||||
Assert.That(actual, Constraints.PropertyCompareConstraint(expected)
|
Assert.That(actual, Constraints.PropertyCompareConstraint(expected)
|
||||||
.IgnoreProperty(x=>x.InvType)
|
.IgnoreProperty(x=>x.InvType)
|
||||||
|
.IgnoreProperty(x=>x.CreatorIdAsUuid)
|
||||||
.IgnoreProperty(x=>x.Description)
|
.IgnoreProperty(x=>x.Description)
|
||||||
.IgnoreProperty(x=>x.CreatorId));
|
.IgnoreProperty(x=>x.CreatorId));
|
||||||
}
|
}
|
||||||
|
|
|
@ -576,8 +576,10 @@ namespace OpenSim.Data.Tests
|
||||||
.IgnoreProperty(x=>x.HasGroupChanged)
|
.IgnoreProperty(x=>x.HasGroupChanged)
|
||||||
.IgnoreProperty(x=>x.IsSelected)
|
.IgnoreProperty(x=>x.IsSelected)
|
||||||
.IgnoreProperty(x=>x.RegionHandle)
|
.IgnoreProperty(x=>x.RegionHandle)
|
||||||
|
.IgnoreProperty(x=>x.RegionUUID)
|
||||||
.IgnoreProperty(x=>x.Scene)
|
.IgnoreProperty(x=>x.Scene)
|
||||||
.IgnoreProperty(x=>x.RootPart.InventorySerial));
|
.IgnoreProperty(x=>x.Children)
|
||||||
|
.IgnoreProperty(x=>x.RootPart));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -403,6 +403,7 @@ namespace OpenSim.Data.Tests
|
||||||
Assert.That(u1a, Constraints.PropertyCompareConstraint(u)
|
Assert.That(u1a, Constraints.PropertyCompareConstraint(u)
|
||||||
.IgnoreProperty(x=>x.HomeRegionX)
|
.IgnoreProperty(x=>x.HomeRegionX)
|
||||||
.IgnoreProperty(x=>x.HomeRegionY)
|
.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)
|
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())
|
if (actual.GetType() != expected.GetType())
|
||||||
{
|
{
|
||||||
propertyNames.Push("GetType()");
|
propertyNames.Push("GetType()");
|
||||||
|
@ -122,6 +131,60 @@ namespace OpenSim.Data.Tests
|
||||||
return true;
|
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.
|
//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);
|
PropertyInfo[] properties = expected.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||||
foreach (var property in properties)
|
foreach (var property in properties)
|
||||||
|
@ -147,41 +210,6 @@ namespace OpenSim.Data.Tests
|
||||||
return false;
|
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);
|
propertyNames.Push(property.Name);
|
||||||
if (!ObjectCompare(expectedValue, actualValue, propertyNames))
|
if (!ObjectCompare(expectedValue, actualValue, propertyNames))
|
||||||
return false;
|
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.
|
//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.
|
// 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);
|
||||||
{
|
|
||||||
ignores.Add(((MemberExpression)express).Member.Name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Otherwise there could be more parameters inside...
|
|
||||||
PullApartExpression(((MemberExpression)express).Expression);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +290,7 @@ namespace OpenSim.Data.Tests
|
||||||
{
|
{
|
||||||
HasInt actual = new HasInt { TheValue = 5 };
|
HasInt actual = new HasInt { TheValue = 5 };
|
||||||
HasInt expected = new HasInt { TheValue = 4 };
|
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);
|
Assert.That(constraint.Matches(actual), Is.True);
|
||||||
}
|
}
|
||||||
|
@ -311,6 +331,28 @@ namespace OpenSim.Data.Tests
|
||||||
Assert.That(constraint.Matches(actual), Is.False);
|
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]
|
[Test]
|
||||||
public void TestColors()
|
public void TestColors()
|
||||||
{
|
{
|
||||||
|
@ -321,5 +363,53 @@ namespace OpenSim.Data.Tests
|
||||||
|
|
||||||
Assert.That(constraint.Matches(actual), Is.True);
|
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