105 lines
3.9 KiB
C#
105 lines
3.9 KiB
C#
using Microsoft.Extensions.Logging.Abstractions;
|
|||
|
|
|
||
|
|
using PrivaPub.Infrastructure.Statistics;
|
||
|
|
using PrivaPub.Models.Statistics;
|
||
|
|
using PrivaPub.Tests.Support;
|
||
|
|
|
||
|
|
namespace PrivaPub.Tests.Statistics
|
||
|
|
{
|
||
|
|
public class InteractionsTests
|
||
|
|
{
|
||
|
|
[Fact]
|
||
|
|
public void The_local_kind_is_kept_only_on_public_and_unlisted_traffic()
|
||
|
|
{
|
||
|
|
Assert.Equal("person", Interactions.Sanitize(new InteractionEvent { Audience = "public", LocalKind = "person" }).LocalKind);
|
||
|
|
Assert.Equal("group", Interactions.Sanitize(new InteractionEvent { Audience = "unlisted", LocalKind = "group" }).LocalKind);
|
||
|
|
Assert.Null(Interactions.Sanitize(new InteractionEvent { Audience = "private", LocalKind = "group" }).LocalKind);
|
||
|
|
Assert.Null(Interactions.Sanitize(new InteractionEvent { Audience = "none", LocalKind = "person" }).LocalKind);
|
||
|
|
Assert.Null(Interactions.Sanitize(new InteractionEvent { LocalKind = "person" }).LocalKind);
|
||
|
|
Assert.Null(Interactions.Sanitize(new InteractionEvent { Audience = "public", LocalKind = "circle" }).LocalKind);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Junk_becomes_other_and_hosts_are_normalised()
|
||
|
|
{
|
||
|
|
var e = Interactions.Sanitize(new InteractionEvent
|
||
|
|
{
|
||
|
|
Host = "Mastodon.Social.",
|
||
|
|
Channel = "sideways",
|
||
|
|
Activity = "https://www.w3.org/ns/activitystreams#Create",
|
||
|
|
Object = "Note",
|
||
|
|
Outcome = "Dropped!",
|
||
|
|
Reason = "not-addressed",
|
||
|
|
Audience = "everyone",
|
||
|
|
Inbox = "front-door",
|
||
|
|
Signature = "cavage:rsa-sha256",
|
||
|
|
Features = new() { "fep-044f", "Bad Feature", "fep-044f" }
|
||
|
|
});
|
||
|
|
|
||
|
|
Assert.Equal("mastodon.social", e.Host);
|
||
|
|
Assert.Equal("other", e.Channel);
|
||
|
|
Assert.Equal("other", e.Activity);
|
||
|
|
Assert.Equal("Note", e.Object);
|
||
|
|
Assert.Equal("other", e.Outcome);
|
||
|
|
Assert.Equal("not-addressed", e.Reason);
|
||
|
|
Assert.Null(e.Audience);
|
||
|
|
Assert.Null(e.Inbox);
|
||
|
|
Assert.Equal("cavage:rsa-sha256", e.Signature);
|
||
|
|
Assert.Equal(new[] { "fep-044f", "other" }, e.Features);
|
||
|
|
Assert.Equal("-", Interactions.Host("evil host/with path"));
|
||
|
|
Assert.Equal("-", Interactions.Host(default));
|
||
|
|
Assert.Equal("social.example", Interactions.HostOf("https://Social.Example:8443/users/x"));
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Latencies_and_waits_fall_into_buckets()
|
||
|
|
{
|
||
|
|
Assert.Equal("le50ms", Interactions.Latency(0));
|
||
|
|
Assert.Equal("le250ms", Interactions.Latency(101));
|
||
|
|
Assert.Equal("inf", Interactions.Latency(31_000));
|
||
|
|
Assert.Equal("le1s", Interactions.Wait(900));
|
||
|
|
Assert.Equal("le60s", Interactions.Wait(59_000));
|
||
|
|
Assert.Equal("inf", Interactions.Wait(100_000_000));
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void An_actor_hash_is_stable_for_a_salt_and_unlinkable_across_salts()
|
||
|
|
{
|
||
|
|
var monday = new byte[32];
|
||
|
|
var tuesday = Enumerable.Repeat((byte)1, 32).ToArray();
|
||
|
|
const string actor = "https://social.example/users/alice";
|
||
|
|
|
||
|
|
var first = InteractionSalts.Hash(monday, actor);
|
||
|
|
|
||
|
|
Assert.Equal(first, InteractionSalts.Hash(monday, actor));
|
||
|
|
Assert.NotEqual(first, InteractionSalts.Hash(tuesday, actor));
|
||
|
|
Assert.NotEqual(first, InteractionSalts.Hash(monday, actor + "2"));
|
||
|
|
Assert.Equal(16, first.Length);
|
||
|
|
Assert.DoesNotContain("alice", first);
|
||
|
|
Assert.Null(InteractionSalts.Hash(default, actor));
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void A_full_ledger_drops_and_counts_but_never_blocks_or_throws()
|
||
|
|
{
|
||
|
|
var ledger = new InteractionLedger(new InteractionSalts(), new StaticOptions<StatisticsOptions>(new StatisticsOptions()), NullLogger<InteractionLedger>.Instance);
|
||
|
|
|
||
|
|
for (var i = 0; i < 10_005; i++)
|
||
|
|
ledger.Record(new InteractionEvent { Channel = Interactions.In });
|
||
|
|
ledger.Record(default);
|
||
|
|
|
||
|
|
Assert.Equal(5, ledger.Dropped);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void A_disabled_ledger_records_nothing()
|
||
|
|
{
|
||
|
|
var ledger = new InteractionLedger(new InteractionSalts(), new StaticOptions<StatisticsOptions>(new StatisticsOptions { Enabled = false }), NullLogger<InteractionLedger>.Instance);
|
||
|
|
|
||
|
|
for (var i = 0; i < 10_005; i++)
|
||
|
|
ledger.Record(new InteractionEvent { Channel = Interactions.In });
|
||
|
|
|
||
|
|
Assert.Equal(0, ledger.Dropped);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|