using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;
using Dpz.Core.Infrastructure;
using Dpz.Core.Shard.Service;
using NUnit.Framework;

namespace Dpz.Core.Server.ObjectStorage.Test;

[TestFixture]
public class ObjectStorageServiceTest : Basic
{
    [Test]
    public async Task SaveAsTest()
    {
        //await service.SaveAsAsync(Uri.EscapeDataString("屏幕截图 2021-11-22 235505.png"), @"D:\ImageTemp\download\1.png");
        await ObjectStorageService.SaveAsAsync(
            "屏幕截图 2021-11-22 235505.png",
            @"D:\ImageTemp\download\1.png"
        );
    }

    [Test]
    [TestCase(@"C:\Users\pengq\Pictures\111.jpg", "111.jpg")]
    public async Task UploadTest(string uploadFilePath, string filename)
    {
        await using var stream = new FileStream(uploadFilePath, FileMode.Open, FileAccess.Read);
        var result = await ObjectStorageService.UploadAsync(
            stream,
            new[] { "Test", "Images" },
            filename
        );

        Assert.That(result, Is.Not.Null);

        Console.WriteLine(JsonSerializer.Serialize(result));
    }

    [Test]
    [TestCase("to-720p.ps1")]
    public async Task DeleteTest(string fileToPath)
    {
        await ObjectStorageService.DeleteAsync(fileToPath);
    }

    [Test]
    public void OutputGmt()
    {
        var uri = new Uri(
            "https://core.dpangzi.com/Home/Image/607369632830f164fbfcc745.webp?width=1170&height=658&cache=True"
        );
        Console.WriteLine(Path.GetExtension(uri.AbsolutePath));
        var s = Uri.EscapeDataString("屏幕截图 2021-11-22 235505.png");
        Console.WriteLine(s);
        Console.WriteLine(DateTime.Now.ToUniversalTime().ToString("R"));
        Console.WriteLine(Configuration.GetSection("upyun")["Host"]);
    }

    [Test]
    [TestCase("/")]
    public async Task GetFolderInfoTest(string path)
    {
        var list = await ObjectStorageService.GetFolderListAsync(path);
        Assert.That(list.Count, Is.GreaterThan(0));

        foreach (var item in list)
        {
            Console.WriteLine(
                $"文件名:{item.Name}\t文件大小:{item.Size}\t类型:{item.FileType}\t修改时间:{item.LastUpdateTime.ToLocalTime()}"
            );
        }
    }

    [Test]
    [TestCase(@"F:\TestData\Apifox-windows-latest.zip")]
    public async Task UploadAsyncTest(string filepath)
    {
        await using var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
        var filename = Path.GetFileName(stream.Name);
        var cloudFile = new CloudFile(stream, new[] { "Test", "Files", filename });
        var result = await ObjectStorageService.UploadFileAsync(cloudFile);

        Assert.That(result, Is.Not.Null);
        Assert.That(result!.Value.Url, Is.Not.Empty);

        Console.WriteLine(result);
    }

    [Test]
    public async Task UploadAsyncTest2()
    {
        await using var stream = ApplicationTools.MemoryStreamManager.GetStream();
        var bytes = "测试;test\r\nthis is test file."u8.ToArray();
        await stream.WriteAsync(bytes, 0, bytes.Length);
        stream.Position = 0;
        var cloudFile = new CloudFile(stream, new[] { "Test", "Files", "test1.txt" });
        var result = await ObjectStorageService.UploadFileAsync(cloudFile);

        Assert.That(result, Is.Not.Null);

        Console.WriteLine(ToJson(result!.Value));
    }

