Added some terrain tests, and found a fun race condition in the sqlite

terrain driver in the process, which is now fixed.  yay for unit tests!
0.6.0-stable
Sean Dague 2008-09-16 19:51:14 +00:00
parent fe7a1af2bd
commit ad379ed136
3 changed files with 99 additions and 28 deletions

View File

@ -470,6 +470,23 @@ namespace OpenSim.Data.SQLite
{ {
int revision = Util.UnixTimeSinceEpoch(); int revision = Util.UnixTimeSinceEpoch();
// This is added to get rid of the infinitely growing
// terrain databases which negatively impact on SQLite
// over time. Before reenabling this feature there
// needs to be a limitter put on the number of
// revisions in the database, as this old
// implementation is a DOS attack waiting to happen.
using (
SqliteCommand cmd =
new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision",
m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":RegionUUID", Util.ToRawUuidString(regionID)));
cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
cmd.ExecuteNonQuery();
}
// the following is an work around for .NET. The perf // the following is an work around for .NET. The perf
// issues associated with it aren't as bad as you think. // issues associated with it aren't as bad as you think.
m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString()); m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString());
@ -483,23 +500,6 @@ namespace OpenSim.Data.SQLite
cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter))); cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter)));
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
// This is added to get rid of the infinitely growing
// terrain databases which negatively impact on SQLite
// over time. Before reenabling this feature there
// needs to be a limitter put on the number of
// revisions in the database, as this old
// implementation is a DOS attack waiting to happen.
using (
SqliteCommand cmd =
new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision < :Revision",
m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":RegionUUID", Util.ToRawUuidString(regionID)));
cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
cmd.ExecuteNonQuery();
}
} }
} }

View File

@ -55,7 +55,7 @@ namespace OpenSim.Data.SQLite.Tests
[TestFixtureTearDown] [TestFixtureTearDown]
public void Cleanup() public void Cleanup()
{ {
System.IO.File.Delete(file); // System.IO.File.Delete(file);
} }
} }
} }

View File

@ -40,17 +40,31 @@ namespace OpenSim.Data.Tests
public class BasicRegionTest public class BasicRegionTest
{ {
public IRegionDataStore db; public IRegionDataStore db;
public UUID region; public UUID region1;
public UUID region2;
public double height1;
public double height2;
public void SuperInit() public void SuperInit()
{ {
region = UUID.Random(); try
{
log4net.Config.XmlConfigurator.Configure();
}
catch (Exception)
{
// I don't care, just leave log4net off
}
region1 = UUID.Random();
height1 = 20;
height2 = 100;
} }
[Test] [Test]
public void T001_LoadEmpty() public void T001_LoadEmpty()
{ {
List<SceneObjectGroup> objs = db.LoadObjects(region); List<SceneObjectGroup> objs = db.LoadObjects(region1);
Assert.That(objs.Count, Is.EqualTo(0)); Assert.That(objs.Count, Is.EqualTo(0));
} }
@ -64,18 +78,18 @@ namespace OpenSim.Data.Tests
SceneObjectGroup sog = NewSOG("object1"); SceneObjectGroup sog = NewSOG("object1");
SceneObjectGroup sog2 = NewSOG("object2"); SceneObjectGroup sog2 = NewSOG("object2");
db.StoreObject(sog, region); db.StoreObject(sog, region1);
db.StoreObject(sog2, region); db.StoreObject(sog2, region1);
// This tests the ADO.NET driver // This tests the ADO.NET driver
List<SceneObjectGroup> objs = db.LoadObjects(region); List<SceneObjectGroup> objs = db.LoadObjects(region1);
Assert.That(objs.Count, Is.EqualTo(2)); Assert.That(objs.Count, Is.EqualTo(2));
} }
[Test] [Test]
public void T011_ObjectNames() public void T011_ObjectNames()
{ {
List<SceneObjectGroup> objs = db.LoadObjects(region); List<SceneObjectGroup> objs = db.LoadObjects(region1);
foreach (SceneObjectGroup sog in objs) foreach (SceneObjectGroup sog in objs)
{ {
SceneObjectPart p = sog.RootPart; SceneObjectPart p = sog.RootPart;
@ -88,16 +102,73 @@ namespace OpenSim.Data.Tests
public void T012_UpdateObject() public void T012_UpdateObject()
{ {
string text = "object1 text"; string text = "object1 text";
SceneObjectGroup sog = FindSOG("object1", region); SceneObjectGroup sog = FindSOG("object1", region1);
sog.RootPart.Text = text; sog.RootPart.Text = text;
db.StoreObject(sog, region); db.StoreObject(sog, region1);
sog = FindSOG("object1", region); sog = FindSOG("object1", region1);
Assert.That(text, Is.EqualTo(sog.RootPart.Text)); Assert.That(text, Is.EqualTo(sog.RootPart.Text));
} }
[Test]
public void T300_NoTerrain()
{
double[,] t1 = db.LoadTerrain(region1);
}
[Test]
public void T301_CreateTerrain()
{
double[,] t1 = GenTerrain(height1);
db.StoreTerrain(t1, region1);
}
[Test]
public void T302_FetchTerrain()
{
double[,] baseterrain1 = GenTerrain(height1);
double[,] baseterrain2 = GenTerrain(height2);
double[,] t1 = db.LoadTerrain(region1);
Assert.That(CompareTerrain(t1, baseterrain1), Is.True);
Assert.That(CompareTerrain(t1, baseterrain2), Is.False);
}
[Test]
public void T303_UpdateTerrain()
{
double[,] baseterrain1 = GenTerrain(height1);
double[,] baseterrain2 = GenTerrain(height2);
db.StoreTerrain(baseterrain2, region1);
double[,] t1 = db.LoadTerrain(region1);
Assert.That(CompareTerrain(t1, baseterrain1), Is.False);
Assert.That(CompareTerrain(t1, baseterrain2), Is.True);
}
// Extra private methods // Extra private methods
private double[,] GenTerrain(double value)
{
double[,] terret = new double[256,256];
terret.Initialize();
for (int x = 0; x < 256; x++)
for (int y = 0; y < 256; y++)
terret[x,y] = value;
return terret;
}
private bool CompareTerrain(double[,] one, double[,] two)
{
for (int x = 0; x < 256; x++)
for (int y = 0; y < 256; y++)
if (one[x,y] != two[x,y])
return false;
return true;
}
private SceneObjectGroup FindSOG(string name, UUID r) private SceneObjectGroup FindSOG(string name, UUID r)
{ {
List<SceneObjectGroup> objs = db.LoadObjects(r); List<SceneObjectGroup> objs = db.LoadObjects(r);