RPC远程过程调用,二进制封装,提供高吞吐低延迟的高性能RPC框架
大石头 authored at 2022-08-10 13:26:19
2.40 KiB
NewLife.Remoting
using System.Reflection;
using System.Text.Json;

namespace MobileSmoke;

/// <summary>移动端冒烟:验证主库在 Android/iOS 上可加载并执行核心 API</summary>
public static class Smoke
{
    /// <summary>执行全部检查</summary>
    /// <returns>通过数、失败数与结果文件路径</returns>
    public static (Int32 Pass, Int32 Fail, String Path) Run()
    {
        var log = new List<String>();
        var pass = 0;
        var fail = 0;

        void Check(String name, Action action)
        {
            try
            {
                action();
                log.Add($"OK {name}");
                pass++;
            }
            catch (Exception ex)
            {
                log.Add($"FAIL {name}: {ex.GetType().Name}: {ex.Message}");
                fail++;
            }
        }

        var asm = typeof(NewLife.Remoting.ApiClient).Assembly;
        Check("assembly:" + asm.GetName().Name, () =>
        {
            if (CountTypes(asm) == 0) throw new Exception("no exported types");
        });
        Check("ApiClient ctor", () => { using var client = new NewLife.Remoting.ApiClient("http://127.0.0.1:5000"); });
        var json = JsonSerializer.Serialize(new
        {
            pass,
            fail,
            arch = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString(),
            os = System.Runtime.InteropServices.RuntimeInformation.OSDescription,
            log,
        });

        // 结果文件写入失败不应吞掉冒烟结论;记录失败原因后照常返回,Android 仍可通过 logcat 判定
        var file = String.Empty;
        try
        {
            var dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            if (String.IsNullOrEmpty(dir)) dir = System.IO.Path.GetTempPath();
            Directory.CreateDirectory(dir);
            file = System.IO.Path.Combine(dir, "smoke.json");
            File.WriteAllText(file, json);
        }
        catch (Exception ex)
        {
            log.Add($"FAIL write smoke.json: {ex.GetType().Name}: {ex.Message}");
            fail++;
        }

        return (pass, fail, file);
    }

    private static Int32 CountTypes(Assembly asm)
    {
        try
        {
            return asm.GetExportedTypes().Length;
        }
        catch (ReflectionTypeLoadException ex)
        {
            return ex.Types.Count(e => e != null);
        }
    }
}