tl;dr
Windows 上で起動しているプロセスを Serverspec でテストする際に調べたので自分メモ。
参考
メモ
やりたかったこと
オレオレスクリプト
以下のようにオレオレスクリプトを起動する。
PS C:\path\to\scripts> start python.exe .\o-re-no-service02.py
実行すると以下のようにコマンドプロンプトが立ち上がって、その中でスクリプトが起動する。

Serverspec on Windows ではどんな風にプロセスの情報を取得しているのか(超ザックリと)
こちらのドキュメントに書かれているように、Serverspec の command については全て PowerShell スクリプトを実行するようになっているので、プロセスの情報を取得する場合には以下のようなスクリプトが実行される(Cmdlet が実行される)。
例えば...
describe process("python.exe") do it { should be_running } end
というテストがある場合には、Serverspec の process.rb から以下のメソッドが呼ばれる。
def running? pid = @runner.get_process(@name, :format => "pid=").stdout not pid.empty? end
次に Specinfra の process.rb 内の以下のメソッドが呼ばる。
def get(process, opts) column = opts[:format].chomp '=' case column when 'pid' # map 'pid' to its windows equivalent get_process_property(process, 'processid') when 'user' %Q!gwmi win32_process -filter "name = '#{process}'" | select -first 1 | %{$_.getowner().user}! when 'group' # no concept of process group on Windows raise NotImplementedError.new('Unable to get process group on Windows') else get_process_property(process, column) end end
そして、マッチャが should be_running の場合には、opts[:format] には pid が指定されているので、同じ process.rb 内の以下の private メソッドを get_process_property(process, processid) で呼び出す。
def get_process_property(process, property) %Q!Get-WmiObject Win32_Process -Filter "name = '#{process}'" | select -First 1 #{property} -ExpandProperty #{property}! end
試しに上記のメソッド内で実行される PowerShell スクリプトを実行してみる。
PS C:\path\to\scripts> Get-WmiObject Win32_Process -Filter "name = 'python.exe'" | select -First 1 processid -ExpandProperty processid
以下のようにプロセス ID が返ってくる。
PS C:\path\to\scripts> Get-WmiObject Win32_Process -Filter "name = 'python.exe'" | select -First 1 processid -ExpandProperty processid 764
ということで...
引数も含めてプロセスが起動していることを確認したい場合にどうするか。
先ほどの PowerShell スクリプトをもう一度実行してみる。但し、以下のように絞込は行わず、全てのプロパティを出力してみる。
PS C:\path\to\scripts> Get-WmiObject Win32_Process -Filter "name = 'python.exe'" | select -First 1
以下のように出力される。
__GENUS : 2
__CLASS : Win32_Process
__SUPERCLASS : CIM_Process
__DYNASTY : CIM_ManagedSystemElement
__RELPATH : Win32_Process.Handle="764"
__PROPERTY_COUNT : 45
__DERIVATION : {CIM_Process, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER : WIN-LLA3FAS3UBE
__NAMESPACE : root\cimv2
__PATH : \\WIN-LLA3FAS3UBE\root\cimv2:Win32_Process.Handle="764"
Caption : python.exe
CommandLine : "C:\Python27\python.exe" .\o-re-no-service02.py
CreationClassName : Win32_Process
CreationDate : 20160320094741.949928+000
CSCreationClassName : Win32_ComputerSystem
CSName : WIN-LLA3FAS3UBE
Description : python.exe
ExecutablePath : C:\Python27\python.exe
ExecutionState :
Handle : 764
HandleCount : 68
InstallDate :
KernelModeTime : 156001
MaximumWorkingSetSize : 1380
MinimumWorkingSetSize : 200
Name : python.exe
OSCreationClassName : Win32_OperatingSystem
OSName : Microsoft Windows Server 2012 Standard|C:\Windows|\Device\Harddisk0\Partition2
OtherOperationCount : 2233
OtherTransferCount : 36862
PageFaults : 1731
PageFileUsage : 3292
ParentProcessId : 1032
PeakPageFileUsage : 3292
PeakVirtualSize : 68542464
PeakWorkingSetSize : 6712
Priority : 8
PrivatePageCount : 3371008
ProcessId : 764
QuotaNonPagedPoolUsage : 7
QuotaPagedPoolUsage : 124
QuotaPeakNonPagedPoolUsage : 7
QuotaPeakPagedPoolUsage : 124
ReadOperationCount : 118
ReadTransferCount : 493182
SessionId : 2
Status :
TerminationDate :
ThreadCount : 1
UserModeTime : 624004
VirtualSize : 68542464
WindowsVersion : 6.2.9200
WorkingSetSize : 6873088
WriteOperationCount : 1797
WriteTransferCount : 83834
PSComputerName : WIN-LLA3FAS3UBE
ProcessName : python.exe
Handles : 68
VM : 68542464
WS : 6873088
Path : C:\Python27\python.exe
上記を見ると、CommandLine というプロパティにスクリプトを実行した際の引数も出力されているので、この CommandLine を利用すれば良さそうということで、以下のようにテストを書いた。
describe process("python.exe") do it { should be_running } its(:CommandLine) { should match /o-re-no-service02.py/ } end
そして、テスト
以下のようにテストは無事に通った。

良かった。
ということで
process リソースについては
Cmdlet の Get-WmiObject Win32_Process を利用していることが解ったので、必要に応じて Get-WmiObject Win32_Process の出力結果からチェックしたいプロパティをピックアップしてテストを書けば良いと思う。
以上
メモでした! 間違ってたらごめんなさい!