Skip to content

Commit

Permalink
Merge branch 'master' into buffer-on-by-default
Browse files Browse the repository at this point in the history
  • Loading branch information
martincostello authored Oct 7, 2018
2 parents 686e51e + 8fc0465 commit 1ca8883
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 46 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,9 @@ addons:
- libssl-dev
- libunwind8

install:
- git clone https://github.com/etsy/statsd.git
- node ./statsd/stats.js ./src/JustEat.StatsD.Tests/statsdconfig.js &

script:
- ./build.sh
2 changes: 2 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ environment:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
NUGET_XMLDOC_MODE: skip
install:
- git clone https://github.com/etsy/statsd.git ..\statsd
- ps: Start-Process "node" -ArgumentList "..\statsd\stats.js .\src\JustEat.StatsD.Tests\statsdconfig.js" -WindowStyle Hidden
- ps: .\SetAppVeyorBuildVersion.ps1
build_script:
- ps: .\Build.ps1
Expand Down
5 changes: 3 additions & 2 deletions src/Benchmark/UdpStatSendingBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class UdpStatSendingBenchmark
private SocketTransport _transport;
private StringBasedStatsDPublisher _udpSender;
private BufferBasedStatsDPublisher _bufferBasedStatsDPublisher;
private IStatsDPublisher _adaptedStatsDPublisher;
private StatsDPublisher _adaptedStatsDPublisher;

[GlobalSetup]
public void Setup()
Expand Down Expand Up @@ -47,7 +47,8 @@ public void Setup()
[GlobalCleanup]
public void Cleanup()
{
_transport.Dispose();
_transport?.Dispose();
_adaptedStatsDPublisher?.Dispose();
}

[Benchmark]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Net;
using System.Net.Sockets;
using Shouldly;
using Xunit;

namespace JustEat.StatsD.EndpointLookups
{
public static class DnsLookupIpEndpointSourceTests
{
[Fact]
public static void GetEndpointPrefersIPV4WhenHostnameIsLocalhost()
{
// Arrange
var target = new DnsLookupIpEndpointSource("localhost", 8125);

// Act
IPEndPoint actual = target.GetEndpoint();

// Assert
actual.ShouldNotBeNull();
actual.AddressFamily.ShouldBe(AddressFamily.InterNetwork);
actual.Address.ShouldBe(IPAddress.Parse("127.0.0.1"));
actual.Port.ShouldBe(8125);
}
}
}
107 changes: 107 additions & 0 deletions src/JustEat.StatsD.Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Shouldly;
using Xunit;

namespace JustEat.StatsD
{
public static class IntegrationTests
{
[SkippableFact]
public static async Task Can_Send_Metrics_To_StatsD()
{
Skip.If(Environment.GetEnvironmentVariable("CI") == null, "By default, this test is only run during continuous integration.");

// Arrange
var config = new StatsDConfiguration
{
Host = "localhost",
Prefix = Guid.NewGuid().ToString().Replace("-", string.Empty)
};

using (var publisher = new StatsDPublisher(config))
{
// Act - Create a counter
publisher.Increment("apple");

// Act - Create and change a counter
publisher.Increment("bear"); // 1
publisher.Increment(10, "bear"); // 11
publisher.Increment(10, 0, "bear"); // 11
publisher.Decrement("bear"); // 10
publisher.Decrement(5, "bear"); // 5
publisher.Decrement(5, 0, "bear"); // 5

// Act - Mark an event (which is a counter)
publisher.MarkEvent("fish");

// Act - Create a gauge
publisher.Gauge(3.141, "circle");

// Act - Create and change a gauge
publisher.Gauge(10, "dog");
publisher.Gauge(42, "dog");

// Act - Create a timer
publisher.Timing(123, "elephant");
publisher.Timing(TimeSpan.FromSeconds(2), "fox");
publisher.Timing(456, 1, "goose");
publisher.Timing(TimeSpan.FromSeconds(3.5), 1, "hen");

// Act - Increment multiple counters
publisher.Increment(7, 1, "green", "red"); // 7
publisher.Increment(2, 0, "green", "red"); // 7
publisher.Decrement(1, 0, "red", "green"); // 7
publisher.Decrement(4, 1, "red", "green"); // 3

// Assert
var result = await SendCommandAsync("counters");
result.Value<int>(config.Prefix + ".apple").ShouldBe(1);
result.Value<int>(config.Prefix + ".bear").ShouldBe(5);
result.Value<int>(config.Prefix + ".fish").ShouldBe(1);
result.Value<int>(config.Prefix + ".green").ShouldBe(3);
result.Value<int>(config.Prefix + ".red").ShouldBe(3);

result = await SendCommandAsync("gauges");
result.Value<double>(config.Prefix + ".circle").ShouldBe(3.141);
result.Value<int>(config.Prefix + ".dog").ShouldBe(42);

result = await SendCommandAsync("timers");
result[config.Prefix + ".elephant"].Values<int>().ShouldBe(new[] { 123 });
result[config.Prefix + ".fox"].Values<int>().ShouldBe(new[] { 2000 });
result[config.Prefix + ".goose"].Values<int>().ShouldBe(new[] { 456 });
result[config.Prefix + ".hen"].Values<int>().ShouldBe(new[] { 3500 });
}
}

private static async Task<JObject> SendCommandAsync(string command)
{
string json;

using (var client = new TcpClient())
{
client.Connect("localhost", 8126);

byte[] input = Encoding.UTF8.GetBytes(command);
byte[] output = new byte[client.ReceiveBufferSize];

int bytesRead;

using (var stream = client.GetStream())
{
await stream.WriteAsync(input);
bytesRead = await stream.ReadAsync(output);
}

output = output.AsSpan(0, bytesRead).ToArray();

json = Encoding.UTF8.GetString(output).Replace("END", string.Empty);
}

return JObject.Parse(json);
}
}
}
1 change: 1 addition & 0 deletions src/JustEat.StatsD.Tests/JustEat.StatsD.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<PackageReference Include="Shouldly" Version="3.0.1" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Xunit.SkippableFact" Version="1.3.12" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
Expand Down
89 changes: 89 additions & 0 deletions src/JustEat.StatsD.Tests/StringBasedStatsDPublisherTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using Moq;
using Xunit;

