initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,91 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace UnityEditor.CacheServerTests
|
||||
{
|
||||
internal class ByteArrayStream : Stream
|
||||
{
|
||||
private int m_pos;
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return BackingBuffer.Length; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get { return m_pos; }
|
||||
set
|
||||
{
|
||||
m_pos = Math.Min((int)value, BackingBuffer.Length - 1);
|
||||
Debug.Assert(m_pos >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] BackingBuffer { get; private set; }
|
||||
|
||||
public ByteArrayStream(long size)
|
||||
{
|
||||
BackingBuffer = new byte[size];
|
||||
RandomNumberGenerator.Create().GetBytes(BackingBuffer);
|
||||
}
|
||||
|
||||
public override void SetLength(long value) {}
|
||||
public override void Flush() {}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Debug.Assert(count <= BackingBuffer.Length - m_pos); // can't write past out buffer length
|
||||
count = Math.Min(count, buffer.Length - offset); // Don't read past the input buffer length
|
||||
Buffer.BlockCopy(buffer, offset, BackingBuffer, m_pos, count);
|
||||
m_pos += count;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
count = Math.Min(count, BackingBuffer.Length - m_pos); // Don't copy more bytes than we have
|
||||
count = Math.Min(count, buffer.Length - offset); // Don't overrun the destination buffer
|
||||
Buffer.BlockCopy(BackingBuffer, m_pos, buffer, offset, count);
|
||||
m_pos += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
Position = (int)offset;
|
||||
break;
|
||||
|
||||
case SeekOrigin.Current:
|
||||
Position += (int)offset;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
Position = BackingBuffer.Length - (int)offset - 1;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("origin", origin, null);
|
||||
}
|
||||
|
||||
return Position;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8cce051c0b60040d68cd27a80e58f787
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,133 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.CacheServerTests
|
||||
{
|
||||
internal class LocalCacheServer : ScriptableSingleton<LocalCacheServer>
|
||||
{
|
||||
[SerializeField] public string m_path;
|
||||
[SerializeField] public int m_port;
|
||||
[SerializeField] public int m_pid = -1;
|
||||
|
||||
private void Create(int port, ulong size, string cachePath)
|
||||
{
|
||||
var nodeExecutable = Utils.Paths.Combine(EditorApplication.applicationContentsPath, "Tools", "nodejs");
|
||||
nodeExecutable = Application.platform == RuntimePlatform.WindowsEditor
|
||||
? Utils.Paths.Combine(nodeExecutable, "node.exe")
|
||||
: Utils.Paths.Combine(nodeExecutable, "bin", "node");
|
||||
|
||||
if (!Directory.Exists(cachePath))
|
||||
Directory.CreateDirectory(cachePath);
|
||||
|
||||
m_path = cachePath;
|
||||
|
||||
var cacheServerJs = Utils.Paths.Combine(EditorApplication.applicationContentsPath, "Tools", "CacheServer", "main.js");
|
||||
var processStartInfo = new ProcessStartInfo(nodeExecutable)
|
||||
{
|
||||
Arguments = "\"" + cacheServerJs + "\""
|
||||
+ " --port " + port
|
||||
+ " --path \"" + m_path
|
||||
+ "\" --nolegacy"
|
||||
+ " --monitor-parent-process " + Process.GetCurrentProcess().Id
|
||||
// node.js has issues running on windows with stdout not redirected.
|
||||
// so we silence logging to avoid that. And also to avoid CacheServer
|
||||
// spamming the editor logs on OS X.
|
||||
+ " --silent"
|
||||
+ " --size " + size,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var p = new Process { StartInfo = processStartInfo };
|
||||
p.Start();
|
||||
|
||||
m_port = port;
|
||||
m_pid = p.Id;
|
||||
Save(true);
|
||||
}
|
||||
|
||||
public static string CachePath
|
||||
{
|
||||
get { return instance.m_path; }
|
||||
}
|
||||
|
||||
public static int Port
|
||||
{
|
||||
get { return instance.m_port; }
|
||||
}
|
||||
|
||||
public static void Setup(ulong size, string cachePath)
|
||||
{
|
||||
Kill();
|
||||
instance.Create(GetRandomUnusedPort(), size, cachePath);
|
||||
WaitForServerToComeAlive(instance.m_port);
|
||||
}
|
||||
|
||||
public static void Kill()
|
||||
{
|
||||
if (instance.m_pid == -1)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var p = Process.GetProcessById(instance.m_pid);
|
||||
p.Kill();
|
||||
instance.m_pid = -1;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if we could not get a process, there is non alive. continue.
|
||||
}
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
Kill();
|
||||
if (Directory.Exists(instance.m_path))
|
||||
Directory.Delete(instance.m_path, true);
|
||||
}
|
||||
|
||||
private static void WaitForServerToComeAlive(int port)
|
||||
{
|
||||
var start = DateTime.Now;
|
||||
var maximum = start.AddSeconds(5);
|
||||
while (DateTime.Now < maximum)
|
||||
{
|
||||
if (!PingHost("localhost", port, 10)) continue;
|
||||
Console.WriteLine("Server Came alive after {0} ms", (DateTime.Now - start).TotalMilliseconds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetRandomUnusedPort()
|
||||
{
|
||||
var listener = new TcpListener(IPAddress.Any, 0);
|
||||
listener.Start();
|
||||
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
||||
listener.Stop();
|
||||
return port;
|
||||
}
|
||||
|
||||
private static bool PingHost(string host, int port, int timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = new TcpClient())
|
||||
{
|
||||
var result = client.BeginConnect(host, port, null, null);
|
||||
result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(timeout));
|
||||
return client.Connected;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1b623084ee8eb4b9199e34858add3cac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,30 @@
|
|||
using System.IO;
|
||||
using UnityEditor.Build.CacheServer;
|
||||
|
||||
namespace UnityEditor.CacheServerTests
|
||||
{
|
||||
internal class TestDownloadItem : IDownloadItem
|
||||
{
|
||||
private ByteArrayStream m_writeStream;
|
||||
|
||||
public FileId Id { get; private set; }
|
||||
public FileType Type { get; private set; }
|
||||
|
||||
public void Finish() {}
|
||||
public byte[] Bytes
|
||||
{
|
||||
get { return m_writeStream.BackingBuffer; }
|
||||
}
|
||||
|
||||
public Stream GetWriteStream(long size)
|
||||
{
|
||||
return m_writeStream ?? (m_writeStream = new ByteArrayStream(size));
|
||||
}
|
||||
|
||||
public TestDownloadItem(FileId fileId, FileType fileType)
|
||||
{
|
||||
Id = fileId;
|
||||
Type = fileType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b734b613791eb4b0381013f84745a995
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,460 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 012e8bc53e96d4c638db9f5b04ef84de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "UnityEditor.CacheServerTests",
|
||||
"references": [
|
||||
"UnityEditor.CacheServer"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: de0adf19d0a2a46a19acaa82fcb5a988
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace UnityEditor.CacheServerTests
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
public static class Paths
|
||||
{
|
||||
public static string Combine(params string[] components)
|
||||
{
|
||||
if (components.Length < 1)
|
||||
throw new ArgumentException("At least one component must be provided!");
|
||||
|
||||
var path1 = components[0];
|
||||
|
||||
for (var index = 1; index < components.Length; ++index)
|
||||
path1 = Path.Combine(path1, components[index]);
|
||||
|
||||
return path1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 493e67a6e86284a8681aab6f10d05c34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue