WuhuIslandTesting/Library/PackageCache/com.unity.scriptablebuildpipeline@1.21.5/Tests/Editor/CacheServer/Tests.cs
2025-01-07 02:06:59 +01:00

460 lines
15 KiB
C#

using System;
using System.IO;
using System.Threading;
using NUnit.Framework;
using UnityEditor.Build.CacheServer;
using UnityEngine;
using Random = System.Random;
namespace UnityEditor.CacheServerTests
{
[TestFixture]
public class Tests
{
private const string KTestHost = "127.0.0.1";
private const string KInvalidTestHost = "192.0.2.1";
private Random rand;
private static int TestPort
{
get { return LocalCacheServer.Port; }
}
private FileId GenerateFileId()
{
if (rand == null)
rand = new Random();
var guid = new byte[16];
var hash = new byte[16];
rand.NextBytes(guid);
rand.NextBytes(hash);
return FileId.From(guid, hash);
}
[OneTimeSetUp]
public void BeforeAll()
{
var cachePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
LocalCacheServer.Setup(1024 * 1024, cachePath);
rand = new Random();
}
[OneTimeTearDown]
public void AfterAll()
{
LocalCacheServer.Clear();
}
[Test]
public void FileDownloadItem()
{
var fileId = GenerateFileId();
var readStream = new ByteArrayStream(128 * 1024);
var client = new Client(KTestHost, TestPort);
client.Connect();
client.BeginTransaction(fileId);
client.Upload(FileType.Asset, readStream);
client.EndTransaction();
Thread.Sleep(50); // give the server a little time to finish the transaction
var targetFile = Path.GetTempFileName();
var downloadItem = new FileDownloadItem(fileId, FileType.Asset, targetFile);
var mre = new ManualResetEvent(false);
Exception err = null;
client.DownloadFinished += (sender, args) =>
{
try
{
Assert.AreEqual(DownloadResult.Success, args.Result);
Assert.AreEqual(args.DownloadItem.Id, fileId);
Assert.IsTrue(File.Exists(targetFile));
var fileBytes = File.ReadAllBytes(targetFile);
Assert.IsTrue(Util.ByteArraysAreEqual(readStream.BackingBuffer, fileBytes));
}
catch (Exception e)
{
err = e;
}
finally
{
if (File.Exists(targetFile))
File.Delete(targetFile);
mre.Set();
}
};
client.QueueDownload(downloadItem);
Assert.IsTrue(mre.WaitOne(2000));
if (err != null)
throw err;
}
[Test]
public void QueueDownloadFromDownloadFinishedCallback()
{
var fileId = GenerateFileId();
var readStream = new ByteArrayStream(128 * 1024);
var client = new Client(KTestHost, TestPort);
client.Connect();
client.BeginTransaction(fileId);
client.Upload(FileType.Asset, readStream);
client.EndTransaction();
Thread.Sleep(50); // give the server a little time to finish the transaction
var targetFile1 = Path.GetTempFileName();
var downloadItem1 = new FileDownloadItem(fileId, FileType.Asset, targetFile1);
var targetFile2 = Path.GetTempFileName();
var downloadItem2 = new FileDownloadItem(fileId, FileType.Asset, targetFile2);
var mre = new ManualResetEvent(false);
Exception err = null;
client.DownloadFinished += (sender1, args1) =>
{
try
{
Assert.AreEqual(DownloadResult.Success, args1.Result);
Assert.AreEqual(args1.DownloadItem.Id, fileId);
Assert.IsTrue(File.Exists(targetFile1));
var fileBytes = File.ReadAllBytes(targetFile1);
Assert.IsTrue(Util.ByteArraysAreEqual(readStream.BackingBuffer, fileBytes));
}
catch (Exception e)
{
err = e;
}
finally
{
if (File.Exists(targetFile1))
File.Delete(targetFile1);
client.ResetDownloadFinishedEventHandler();
client.DownloadFinished += (sender2, args2) =>
{
try
{
Assert.AreEqual(DownloadResult.Success, args2.Result);
Assert.AreEqual(args2.DownloadItem.Id, fileId);
Assert.IsTrue(File.Exists(targetFile2));
var fileBytes = File.ReadAllBytes(targetFile2);
Assert.IsTrue(Util.ByteArraysAreEqual(readStream.BackingBuffer, fileBytes));
}
catch (Exception e)
{
err = e;
}
finally
{
if (File.Exists(targetFile2))
File.Delete(targetFile2);
mre.Set();
}
};
client.QueueDownload(downloadItem2);
}
};
client.QueueDownload(downloadItem1);
Assert.IsTrue(mre.WaitOne(2000));
if (err != null)
throw err;
}
[Test]
public void Connect()
{
var client = new Client(KTestHost, TestPort);
client.Connect();
client.Close();
}
[Test]
public void ConnectTimeout()
{
var client = new Client(KInvalidTestHost, TestPort);
TimeoutException err = null;
try
{
client.Connect(0);
}
catch (TimeoutException e)
{
err = e;
}
finally
{
client.Close();
Debug.Assert(err != null);
}
}
[Test]
public void TransactionIsolation()
{
var fileId = GenerateFileId();
var readStream = new ByteArrayStream(16 * 1024);
var client = new Client(KTestHost, TestPort);
client.Connect();
Assert.Throws<TransactionIsolationException>(() => client.Upload(FileType.Asset, readStream));
Assert.Throws<TransactionIsolationException>(() => client.EndTransaction());
// Back-to-back begin transactions are allowed
client.BeginTransaction(fileId);
Assert.DoesNotThrow(() => client.BeginTransaction(fileId));
}
[Test]
public void UploadDownloadOne()
{
var fileId = GenerateFileId();
var readStream = new ByteArrayStream(16 * 1024);
var client = new Client(KTestHost, TestPort);
client.Connect();
client.BeginTransaction(fileId);
client.Upload(FileType.Asset, readStream);
client.EndTransaction();
Thread.Sleep(50); // give the server a little time to finish the transaction
var downloadItem = new TestDownloadItem(fileId, FileType.Asset);
client.QueueDownload(downloadItem);
Exception err = null;
var mre = new ManualResetEvent(false);
client.DownloadFinished += (sender, args) =>
{
try
{
Assert.AreEqual(0, args.DownloadQueueLength);
Assert.AreEqual(DownloadResult.Success, args.Result);
Assert.AreEqual(fileId, args.DownloadItem.Id);
}
catch (Exception e)
{
err = e;
}
finally
{
mre.Set();
}
};
Assert.IsTrue(mre.WaitOne(2000));
if (err != null)
throw err;
Assert.IsTrue(Util.ByteArraysAreEqual(readStream.BackingBuffer, downloadItem.Bytes));
}
[Test]
public void DownloadMany()
{
const int fileCount = 5;
var fileIds = new FileId[fileCount];
var fileStreams = new ByteArrayStream[fileCount];
var client = new Client(KTestHost, TestPort);
client.Connect();
// Upload files
var rand = new Random();
for (var i = 0; i < fileCount; i++)
{
fileIds[i] = GenerateFileId();
fileStreams[i] = new ByteArrayStream(rand.Next(64 * 1024, 128 * 1024));
client.BeginTransaction(fileIds[i]);
client.Upload(FileType.Asset, fileStreams[i]);
client.EndTransaction();
}
Thread.Sleep(50);
// Download
var receivedCount = 0;
Exception err = null;
var mre = new ManualResetEvent(false);
client.DownloadFinished += (sender, args) =>
{
try
{
Assert.AreEqual(args.Result, DownloadResult.Success);
Assert.AreEqual(args.DownloadItem.Id, fileIds[receivedCount]);
var downloadItem = (TestDownloadItem)args.DownloadItem;
Assert.IsTrue(Util.ByteArraysAreEqual(fileStreams[receivedCount].BackingBuffer, downloadItem.Bytes));
receivedCount++;
Assert.AreEqual(fileCount - receivedCount, args.DownloadQueueLength);
}
catch (Exception e)
{
err = e;
}
finally
{
if (err != null || receivedCount == fileCount)
mre.Set();
}
};
for (var i = 0; i < fileCount; i++)
client.QueueDownload(new TestDownloadItem(fileIds[i], FileType.Asset));
Assert.AreEqual(fileCount, client.DownloadQueueLength);
Assert.IsTrue(mre.WaitOne(2000));
if (err != null)
throw err;
Assert.AreEqual(fileCount, receivedCount);
}
[Test]
public void DonwloadFileNotFound()
{
var client = new Client(KTestHost, TestPort);
client.Connect();
var fileId = FileId.From(new byte[16], new byte[16]);
var mre = new ManualResetEvent(false);
var downloadItem = new TestDownloadItem(fileId, FileType.Asset);
client.QueueDownload(downloadItem);
Exception err = null;
client.DownloadFinished += (sender, args) =>
{
try
{
Assert.AreEqual(args.Result, DownloadResult.FileNotFound);
Assert.AreEqual(args.DownloadItem.Id, fileId);
}
catch (Exception e)
{
err = e;
}
finally
{
mre.Set();
}
};
mre.WaitOne(500);
if (err != null)
throw err;
}
[Test]
public void ResetDownloadFinishedEventHandler()
{
var fileId = GenerateFileId();
var readStream = new ByteArrayStream(16 * 1024);
var client = new Client(KTestHost, TestPort);
client.Connect();
client.BeginTransaction(fileId);
client.Upload(FileType.Asset, readStream);
client.EndTransaction();
Thread.Sleep(50);
var downloadItem = new TestDownloadItem(fileId, FileType.Asset);
// Add two listeners that will assert if called
client.DownloadFinished += (sender, args) => { Debug.Assert(false); };
client.DownloadFinished += (sender, args) => { Debug.Assert(false); };
// Clear the listeners so they will not be called
client.ResetDownloadFinishedEventHandler();
client.QueueDownload(downloadItem);
var mre = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(state =>
{
while (client.DownloadQueueLength > 0)
Thread.Sleep(0);
mre.Set();
});
Assert.IsTrue(mre.WaitOne(2000));
}
static void WriteBytesToStream(Stream stream, byte[] buffer, int offset, int count)
{
// Write to stream, and reset position for read
stream.Write(buffer, offset, count);
stream.Position -= count;
}
[Test]
public void ReadHeader_AppendsDataToBuffer()
{
using (var stream = new MemoryStream())
{
var client = new Client(KTestHost, TestPort);
client.m_stream = stream;
Exception err = null;
var resetEvent = new ManualResetEvent(false);
var testBuffer = new byte[] { (byte)'-', (byte)'0' };
WriteBytesToStream(stream, testBuffer, (int)stream.Length, 1);
// Setup checks / callback
client.OnReadHeader += (bytesRead, readBuffer) =>
{
try
{
// Validate written and read bytes match
Assert.AreEqual((int)stream.Length, bytesRead);
// Validate buffer contents are correct up to the current written bytes
for (int i = 0; i < (int)stream.Length; i++)
Assert.AreEqual(testBuffer[i], readBuffer[i]);
if ((int)stream.Length < testBuffer.Length)
WriteBytesToStream(stream, testBuffer, (int)stream.Length, 1);
else
resetEvent.Set();
}
catch (Exception e)
{
err = e;
resetEvent.Set();
}
};
// Run test
client.ReadNextDownloadResult();
Assert.IsTrue(resetEvent.WaitOne(2000));
if (err != null)
throw err;
}
}
}
}