しばたテックブログ

気分で書いている技術ブログです。

Windows 10でロードアベレージを取得する?

小ネタです。

ふと、「Bash on Ubuntu on Windowsを使えばWindowsでもロードアベレージを取得できるよなぁ…」と思ったので実際に試してみました。

Windowsのロードアベレージ

www.atmarkit.co.jp

上の記事に詳細が説明されていますが、WindowsではUNIXやLinuxのロードアベレージと同等の値を取得することはできません。
類似の値としてパフォーマンスカウンターの\System\Processor Queue Lengthが紹介されており、通常はこれを使うしかありません。

PowerShellでこの値を取得するにはGet-Counterコマンドを使い以下の様にすれば良いです。

(Get-Counter -Counter "\System\Processor Queue Length").CounterSamples.CookedValue

このカウンターはデフォルトのスケールが1なのでCookedValueがそのまま使えます。

また、平均を取るには以下の様な感じすれば一応可能です。*1
(以下のサンプルを実行すると1分間待たされるので注意してください)

# UNIX/Linuxでのサンプリング間隔は5秒だそうなので、それに合わせて1分間の平均を求めます
(Get-Counter -Counter "\System\Processor Queue Length" -SampleInterval 5 -MaxSamples 12).CounterSamples.CookedValue `
    | Measure-Object -Average | Select-Object -ExpandProperty Average

Windows 10でロードアベレージを取得する

Windows 10でWSLを有効にすればWindows内でUbuntuが動作しますので、Ubuntu経由でロードアベレージの値が取得できるはずです。

Ubuntuでロードアベレージを取得するにはtopuptimeといったコマンドや/proc/loadavgを参照すれば可能です。

f:id:stknohg:20170427225852p:plain

f:id:stknohg:20170427230745p:plain

f:id:stknohg:20170427225912p:plain

やり方はいろいろありますが、今回は/proc/loadavgを参照する方法で2パターン試してみました。

方法.1

最初の方法はこんな感じです。

# PowerShell
'cat /proc/loadavg|awk ''{print "@{Load1="$1";Load5="$2";Load15="$3";}"}'';exit;' | bash | iex

実行結果)

f:id:stknohg:20170427230256p:plain

UbuntuのBashで/proc/loadavgの値を取得、awkでPowerShellのHashTableの書式(@{Load1=$1;Load5=$2;Load15=$3;})に成形し、Invoke-Expression(iex)でHashTableに変換しています。

方法.2

もう一つの方法はこんな感じです。

# PowerShell
'cat /proc/loadavg;exit;' | bash | % {$v=-split $_;@{Load1=$v[0];Load5=$v[1];Load15=$v[2];}}

実行結果)

f:id:stknohg:20170427230307p:plain

こちらは、Bashでは/proc/loadavgの値を取得するだけにして、PowerShellで値の成形をする様にしています。

他にもいろいろなやり方があると思います。
BashとPowerShellをどういった塩梅で組み合わせるかを考えるのはとても楽しいです。

残念なお知らせ

ここまで書いておいてアレなのですが非常に残念なお知らせがあります。

このエントリの内容を試している最中にロードアベレージの値が全然変化せず、違和感を感じたので調査してみたところ、以下のIssueが上がっていました。

github.com

現時点ではBash on Ubuntu on Windowsのロードアベレージは0.52 0.58 0.59のダミー値を返すというふざけた状態でした…*2
まだベータ版ですので値が取れないのは仕方ないと思いますが、せめて0 0 0といった自明な値にしておいてほしいものです。

こちらについては気長に待つしかないといったところでしょう。

最後に

最後にとんでもないオチがついてしまいましたがこんな感じです。
本エントリは現時点では全く役に立ちませんが、いずれ役に立つ日がくると信じています。

いまのところはBashとPowerShellを組み合わせて使う一例として見ていただければと思います。

*1:実運用では使えないと思いますが…

*2:しばらく普通に騙されてましたよ…

Pester 4での新機能・変更点まとめ

元ネタはこちら。

github.com

そろそろPester 4のリリースも近づいているかなと思い、新機能や変更点をざっくりとまとめてみました。

Pester 4のインストール

現時点での最新版はVer.4.0.3(Release Candidate扱い)となっており、PowerShell Galleryから入手することができます。

Install-Module Pesterコマンドで普通にインストールできるはずですが、PowerShell 5.0以降の環境であれば標準でPester(Ver.3系)がインストール済みであるため-Force-SkipPublisherCheckgetパラメーターを指定する必要があるかもしれません。
私の環境では両方のパラメーター指定が必要でした。

インストール例)

Install-Module Pester -Scope CurrentUser -Force -SkipPublisherCheckget

これでPester 4の新機能を試すことができます。

1. 文法の変更

最初はVer.4で発生した文法の変更について記載します。

Shouldとともに使用していたBe等の動詞がVer.4から名前付きのダイナミックパラメーターとなり、-Beの様に指定することが可能になりました。
互換性を維持するため従来の記法は残されていますがいずれ廃止されるそうです。(時期は未定)

以下に簡単な例を示します。

# 従来の文法
Import-Module Pester -MaximumVersion 3.4.0 -Force

Describe '従来の文法 - 動詞のパラメーター化' {
    It '足し算のテスト' {
        1 + 1 | Should Be 2
    }
}
# Ver.4からの文法
Import-Module Pester -MinimumVersion 4.0.3 -Force

Describe '新しい文法 - 動詞のパラメーター化' {
    It '足し算のテスト' {
        # BeなどがShouldの名前付きパラメーターに
        1 + 1 | Should -Be 2
    }
}

この変更によりISEやVSCodeなどのインテリセンスに各動詞が表示される様になり、よりコーディングがしやくすなります。

f:id:stknohg:20170414200034p:plain

2. 配列を入力する際の仕様変更

Should Beにおける配列の扱いがVer.4から変更されます。

Ver.3までは以下のテストは$trueを返していましたが、Ver.4からこれは$falseを返す様になります。

# 従来の挙動
Import-Module Pester -MaximumVersion 3.4.0 -Force

Describe '従来の文法 - 配列の挙動' {
    It 'バージョン3までは通るテスト' {
        @( $true, $true, $true ) | Should Be $true
    }
}

Ver.4からこのテストを通すには以下の様に記述する必要があります。

# Ver.4からの挙動
Import-Module Pester -MinimumVersion 4.0.3 -Force

Describe '新しい文法 - 配列の挙動' {
    It 'バージョン4で通るテスト' {
        @( $true, $true, $true ) | Should -Be @( $true, $true, $true )
    }
}

見てわかるかと思いますが、Ver.4からはShouldに対して配列の要素ではなく配列全体が比較の対象になる様に変更されています。

3. 表示色の刷新

Ver.4からテスト結果の表示色が新しくなります。

Ver.3までの色はこちら。

f:id:stknohg:20170414200756p:plain

Ver.4からの色はこちら。

f:id:stknohg:20170414200817p:plain

色を変えた意図がいまいち掴めなかったのですが、コミットログを追う限りでは、従来ホスト毎にカラースキームを持ち色分けしていた部分を統一しシンプルにした影響を受けている様です。

4. ContextとDescribeのネスト

Ver.4からContextDescribeをネストすることが可能になります。
Ver.3まではネストするとエラーになりました。

設定例)

# Ver.4からの挙動
Import-Module Pester -MinimumVersion 4.0.3 -Force

Describe '新しい文法 - Describe ネスト1' {
    Describe '新しい文法 - Describe ネスト2' {
        Context '新しい文法 - Context ネスト1' {
            It '足し算のテスト' {
                1 + 1 | Should -Be 2
            }
        }
    }
}

5. Gherkinのサポート

Ver.4からPesterでGherkin(ガーキン)を使ったFeatureファイルによるテストがサポートされる様になりました。

Gherkinとは何ぞやといった話については、

いまさら聞けないTDD/BDD超入門(2):TDD/BDDの思想とテスティングフレームワークの関係を整理しよう (3/3) - @IT

Cucumber のフィーチャの文法 - Gherkin | そんなこと覚えてない

が参考になります。

使い方としては、Featureファイル(ほげほげ.feature)とStepファイル(ほげほげ.steps.ps1)を記述し、Invoke-Gherkinコマンドを呼ぶことでテストを実行することができます。
Featureファイルにおける各機能は以下の様にPesterの機能と対応しています。

  • Feature(フィーチャ) = Describe
  • Scenario(シナリオ) = Context
  • 各ステップ = It

正直良い例が思いつかなったので、先述の@ITの記事にあるサンプルをPesterに合わせた形にして例示します。

Featureファイル(Sample.feature)

# language: ja
フィーチャ: TDDのサイクルはRED、GREEN、REFACTORからなっています。
  GREENからREFACTORを飛ばすことはありますが、REDからGREENを飛ばしてREFACTORしないのが特徴です。
  これはテストなどによって保証されている範囲でのみ内部を変更することを「REFACTORING」と呼ぶという定義によるものです。
  
  シナリオ: プロジェクトを始めるときにTDDの最初の一歩になる手順
    前提 プロジェクトを始めるときはテストがない
    もし 要求を満たすテストを追加する
    かつ テストを実行する
    ならば テストが失敗して、TDDでいう「RED」になる

Stepファイル(Sample.steps.ps1)

Given 'プロジェクトを始めるときはテストがない' {
    # 処理
}
When '要求を満たすテストを追加する' {
    # 処理
}

And 'テストを実行する' {
    # 処理
}

Then 'テストが失敗して、TDDでいう「RED」になる' {
    # 処理
}

テスト実行例)

# カレントディレクトリにあるすべての.featureファイルを実行する
Invoke-Gherkin

# Pathを指定する場合
# [Feature名].Steps.ps1 という名称のStepファイルを自動で取り込む
Invoke-Gherkin -Path .\Sample.feature

実行した結果はこんな感じになります。
まだ英語以外の言語では警告がでる様です。

f:id:stknohg:20170414204928p:plain

ちなみにGitHubにもサンプルがありますのでこちらを参照するのも良いかと思います。

6. 非推奨、または廃止された機能

Ver.4になって非推奨、または廃止された機能は以下となります。

  • Invoke-Pester-Quietパラメーターは非推奨になり、代わりに-Show Noneを使うことが推奨されます。
    -ShowパラメーターにはPester.OutputTypes列挙型の値を指定することができ、以下の様に定義されています。
namespace Pester
{
    [Flags]
    public enum OutputTypes
    {
        None = 0,
        Default = 1,
        Passed = 2,
        Failed = 4,
        Pending = 8,
        Skipped = 16,
        Inconclusive = 32,
        Describe = 64,
        Context = 128,
        Summary = 256,
        Header = 512,
        All = Default | Passed | Failed | Pending | Skipped | Inconclusive | Describe | Context | Summary | Header,
        Fails = Default | Failed | Pending | Skipped | Inconclusive | Describe | Context | Summary | Header
    }
}
  • New-TestDriveItemは無くなりました。(ただ、昔から無い様に見受けられます...)

  • Invoke-Pester-OutputXmlパラメーターは無くなり、-OutputFile-OutputFormatの組み合わせに変更されます。
    -OutputFormatはいまのところNUnitXmlのみですが、今後のバージョンで増える可能性はありそうです。

最後に

とりあえずこんな感じです。
Pester 4のリリース時期はまだ具体的に決まっていない様ですが、今から備えておくのも良いかと思います。

Windows 7にPowerShell 6.0をインストールする

【2017/12/27追記】

最新のPowerShell 6.0 RC2での手順を別エントリに記載しました。

blog.shibata.tech

インストール手順はこちらのエントリをご覧ください。


割と誰得なエントリです。

PowerShell 6.0のサポートしているプラットフォームにWindows 7があったので実際に試したところ意外とハマったので記録を残しておきます。

インストール方法について

github.com

Windows 7向けのPowerShell 6.0(現時点ではAlpha 17)はMSIのインストーラーが提供されています。

公式のインストール手順にはMSIを実行するだけ、Windows 8.1、Windows 2012R2ではVisual Studio 2015 の Visual C++ 再頒布可能パッケージも必要だと記載されているだけであり、Windows 7向けには特に注意書きなどは記載されていません...

一抹の不安を感じますがこの手順を信じて進めてみることにします。

Windows 7にPowerShell 6.0をインストールする

今回は32Bit版での手順を紹介します。
64Bit版もやることは同じです。

1. とりあえずMSIをインストールすると...

インストール媒体からOSをインストールした直後の状態でMSIを実行しPowerShell 6.0をインストールすると、インストール自体はできるのですがプログラムを実行すると以下のエラーが出てしまいます。

コンピューターに api-ms-win-crt-runtime-l1-1-0.dll がないため プログラムを開始できません。 この問題を解決するには、プログラムを再インストールしてみてください。

f:id:stknohg:20170401081756p:plain

詳細ついては特に説明不要かと思います。
Windows 7でもWindows 8.1、Windows 2012R2同様にVisual Studio 2015 の Visual C++ 再頒布可能パッケージが必要となります。

2. SP1のインストール

Visual Studio 2015 の Visual C++ 再頒布可能パッケージをインストールするには、Windows 7 SP1である必要があります。

このためSP1が適用されていない環境では先にSP1にする必要があります。
この手順については細かく説明しませんが、Windows UpdateかKB976932を適用してください。

3. Visual Studio 2015 の Visual C++ 再頒布可能パッケージのインストール

SP1を適用したらVisual Studio 2015 の Visual C++ 再頒布可能パッケージをインストールしてください。
インストーラーの指示に従うだけですのでこの手順についても細かく説明はしません。

4. KB2533623 の適用

Visual Studio 2015 の Visual C++ 再頒布可能パッケージをインストールした後でPowerShell 6.0を実行すると、今度は以下のエラーが出てしまいました。

Failed to load the dll from [C:\Program Files\PowerShell\6.0.0.17\hostfxr.dll],
HRESULT: 0x80070057 The library hostfxr.dll was found, but loading it from C:\Program Files\PowerShell\6.0.0.17\hostfxr.dll failed

f:id:stknohg:20170401081920p:plain

エラーメッセージを見るに.NET Coreの起動に必要な何かが不足していることがわかります。

そこで.NET Coreの利用に必要な事前条件を確認すると、

For Windows 7 and Windows Server 2008 machines only:
Make sure that your Windows installation is up-to-date and includes hotfix KB2533623 installed through Windows Update.

と記載されており、KB2533623を適用する必要があることがわかります。

この更新を適用することで無事PowerShell 6.0を起動することができました。

f:id:stknohg:20170401081934p:plain

おまけ

Visual Studio Code PowerShell拡張はPowerShell 3.0以上であれば使えます。

f:id:stknohg:20170401082714p:plain

settings.jsonpowershell.developer.powerShellExePathにPowerShell 6.0のパスを設定することでWindows 7でもPowerShell拡張を使うことが可能です。

// settings.json
{
    "powershell.developer.powerShellExePath": "C:\\Program Files\\PowerShell\\6.0.0.17\\powershell.exe"
}

f:id:stknohg:20170401082547p:plain

右下のPowerShellのバージョン欄がちゃんと6.0になっていることがわかります。

最後に

とりあえずこんな感じです。

現時点でWindows 7を扱う環境であれば、大抵の場合SP1および最新の(またはそれに近い)Windows Updateが適用されていると思いますので、本エントリの様にハマることは少ないと思います。

また、Windows 7ではWMF 5.1(PowerShell 5.1)もインストールすることができますので通常はこちらをインストールすることになるでしょう。

stknohg.hatenablog.jp

もともと本エントリを書こうと思った動機は「何らかの理由でPowerShell 3.0以降をインストールすることができない環境にPowerShell 6.0をサクッとインストールして代替とすることができないか?」だったのですが、現実はそう甘くなかったです。