Skip to content

Commit 59a45ab

Browse files
committed
Merge pull request #336 from MalcolmEvershed/sqlserver
Get SQL Server working with ASP.NET tests on Windows
2 parents 066eb93 + 6f62b2f commit 59a45ab

10 files changed

+247
-5
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,21 @@ Now you can run tests:
148148
python run-tests.py -s server-ip -c client-ip -i "C:\Users\Administrator\Desktop\client.key" --max-threads 2 --duration 30 --sleep 5 --name win --test aspnet --type all
149149

150150

151+
### SQL Server on Windows Instructions
152+
153+
Server installation scripts for Windows Server 2012 with SQL Server 2012 Standard on Amazon EC2.
154+
155+
Instructions:
156+
157+
* Create an instance from the [Windows Server 2012 RTM English 64-bit SQL 2012 Standard](https://aws.amazon.com/amis/amazon-ebs-backed-windows-server-2012-rtm-english-64-bit-sql-2012-standard) image on Amazon EC2
158+
* Connect to it via Remote Desktop
159+
* Run a `Command Prompt` as Administrator
160+
* Enter `powershell -ExecutionPolicy Bypass -Command "iex (New-Object Net.WebClient).DownloadString('https://raw.github.com/TechEmpower/FrameworkBenchmarks/master/setup-sqlserver-bootstrap.ps1')"`
161+
* This will configure SQL Server, the Windows Firewall, and populate the database.
162+
163+
Now, when running `python run-tests.py`, just add `-d <ip of SQL Server instance>`. This works for the (Windows Server-based) `aspnet-sqlserver-raw` and `aspnet-sqlserver-entityframework` tests.
164+
165+
151166
## Result Files
152167

153168
After a test run, the directory ~/FrameworkBenchmarks/results/machine-name/timestamp will contains all the result files. In this folder are four files: three CSV files, one for each of the test types (json, db, query), and a single results.json file that contains all the results as well as some additional information. The results.json file is what we use to drive our blog post, and may or may not be useful to you. There are three subdirectories: one for each of the test types (json, db, query), each of these directories contain the raw weighttp results for each framework.

aspnet/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* Npgsql 2.0.12 ([custom build](https://github.com/pdonald/Npgsql2))
3838
* Entity Framework 6.0.0-alpha3
3939
* Mongo C# Driver 1.8.1
40+
* SqlClient Data Provider for SQL Server
4041

4142
**Developer Tools**
4243

@@ -63,4 +64,4 @@
6364
make
6465
sudo make install
6566

66-
mozroots --import --sync
67+
mozroots --import --sync

aspnet/benchmark_config

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@
5353
"port": 8080,
5454
"sort": 93
5555
},
56+
"sqlserver-raw": {
57+
"setup_file": "setup_iis",
58+
"os": "nt",
59+
"db_url": "/ado/sqlserver",
60+
"query_url": "/ado/sqlserver?queries=",
61+
"fortune_url": "/ado/sqlserver/fortunes",
62+
"update_url": "/ado/sqlserver/update?queries=",
63+
"port": 8080,
64+
"sort": 94
65+
},
5666
"mysql-entityframework": {
5767
"setup_file": "setup_iis",
5868
"os": "nt",
@@ -61,7 +71,7 @@
6171
"fortune_url": "/entityframework/mysql/fortunes",
6272
"update_url": "/entityframework/mysql/update?queries=",
6373
"port": 8080,
64-
"sort": 94
74+
"sort": 95
6575
},
6676
"postgresql-entityframework": {
6777
"setup_file": "setup_iis",
@@ -71,7 +81,17 @@
7181
"fortune_url": "/entityframework/postgresql/fortunes",
7282
"update_url": "/entityframework/postgresql/update?queries=",
7383
"port": 8080,
74-
"sort": 95
84+
"sort": 96
85+
},
86+
"sqlserver-entityframework": {
87+
"setup_file": "setup_iis",
88+
"os": "nt",
89+
"db_url": "/entityframework/sqlserver",
90+
"query_url": "/entityframework/sqlserver?queries=",
91+
"fortune_url": "/entityframework/sqlserver/fortunes",
92+
"update_url": "/entityframework/sqlserver/update?queries=",
93+
"port": 8080,
94+
"sort": 97
7595
},
7696
"mono": {
7797
"setup_file": "setup_nginx",

aspnet/src/Application.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private void Routes()
4545
name: "WithProviders",
4646
url: "{controller}/{providerName}/{action}",
4747
defaults: new { action = "Index" },
48-
constraints: new { controller = "ado|entityframework", providerName = "mysql|postgresql" }
48+
constraints: new { controller = "ado|entityframework", providerName = "mysql|postgresql|sqlserver" }
4949
);
5050

5151
RouteTable.Routes.MapRoute(

aspnet/src/Controllers/AdoController.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,16 @@ public ActionResult Update(string providerName, int? queries)
143143
if (world == null)
144144
continue;
145145

146+
DbParameter idUpdateParameter = updateCommand.CreateParameter();
147+
idUpdateParameter.ParameterName = "@ID";
148+
idUpdateParameter.Value = randomID;
149+
146150
DbParameter numberParameter = updateCommand.CreateParameter();
147151
numberParameter.ParameterName = "@Number";
148152
numberParameter.Value = randomNumber;
149153

150154
updateCommand.Parameters.Clear();
151-
updateCommand.Parameters.Add(idParameter);
155+
updateCommand.Parameters.Add(idUpdateParameter);
152156
updateCommand.Parameters.Add(numberParameter);
153157

154158
updateCommand.ExecuteNonQuery();

aspnet/src/Web.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@
99
<add name="MySQL" connectionString="server=localhost; user id=benchmarkdbuser; password=benchmarkdbpass; database=hello_world" providerName="MySql.Data.MySqlClient"/>
1010
<add name="PostgreSQL" connectionString="server=localhost; user id=benchmarkdbuser; password=benchmarkdbpass; database=hello_world" providerName="Npgsql"/>
1111
<add name="MongoDB" connectionString="mongodb://localhost"/>
12+
<add name="SQLServer" connectionString="server=localhost; user id=benchmarkdbuser; password=B3nchmarkDBPass; database=hello_world" providerName="System.Data.SqlClient"/>
1213
</connectionStrings>
1314
<!-- ADO.NET -->
1415
<system.data>
1516
<DbProviderFactories>
1617
<clear/>
1718
<add name="MySql.Data.MySqlClient" description="Data Provider for MySQL" invariant="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.7.2.0"/>
1819
<add name="Npgsql" description="Data Provider for PostgreSQL" invariant="Npgsql" type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0"/>
20+
<add name="SqlClient Data Provider" description=".Net Framework Data Provider for SqlServer" invariant="System.Data.SqlClient" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
1921
</DbProviderFactories>
2022
</system.data>
2123
<!-- Entity Framework -->
2224
<entityFramework>
2325
<providers>
2426
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity, Version=6.7.2.0"/>
2527
<provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, Npgsql, Version=2.0.12.0"/>
28+
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
2629
</providers>
2730
</entityFramework>
2831
<appSettings>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- This SQL Server T-SQL script creates the database user and hello_world database.
2+
--
3+
-- To run this script, login to an administrator account in Windows, open a command prompt and run:
4+
--
5+
-- "%ProgramFiles%\Microsoft SQL Server\110\Tools\binn\sqlcmd.exe" -i <filename of this file>
6+
--
7+
8+
IF EXISTS (SELECT * FROM sys.server_principals WHERE name = 'benchmarkdbuser')
9+
DROP LOGIN benchmarkdbuser
10+
GO
11+
12+
-- This password has mixed-case and a number to satisfy the Windows password policy
13+
CREATE LOGIN benchmarkdbuser WITH PASSWORD = 'B3nchmarkDBPass'
14+
GO
15+
16+
IF EXISTS(SELECT * FROM SYS.DATABASES WHERE NAME='hello_world')
17+
DROP DATABASE hello_world
18+
GO
19+
20+
CREATE DATABASE hello_world
21+
GO
22+
USE hello_world
23+
GO
24+
25+
-- Give this user total power over the database
26+
CREATE USER benchmarkdbuser FOR LOGIN benchmarkdbuser
27+
EXEC sp_addrolemember 'db_owner', 'benchmarkdbuser'
28+
GO

config/create-sqlserver.sql

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
-- This SQL Server T-SQL script creates and populates the World and Fortune tables.
2+
--
3+
-- To run this script, make sure that you've already run create-sqlserver-login-and-database.sql
4+
-- to create the database user and database, then open a command prompt and run:
5+
--
6+
-- "%ProgramFiles%\Microsoft SQL Server\110\Tools\binn\sqlcmd.exe" -U benchmarkdbuser -P B3nchmarkDBPass -d hello_world -i <filename of this file>
7+
8+
IF OBJECT_ID('World', 'U') IS NOT NULL
9+
DROP TABLE World
10+
GO
11+
12+
CREATE TABLE World (
13+
id int NOT NULL IDENTITY PRIMARY KEY,
14+
randomNumber int NOT NULL default 0
15+
)
16+
GO
17+
18+
-- Populate World table
19+
DECLARE @RowCount INT
20+
DECLARE @Random INT
21+
SET @RowCount = 0
22+
23+
WHILE @RowCount < 10000
24+
BEGIN
25+
SELECT @Random = ((10000 + 1) - 1) * RAND() + 1
26+
INSERT INTO World (randomNumber) VALUES (@Random)
27+
SET @RowCount = @RowCount + 1
28+
END
29+
30+
GO
31+
32+
IF OBJECT_ID('Fortune', 'U') IS NOT NULL
33+
DROP TABLE Fortune
34+
GO
35+
36+
-- Note that this uses nvarchar to make sure that the column is Unicode.
37+
CREATE TABLE Fortune (
38+
id int NOT NULL IDENTITY PRIMARY KEY,
39+
message nvarchar(2048) NOT NULL
40+
)
41+
GO
42+
43+
INSERT INTO Fortune (message) VALUES (N'fortune: No such file or directory');
44+
INSERT INTO Fortune (message) VALUES (N'A computer scientist is someone who fixes things that aren''t broken.');
45+
INSERT INTO Fortune (message) VALUES (N'After enough decimal places, nobody gives a damn.');
46+
INSERT INTO Fortune (message) VALUES (N'A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1');
47+
INSERT INTO Fortune (message) VALUES (N'A computer program does what you tell it to do, not what you want it to do.');
48+
INSERT INTO Fortune (message) VALUES (N'Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen');
49+
INSERT INTO Fortune (message) VALUES (N'Any program that runs right is obsolete.');
50+
INSERT INTO Fortune (message) VALUES (N'A list is only as strong as its weakest link. — Donald Knuth');
51+
INSERT INTO Fortune (message) VALUES (N'Feature: A bug with seniority.');
52+
INSERT INTO Fortune (message) VALUES (N'Computers make very fast, very accurate mistakes.');
53+
INSERT INTO Fortune (message) VALUES (N'<script>alert("This should not be displayed in a browser alert box.");</script>');
54+
INSERT INTO Fortune (message) VALUES (N'フレームワークのベンチマーク');
55+
GO

setup-sqlserver-bootstrap.ps1

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# To download and run this script, open an elevated Command Prompt and then run:
2+
#
3+
# powershell -ExecutionPolicy Bypass -Command "iex (New-Object Net.WebClient).DownloadString('https://raw.github.com/TechEmpower/FrameworkBenchmarks/master/setup-sqlserver-bootstrap.ps1')"
4+
5+
$basedir = "C:\FrameworkBenchmarks"
6+
$rawRepo = "https://raw.github.com/TechEmpower/FrameworkBenchmarks/master"
7+
8+
$config_url = $basedir + "/config"
9+
$config_local = $basedir + "\config"
10+
$setup_sqlserver_url = $rawRepo + "/setup-sqlserver.ps1"
11+
$setup_sqlserver_local = $basedir + "\setup-sqlserver.ps1"
12+
$create_sqlserver_login_and_database_url = $config_url + "/create-sqlserver-login-and-database.sql"
13+
$create_sqlserver_login_and_database_local = $config_local + "/create-sqlserver-login-and-database.sql"
14+
$create_sqlserver_url = $config_url + "/create-sqlserver.sql"
15+
$create_sqlserver_local = $config_local + "/create-sqlserver.sql"
16+
17+
Write-Host "Creating directory: $config`n"
18+
New-Item -Path $config_local -Type Directory -Force | Out-Null
19+
20+
Write-Host "Downloading setup files...`n"
21+
(New-Object System.Net.WebClient).DownloadFile($setup_sqlserver_url, $setup_sqlserver_local)
22+
(New-Object System.Net.WebClient).DownloadFile($create_sqlserver_login_and_database_url, $create_sqlserver_login_and_database_local)
23+
(New-Object System.Net.WebClient).DownloadFile($create_sqlserver_url, $create_sqlserver_local)
24+
25+
powershell -ExecutionPolicy Bypass -File $setup_sqlserver_local

setup-sqlserver.ps1

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# This script downloads and installs SQL Server and opens it on port 1433.
2+
#
3+
# To run this script, run an elevated Command Prompt and enter:
4+
#
5+
# powershell -ExecutionPolicy Bypass -File <this script's filename>
6+
7+
$basedir = "C:\FrameworkBenchmarks"
8+
$workdir = "$basedir\installs"
9+
New-Item -Path $workdir -Type directory -Force | Out-Null
10+
11+
If (-Not (Get-Service | ? Name -Eq "MSSQLSERVER")) {
12+
13+
Write-Host "Could not find default SQL Server instance, MSSQLSERVER."
14+
Write-Host "Downloading SQL Server (several GBs)..."
15+
16+
# URLs from http://www.microsoft.com/en-us/download/details.aspx?id=35575
17+
18+
$sqlserver_exe_url = "http://download.microsoft.com/download/3/B/D/3BD9DD65-D3E3-43C3-BB50-0ED850A82AD5/SQLServer2012SP1-FullSlipstream-x64-ENU.exe"
19+
$sqlserver_exe_local = "$workdir\SQLServer2012SP1-FullSlipstream-x64-ENU.exe"
20+
(New-Object System.Net.WebClient).DownloadFile($sqlserver_exe_url, $sqlserver_exe_local)
21+
22+
$sqlserver_box_url = "http://download.microsoft.com/download/3/B/D/3BD9DD65-D3E3-43C3-BB50-0ED850A82AD5/SQLServer2012SP1-FullSlipstream-x64-ENU.box"
23+
$sqlserver_box_local = "$workdir\SQLServer2012SP1-FullSlipstream-x64-ENU.box"
24+
(New-Object System.Net.WebClient).DownloadFile($sqlserver_box_url, $sqlserver_box_local)
25+
26+
Write-Host "Installing SQL Server..."
27+
28+
# Install only the SQL Server database engine.
29+
# Use a default instance name.
30+
# Make %COMPUTERNAME%\Administrators have administrative rights.
31+
32+
# The following is not used because this is done in PowerShell below.
33+
# /securitymode=SQL /sapwd=S3cr3tS3cr3t /TCPENABLED=1
34+
# Allow Windows Authentication or old-style SQL authentication.
35+
# The password of the sa account is specified.
36+
# SQL Server will be listening on TCP port 1433.
37+
#
38+
Start-Process "$sqlserver_exe_local" "/q /action=install /features=SQLEngine /INSTANCENAME=MSSQLSERVER /SQLSYSADMINACCOUNTS=Administrators /IACCEPTSQLSERVERLICENSETERMS" -Wait
39+
}
40+
41+
# In case we just installed SQL Server and the environment variables haven't been refreshed, manually
42+
# refresh PSModulePath so that Import-Module sqlps will work.
43+
44+
$env:PSModulePath = [Environment]::GetEnvironmentVariable("PSModulePath", [System.EnvironmentVariableTarget]::Machine)
45+
46+
Import-Module sqlps
47+
48+
Write-Host "Setting SQL Server to start on boot..."
49+
50+
Set-Service MSSQLSERVER -StartupType Automatic
51+
52+
Write-Host "Ensuring that SQL Server is started..."
53+
54+
Start-Service MSSQLSERVER
55+
56+
Write-Host "Enabling SQL authentication..."
57+
58+
# Enable SQL authentication
59+
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server')
60+
$s.Settings.LoginMode = [Microsoft.SqlServer.Management.SMO.ServerLoginMode]::Mixed
61+
$s.Alter()
62+
63+
Write-Host "Configuring SQL Server to listen on TCP (default port 1433)..."
64+
65+
# Enable the TCP protocol on the default instance.
66+
$wmi = New-Object ('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer')
67+
$uri = "ManagedComputer[@Name='" + (Get-Content env:computername) + "']/ ServerInstance[@Name='MSSQLSERVER']/ServerProtocol[@Name='Tcp']"
68+
$Tcp = $wmi.GetSmoObject($uri)
69+
$Tcp.IsEnabled = $true
70+
$Tcp.Alter()
71+
72+
Write-Host "Restarting SQL Server..."
73+
74+
Restart-Service -Name MSSQLSERVER
75+
76+
If (-Not (Get-NetFirewallPortFilter | ? LocalPort -Eq "1433")) {
77+
Write-Host "Opening port 1433 in firewall..."
78+
New-NetFirewallRule -DisplayName "SQL 1433" -Action Allow -Direction Inbound -LocalPort 1433 -Protocol TCP | Out-Null
79+
} else {
80+
Write-Host "Port 1433 is already configured in firewall."
81+
}
82+
83+
Write-Host "Creating SQL Server login and populated database..."
84+
85+
# Connect with Windows Authentication, assuming that we have access.
86+
Invoke-Sqlcmd -InputFile "$basedir\config\create-sqlserver-login-and-database.sql" -OutputSqlErrors $True
87+
88+
# Now that benchmarkdbuser has been created, we can connect with those credentials.
89+
Invoke-Sqlcmd -Username benchmarkdbuser -Password B3nchmarkDBPass -Database hello_world -InputFile "$basedir\config\create-sqlserver.sql" -OutputSqlErrors $True
90+
91+
Write-Host "Done."

0 commit comments

Comments
 (0)