-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathverify.ps1
More file actions
164 lines (139 loc) · 8.02 KB
/
Copy pathverify.ps1
File metadata and controls
164 lines (139 loc) · 8.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# verify.ps1 — end-to-end verification that kvstore actually works.
#
# Runs three checks beyond the unit-test suite:
# 1. Live RESP smoke test against a real TCP server (17 commands)
# 2. Crash recovery: write 5,000 keys, kill -9 the server, restart, verify
# 3. JMH performance benchmarks (optional, slow — pass -SkipBench to skip)
#
# Run from the project root:
# pwsh -File verify.ps1
# pwsh -File verify.ps1 -SkipBench
param([switch]$SkipBench)
$env:JAVA_HOME = "C:\Program Files\Microsoft\jdk-21.0.11.10-hotspot"
$env:PATH = "$env:JAVA_HOME\bin;$env:USERPROFILE\tools\maven\apache-maven-3.9.16\bin;$env:PATH"
Set-Location $PSScriptRoot
function MkResp { param([string[]]$Parts)
$sb = New-Object System.Text.StringBuilder
[void]$sb.Append("*$($Parts.Count)`r`n")
foreach ($a in $Parts) {
$bytes = [System.Text.Encoding]::UTF8.GetByteCount($a)
[void]$sb.Append("`$$bytes`r`n$a`r`n")
}
return $sb.ToString()
}
function Send-Multi { param([string]$Address, [int]$Port, [string[]]$Commands)
$client = New-Object System.Net.Sockets.TcpClient($Address, $Port)
$stream = $client.GetStream()
$replies = @()
foreach ($c in $Commands) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($c)
$stream.Write($bytes, 0, $bytes.Length); $stream.Flush()
Start-Sleep -Milliseconds 100
$buf = New-Object byte[] 8192
try { $n = $stream.Read($buf, 0, $buf.Length); $replies += [System.Text.Encoding]::UTF8.GetString($buf, 0, $n) }
catch { $replies += "[error]" }
}
$client.Close()
return $replies
}
function Fmt { param([string]$s) return $s.Replace("`r","\r").Replace("`n","\n") }
# ----------------------------------------------------------------------------
Write-Output "=== Build ==="
if (-not (Test-Path target/kvstore-0.1.0.jar)) {
mvn package -DskipTests -q
}
if (-not (Test-Path target/kvstore-0.1.0.jar)) {
Write-Error "Build failed"; exit 1
}
Write-Output "Built target/kvstore-0.1.0.jar"
# ----------------------------------------------------------------------------
Write-Output ""
Write-Output "=== 1. Live RESP smoke test ==="
Get-Process java -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
if (Test-Path verify-data) { Remove-Item -Recurse -Force verify-data -ErrorAction SilentlyContinue }
$srv = Start-Process -FilePath "java" -ArgumentList "-jar","target/kvstore-0.1.0.jar","serve","--port","6392","--data","verify-data" -NoNewWindow -RedirectStandardOutput "verify-srv.log" -RedirectStandardError "verify-srv.err.log" -PassThru
Start-Sleep -Seconds 3
$tests = @(
@{ Name="PING"; Cmd=(MkResp @("PING")); Expect="+PONG`r`n" },
@{ Name="SET hello"; Cmd=(MkResp @("SET","hello","world")); Expect="+OK`r`n" },
@{ Name="GET hello"; Cmd=(MkResp @("GET","hello")); Expect="`$5`r`nworld`r`n" },
@{ Name="INCR counter"; Cmd=(MkResp @("INCR","counter")); Expect=":1`r`n" },
@{ Name="INCRBY counter 9"; Cmd=(MkResp @("INCRBY","counter","9")); Expect=":10`r`n" },
@{ Name="DECR counter"; Cmd=(MkResp @("DECR","counter")); Expect=":9`r`n" },
@{ Name="SET ttl EX 60"; Cmd=(MkResp @("SET","ttlkey","tmp","EX","60")); Expect="+OK`r`n" },
@{ Name="TTL ttlkey"; Cmd=(MkResp @("TTL","ttlkey")); ExpectPattern="^:[1-9]\d*`r`n$" },
@{ Name="EXISTS hello miss"; Cmd=(MkResp @("EXISTS","hello","missing")); Expect=":1`r`n" },
@{ Name="MGET 3 keys"; Cmd=(MkResp @("MGET","hello","counter","missing")); ExpectPattern="^\*3`r`n" },
@{ Name="DBSIZE"; Cmd=(MkResp @("DBSIZE")); ExpectPattern="^:\d+`r`n$" },
@{ Name="SCAN a z"; Cmd=(MkResp @("SCAN","a","z")); ExpectPattern="^\*\d+`r`n" },
@{ Name="BGSAVE"; Cmd=(MkResp @("BGSAVE")); Expect="+Background saving started`r`n" },
@{ Name="LASTSAVE"; Cmd=(MkResp @("LASTSAVE")); ExpectPattern="^:\d+`r`n$" },
@{ Name="DEL hello"; Cmd=(MkResp @("DEL","hello")); Expect=":1`r`n" },
@{ Name="GET hello (gone)"; Cmd=(MkResp @("GET","hello")); Expect="`$-1`r`n" },
@{ Name="Unknown cmd"; Cmd=(MkResp @("FROBNICATE")); ExpectPattern="^-ERR unknown" }
)
$replies = Send-Multi "127.0.0.1" 6392 ($tests | ForEach-Object { $_.Cmd })
$pass = 0; $fail = 0
for ($i = 0; $i -lt $tests.Count; $i++) {
$t = $tests[$i]; $r = $replies[$i]
$ok = $false
if ($t.Expect) { $ok = ($r -eq $t.Expect) }
elseif ($t.ExpectPattern) { $ok = ($r -match $t.ExpectPattern) }
if ($ok) { $pass++ } else { $fail++ }
$status = if ($ok) { "PASS" } else { "FAIL" }
Write-Output ("[$status] {0,-22} -> {1}" -f $t.Name, (Fmt $r))
}
Write-Output "Smoke test: $pass passed, $fail failed"
Stop-Process -Id $srv.Id -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
# ----------------------------------------------------------------------------
Write-Output ""
Write-Output "=== 2. Crash recovery test ==="
if (Test-Path verify-data) { Remove-Item -Recurse -Force verify-data -ErrorAction SilentlyContinue }
$srv = Start-Process -FilePath "java" -ArgumentList "-jar","target/kvstore-0.1.0.jar","serve","--port","6393","--data","verify-data" -NoNewWindow -RedirectStandardOutput "verify-srv.log" -RedirectStandardError "verify-srv.err.log" -PassThru
Start-Sleep -Seconds 3
Write-Output "Server PID: $($srv.Id) — writing 5,000 keys..."
$cmds = @()
for ($i = 0; $i -lt 5000; $i++) { $cmds += MkResp @("SET", "key-$($i.ToString('D5'))", "value-$i") }
$null = Send-Multi "127.0.0.1" 6393 $cmds
$pre = Send-Multi "127.0.0.1" 6393 @((MkResp @("DBSIZE")))
Write-Output ("Pre-crash DBSIZE: " + (Fmt $pre[0]))
Write-Output "Killing server with -9..."
Stop-Process -Id $srv.Id -Force
Start-Sleep -Seconds 2
Write-Output "Restarting..."
$srv2 = Start-Process -FilePath "java" -ArgumentList "-jar","target/kvstore-0.1.0.jar","serve","--port","6394","--data","verify-data" -NoNewWindow -RedirectStandardOutput "verify-srv.log" -RedirectStandardError "verify-srv.err.log" -PassThru
Start-Sleep -Seconds 4
$verify = Send-Multi "127.0.0.1" 6394 @(
(MkResp @("GET","key-00000")),
(MkResp @("GET","key-02500")),
(MkResp @("GET","key-04999")),
(MkResp @("DBSIZE"))
)
$survivors = 0
if ($verify[0] -match "value-0`r`n$") { Write-Output "[PASS] key-00000 survived"; $survivors++ } else { Write-Output "[FAIL] key-00000 -> $(Fmt $verify[0])" }
if ($verify[1] -match "value-2500`r`n$") { Write-Output "[PASS] key-02500 survived"; $survivors++ } else { Write-Output "[FAIL] key-02500 -> $(Fmt $verify[1])" }
if ($verify[2] -match "value-4999`r`n$") { Write-Output "[PASS] key-04999 survived"; $survivors++ } else { Write-Output "[FAIL] key-04999 -> $(Fmt $verify[2])" }
Write-Output ("Post-crash DBSIZE: " + (Fmt $verify[3]))
Write-Output "Crash recovery: $survivors / 3 spot-checked keys survived"
Stop-Process -Id $srv2.Id -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
# ----------------------------------------------------------------------------
if (-not $SkipBench) {
Write-Output ""
Write-Output "=== 3. JMH benchmarks (~2 min) ==="
if (-not (Test-Path target/kvstore-0.1.0-benchmarks.jar)) {
Write-Output "Building benchmarks jar..."
mvn package -DskipTests -q
}
java -jar target/kvstore-0.1.0-benchmarks.jar -wi 1 -i 2 -f 1 -t 1 2>&1 | Select-Object -Last 12
}
# ----------------------------------------------------------------------------
# Cleanup
Get-Process java -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
if (Test-Path verify-data) { Remove-Item -Recurse -Force verify-data -ErrorAction SilentlyContinue }
Remove-Item verify-srv.log,verify-srv.err.log -ErrorAction SilentlyContinue
Write-Output ""
Write-Output "=== Done ==="