Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/TraceClient/TraceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public sealed class TraceClient : IDisposable
/// <summary>The most tags the server accepts on one report.</summary>
public const int MaxTags = 32;

/// <summary>The longest application, name, tag key or tag value the server accepts, in UTF-16 chars.</summary>
/// <summary>The longest application, name, tag key or tag value the server accepts, in UTF-16 chars.
/// The program's version and installation ID are tag values too, so the constructor rejects either past it.</summary>
public const int MaxLength = 255;

/// <summary>Environment variable that turns reporting off: <c>off</c>, <c>false</c>, <c>0</c>, <c>no</c>.</summary>
Expand Down Expand Up @@ -122,9 +123,10 @@ public sealed class TraceClient : IDisposable
/// <paramref name="version"/>, reporting to the trace server at
/// <paramref name="baseUrl"/>. Throws <see cref="ArgumentException"/> only for a
/// missing or malformed <paramref name="baseUrl"/>, a missing
/// <paramref name="application"/>, or a missing <paramref name="version"/> or
/// one longer than <see cref="MaxLength"/> characters -- programming errors,
/// not runtime ones.
/// <paramref name="application"/>, a missing <paramref name="version"/> or
/// one longer than <see cref="MaxLength"/> characters, or an
/// <paramref name="installId"/> longer than <see cref="MaxLength"/> characters --
/// programming errors, not runtime ones.
/// </summary>
/// <param name="baseUrl">The trace server, e.g. <c>https://trace.danielstephenson.dev</c>.</param>
/// <param name="application">The program's name, exactly as its key was issued for.</param>
Expand Down
32 changes: 32 additions & 0 deletions tests/TraceClient.Tests/TraceClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,38 @@ public void Json_RejectsATagKeyLongerThanTheLimitAndNamesOnlyItsStart()
Assert.Null(body);
}

[Fact]
public void Json_RejectsANameLongerThanTheLimitButNotOneAtIt()
{
string longest = new string('n', TraceClient.MaxLength);
string tooLong = new string('n', TraceClient.MaxLength + 1);

string problem = TraceClient.Json("App", tooLong, null, null, out string rejected);

Assert.Equal("name longer than " + TraceClient.MaxLength + " characters", problem);
Assert.Null(rejected);
Assert.Null(TraceClient.Json("App", longest, null, null, out string accepted));
Assert.Contains(longest, accepted);
}

[Fact]
public void Json_RejectsATagValueLongerThanTheLimitAndNamesItsKey()
{
// The reason names the key, not the value: the value is what ran
// away, and the key is what the program can find in its source.
string tooLongValue = new string('v', TraceClient.MaxLength + 1);
string longestValue = new string('v', TraceClient.MaxLength);

string problem = TraceClient.Json("App", "n", null,
new Dictionary<string, string> { { "level", tooLongValue } }, out string body);

Assert.Equal("tag level longer than " + TraceClient.MaxLength + " characters", problem);
Assert.Null(body);
Assert.Null(TraceClient.Json("App", "n", null,
new Dictionary<string, string> { { "level", longestValue } }, out string accepted));
Assert.Contains("\"level\":\"" + longestValue + "\"", accepted);
}

[Fact]
public void Quote_EscapesCarriageReturnAndEveryOtherControlCharacter()
{
Expand Down
Loading