Skip to content

Commit fccc4a7

Browse files
ericavellaErica Vellanoweth
andauthored
Sysbench changes, formalizing a database population design (#651)
* merging flexible logic with sysbench configuration, keeping it consistent with database workloads * editing test * docs change * adding innodb buffer size & other vars * fixing profile * inc package version * fixing tests --------- Co-authored-by: Erica Vellanoweth <evellanoweth@microsoft.com>
1 parent 3ba552b commit fccc4a7

17 files changed

Lines changed: 537 additions & 428 deletions

File tree

src/VirtualClient/VirtualClient.Actions.FunctionalTests/SysbenchProfileTests.cs

Lines changed: 46 additions & 46 deletions
Large diffs are not rendered by default.

src/VirtualClient/VirtualClient.Actions.UnitTests/Sysbench/SysbenchClientExecutorTests.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public async Task SysbenchClientExecutorRunsTheExpectedWorkloadCommand()
9090
{
9191
SetupDefaultBehavior();
9292

93-
string expectedCommand = @$"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 10 --recordCount 1000 --threadCount 8 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
93+
string expectedCommand = @$"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 8 --tableCount 10 --recordCount 1000 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
9494
bool commandExecuted = false;
9595

9696
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
@@ -136,7 +136,7 @@ public async Task SysbenchClientExecutorUsesDefinedParametersWhenRunningTheWorkl
136136
this.fixture.Parameters[nameof(SysbenchClientExecutor.TableCount)] = "40";
137137
this.fixture.Parameters[nameof(SysbenchClientExecutor.DatabaseScenario)] = "Configure";
138138

139-
string expectedCommand = @$"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 40 --recordCount 1000 --threadCount 64 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
139+
string expectedCommand = @$"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 64 --tableCount 40 --recordCount 1000 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
140140
bool commandExecuted = false;
141141

142142
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
@@ -179,7 +179,7 @@ public async Task SysbenchClientExecutorRunsTheExpectedBalancedScenario()
179179

180180
this.fixture.Parameters[nameof(SysbenchClientExecutor.DatabaseScenario)] = "Balanced";
181181

182-
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 10 --recordCount 1000 --threadCount 8 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
182+
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 8 --tableCount 10 --recordCount 1000 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
183183
bool commandExecuted = false;
184184

185185
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
@@ -222,7 +222,7 @@ public async Task SysbenchClientExecutorRunsInMemoryScenario()
222222

223223
this.fixture.Parameters[nameof(SysbenchClientExecutor.DatabaseScenario)] = "InMemory";
224224

225-
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 10 --recordCount 100000 --threadCount 8 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
225+
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 8 --tableCount 10 --recordCount 100000 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
226226
bool commandExecuted = false;
227227

228228
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
@@ -264,8 +264,9 @@ public async Task SysbenchClientExecutorRunsTheExpectedTPCCWorkloadCommand()
264264
SetupDefaultBehavior();
265265

266266
this.fixture.Parameters[nameof(SysbenchClientExecutor.Benchmark)] = "TPCC";
267+
this.fixture.Parameters[nameof(SysbenchClientExecutor.Workload)] = "tpcc";
267268

268-
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark TPCC --tableCount 10 --warehouses 100 --threadCount 8 --workload tpcc --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
269+
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem MySQL --benchmark TPCC --threadCount 8 --tableCount 10 --warehouses 100 --workload tpcc --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
269270
bool commandExecuted = false;
270271

271272
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
@@ -308,7 +309,7 @@ public async Task SysbenchClientExecutorRunsTheExpectedPostgreSQLOLTPWorkloadCom
308309

309310
this.fixture.Parameters[nameof(SysbenchClientExecutor.DatabaseSystem)] = "PostgreSQL";
310311

311-
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem PostgreSQL --benchmark OLTP --tableCount 10 --recordCount 1000 --threadCount 8 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
312+
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem PostgreSQL --benchmark OLTP --threadCount 8 --tableCount 10 --recordCount 1000 --workload oltp_read_write --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
312313
bool commandExecuted = false;
313314

314315
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
@@ -351,8 +352,9 @@ public async Task SysbenchClientExecutorRunsTheExpectedPostgreSQLTPCCWorkloadCom
351352

352353
this.fixture.Parameters[nameof(SysbenchClientExecutor.DatabaseSystem)] = "PostgreSQL";
353354
this.fixture.Parameters[nameof(SysbenchClientExecutor.Benchmark)] = "TPCC";
355+
this.fixture.Parameters[nameof(SysbenchClientExecutor.Workload)] = "tpcc";
354356

355-
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem PostgreSQL --benchmark TPCC --tableCount 10 --warehouses 100 --threadCount 8 --workload tpcc --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
357+
string expectedCommand = $"python3 {this.mockPackagePath}/run-workload.py --dbName sbtest --databaseSystem PostgreSQL --benchmark TPCC --threadCount 8 --tableCount 10 --warehouses 100 --workload tpcc --hostIpAddress 1.2.3.5 --durationSecs 10 --password [A-Za-z0-9+/=]+";
356358
bool commandExecuted = false;
357359

358360
this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>

src/VirtualClient/VirtualClient.Actions.UnitTests/Sysbench/SysbenchConfigurationTests.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public void SetupDefaultBehavior()
4949
this.fixture.Parameters = new Dictionary<string, IConvertible>()
5050
{
5151
{ nameof(SysbenchConfiguration.DatabaseSystem), "MySQL" },
52+
{ nameof(SysbenchConfiguration.Action), "PopulateTables" },
5253
{ nameof(SysbenchConfiguration.Benchmark), "OLTP" },
5354
{ nameof(SysbenchConfiguration.DatabaseName), "sbtest" },
5455
{ nameof(SysbenchConfiguration.PackageName), "sysbench" },
@@ -77,7 +78,7 @@ public async Task SysbenchConfigurationSkipsSysbenchInitialization()
7778

7879
string[] expectedCommands =
7980
{
80-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 10 --recordCount 1000 --threadCount 8 --password [A-Za-z0-9+/=]+",
81+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 8 --tableCount 10 --recordCount 1000 --password [A-Za-z0-9+/=]+ --host \"1.2.3.5\"",
8182
};
8283

8384
int commandNumber = 0;
@@ -122,7 +123,7 @@ public async Task SysbenchConfigurationPreparesDatabase()
122123
string[] expectedCommands =
123124
{
124125
$"python3 {this.mockPackagePath}/configure-workload-generator.py --distro Ubuntu --databaseSystem MySQL --packagePath {this.mockPackagePath}",
125-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 10 --recordCount 1000 --threadCount 8 --password [A-Za-z0-9+/=]+",
126+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 8 --tableCount 10 --recordCount 1000 --password [A-Za-z0-9+/=]+",
126127
};
127128

128129
int commandNumber = 0;
@@ -173,7 +174,7 @@ public async Task SysbenchConfigurationUsesDefinedParametersWhenRunningTheWorklo
173174
string[] expectedCommands =
174175
{
175176
$"python3 {this.mockPackagePath}/configure-workload-generator.py --distro Ubuntu --databaseSystem MySQL --packagePath {this.mockPackagePath}",
176-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --tableCount 40 --recordCount 1000 --threadCount 16 --password [A-Za-z0-9+/=]+",
177+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark OLTP --threadCount 16 --tableCount 40 --recordCount 1000 --password [A-Za-z0-9+/=]+",
177178
};
178179

179180
int commandNumber = 0;
@@ -213,7 +214,7 @@ public async Task SysbenchConfigurationUsesDefinedParametersWhenRunningTheWorklo
213214
}
214215

215216
[Test]
216-
public async Task SysbenchConfigurationSkipsDatabasePopulationWhenInitialized()
217+
public void SysbenchConfigurationThrowsErrorWhenDatabasePopulated()
217218
{
218219
this.fixture.StateManager.OnGetState().ReturnsAsync(JObject.FromObject(new SysbenchExecutor.SysbenchState()
219220
{
@@ -258,7 +259,8 @@ public async Task SysbenchConfigurationSkipsDatabasePopulationWhenInitialized()
258259

259260
using (TestSysbenchConfiguration SysbenchExecutor = new TestSysbenchConfiguration(this.fixture.Dependencies, this.fixture.Parameters))
260261
{
261-
await SysbenchExecutor.ExecuteAsync(CancellationToken.None).ConfigureAwait(false);
262+
DependencyException error = Assert.ThrowsAsync<DependencyException>(() => SysbenchExecutor.ExecuteAsync(CancellationToken.None));
263+
Assert.IsTrue(error.Reason == ErrorReason.NotSupported);
262264
}
263265
}
264266

@@ -274,7 +276,7 @@ public async Task SysbenchConfigurationProperlyExecutesTPCCPreparation()
274276

275277
string[] expectedCommands =
276278
{
277-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark TPCC --tableCount 10 --warehouses 100 --threadCount 8 --password [A-Za-z0-9+/=]+"
279+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark TPCC --threadCount 8 --tableCount 10 --warehouses 100 --password [A-Za-z0-9+/=]+ --host \"1.2.3.5\""
278280
};
279281

280282
int commandNumber = 0;
@@ -330,7 +332,7 @@ public async Task SysbenchConfigurationProperlyExecutesTPCCConfigurablePreparati
330332

331333
string[] expectedCommands =
332334
{
333-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark TPCC --tableCount 40 --warehouses 1000 --threadCount 16 --password [A-Za-z0-9+/=]+"
335+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem MySQL --benchmark TPCC --threadCount 16 --tableCount 40 --warehouses 1000 --password [A-Za-z0-9+/=]+ --host \"1.2.3.5\""
334336
};
335337

336338
int commandNumber = 0;
@@ -386,7 +388,7 @@ public async Task SysbenchConfigurationProperlyExecutesPostgreSQLOLTPConfigurabl
386388

387389
string[] expectedCommands =
388390
{
389-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem PostgreSQL --benchmark OLTP --tableCount 40 --recordCount 1000 --threadCount 16 --password [A-Za-z0-9+/=]+"
391+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem PostgreSQL --benchmark OLTP --threadCount 16 --tableCount 40 --recordCount 1000 --password [A-Za-z0-9+/=]+"
390392
};
391393

392394
int commandNumber = 0;
@@ -444,7 +446,7 @@ public async Task SysbenchConfigurationProperlyExecutesPostgreSQLTPCCConfigurabl
444446

445447
string[] expectedCommands =
446448
{
447-
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem PostgreSQL --benchmark TPCC --tableCount 40 --warehouses 1000 --threadCount 16 --password [A-Za-z0-9+/=]+"
449+
$"python3 {this.mockPackagePath}/populate-database.py --dbName sbtest --databaseSystem PostgreSQL --benchmark TPCC --threadCount 16 --tableCount 40 --warehouses 1000 --password [A-Za-z0-9+/=]+ --host \"1.2.3.5\""
448450
};
449451

450452
int commandNumber = 0;

src/VirtualClient/VirtualClient.Actions/HammerDB/HammerDBExecutor.cs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ namespace VirtualClient.Actions
1616
using VirtualClient;
1717
using VirtualClient.Common;
1818
using VirtualClient.Common.Extensions;
19-
using VirtualClient.Common.Platform;
2019
using VirtualClient.Common.Telemetry;
2120
using VirtualClient.Contracts;
2221

@@ -44,6 +43,18 @@ public HammerDBExecutor(IServiceCollection dependencies, IDictionary<string, ICo
4443
this.stateManager = this.SystemManager.StateManager;
4544
}
4645

46+
/// <summary>
47+
/// The specifed action that controls the execution of the dependency.
48+
/// </summary>
49+
public string Action
50+
{
51+
get
52+
{
53+
this.Parameters.TryGetValue(nameof(this.Action), out IConvertible action);
54+
return action?.ToString();
55+
}
56+
}
57+
4758
/// <summary>
4859
/// Defines the name of the createDB TCL file.
4960
/// </summary>
@@ -196,7 +207,7 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel
196207
HammerDBState state = await this.stateManager.GetStateAsync<HammerDBState>(nameof(HammerDBState), cancellationToken)
197208
?? new HammerDBState();
198209

199-
if (state.DatabaseCreated != 2)
210+
if (!state.DatabasePopulated)
200211
{
201212
await this.Logger.LogMessageAsync($"{this.TypeName}.{this.Scenario}", telemetryContext.Clone(), async () =>
202213
{
@@ -205,8 +216,12 @@ await this.Logger.LogMessageAsync($"{this.TypeName}.{this.Scenario}", telemetryC
205216
await this.PrepareSQLDatabase(telemetryContext, cancellationToken);
206217
}
207218
});
208-
state.DatabaseCreated++;
209-
await this.stateManager.SaveStateAsync<HammerDBState>(nameof(HammerDBState), state, cancellationToken);
219+
220+
if (this.Action == ConfigurationAction.PopulateTables)
221+
{
222+
state.DatabasePopulated = true;
223+
await this.stateManager.SaveStateAsync<HammerDBState>(nameof(HammerDBState), state, cancellationToken);
224+
}
210225
}
211226
}
212227

@@ -318,9 +333,20 @@ private async Task PrepareSQLDatabase(EventContext telemetryContext, Cancellatio
318333

319334
private async Task ConfigureCreateHammerDBFile(EventContext telemetryContext, CancellationToken cancellationToken)
320335
{
336+
string warehouseCount = this.WarehouseCount;
337+
string virtualUsers = this.VirtualUsers;
338+
339+
// For CreateTables action, we set warehouse count and virtual users to 1
340+
// Then will run populate again to fill up the tables in entirety.
341+
if (this.Action == ConfigurationAction.CreateTables)
342+
{
343+
warehouseCount = "1";
344+
virtualUsers = "1";
345+
}
346+
321347
string command = $"python3";
322348
string arguments = $"{this.HammerDBPackagePath}/configure-workload-generator.py --workload {this.Workload} --sqlServer {this.SQLServer} --port {this.Port}" +
323-
$" --virtualUsers {this.VirtualUsers} --warehouseCount {this.WarehouseCount} --password {this.SuperUserPassword} --dbName {this.DatabaseName} --hostIPAddress {this.ServerIpAddress}";
349+
$" --virtualUsers {virtualUsers} --warehouseCount {warehouseCount} --password {this.SuperUserPassword} --dbName {this.DatabaseName} --hostIPAddress {this.ServerIpAddress}";
324350

325351
using (IProcessProxy process = await this.ExecuteCommandAsync(
326352
command,
@@ -406,18 +432,34 @@ public bool HammerDBInitialized
406432
}
407433
}
408434

409-
public int DatabaseCreated
435+
public bool DatabasePopulated
410436
{
411437
get
412438
{
413-
return this.Properties.GetValue<int>(nameof(HammerDBState.DatabaseCreated), 0);
439+
return this.Properties.GetValue<bool>(nameof(HammerDBState.DatabasePopulated), false);
414440
}
415441

416442
set
417443
{
418-
this.Properties[nameof(HammerDBState.DatabaseCreated)] = value;
444+
this.Properties[nameof(HammerDBState.DatabasePopulated)] = value;
419445
}
420446
}
421447
}
448+
449+
/// <summary>
450+
/// Supported HammerDB Configuration actions.
451+
/// </summary>
452+
internal class ConfigurationAction
453+
{
454+
/// <summary>
455+
/// Initializes the tables on the database.
456+
/// </summary>
457+
public const string CreateTables = nameof(CreateTables);
458+
459+
/// <summary>
460+
/// Populates Database on server.
461+
/// </summary>
462+
public const string PopulateTables = nameof(PopulateTables);
463+
}
422464
}
423465
}

0 commit comments

Comments
 (0)