    [Test]
    [TestCase(@"C:\Users\pengq\Downloads\OnboardMemoryManager_2.1.7479.exe")]
    public async Task Md5Test(string filePath)
    {
        var stopwatch = Stopwatch.StartNew();
        await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        await using var stream = ApplicationTools.MemoryStreamManager.GetStream();
        await fileStream.CopyToAsync(stream);
        stream.Position = 0;
        using var md5 = MD5.Create();
        var hashBytes = await md5.ComputeHashAsync(stream);
        var md5Value = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
        stopwatch.Stop();

        Assert.That(md5Value, Is.Not.Null.Or.Empty);

        Console.WriteLine(md5Value);
        Console.WriteLine($"{stopwatch.Elapsed:c}");
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个使用 NUnit 编写的单元/集成测试类(ObjectStorageServiceTest),用于测试项目中与“对象存储服务”(ObjectStorageService)相关的各种操作。总体上它演示并验证了上传、下载(或保存为本地文件)、删除、列目录、以及计算文件 MD5 等功能。下面按方法逐个解释:

类和依赖

  • 类名:ObjectStorageServiceTest,标记为 [TestFixture],继承自 Basic(项目中一个基类,可能提供配置/公共工具)。
  • 引用了 Dpz.Core.Infrastructure、Dpz.Core.Shard.Service 等项目内部库,表明 ObjectStorageService、ApplicationTools、CloudFile 等是项目自定义的服务/工具。
  • 使用 NUnit 特性 [Test]、[TestCase] 定义测试用例;大量方法是异步 Task。

各测试方法说明

  1. SaveAsTest
  • 调用 ObjectStorageService.SaveAsAsync(string objectName, string localPath)。
  • 作用:将对象存储中的名为 "屏幕截图 2021-11-22 235505.png" 的文件保存到本地路径 @"D:\ImageTemp\download\1.png"。
  • 注释掉的一行展示了对文件名先进行 Uri.EscapeDataString 的变换(对中文及空格做 URL 编码)。
  • 这是一个对“从云端下载并保存为本地文件”功能的测试。
  1. UploadTest(string uploadFilePath, string filename)
  • 通过 FileStream 打开本地文件(TestCase 示例:C:\Users\pengq\Pictures\111.jpg)。
  • 调用 ObjectStorageService.UploadAsync(Stream stream, string[] pathSegments, string filename) 将流上传到对象存储,路径分片为 new[] { "Test", "Images" }。
  • 断言返回结果不为 null,并把结果序列化为 JSON 输出到控制台。
  • 验证上传接口返回值及基本正确性。
  1. DeleteTest(string fileToPath)
  • 调用 ObjectStorageService.DeleteAsync(fileToPath) 删除对象存储中的文件(TestCase 示例: "to-720p.ps1")。
  • 作用:测试删除接口能否成功执行(无断言只是调用,若抛异常则测试失败)。
  1. OutputGmt
  • 不是对服务的调用,更多是一些工具/行为的演示:
    • 解析一个 URL,输出 Path.GetExtension(uri.AbsolutePath)(文件扩展名)。
    • 对文件名做 Uri.EscapeDataString 的输出(URL 编码示例)。
    • 输出当前时间的 GMT/RFC1123 格式:DateTime.Now.ToUniversalTime().ToString("R")。
    • 从配置中读取 Configuration.GetSection("upyun")["Host"] 并输出(演示读取配置项)。
  • 用于辅助检查和调试编码/时间/配置相关行为。
  1. GetFolderInfoTest(string path)
  • 调用 ObjectStorageService.GetFolderListAsync(path)(TestCase 示例 "/"),获取目录列表。
  • 断言返回列表 Count > 0。
  • 遍历并输出每个条目的信息:Name, Size, FileType, LastUpdateTime(转换为本地时间)。
  • 作用:测试列出某个路径下文件/文件夹信息的能力及返回数据内容。
  1. UploadAsyncTest(string filepath)
  • 打开本地大文件(示例 F:\TestData\Apifox-windows-latest.zip)。
  • 使用 CloudFile 类包装流和目标路径(new[] { "Test", "Files", filename })。
  • 调用 ObjectStorageService.UploadFileAsync(cloudFile) 上传。
  • 断言结果不为 null,并且 result.Value.Url 不为空(即上传后能拿到文件 URL)。
  • 打印结果到控制台。
  • 作用:测试基于 CloudFile 的上传流程(通常是更完整的元数据/路径封装)。
  1. UploadAsyncTest2()
  • 从 ApplicationTools.MemoryStreamManager.GetStream() 获取内存流(可能是可重用的内存池实现)。
  • 将一些字节写入(示例内容包含中文和英文),重设 Position = 0。
  • 将流包装为 CloudFile 并调用 UploadFileAsync 上传。
  • 断言返回非空并打印 JSON(ToJson(result.Value))。
  • 作用:测试内存流上传、文本内容上传路径封装与返回值序列化。
  1. Md5Test(string filePath)
  • 使用 Stopwatch 测量时间。
  • 打开本地文件,拷贝到内存流(MemoryStreamManager.GetStream),将 Position 设为 0。
  • 使用 System.Security.Cryptography.MD5.Create() 计算内存流的 MD5 异步哈希(ComputeHashAsync)。
  • 将哈希字节转为小写十六进制字符串 md5Value 并断言非空。
  • 输出 md5 值和耗时。
  • 作用:验证对文件计算 MD5 的实现及性能测量。

通用特征与注意事项

  • 大量方法使用 async/await 和 await using,确保流正确释放。
  • 测试依赖外部资源:本地路径文件、对象存储服务(可能是 Upyun 或其他),以及 Configuration 中的配置信息(例如 "upyun" 节点)。在缺乏正确配置或网络权限时,这些测试会失败或抛异常——所以这些更像集成测试而非纯单元测试。
  • CloudFile、ApplicationTools.MemoryStreamManager、ObjectStorageService、ToJson 等是项目自定义工具/服务,具体行为取决于项目实现。
  • 输出(Console.WriteLine)用于在测试运行时观察返回数据、调试信息和时间等。

总结

  • 这个测试类覆盖了对象存储的典型操作:上传(流、大文件、内存流)、下载保存到本地、删除、列目录与文件元信息、以及文件完整性(MD5)计算与性能测量。测试通过断言和控制台输出验证或展示操作结果。
评论加载中...