Skip to content

Commit 1790779

Browse files
author
Lessley Dennington
committed
trace2: add sid
A key component of Git's TRACE2 tracing system is the session id (sid). This identifies the process instance to allow all events emitted by it to be identified. We check to see if a parent sid (i.e. from a Git process) exists. If so, we separate this sid from the GCM sid (a GUID) using a "/". If there is no parent sid, we simply generate a GUID for the GCM sid and use that. The above also requires addition of a new SetEnvironmentVariable() method in EnvironmentBase.cs to set the GCM-specific SID variable.
1 parent f6736ac commit 1790779

File tree

7 files changed

+118
-8
lines changed

7 files changed

+118
-8
lines changed

src/shared/Core.Tests/EnvironmentTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,37 @@ public void MacOSEnvironment_TryLocateExecutable_Paths_Are_Ignored()
150150
Assert.True(actualResult);
151151
Assert.Equal(expectedPath, actualPath);
152152
}
153+
154+
[PlatformFact(Platforms.Posix)]
155+
public void PosixEnvironment_SetEnvironmentVariable_Sets_Expected_Value()
156+
{
157+
var variable = "FOO_BAR";
158+
var value = "baz";
159+
160+
var fs = new TestFileSystem();
161+
var envars = new Dictionary<string, string>();
162+
var env = new PosixEnvironment(fs, envars);
163+
164+
env.SetEnvironmentVariable(variable, value);
165+
166+
Assert.Contains(env.Variables, item
167+
=> item.Key.Equals(variable) && item.Value.Equals(value));
168+
}
169+
170+
[PlatformFact(Platforms.Windows)]
171+
public void WindowsEnvironment_SetEnvironmentVariable_Sets_Expected_Value()
172+
{
173+
var variable = "FOO_BAR";
174+
var value = "baz";
175+
176+
var fs = new TestFileSystem();
177+
var envars = new Dictionary<string, string>();
178+
var env = new WindowsEnvironment(fs, envars);
179+
180+
env.SetEnvironmentVariable(variable, value);
181+
182+
Assert.Contains(env.Variables, item
183+
=> item.Key.Equals(variable) && item.Value.Equals(value));
184+
}
153185
}
154186
}

src/shared/Core.Tests/Trace2Tests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Text.RegularExpressions;
2+
using GitCredentialManager.Tests.Objects;
3+
using Xunit;
4+
5+
namespace GitCredentialManager.Tests;
6+
7+
public class Trace2Tests
8+
{
9+
[Theory]
10+
[InlineData("20190408T191610.507018Z-H9b68c35f-P000059a8")]
11+
[InlineData("")]
12+
public void SetSid_Envar_Returns_Expected_Value(string parentSid)
13+
{
14+
Regex rx = new Regex(@$"{parentSid}\/[\d\w-]*");
15+
16+
var environment = new TestEnvironment();
17+
environment.Variables.Add("GIT_TRACE2_PARENT_SID", parentSid);
18+
19+
var trace2 = new Trace2(environment);
20+
var sid = trace2.SetSid();
21+
22+
Assert.Matches(rx, sid);
23+
}
24+
}

src/shared/Core/EnvironmentBase.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ public interface IEnvironment
5656
/// <param name="workingDirectory">Working directory for the new process.</param>
5757
/// <returns><see cref="Process"/> object ready to start.</returns>
5858
Process CreateProcess(string path, string args, bool useShellExecute, string workingDirectory);
59+
60+
/// <summary>
61+
/// Set an environment variable at the specified target level.
62+
/// </summary>
63+
/// <param name="variable">Name of the environment variable to set.</param>
64+
/// <param name="value">Value of the environment variable to set.</param>
65+
/// <param name="target">Target level of environment variable to set (Machine, Process, or User).</param>
66+
void SetEnvironmentVariable(string variable, string value,
67+
EnvironmentVariableTarget target = EnvironmentVariableTarget.Process);
5968
}
6069

6170
public abstract class EnvironmentBase : IEnvironment
@@ -141,6 +150,16 @@ internal virtual bool TryLocateExecutable(string program, ICollection<string> pa
141150
path = null;
142151
return false;
143152
}
153+
154+
public void SetEnvironmentVariable(string variable, string value,
155+
EnvironmentVariableTarget target = EnvironmentVariableTarget.Process)
156+
{
157+
if (Variables.Keys.Contains(variable)) return;
158+
Environment.SetEnvironmentVariable(variable, value, target);
159+
Variables = GetCurrentVariables();
160+
}
161+
162+
protected abstract IReadOnlyDictionary<string, string> GetCurrentVariables();
144163
}
145164

