GradleのtestLogging
testLoggingの初期値(LogLevel別)
調べたことを表にまとめるとこうだった。
debug | info | lifecycle | warn | quiet | error | ||
---|---|---|---|---|---|---|---|
events | STARTED | ○ | × | × | × | × | × |
PASSED | ○ | × | × | × | × | × | |
SKIPPED | ○ | ○ | × | × | × | × | |
FAILED | ○ | ○ | ○ | × | × | × | |
STANDARD_OUT | ○ | ○ | × | × | × | × | |
STANDARD_ERROR | ○ | ○ | × | × | × | × | |
displayGranularity | 2 | 2 | 2 | 2 | 2 | 2 | |
maxGranularity | -1 | -1 | -1 | -1 | -1 | -1 | |
minGranularity | 0 | -1 | -1 | -1 | -1 | -1 | |
showExceptions | true | true | true | true | true | true | |
showCauses | true | true | true | true | true | true | |
showStackTraces | true | true | true | true | true | true | |
exceptionFormat | FULL | FULL | SHORT | FULL | FULL | FULL | |
stackTraceFilters | ENTRY_POINT | × | × | × | × | × | × |
TRUNCATE | × | ○ | ○ | ○ | ○ | ○ | |
GROOVY | × | × | × | × | × | × | |
showStandardStreams | true | true | false | false | false | false |
テストの開始ログが欲しい
lifecycleだとテストが動いてるのか止まっているのか良くわからない。
仮に初期値のままやるのであれば、gradle --debugとか頭おかしいことをすることになる。
では、lifecycleのeventsにSTARTEDを加えるのか?
それだとテストメソッドごとにログがでてきて憤死する。
せめて、テストクラスごとにログがでてくれればいい。
そういうときって、TestタスクのbeforeSuiteを書けばできそうだ。
test { beforeSuite { desc -> logger.lifecycle("{} {}",desc.name, tasks.testing.logging.TestLogEvent.STARTED) } }
あと、gradle --infoのときはテストメソッドの開始ログ、終了ログを出してやろう。
でも、標準出力と標準エラーはごめんこうむりたい。
test { testLogging { info { events "started","passed","skipped","failed" } } }
lifecycleだけexceptionFormat=SHORTなのは嫌
test {
exceptionFormat "FULL"
}
もしくは
test {
testLogging {
lifecycle {
exceptionFormat "FULL"
}
}
}
テスト結果の統計を見たい
何もしなくてもTestタスク全体の統計はでるけど、テストクラス単位のも出してみるか。
そういう時はafterSuiteを使う。
ちょっと懲りすぎかもしれないがこういうコード。
test { afterSuite { desc, result -> def event = tasks.testing.logging.TestLogEvent.FAILED def level = logging.LogLevel.ERROR if( tasks.testing.TestResult.ResultType.SUCCESS == result.resultType ){ event = tasks.testing.logging.TestLogEvent.PASSED level = logging.LogLevel.LIFECYCLE } else if ( tasks.testing.TestResult.ResultType.SKIPPED == result.resultType ){ event = tasks.testing.logging.TestLogEvent.SKIPPED level = logging.LogLevel.WARN } logger.log(level, "{} {} total={} passed={} skipped={} failed={} elapse={} sec", desc.className, event, result.testCount, result.successfulTestCount, result.skippedTestCount, result.failedTestCount, (result.endTime - result.startTime)/1000) } }
独自クラスローダーとJacoco
ダイエット
ダイエットの方針
高いカロリーを認識する
松屋
日高屋
なか卯
マクドナルド
ドミノピザ
夜の食事を500kcalに抑える
野菜ジュースは飲まない
シリアルも取らない
運動してないならプロテインを取らない
基礎代謝のことを考える
脂肪1kg 7700kcal
体重計には乗らない
長風呂をする
ELECOM スマートフォン用 防水ケース JIS保護等級 IP47取得 iPhone Android 水に浮く ネックストラップ付属 4.7インチ 汎用 ブルー P-01WPSBU
- 出版社/メーカー: エレコム
- 発売日: 2014/03/07
- メディア: エレクトロニクス
- この商品を含むブログを見る
オウルテック iPhone6s/6sPlus Xperia GALAXY Note3も入る 大きめサイズのスマートフォン用防水・防塵ケース 保護等級IP68取得 OWL-MAWP03(BK)
- 出版社/メーカー: オウルテック
- 発売日: 2013/05/15
- メディア: エレクトロニクス
- この商品を含むブログを見る
部分痩せはどうする
心拍数を測定する
- 作者: 本川達雄
- 出版社/メーカー: 中央公論社
- 発売日: 1992/08
- メディア: 新書
- 購入: 26人 クリック: 1,301回
- この商品を含むブログ (168件) を見る
目標心拍数=運動強度×(最大心拍数-安静時心拍数)+安静時心拍数
筋肉をつけて痩せるなんて考えない
実は筋肉が1kg増えることで上がる基礎代謝はたった13kcalなんです。
永谷園 1杯でしじみ70個分のちから みそ汁 3食入×10個
- 出版社/メーカー: 永谷園
- メディア: 食品&飲料
- この商品を含むブログを見る
永谷園 お茶碗1杯でしじみ70個分のちから しじみソフトふりかけ 40g×5個
- 出版社/メーカー: 永谷園
- メディア: 食品&飲料
- この商品を含むブログを見る
JMockitで拡張クラスローダーに読まれるクラスをモックするのを足掻いた結果
- lib/extにjarを置く
- -Djava.ext.dirsでディレクトリを指定
- 拡張クラスローダーに寄せる
- アプリケーションクラスローダーに寄せる
gradleのTestFilterのパターンの書き方がイマイチだ
gradleのTestタスクにfilterが書ける。
このfilterに書くときのパターンの指定の解釈がうざい。
gradle/TestSelectionMatcher.java at master · gradle/gradle · GitHub
指定したパターン文字列を、アスタリスクでスプリットして、
それぞれの頭に".*"を付けてからパターンコンパイルしているように見える。
アスタリスク以外は、Pattern.quote(String)で、全部リテラルにしている。
ピリオドもリテラルになるじゃないか。
test01、test02メソッドの二つだけをヒットさせたときに、
正規表現で[1-2]みたいなのを書きたいけど解釈してくれないよね。
我慢してピリオドにしたとしてもリテラルに解釈されたら無理だよね。
二回書けということなのかよ。
test << { filter { includeTestsMatching '*test01' includeTestsMatching '*test02' } }
どうせPattern.compileするのに、なんで正規表現を受け付けない。
Gradle MVS Dataset Plugin試作品 - Gradle Nested Container
データセットをgradleから作るようにする。
必要となるもの:
gradle ssh plugin
USSのtsocmdコマンド
TSO/E ALLOCATEコマンドの知識
仕組み:
Linux/Windowsでgradleを動かして、z/OSにsshしてtsocmdでデータセットを作成する。
こんな感じでbuild.gradleに書く。
datasets { "hlq.aaa" { vol = 'VOL001' dsorg = 'PS' recfm = 'F,B' lrecl = 80 space = '(10,10) TRACKS' initialData { srcEncoding = '1208' destEncoding = '1047' } } "hlq.bbb" { vol='VOL002' dsorg='PO' members { "MYJCL" { initialData { srcEncoding = '1208' destEncoding = '1047' } } } } }
もっと省略して書けるようにすることもできるだろう。
上の例では、POならDSNTYPE(PDS)やろ的な省略をしているし、lrecl未指定なら80やろ的な省略をしている。
プラグインはこんな感じで書く。
import org.gradle.api.Plugin import org.gradle.api.Project class DatasetPlugin implements Plugin<Project> { void apply(Project project) { def datasets = project.container(Dataset){ String name -> def dataset = project.extensions.create(name,Dataset,name) dataset.extensions.create('initialData',InitialData,'initialData') dataset.extensions.members = project.container(PDSMember){ String memberName -> def member = dataset.extensions.create(memberName,PDSMember,memberName,dataset) member.extensions.create('initialData',InitialData,'initialData') member } dataset } project.extensions.datasets = datasets } }
PDSMemberのところが、コンテナの中にコンテナを作ってる箇所。
Datasetクラスは、TSO/E ALLOCATEコマンドのパラメータから作成する。
Datasetクラスには、generateAllocCmd()などを定義して、sshのexecuteに渡すコマンドを組み立ててリターンするようにする。
そのコマンドは、こんな感じに組み立てる。
"ALLOCATE DATASET('hlq.aaa') VOLUME(VOL001)...."
sshセッションで使うときは、こんな感じに書ける。
execute "tsocmd \"" + datasets['hlq.aaa'].generateAllocCmd() + "\""
なんかメソッド長いから、コマンド用クラスを挟んで、datasets['hlq.aaa'].cmd.alloc()みたいにしようかな。
入れ子構造がほしかったのは、初期データを順次データセットにぶち込みたいから。
それと、PDSメンバを管理し、PDSメンバも初期データをぶち込みたいから。
初期データには、まだfileプロパティを書いていないが、イメージはある。
initialData { srcEncoding = '1208' destEncoding = '1047' file = sourceSets['test'].output.resources.getAsFileTree.matching{include '**/MYJCL.jcl'}.getSingleFile() }
いったんUSSに配置して、iconvかけて、cpコマンドでデータセットに持っていく。
それをするために、エンコーディングを持たせているが、
初期値を1208,1047に設定してしまえば、より簡潔に書けることになる。
データセット作成機能:
上述のようなやり方でallocateは実現できます。
データセット初期データ機能:
iconvとcpコマンドで実現。mvでもいいかな。
おそらくInitialDataにcpコマンドのオプションをもう少し持たせる必要があるかもしれない。
また、改行コードの扱いも面倒。CRはsedで取り除くのかな。cpコマンドのオプションで、crnlとかもあったはず。
データセット存在確認:
tsocmdでLISTDSを使い、その標準出力をgrepかけて判定することで可能。
データセット削除機能:
tsocmdでFREEを使えばできる。
PDSメンバだけをFREEできるのかは不安要素、できそうなことは書いてる。
データセット圧縮機能:
んー、まだ調べ切れていない。
できる気はしていない。
PDSEにしなよって話か。
DatasetクラスとPDSMemberクラスは、descriptionプロパティをつけておく。
実はPDSMemberクラスはdescriptionプロパティしかない。。。
説明は大事。なんのためのデータセットだよ、分かんねーよ。
コードは日々改良を重ねている。PDSメンバのデータセットに初期データをぶちこむには、PDSMemberクラスのコンストラクタに、ExtensionAwareになってるDatasetクラスを渡して名前を組み立てさせるのはよさそうだ。
PDSメンバをssh経由でこねくるときは、括弧がついてるせいで、ダブルクォートで囲むなどしないといけないのが面倒臭いな。。。
このエントリーで書いてる書き方だと、すごく縦に長くなっていくから、実際には、セミコロンを使って今は横長にしてる。
書き方については、もっと工夫ができて、例えばDatasetクラスにjcllib(Map
ボリューム名は必須。dirやspaceは書いてほしいが、書いてなくても初期値を用意する。
ほかには、ログ出力としての置き場になってるところはspaceパラメータを多めにした簡易定義メソッドを用意してあげるとか。
recfmや、spaceの書き方を不思議に思われるかもしれないが、こっちのほうが楽にいける。
データセット名の一部を-Pで渡した値にすることもできている。システム名だとか、ホスト名だとか、ボリューム名だとか。
これができることは大事だ。
DatasetやらPDSMemberがExtensionAwareになっているのを利用して、どのテストに必要なのか印を付けられなくもない、しかし実際にはTestタスクで動くものとの連動はイメージがわかない。
ほかには、MVSデータセットと、リポジトリの資材が本当に同期しているかの確認を処理させることも考えられるかも。いや、processTestResourceなどで書き換えるので差分は出てしまうなぁ。これはやめておこう。
あー、マルチボリュームもできるのかを検証しとらんわー。ニーズは極小だから後回しかな。
まじ、やりたいことがたくさんある。