Commit d40d05dc d40d05dce40734cee1995a43bd88fce6db6caff9 by Christian Gerdes

Makeover of SetTestParameter

- New feature that uses a Queue
- Using Categories in Properties
- New names and descriptions
1 parent d16f64d4
......@@ -158,7 +158,7 @@ namespace LIL_VSTT_Plugins
}
[DisplayName("Set Test Context Parameters")]
[Description("(C) Copyright 2011 LIGHTS IN LINE AB\r\nSätter parametrar i testcontextet för tester i mixen hämtat från en CSV fil")]
[Description("(C) Copyright 2011 LIGHTS IN LINE AB\r\nSätter parametrar i testcontextet för tester i mixen hämtat från en CSV fil.")]
public class SetTestParameter : ILoadTestPlugin
{
// Summary:
......@@ -192,16 +192,27 @@ namespace LIL_VSTT_Plugins
private bool stop = false;
private int timeWait = 0;
private int nextAvailableRow = 0;
private StringCollection myParams = new StringCollection();
private Queue<String> myUsedQueue = new Queue<string>();
private Queue<String> myUnUsedQueue = new Queue<string>();
private Random random = new Random();
private Dictionary<string, int> testIterations = new Dictionary<string, int>();
private Dictionary<int, int> userRow = new Dictionary<int, int>();
private LoadTest m_loadTest;
#region guiparams
[Category("Context")]
[DisplayName("Parameter Namn")]
[Description("Ange namnet på parametern som vi ska lägga till i TestContext, om det är flera använd CSV format med kommatecken som separator.")]
[DefaultValue("UserName")]
public string Parameter_Name
{
get { return myParameterName; }
set { myParameterName = value; }
}
[Category("XDebug")]
[DisplayName("Debug Mode")]
[Description("Set True in order to enable Debug Mode. Each agent will log debug messages to the given Debug Log File.")]
[DefaultValue(false)]
......@@ -211,6 +222,7 @@ namespace LIL_VSTT_Plugins
set { myDebug = value; }
}
[Category("XDebug")]
[DisplayName("Debug Log File")]
[Description("Log file path to be used for debug logging, if enabled (True)")]
[DefaultValue("C:\\Temp\\SetTestParameterDebug.log")]
......@@ -220,8 +232,9 @@ namespace LIL_VSTT_Plugins
set { myDebugLogFile = value; }
}
[DisplayName("CSV filens sökväg")]
[Description("Ange den fullständiga sökvägen till CSV filen. Observera att filen behöver finnas på alla agenterna också om du inte kör lokalt.")]
[Category("CSV Testdata")]
[DisplayName("Filens sökväg")]
[Description("Ange filens namn om den finns som Deployment Item i dina testsettings, eller fullständig sökväg om den inte deployas. Du kan ange en nätverksmappad disk eller UNC sökväg. Vid lokal sökväg behöver filen finnas på den agent där pluginet körs, vilket är alla agenter om du inte anger undantag.")]
[DefaultValue("C:\\Userdata.csv")]
public string Connection_String
{
......@@ -229,8 +242,9 @@ namespace LIL_VSTT_Plugins
set { myConnectionString = value; }
}
[DisplayName("CSV filen har kolumnamn")]
[Description("Ange om csv filen har rubriker i form av kolumnnamn. Om du sätter True kommer kolmnens rubrik att användas som parameternamn istället.")]
[Category("CSV Testdata")]
[DisplayName("Filen har kolumner med namn")]
[Description("Ange om csv filen har rubriker i form av kolumnnamn på första raden. Om du sätter True kommer även kolumnens namn att användas som parameternamn istället.")]
[DefaultValue(false)]
public bool Has_col_name
{
......@@ -238,8 +252,9 @@ namespace LIL_VSTT_Plugins
set { myHasColName = value; }
}
[DisplayName("CSV Autosplit per agent")]
[Description("Ange True om du vill att filen automatiskt ska splittas mellan alla aktiva agenter.")]
[Category("CSV Testdata")]
[DisplayName("Autosplit per agent")]
[Description("Ange True om du vill att filen automatiskt ska splittas mellan alla aktiva agenter i testet. Obligatoriskt för att kunna ha unikt testdata över hela ditt loadtest då agenterna inte pratar med varandra under körningen.")]
[DefaultValue(false)]
public bool Autosplit
{
......@@ -247,7 +262,8 @@ namespace LIL_VSTT_Plugins
set { myUseAutoSplit = value; }
}
[DisplayName("CSV Ignorera blankskott")]
[Category("CSV Testdata")]
[DisplayName("Ignorera blankskott")]
[Description("Ange False om du inte vill att rader med blankskott ignoreras (tomma/blanka rader eller samtliga kolumner tomma/blanka).")]
[DefaultValue(true)]
public bool IgnoreBlanks
......@@ -256,15 +272,7 @@ namespace LIL_VSTT_Plugins
set { myIgnoreBlanks = value; }
}
[DisplayName("Context Parameter Namn")]
[Description("Ange namnet på parametern som vi ska lägga till i TestContext, om det är flera använd CSV format.")]
[DefaultValue("UserName")]
public string Parameter_Name
{
get { return myParameterName; }
set { myParameterName = value; }
}
[Category("Loggning")]
[DisplayName("Loggfilens namn")]
[Description("Ange den fullständiga sökvägen till logg filen. Om filen finns kommer den inte skrivas över utan läggas till i slutet.")]
[DefaultValue("C:\\Temp\\Fungerande.log")]
......@@ -274,7 +282,8 @@ namespace LIL_VSTT_Plugins
set { myLogFileString = value; }
}
[DisplayName("Loggfilens namn: Lägg till ID")]
[Category("Loggning")]
[DisplayName("Lägg till ID")]
[Description("Ange True om du vill att Agent ID samt VU ID läggs till automatiskt i slutet på filnamnet.")]
[DefaultValue(false)]
public bool LogFileAppendID
......@@ -283,7 +292,8 @@ namespace LIL_VSTT_Plugins
set { myLogAppendID = value; }
}
[DisplayName("Loggfilens namn: Lägg till Namn")]
[Category("Loggning")]
[DisplayName("Lägg till Namn")]
[Description("Ange True om du vill att Scenario Name samt Test Name läggs till automatiskt i slutet på filnamnet.")]
[DefaultValue(false)]
public bool LogFileAppendName
......@@ -292,26 +302,29 @@ namespace LIL_VSTT_Plugins
set { myLogAppendName = value; }
}
[DisplayName("Välj slumpmässigt?")]
[Description("Ange True om du vill välja en slumpmässig användare. False går igenom listan sekventiellt.")]
[DefaultValue(true)]
public bool Use_Random
[Category("Radmappning")]
[DisplayName("1: Test Iteration Number")]
[Description("Varje iteration av ett och samma test på samma Agent, får en ny rad från din fil. Testets iterationsnummer mappas till raderna i din testdatafil. Börjar på 1 på varje Agent. Autosplit fördelar rader mellan agenter.")]
[DefaultValue(false)]
public bool Use_UniqueTestIteration
{
get { return myUseRandom; }
set { myUseRandom = value; }
get { return myUseUniqueTestIteration; }
set { myUseUniqueTestIteration = value; }
}
[DisplayName("Välj unikt per VU?")]
[Description("Ange True om du vill att varje LoadTest VU ska ha sitt eget unika värde och återanvända detta i varje iteration. Stänger av slumpmässigt val.")]
[Category("Radmappning")]
[DisplayName("2: Total Iteration Number")]
[Description("Varje iteration av ett test på samma Agent, oavsett test, får en ny rad från din fil. Agentens Globala iterationsnummer mappas till raderna i din testdatafil. Börjar på 1 på varje Agent. Autosplit fördelar rader mellan agenter.")]
[DefaultValue(false)]
public bool Use_Unique
public bool Use_UniqueIteration
{
get { return myUseUnique; }
set { myUseUnique = value; }
get { return myUseUniqueIteration; }
set { myUseUniqueIteration = value; }
}
[DisplayName("Välj unikt per VU per Testdatafil?")]
[Description("Ange True om du vill att varje testdatafil (CSV) hanteras separat för varje unik VU. Pluginet kommer då komma ihåg vilka rader som delats ut separat för varje fil.")]
[Category("Radmappning")]
[DisplayName("3: FIFO Kö med Pop/Enqueue")]
[Description("Varje rad läses in i en kö på agenten. När en VU vill köra ett test får den raden överst i kön. När en VU är klar med iterationen av ett test läggs raden tillbaka sist i kön. Detta säkerställer att du inte behöver fler rader i testdata filen än antalet samtidiga/parallella VU som kör dina tester, även om du har olika testdatafiler för olika tester. Varje agent börjar på rad 1 i filen om du inte använder Autosplit.")]
[DefaultValue(false)]
public bool Use_UniqueFiles
{
......@@ -319,26 +332,38 @@ namespace LIL_VSTT_Plugins
set { myUseUniqueFiles = value; }
}
[DisplayName("Välj unikt per Iteration?")]
[Description("Ange True om du vill att varje LoadTest VU ska ha sitt eget unika värde för varje iteration av alla tester, dvs aldrig återanvändas av någon VU i något test. Gäller före unikt per test iteration.")]
[Category("Radmappning")]
[DisplayName("4: Virtual User ID Number")]
[Description("Varje ny VU får en egen rad från din fil, och återanvänder denna rad om den kör fler tester/iterationer. Agentens Virtual User ID Number mappas till raderna i din testdatafil. En VU varierar vilka tester den kör i din mix. En ny VU (enligt procent nya VU i run settings) får ett nytt nummer och därmed en ny rad i din fil. Första VU får nummer 1 på varje Agent. Autosplit fördelar rader mellan agenter.")]
[DefaultValue(false)]
public bool Use_UniqueIteration
public bool Use_Unique
{
get { return myUseUniqueIteration; }
set { myUseUniqueIteration = value; }
get { return myUseUnique; }
set { myUseUnique = value; }
}
[DisplayName("Välj unikt per Test Iteration?")]
[Description("Ange True om du vill att varje LoadTest VU ska ha sitt eget unika värde för varje iteration av respektive test, dvs aldrig återanvändas av någon VU som kör samma test.")]
[Category("Radmappning")]
[DisplayName("5: Slumpmässigt")]
[Description("Slumpmässigt val av rader i filen. Ingen kontroll eller viss ordning och flera VU kan slumpa fram samma rad.")]
[DefaultValue(false)]
public bool Use_UniqueTestIteration
public bool Use_Random
{
get { return myUseUniqueTestIteration; }
set { myUseUniqueTestIteration = value; }
get { return myUseRandom; }
set { myUseRandom = value; }
}
[Category("Radmappning")]
[DisplayName("6: Virtual User Iteration Number")]
[Description("Varje VU väljer rad baserat på antalet tidigare tester/iterationer den gjort. Varje ny VU börjar på rad 1. Om procent nya VU är 100 används endast rad 1 i alla tester. Observera att en VU som inte är ny kommer att byta mellan olika tester under din körning, om du har flera tester/skript i din mix. Om du använder undantag och flera instanser av detta plugin, kommer vissa rader att hoppas över.")]
[DefaultValue(true)]
public bool Use_Seq
{
get; set; // Fake. Actually enabled by setting all other options above to false.
}
[DisplayName("Välj sekventiell loop?")]
[Description("Ange true om du vill börja om från början om sekventiell läsning får slut på värden. Gäller även Unik läsning. Om data tar slut kommer sista värdet ges till alla om sekventiell loop inte tillåts")]
[Category("CSV Testdata")]
[DisplayName("Loopa testdata")]
[Description("Ange true om du vill börja om från början av testdatafilen när alla används en gång. Gäller alla unik typer utom Push/Pull. Med False på detta val kommer sista raden ges till alla om datat tar slut, eller OutOfTestDataException slängas och loadtestet stoppas om det är aktiverat.")]
[DefaultValue(false)]
public bool Use_Loop
{
......@@ -346,7 +371,8 @@ namespace LIL_VSTT_Plugins
set { mySeqLoop = value; }
}
[DisplayName("OutOfTestDataException?")]
[Category("CSV Testdata")]
[DisplayName("Avbryt med OutOfTestDataException")]
[Description("Ange true om du vill att ditt loadtest ska stoppas om testdata tar slut (och Sekventiell Loop är satt till false).")]
[DefaultValue(false)]
public bool ThrowException
......@@ -354,6 +380,7 @@ namespace LIL_VSTT_Plugins
get; set;
}
[Category("Loggning")]
[DisplayName("Logga fungerande till fil?")]
[Description("Ange True om du vill att poster vars tester slutar i Pass ska loggas till fil (c:\\fungerande.log). Om filen redan finns läggs de till i slutet.")]
[DefaultValue(false)]
......@@ -363,8 +390,9 @@ namespace LIL_VSTT_Plugins
set { myLogToFile = value; }
}
[Category("Undantag")]
[DisplayName("Endast dessa Tester")]
[Description("Parametrar sätts endast på tester i test mixen där namnet eller del av namnet för testet finns i denna lista. Lämna blankt för att sätta i alla tester.")]
[Description("Denna instans av pluginet körs endast på Tester i test mixen där namnet eller del av namnet för testet finns i denna lista. Lämna blankt för att köra i alla tester.")]
[DefaultValue("")]
public string Test_Names
{
......@@ -372,8 +400,9 @@ namespace LIL_VSTT_Plugins
set { myTestNames = value; }
}
[Category("Undantag")]
[DisplayName("Endast dessa Scenarios")]
[Description("Parametrar sätts endast på Scenarion där namnet eller del av namnet för scenariot finns i denna lista. Lämna blankt för att sätta i alla scenarion.")]
[Description("Denna instans av pluginet körs endast på Scenarion där namnet eller del av namnet för scenariot finns i denna lista. Lämna blankt för att köra i alla scenarion.")]
[DefaultValue("")]
public string Scenario_Names
{
......@@ -381,8 +410,9 @@ namespace LIL_VSTT_Plugins
set { myScenarioNames = value; }
}
[Category("Undantag")]
[DisplayName("Endast dessa Agenter")]
[Description("Parametrar sätts endast på Agenter där namnet eller del av namnet för agenten finns i denna lista. Lämna blankt för att sätta i alla agenter.")]
[Description("Denna instans av pluginet körs endast på Agenter där namnet eller del av namnet för agenten finns i denna lista. Lämna blankt för att köra på alla agenter.")]
[DefaultValue("")]
public string Agent_Names
{
......@@ -475,23 +505,23 @@ namespace LIL_VSTT_Plugins
{
if (shouldRun(e))
{
int row = 0;
string strParams = "OutOfData";
// Go single threaded
lock (userRow)
lock (myUnUsedQueue)
{
// Check if the user already has a row in our file, otherwise get the next one
if (userRow.ContainsKey(e.UserContext.UserId)) row = userRow[e.UserContext.UserId];
else
if(myUnUsedQueue.Count > 0)
{
// New user, get the next row and increase the counter
row = nextAvailableRow++;
// Save the row for this user
userRow[e.UserContext.UserId] = row;
strParams = myUnUsedQueue.Dequeue();
e.UserContext["QueueVal"] = strParams;
} else
{
// Out of testdata
e.UserContext["QueueVal"] = null;
stopAndThrow();
}
}
string strParams = this.getSeqUser(row);
setParameters(strParams, e);
if (myDebug) lock (myDebugLogFile) { File.AppendAllText(myDebugLogFile, DateTime.Now.ToLocalTime() + " File: " + myConnectionString + " Test: " + e.TestName + " VU: " + e.UserContext.UserId + " Row: " + row + " Value: \"" + strParams + "\"\r\n"); }
if (myDebug) lock (myDebugLogFile) { File.AppendAllText(myDebugLogFile, DateTime.Now.ToLocalTime() + " File: " + myConnectionString + " Test: " + e.TestName + " VU: " + e.UserContext.UserId + " Value: \"" + strParams + "\" PULL\r\n"); }
}
}
......@@ -499,7 +529,13 @@ namespace LIL_VSTT_Plugins
{
if (shouldRun(e))
{
String queueVal = (String)e.UserContext["QueueVal"];
if (queueVal != null)
lock (myUnUsedQueue)
{
myUnUsedQueue.Enqueue(queueVal);
}
if (myDebug) lock (myDebugLogFile) { File.AppendAllText(myDebugLogFile, DateTime.Now.ToLocalTime() + " File: " + myConnectionString + " Test: " + e.TestName + " VU: " + e.UserContext.UserId + " Value: \"" + queueVal + "\" PUSH\r\n"); }
}
}
......@@ -604,11 +640,7 @@ namespace LIL_VSTT_Plugins
// Handle out of testdata here
if (ThrowException)
{
foreach (LoadTestScenario s in m_loadTest.Scenarios)
{
s.CurrentLoad = 0;
}
this.stop = true;
stopAndThrow();
return "OutOfData";
}
else return myParams[myParams.Count - 1];
......@@ -616,11 +648,20 @@ namespace LIL_VSTT_Plugins
}
}
void stopAndThrow()
{
if(m_loadTest != null)
foreach (LoadTestScenario s in m_loadTest.Scenarios)
{
s.CurrentLoad = 0;
}
this.stop = true;
}
bool initUserArray(string path, int agentCount, int agentId)
{
if (path.Length > 0)
{
//StreamReader re = File.OpenText(path);
StreamReader re = new StreamReader(path, System.Text.Encoding.Default);
string input = null;
int lineNum = 0;
......@@ -646,13 +687,15 @@ namespace LIL_VSTT_Plugins
else ifAgentId = dataNum + 1;
if (ifAgentId == agentId)
{
myParams.Add(input.TrimEnd(trim));
if (myUseUniqueFiles) myUnUsedQueue.Enqueue(input.TrimEnd(trim));
else myParams.Add(input.TrimEnd(trim));
}
dataNum++;
}
else
{
myParams.Add(input.TrimEnd(trim));
if (myUseUniqueFiles) myUnUsedQueue.Enqueue(input.TrimEnd(trim));
else myParams.Add(input.TrimEnd(trim));
}
}
}
......