Skip to content

Commit

Permalink
Redesigned result window and added save as csv
Browse files Browse the repository at this point in the history
  • Loading branch information
Tore Lervik committed Jun 8, 2013
1 parent 01ffc91 commit f075846
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 81 deletions.
5 changes: 1 addition & 4 deletions Netling.Client/LineGraphControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="300">
<Grid>
<TextBlock x:Name="Title" Margin="30,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Grid Margin="10,20,0,0">
<oxy:Plot x:Name="Graph" Background="Transparent" Margin="30, -8, -15, -7"></oxy:Plot>
</Grid>
<oxy:Plot x:Name="Graph" Background="Transparent" Margin="30, -1, -8, 0"></oxy:Plot>
</Grid>
</UserControl>
28 changes: 6 additions & 22 deletions Netling.Client/LineGraphControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;

namespace Netling.Client
{
/// <summary>
/// Interaction logic for LineGraphControl.xaml
/// </summary>
public partial class LineGraphControl : UserControl
{
public LineGraphControl()
{
InitializeComponent();
}

public void Plot(string title, IEnumerable<DataPoint> points)
public void Draw(IEnumerable<DataPoint> points)
{
Title.Text = title;

var plotModel = new PlotModel
{
PlotMargins = new OxyThickness(0),
AutoAdjustPlotMargins = false
AutoAdjustPlotMargins = false,
PlotAreaBorderThickness = 0
};

plotModel.Axes.Add(new LinearAxis
{
MinimumPadding = 0.0,
MaximumPadding = 0.0,
MinimumPadding = 0.01,
MaximumPadding = 0.01,
IsAxisVisible = false,
IsZoomEnabled = false,
IsPanEnabled = false,
Expand Down
15 changes: 8 additions & 7 deletions Netling.Client/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Grid Margin="10">
<TextBlock Text="Threads" VerticalAlignment="Top" HorizontalAlignment="Left"/>

<ComboBox x:Name="Threads" VerticalAlignment="Top" HorizontalAlignment="Left" Width="100" Height="25" Margin="0,21,0,0">
<ComboBox x:Name="Threads" VerticalAlignment="Top" HorizontalAlignment="Left" Width="60" Height="25" Margin="0,21,0,0">
<ComboBoxItem IsSelected="True">1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>4</ComboBoxItem>
Expand All @@ -15,19 +15,20 @@
<ComboBoxItem>64</ComboBoxItem>
</ComboBox>

<TextBlock Text="Runs" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="120,0,0,0"/>
<ComboBox x:Name="Runs" VerticalAlignment="Top" HorizontalAlignment="Left" Width="100" Height="25" Margin="120,21,0,0">
<ComboBoxItem>10</ComboBoxItem>
<ComboBoxItem>100</ComboBoxItem>
<TextBlock Text="Duration" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="80,0,0,0"/>
<ComboBox x:Name="Duration" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120" Height="25" Margin="80,21,0,0">
<ComboBoxItem>1 run</ComboBoxItem>
<ComboBoxItem>10 runs</ComboBoxItem>
<ComboBoxItem>100 runs</ComboBoxItem>
<ComboBoxItem IsSelected="True">10 seconds</ComboBoxItem>
<ComboBoxItem>20 seconds</ComboBoxItem>
<ComboBoxItem>1 minute</ComboBoxItem>
<ComboBoxItem>10 minutes</ComboBoxItem>
<ComboBoxItem>1 hour</ComboBoxItem>
<ComboBoxItem>Unlimited</ComboBoxItem>
<ComboBoxItem>Until canceled</ComboBoxItem>
</ComboBox>

<TextBlock Text="URL's" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,61,0,0"/>
<TextBlock Text="URLs" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,61,0,0"/>
<TextBox x:Name="Urls" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0,82,0,40" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"/>

<Button Content="Run" x:Name="StartButton" Background="#ff0079c5" BorderThickness="0" Foreground="White" Click="StartButton_Click" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="100" Height="30"/>
Expand Down
22 changes: 17 additions & 5 deletions Netling.Client/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,18 @@ private void StartButton_Click(object sender, RoutedEventArgs e)
TimeSpan duration = default(TimeSpan);
int runs = 0;
var threads = Convert.ToInt32(Threads.SelectionBoxItem);
var runsText = (string)((ComboBoxItem)Runs.SelectedItem).Content;
var durationText = (string)((ComboBoxItem)Duration.SelectedItem).Content;
StatusProgressbar.IsIndeterminate = false;

switch (runsText)
switch (durationText)
{
case "10":
case "1 run":
runs = 1;
break;
case "10 runs":
runs = 10;
break;
case "100":
case "100 runs":
runs = 100;
break;
case "10 seconds":
Expand All @@ -60,9 +64,10 @@ private void StartButton_Click(object sender, RoutedEventArgs e)
duration = TimeSpan.FromHours(1);
timeLimited = true;
break;
case "Unlimited":
case "Until canceled":
duration = TimeSpan.MaxValue;
timeLimited = true;
StatusProgressbar.IsIndeterminate = true;
break;

}
Expand All @@ -72,6 +77,10 @@ private void StartButton_Click(object sender, RoutedEventArgs e)
if (!urls.Any())
return;

Threads.IsEnabled = false;
Duration.IsEnabled = false;
Urls.IsEnabled = false;

cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
var job = new Job<UrlResult>();
Expand Down Expand Up @@ -106,6 +115,9 @@ private void OnProgress(double amount)

private void JobCompleted()
{
Threads.IsEnabled = true;
Duration.IsEnabled = true;
Urls.IsEnabled = true;
StartButton.Content = "Run";
StatusProgressbar.Visibility = Visibility.Hidden;
cancellationTokenSource = null;
Expand Down
59 changes: 32 additions & 27 deletions Netling.Client/ResultWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="http://oxyplot.codeplex.com"
xmlns:client="clr-namespace:Netling.Client"
Title="Result" Height="400" Width="800" MinHeight="210" MinWidth="700" WindowStyle="SingleBorderWindow">
Title="Result" Height="500" Width="500" MinHeight="200" MinWidth="410" WindowStyle="SingleBorderWindow">
<Grid Margin="10,20,10,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" MinWidth="363" MaxWidth="400" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<StackPanel VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Top" Margin="0,0,0,20">
<Grid VerticalAlignment="Top">
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" Width="140">
<TextBlock Text="Requests per second" VerticalAlignment="Top" HorizontalAlignment="Center"/>
Expand All @@ -19,10 +20,10 @@
<TextBlock Text="Avg response time" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<TextBlock x:Name="ResponseTime" Text="0" VerticalAlignment="Top" Foreground="#ff0079c5" HorizontalAlignment="Center" FontSize="32" Margin="0,16,0,0"/>
</Grid>

<Grid VerticalAlignment="Top" HorizontalAlignment="Right" Width="140">
<TextBlock Text="Total requests" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<TextBlock x:Name="TotalRequests" Text="0" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="32" Margin="0,16,0,0"/>
<TextBlock Text="Bandwidth (mbit)" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<TextBlock x:Name="Bandwidth" Text="0" VerticalAlignment="Top" Foreground="#ff0079c5" HorizontalAlignment="Center" FontSize="32" Margin="0,16,0,0"/>
</Grid>
</Grid>

Expand All @@ -31,10 +32,10 @@
<TextBlock Text="Elapsed (ms)" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<TextBlock x:Name="Elapsed" Text="0" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="32" Margin="0,16,0,0"/>
</Grid>

<Grid VerticalAlignment="Top" HorizontalAlignment="Center" Width="140">
<TextBlock Text="Bandwidth (mbit)" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<TextBlock x:Name="Bandwidth" Text="0" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="32" Margin="0,16,0,0"/>
<TextBlock Text="Total requests" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<TextBlock x:Name="TotalRequests" Text="0" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="32" Margin="0,16,0,0"/>
</Grid>

<Grid VerticalAlignment="Top" HorizontalAlignment="Right" Width="140">
Expand All @@ -43,21 +44,25 @@
</Grid>
</Grid>
</StackPanel>
<TabControl Grid.Row="1" Margin="0,0,0,10" Padding="0">
<TabItem Header="Requests per second">
<client:LineGraphControl x:Name="RequestsPerSecondGraph"/>
</TabItem>
<TabItem Header="Response times">
<client:LineGraphControl x:Name="ResponseTimeGraph"/>
</TabItem>
<TabItem Header="Urls">
<DataGrid AutoGenerateColumns="False" x:Name="UrlSummary" BorderThickness="0" AreRowDetailsFrozen="True" CanUserResizeRows="False" RowHeaderWidth="0" IsReadOnly="True" Background="Transparent">
<DataGrid.Columns>
<DataGridTextColumn Header="Avg resp" Binding="{Binding Path=ResponseTime}" Width="60" />
<DataGridTextColumn Header="Size (KB)" Binding="{Binding Path=Size}" Width="60" />
<DataGridTextColumn Header="Errors" Binding="{Binding Path=Errors}" Width="45" />
<DataGridTextColumn Header="Url" Binding="{Binding Path=Url}" Width="500" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
</TabControl>

<DataGrid AutoGenerateColumns="False" x:Name="UrlSummary" Margin="0,165,0,0" AreRowDetailsFrozen="True" CanUserResizeRows="False" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Avg resp" Binding="{Binding Path=ResponseTime}" Width="60" />
<DataGridTextColumn Header="Size (KB)" Binding="{Binding Path=Size}" Width="60" />
<DataGridTextColumn Header="Errors" Binding="{Binding Path=Errors}" Width="60" />
<DataGridTextColumn Header="Url" Binding="{Binding Path=Url}" Width="500" />
</DataGrid.Columns>
</DataGrid>

<Grid Grid.Column="1">
<client:LineGraphControl x:Name="Graph"/>
</Grid>


<Button Content="Save result data" Visibility="Hidden" VerticalAlignment="Bottom" Background="#ff0079c5" BorderThickness="0" Foreground="White" Margin="0,100,0,0" Height="30"/>
<Button Grid.Row="2" Content="Save" Click="Button_Click" Width="100" VerticalAlignment="Bottom" Padding="10,0" HorizontalAlignment="Left" Background="#ff0079c5" BorderThickness="0" Foreground="White" Height="30"/>
</Grid>
</Window>
47 changes: 37 additions & 10 deletions Netling.Client/ResultWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using Netling.Core.Models;
using OxyPlot;
Expand All @@ -26,29 +28,29 @@ public ResultWindow(JobResult<UrlResult> result)
Bandwidth.Text = string.Format("{0:0}", Math.Round(result.BytesPrSecond * 8 / 1024 / 1024, MidpointRounding.AwayFromZero));
Errors.Text = result.Errors.ToString(CultureInfo.InvariantCulture);

Title = string.Format("Threads: {0}, runs: {1}, url's: {2}", result.Threads, result.Runs, result.Results.Select(r => r.Url).Distinct().Count());
//Title = string.Format("{0} threads, {1:0.#} seconds duration & {2} URLs", result.Threads, result.ElapsedMilliseconds / 1000, result.Results.Select(r => r.Url).Distinct().Count());

LoadUrlSummary();
LoadGraph();
LoadGraphs();
}

private void LoadGraph()
private void LoadGraphs()
{
//var result = Result.Results
// .Where(r => !r.IsError)
// .GroupBy(r => (r.StartTime.Ticks/10000 + r.ResponseTime) / 1000)
// .OrderBy(r => r.Key)
// .Select(r => new DataPoint(r.Key, r.Count()));
var result = Result.Results
.Where(r => !r.IsError)
.GroupBy(r => (r.StartTime.Ticks / 10000 + r.ResponseTime) / 1000)
.OrderBy(r => r.Key)
.Select(r => new DataPoint(r.Key, r.Count()));

//Graph.Plot("Requests per second", result);
RequestsPerSecondGraph.Draw(result);

var i = 1;
var ms = Result.Results
.Where(r => !r.IsError)
.OrderByDescending(r => r.ResponseTime)
.Select(r => new DataPoint(i++, r.ResponseTime));

Graph.Plot("Responstime", ms);
ResponseTimeGraph.Draw(ms);
}

private void LoadUrlSummary()
Expand All @@ -70,6 +72,31 @@ private void LoadUrlSummary()

UrlSummary.ItemsSource = list;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
var dialog = new Microsoft.Win32.SaveFileDialog
{
FileName = string.Format("Result-{0:yyyy.MM.dd_HHmm}", DateTime.Now),
DefaultExt = ".csv",
Filter = "Comma-separated values (.csv)|*.csv"
};

if (dialog.ShowDialog() == true)
{
var sb = new StringBuilder();
sb.Append("StartTime;EndTime;Error;ThreadId;ResponseTime;Bytes;Url");
var startTimeZero = Result.Results.OrderBy(r => r.StartTime).First().StartTime.Ticks/10000;

foreach (var result in Result.Results)
{
var startTime = result.StartTime.Ticks / 10000 - startTimeZero;
sb.Append(string.Format("\r\n{0};{1};{2};{3};{4};{5};{6}", startTime, startTime + result.ResponseTime, result.IsError ? 1 : 0, result.ThreadId, result.ResponseTime, result.Bytes, result.Url));
}

File.WriteAllText(dialog.FileName, sb.ToString());
}
}
}

public class SummaryResult
Expand Down
2 changes: 1 addition & 1 deletion Netling.Core/Job.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class Job<T> where T : IResult

WaitHandle.WaitAll(events.ToArray());

return new JobResult<T>(threads, runs, sw.Elapsed.TotalMilliseconds, results.SelectMany(r => r, (a, b) => b).ToList());
return new JobResult<T>(threads, sw.Elapsed.TotalMilliseconds, results.SelectMany(r => r, (a, b) => b).ToList());
}
}
}
8 changes: 3 additions & 5 deletions Netling.Core/Models/JobResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ namespace Netling.Core.Models
public class JobResult<T> where T : IResult
{
public int Threads { get; private set; }
public int Runs { get; private set; }
public int Count { get; private set; }
public double ElapsedMilliseconds { get; private set; }
public int Errors { get; private set; }
public List<T> Results { get; private set; }
public double BytesPrSecond { get; private set; }
public double JobsPerSecond { get; private set; }

public JobResult(int threads, int runs, double elapsedMilliseconds, List<T> results)
public JobResult(int threads, double elapsedMilliseconds, List<T> results)
{
Threads = threads;
Runs = runs;
ElapsedMilliseconds = elapsedMilliseconds;
Results = results;
Count = results.Count;
Expand All @@ -26,9 +24,9 @@ public JobResult(int threads, int runs, double elapsedMilliseconds, List<T> resu
JobsPerSecond = results.Count(r => !r.IsError) / (elapsedMilliseconds / 1000);
}

public static JobResult<T> Create(int threads, int runs, double elapsedMilliseconds, List<T> results)
public static JobResult<T> Create(int threads, double elapsedMilliseconds, List<T> results)
{
return new JobResult<T>(threads, runs, elapsedMilliseconds, results);
return new JobResult<T>(threads, elapsedMilliseconds, results);
}
}
}

0 comments on commit f075846

Please sign in to comment.