diff --git a/src/TraceClient/TraceClient.cs b/src/TraceClient/TraceClient.cs
index ef2ef79..56211e1 100644
--- a/src/TraceClient/TraceClient.cs
+++ b/src/TraceClient/TraceClient.cs
@@ -370,7 +370,9 @@ private static bool IsYes(string value)
/// Reports that happened, with an optional numeric
/// value and optional string tags. Returns immediately and never throws.
/// The program's version is added as the tag version unless
- /// already has one; itself is
+ /// already has one, and so is , if
+ /// any, as the tag install, unless has one or it
+ /// would pass ; itself is
/// never modified. A report the server would reject for its size -- more than
/// tags, or a string longer than --
/// is dropped here instead of being sent.
diff --git a/tests/TraceClient.Tests/InstallIdTest.cs b/tests/TraceClient.Tests/InstallIdTest.cs
index 06a92a0..acc885e 100644
--- a/tests/TraceClient.Tests/InstallIdTest.cs
+++ b/tests/TraceClient.Tests/InstallIdTest.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -157,6 +158,45 @@ public void Client_WithAnUnwritableFileStillReportsWithAnInMemoryId()
Assert.Contains(log, m => m.Contains("in-memory install ID"));
}
+ [Fact]
+ public void Client_WithAnUnreadableFileLogsWhyAndLeavesItAlone()
+ {
+ // A directory where the file should be: unreadable as a file on every OS.
+ string path = Path.Combine(_directory, "install-id");
+ Directory.CreateDirectory(path);
+ var log = new ConcurrentQueue();
+
+ var client = new TraceClient(_server.BaseUrl, "MyGame", "1.2.3", key: "k", log: log.Enqueue,
+ installIdFile: path);
+ client.Report("startup");
+ client.Close();
+
+ Assert.True(IsGuid(client.InstallId), client.InstallId);
+ Assert.True(Directory.Exists(path));
+ // The prefix is doubled today (#21); this pins it until that is fixed.
+ Assert.Contains(log, m => m.StartsWith("[trace] [trace] using an in-memory install ID for this process: could not read " + path + ": "));
+ Assert.DoesNotContain(log, m => m.Contains("could not write"));
+ Assert.Contains("\"install\":\"" + client.InstallId + "\"", _server.Received.Single().Body);
+ }
+
+ [Fact]
+ public void Client_WhoseIdFileFailsStillConstructsWhenTheLoggerThrows()
+ {
+ string path = Path.Combine(_directory, "install-id");
+ Directory.CreateDirectory(path);
+ int calls = 0;
+
+ var client = new TraceClient(_server.BaseUrl, "MyGame", "1.2.3", key: "k",
+ log: m => { Interlocked.Increment(ref calls); throw new InvalidOperationException("logger broke"); },
+ installIdFile: path);
+ client.Report("startup");
+ client.Close();
+
+ Assert.True(calls > 0); // the failure was offered to the logger
+ Assert.True(IsGuid(client.InstallId), client.InstallId);
+ Assert.Contains("\"install\":\"" + client.InstallId + "\"", _server.Received.Single().Body);
+ }
+
[Fact]
public void DisabledClient_NeverMakesUpOrWritesAnId()
{