146165
public static class EnvironmentExtensions

src/shared/Core/Interop/Posix/PosixEnvironment.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34

45
namespace GitCredentialManager.Interop.Posix
56
{
67
public class PosixEnvironment : EnvironmentBase
78
{
89
public PosixEnvironment(IFileSystem fileSystem)
9-
: this(fileSystem, GetCurrentVariables()) { }
10+
: this(fileSystem, null) { }
1011

1112
internal PosixEnvironment(IFileSystem fileSystem, IReadOnlyDictionary<string, string> variables)
1213
: base(fileSystem)
1314
{
14-
EnsureArgument.NotNull(variables, nameof(variables));
15-
Variables = variables;
15+
Variables = variables ?? GetCurrentVariables();
1616
}
1717

1818
#region EnvironmentBase
@@ -34,7 +34,7 @@ protected override string[] SplitPathVariable(string value)
3434

3535
#endregion
3636

37-
private static IReadOnlyDictionary<string, string> GetCurrentVariables()
37+
protected override IReadOnlyDictionary<string, string> GetCurrentVariables()
3838
{
3939
var dict = new Dictionary<string, string>();
4040
var variables = Environment.GetEnvironmentVariables();

src/shared/Core/Interop/Windows/WindowsEnvironment.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.IO;
5+
using System.Linq;
56
using System.Text;
67

78
namespace GitCredentialManager.Interop.Windows
89
{
910
public class WindowsEnvironment : EnvironmentBase
1011
{
1112
public WindowsEnvironment(IFileSystem fileSystem)
12-
: this(fileSystem, GetCurrentVariables()) { }
13+
: this(fileSystem, null) { }
1314

1415
internal WindowsEnvironment(IFileSystem fileSystem, IReadOnlyDictionary<string, string> variables)
1516
: base(fileSystem)
1617
{
17-
EnsureArgument.NotNull(variables, nameof(variables));
18-
Variables = variables;
18+
Variables = variables ?? GetCurrentVariables();
1919
}
2020

2121
#region EnvironmentBase
@@ -84,7 +84,7 @@ public override Process CreateProcess(string path, string args, bool useShellExe
8484

8585
#endregion
8686

87-
private static IReadOnlyDictionary<string, string> GetCurrentVariables()
87+
protected override IReadOnlyDictionary<string, string> GetCurrentVariables()
8888
{
8989
// On Windows it is technically possible to get env vars which differ only by case
9090
// even though the general assumption is that they are case insensitive on Windows.

src/shared/Core/Trace2.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ public class Trace2 : DisposableObject, ITrace2
2525
private readonly object _writersLock = new object();
2626
private List<ITrace2Writer> _writers = new List<ITrace2Writer>();
2727

28+
private const string GitSidVariable = "GIT_TRACE2_PARENT_SID";
29+
30+
private IEnvironment _environment;
31+
private string _sid;
32+
33+
public Trace2(IEnvironment environment)
34+
{
35+
_environment = environment;
36+
_sid = SetSid();
37+
}
38+
2839
protected override void ReleaseManagedResources()
2940
{
3041
lock (_writersLock)
@@ -62,6 +73,22 @@ private void AddWriter(ITrace2Writer writer)
6273
}
6374
}
6475

76+
internal string SetSid()
77+
{
78+
var sids = new List<string>();
79+
if (_environment.Variables.TryGetValue(GitSidVariable, out string parentSid))
80+
{
81+
sids.Add(parentSid);
82+
}
83+
84+
// Add GCM "child" sid
85+
sids.Add(Guid.NewGuid().ToString("D"));
86+
var combinedSid = string.Join("/", sids);
87+
88+
_environment.SetEnvironmentVariable(GitSidVariable, combinedSid);
89+
return combinedSid;
90+
}
91+
6592
private void WriteMessage(Trace2Message message)
6693
{
6794
ThrowIfDisposed();

src/shared/TestInfrastructure/Objects/TestEnvironment.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ public Process CreateProcess(string path, string args, bool useShellExecute, str
116116

117117
return new Process { StartInfo = psi };
118118
}
119+
120+
public void SetEnvironmentVariable(string variable, string value,
121+
EnvironmentVariableTarget target = EnvironmentVariableTarget.Process)
122+
{
123+
if (Variables.Keys.Contains(variable)) return;
124+
Environment.SetEnvironmentVariable(variable, value, target);
125+
Variables.Add(variable, value);
126+
}
119127

120128
#endregion
121129
}

0 commit comments

Comments
 (0)