WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Tests/Editor/HostingServices/HttpHostingServiceTests.cs
2025-01-07 02:06:59 +01:00

387 lines
13 KiB
C#

using System;
using System.IO;
using System.Net;
using NUnit.Framework;
using UnityEditor.AddressableAssets.HostingServices;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;
using UnityEngine.TestTools;
namespace UnityEditor.AddressableAssets.Tests.HostingServices
{
using Random = System.Random;
public class HttpHostingServiceTests
{
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri uri)
{
var w = base.GetWebRequest(uri);
Debug.Assert(w != null);
w.Timeout = 2000;
return w;
}
}
HttpHostingService m_Service;
string m_ContentRoot;
readonly WebClient m_Client;
public HttpHostingServiceTests()
{
m_Client = new MyWebClient();
}
static byte[] GetRandomBytes(int size)
{
var rand = new Random();
var buf = new byte[size];
rand.NextBytes(buf);
return buf;
}
[OneTimeSetUp]
public void SetUp()
{
m_Service = new HttpHostingService();
var dirName = Path.GetRandomFileName();
m_ContentRoot = Path.Combine(Path.GetTempPath(), dirName);
Assert.IsNotEmpty(m_ContentRoot);
Directory.CreateDirectory(m_ContentRoot);
m_Service.HostingServiceContentRoots.Add(m_ContentRoot);
}
[TearDown]
public void Cleanup()
{
m_Service.StopHostingService();
}
[OneTimeTearDown]
public void TearDown()
{
if (!string.IsNullOrEmpty(m_ContentRoot) && Directory.Exists(m_ContentRoot))
Directory.Delete(m_ContentRoot, true);
}
[TestCase("subdir", "subdir1")] //"subdir3")]
[TestCase("subdír☠", "subdirãúñ", TestName = "ShouldServeFilesWSpecialCharacters")] //"subdirü",
public void ShouldServeRequestedFiles(string subdir1, string subdir2) // string subdir3)
{
var fileNames = new[]
{
Path.GetRandomFileName(),
Path.Combine(subdir1, Path.GetRandomFileName()),
Path.Combine(subdir2, Path.GetRandomFileName())
};
foreach (var fileName in fileNames)
{
var filePath = Path.Combine(m_ContentRoot, fileName);
var bytes = GetRandomBytes(1024);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllBytes(filePath, bytes);
m_Service.StartHostingService();
Assert.IsTrue(m_Service.IsHostingServiceRunning);
var url = string.Format("http://127.0.0.1:{0}/{1}", m_Service.HostingServicePort, fileName);
try
{
var data = m_Client.DownloadData(url);
Assert.AreEqual(data.Length, bytes.Length);
for (var i = 0; i < data.Length; i++)
if (bytes[i] != data[i])
Assert.Fail("Data does not match {0} != {1}", bytes[i], data[i]);
}
catch (Exception e)
{
Assert.Fail(e.Message);
}
}
}
private class MockHttpContext : HttpHostingService.IHttpContext
{
public Uri Url { get; set; }
public string ContentType { get; set; }
public long ContentLength { get; set; }
public Stream OutputStream { get; set; }
public Uri GetRequestUrl()
{
return Url;
}
public void SetResponseContentType(string contentType)
{
ContentType = contentType;
}
public void SetResponseContentLength(long contentLength)
{
ContentLength = contentLength;
}
public Stream GetResponseOutputStream()
{
return OutputStream;
}
}
[Test]
public void FileUploadOperationSplitsDownload()
{
string subdir1 = "subdir";
string subdir2 = "subdir1"; // Remove comment when Mono limit Fixed
string subdir3 = "subdir3";
var fileNames = new[]
{
Path.GetRandomFileName(),
Path.Combine(subdir1, Path.GetRandomFileName()),
Path.Combine(subdir2, Path.Combine(subdir3, Path.GetRandomFileName())),
Path.Combine(subdir3, Path.GetRandomFileName()),
};
foreach (var fileName in fileNames)
{
var filePath = Path.Combine(m_ContentRoot, fileName);
var bytes = GetRandomBytes(1024);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllBytes(filePath, bytes);
// we execute every 250ms so you can divide upload speed by 4
// to see how much each update will process
var uploadSpeed = 2048;
var cleanupCalled = false;
Action cleanup = () => { cleanupCalled = true; };
var context = new MockHttpContext();
using (MemoryStream outputStream = new MemoryStream(1024))
{
context.OutputStream = outputStream;
context.Url = new Uri("http://127.0.0.1:55555");
var op = new HttpHostingService.FileUploadOperation(context, filePath, uploadSpeed, cleanup);
op.Update(null);
Assert.AreEqual(512, context.OutputStream.Length);
op.Update(null);
}
Assert.AreEqual(1024, context.ContentLength);
Assert.AreEqual("application/octet-stream", context.ContentType);
Assert.IsTrue(cleanupCalled);
}
}
[Test]
public void FileUploadOperationCallsCleanupOnError()
{
string subdir1 = "subdir";
var fileName = Path.Combine(subdir1, Path.GetRandomFileName());
var filePath = Path.Combine(m_ContentRoot, fileName);
// we intentionally do not initialize a test file
var uploadSpeed = 2048;
var exceptionThrown = false;
var cleanupCalled = false;
Action cleanup = () => { cleanupCalled = true; };
var context = new MockHttpContext();
try
{
var _ = new HttpHostingService.FileUploadOperation(context, filePath, uploadSpeed, cleanup);
}
catch (Exception e)
{
exceptionThrown = true;
}
LogAssert.Expect(LogType.Exception, $"DirectoryNotFoundException: Could not find a part of the path \"{filePath}\".");
Assert.IsTrue(cleanupCalled);
Assert.IsTrue(exceptionThrown);
}
[Test]
public void FileUploadOperationHandlesError()
{
var fileName = Path.GetRandomFileName();
var filePath = Path.Combine(m_ContentRoot, fileName);
var bytes = GetRandomBytes(1024);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllBytes(filePath, bytes);
// we execute every 250ms so you can divide upload speed by 4
// to see how much each update will process
var uploadSpeed = 2048;
var cleanupCalled = false;
var exceptionCaught = false;
Action cleanup = () => { cleanupCalled = true; };
var context = new MockHttpContext();
using (MemoryStream outputStream = new MemoryStream(1024))
{
try
{
context.OutputStream = outputStream;
// close the output stream to trigger an exception on writes
outputStream.Close();
context.Url = new Uri("http://127.0.0.1:55555");
var op = new HttpHostingService.FileUploadOperation(context, filePath, uploadSpeed, cleanup);
op.Update(null);
}
catch (Exception e)
{
exceptionCaught = true;
}
}
Assert.IsTrue(cleanupCalled);
Assert.IsTrue(exceptionCaught);
}
[Test]
public void HttpServiceCompletesWithUploadSpeedWhenExpected()
{
string subdir1 = "subdir";
string subdir2 = "subdir1";
string subdir3 = "subdir3";
var fileNames = new[]
{
Path.GetRandomFileName(),
Path.Combine(subdir1, Path.GetRandomFileName()),
Path.Combine(subdir2, Path.Combine(subdir3, Path.GetRandomFileName())),
Path.Combine(subdir3, Path.GetRandomFileName()),
};
m_Service.StartHostingService();
try
{
foreach (var fileName in fileNames)
{
var filePath = Path.Combine(m_ContentRoot, fileName);
var bytes = GetRandomBytes(1024);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllBytes(filePath, bytes);
m_Service.UploadSpeed = 2048;
Assert.IsTrue(m_Service.IsHostingServiceRunning);
var url = string.Format("http://127.0.0.1:{0}/{1}", m_Service.HostingServicePort, fileName);
try
{
var downloadedBytes = m_Client.DownloadData(new Uri(url));
Assert.AreEqual(1024, downloadedBytes.Length);
}
catch (Exception e)
{
Assert.Fail(e.Message);
}
}
}
finally
{
m_Service.StopHostingService();
}
}
[Test]
public void ShouldRespondWithStatus404IfFileDoesNotExist()
{
m_Service.StartHostingService();
Assert.IsTrue(m_Service.IsHostingServiceRunning);
var url = string.Format("http://127.0.0.1:{0}/{1}", m_Service.HostingServicePort, "foo");
try
{
m_Client.DownloadData(url);
}
catch (WebException e)
{
var response = (HttpWebResponse)e.Response;
Assert.AreEqual(response.StatusCode, HttpStatusCode.NotFound);
}
catch (Exception)
{
Assert.Fail();
}
}
// StartHostingService
[Test]
public void StartHostingServiceShould_AssignPortIfUnassigned()
{
m_Service.StartHostingService();
Assert.Greater(m_Service.HostingServicePort, 0);
}
// OnBeforeSerialize
[Test]
public void OnBeforeSerializeShould_PersistExpectedDataToKeyDataStore()
{
m_Service.StartHostingService();
var port = m_Service.HostingServicePort;
var data = new KeyDataStore();
m_Service.OnBeforeSerialize(data);
Assert.AreEqual(port, data.GetData("HostingServicePort", 0));
}
[Test]
public void OnBeforeSerializeShould_WasEnableCorrectToKeyDataStore()
{
m_Service.StartHostingService();
var data = new KeyDataStore();
m_Service.OnDisable();
m_Service.OnBeforeSerialize(data);
Assert.IsTrue(data.GetData("IsEnabled", false), "Hosting server was started before shutting down. IsEnabled expected to be true");
}
// OnAfterDeserialize
[Test]
public void OnAfterDeserializeShould_RestoreExpectedDataFromKeyDataStore()
{
var data = new KeyDataStore();
data.SetData("HostingServicePort", 1234);
m_Service.OnAfterDeserialize(data);
Assert.AreEqual(1234, m_Service.HostingServicePort);
}
// ResetListenPort
[Test]
public void ResetListenPortShould_AssignTheGivenPort()
{
m_Service.ResetListenPort(1234);
Assert.AreEqual(1234, m_Service.HostingServicePort);
}
[Test]
public void ResetListenPortShould_AssignRandomPortIfZero()
{
var oldPort = m_Service.HostingServicePort;
m_Service.ResetListenPort();
m_Service.StartHostingService();
Assert.Greater(m_Service.HostingServicePort, 0);
Assert.AreNotEqual(m_Service.HostingServicePort, oldPort);
}
[Test]
public void ResetListenPortShouldNot_StartServiceIfItIsNotRunning()
{
m_Service.StopHostingService();
m_Service.ResetListenPort();
Assert.IsFalse(m_Service.IsHostingServiceRunning);
}
[Test]
public void ResetListenPortShould_RestartServiceIfRunning()
{
m_Service.StartHostingService();
m_Service.ResetListenPort();
Assert.IsTrue(m_Service.IsHostingServiceRunning);
}
}
}