tl;dr
Windows 上で起動しているプロセスを Serverspec でテストする際に調べたので自分メモ。
参考
github.com
serverspec.org
github.com
メモ
やりたかったこと
対象の Windows ホスト上で自分で作った Python スクリプトが引数も含めて正常に動いているかについてチェックしたかった
オレオレスクリプト
以下のようにオレオレスクリプトを起動する。
PS C:pathtoscripts> 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:pathtoscripts> Get-WmiObject Win32_Process -Filter "name = 'python.exe'" | select -First 1 processid -ExpandProperty processid
以下のようにプロセス ID が返ってくる。
PS C:pathtoscripts> Get-WmiObject Win32_Process -Filter "name = 'python.exe'" | select -First 1 processid -ExpandProperty processid 764
ということで…
引数も含めてプロセスが起動していることを確認したい場合にどうするか。
先ほどの PowerShell スクリプトをもう一度実行してみる。但し、以下のように絞込は行わず、全てのプロパティを出力してみる。
PS C:pathtoscripts> 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 : rootcimv2 __PATH : \WIN-LLA3FAS3UBErootcimv2:Win32_Process.Handle="764" Caption : python.exe CommandLine : "C:Python27python.exe" .o-re-no-service02.py CreationClassName : Win32_Process CreationDate : 20160320094741.949928+000 CSCreationClassName : Win32_ComputerSystem CSName : WIN-LLA3FAS3UBE Description : python.exe ExecutablePath : C:Python27python.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|DeviceHarddisk0Partition2 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:Python27python.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
の出力結果からチェックしたいプロパティをピックアップしてテストを書けば良いと思う。
以上
メモでした! 間違ってたらごめんなさい!