namespace JustEat.StatsD
{
public static class StringBasedStatsDPublisherTests
{
[Fact]
public static void Decrement_Sends_Multiple_Metrics()
{
// Arrange
var mock = new Mock<IStatsDTransport>();

var config = new StatsDConfiguration
{
Prefix = "red",
};

var publisher = new StringBasedStatsDPublisher(config, mock.Object);

// Act
publisher.Decrement(10, 1, "white", "blue");

// Assert
mock.Verify((p) => p.Send("red.white:-10|c"), Times.Once());
mock.Verify((p) => p.Send("red.blue:-10|c"), Times.Once());
}

[Fact]
public static void Increment_Sends_Multiple_Metrics()
{
// Arrange
var mock = new Mock<IStatsDTransport>();

var config = new StatsDConfiguration
{
Prefix = "red",
};

var publisher = new StringBasedStatsDPublisher(config, mock.Object);

// Act
publisher.Increment(10, 1, "white", "blue");

// Assert
mock.Verify((p) => p.Send("red.white:10|c"), Times.Once());
mock.Verify((p) => p.Send("red.blue:10|c"), Times.Once());
}

[Fact]
public static void Metrics_Not_Sent_If_Array_Is_Null_Or_Empty()
{
// Arrange
var mock = new Mock<IStatsDTransport>();
var config = new StatsDConfiguration();

var publisher = new StringBasedStatsDPublisher(config, mock.Object);

// Act
publisher.Decrement(1, 1, null as string[]);
publisher.Increment(1, 1, null as string[]);
publisher.Decrement(1, 1, Array.Empty<string>());
publisher.Increment(1, 1, Array.Empty<string>());
publisher.Decrement(1, 1, new[] { string.Empty });
publisher.Increment(1, 1, new[] { string.Empty });

// Assert
mock.Verify((p) => p.Send(It.IsAny<string>()), Times.Never());
}

[Fact]
public static void Metrics_Not_Sent_If_No_Metrics()
{
// Arrange
var mock = new Mock<IStatsDTransport>();
var config = new StatsDConfiguration();

var publisher = new StringBasedStatsDPublisher(config, mock.Object);

// Act
publisher.Decrement(1, 0, new[] { "foo" });
publisher.Increment(1, 0, new[] { "bar" });

// Assert
mock.Verify((p) => p.Send(It.IsAny<string>()), Times.Never());
}
}
}
22 changes: 12 additions & 10 deletions src/JustEat.StatsD.Tests/WhenCreatingStatsDPublisher.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using JustEat.StatsD.Buffered;
using Moq;
using Shouldly;
using Xunit;
Expand Down Expand Up @@ -82,9 +81,10 @@ public void BufferBasedTransportShouldBeChosenIfAvailableAndAskedFor()

var transport = new BothVersionsTransportMock();

var publisher = new StatsDPublisher(config, transport);

publisher.MarkEvent("test");
using (var publisher = new StatsDPublisher(config, transport))
{
publisher.MarkEvent("test");
}

transport.BufferedCalls.ShouldBe(1);
transport.StringCalls.ShouldBe(0);
Expand All @@ -101,9 +101,10 @@ public void BufferBasedTransportShouldBeChosenByDefault()

var transport = new BothVersionsTransportMock();

var publisher = new StatsDPublisher(config, transport);

publisher.MarkEvent("test");
using (var publisher = new StatsDPublisher(config, transport))
{
publisher.MarkEvent("test");
}

transport.BufferedCalls.ShouldBe(1);
transport.StringCalls.ShouldBe(0);
Expand All @@ -120,9 +121,10 @@ public void StringBasedTransportShouldBeUsedIfBufferedIsNotAvailable()

var transport = new Mock<IStatsDTransport>(MockBehavior.Loose);

var publisher = new StatsDPublisher(config, transport.Object);

publisher.MarkEvent("test");
using (var publisher = new StatsDPublisher(config, transport.Object))
{
publisher.MarkEvent("test");
}

transport.Verify(x => x.Send(It.IsAny<string>()), Times.Once);
}
Expand Down
Loading

0 comments on commit 1ca8883

Please sign in to comment.