2012年9月25日火曜日

TaskScheduler注意メモ


batファイルをTaskSchedulerで起動する場合,
開始[]ボックスに
batファイルのあるディレクトリを指定してやらないとうまく走ってくれない


画像を使ってみたかっただけかもしれない(・ω・`)

ClosureLinterによる静的解析

前回の続き.

コーディング規約どうしよう, というお話.
CheckStyleをjavascript用に作り直したりと, 手が無いこともないわけだが何より

時間がない

OTL

なので, 割と軽めに導入できるものを所望.
するとそこに現れたのが表題の, Closure Linter.
どうやらこいつは, Google先生が決めた規約にのっとったチェックをしてくれるツールらしい.
from GoogleDevelopers

条件反射で飛びついた自分の前に現れたのは, コマンドラインから起動されるClosureLinter.

ま た . b a t か よ ( ゚д゚ )



と反射的に考えてしまった自分はだいぶ.batに染まっているようですorz

何はともあれ使い方まとめ.


Ⅰ. Closure linter使い方 -準備編

1. Pythonで動きます. Python2.7.3.exeでPythonをインストールします.(Ver.2.7の理由は2. で)以降はデフォのディレクトリにインストールしたとします.
Python:http://python.org/download/ 自分のマシンに合ったものをどうぞ.
2. easy_installするためにsetuptools-0.6c11.win32-py2.7.exeを使用します.このsetuptools(ryが2.7を最後に更新されていないため, それ以降のPythonでは使えません.(1. の理由)
setuptools:http://pypi.python.org/pypi/setuptools Downloadsから
3. easy_installします. C:\Python27\Scriptsでcmdを起動します.パスを通しておくと楽かも.てゆうかbat使いたいなら通しておこう
4. easy_install http://closure-linter.googlecode.com/files/closure_linter-latest.tar.gz と入力します. インストールが始まり, つらつらとメッセージが出てきます.
5. 準備完了

Ⅱ. Closure linter使い方 -実行編

1. パスは通しておきましょう. 環境変数のpathの末尾に;C:\Python27\Scriptsを追加します.(cmdでpathと打ってみてちゃんと出てくることを確認しましょう.)
2. 早速解析しましょう. cmdを開き, gjslint 解析したい.jsのパス と入力します.
3. 成功していれば結果がコンソールに出ます.
4. パスのファイル名の部分を *.jsと置くと, そのディレクトリの.jsを順に全て解析してくれます.日本語にはならないみたいです(・ω・`)
5. 特別な.jsは他においておきましょう.一生懸命解析してダメだししてくれます. 正直鬱陶しいです. よけてくれる設定もあるらしいけど…

Ⅲ. Closure linter使い方 -.bat利用編


A. とりあえず修正するところを出力してくれるbat.
gjslint 解析したい.jsのパス > 結果を出力したい.txtなどへのパス
"解析したい.jsのパス"ディレクトリにある.jsを全てチェックし, その様子を"結果を出力したい.txtなどへのパス"に書き出してくれる. あくまで結果を教えてくれるだけ.直すのは自分で.(・д・`)
このままだと上書きするので, 過去ログ残したい!とか思うなら > を >> に置き換える. ファイル容量には注意. あくまで自己責任で.
ちなみに > はcmdのコマンド. Closure Linter とは関係ないので > 以下は無くてもOK. ただし結果がcmd上にしか出ないので出力してもらったほうが何かと便利.


B. コマンドで直せるものは直してもらうbat
copy  解析したい.jsのパス  C:\js_copy\ 
gjslint  解析したい.jsのパス  > 結果を出力したい.txtなどへのパス 
fixjsstyle 解析したい.jsのパス

1行目 とりあえず退避. "解析したい.jsのパス"にある全ての.jsをC:\js_copyにコピーする.
2行目 これは同じ. 解析結果の書き出し.
3行目 fixjsstyleのコマンドで, 直せるものは全部直してくれる. ただ改行とか空白とかは直してくれない. ; の打ち忘れなんかはやってくれる. あまり当てにしてはいけない.

なんかⅡとⅢを分ける必要なかった気がしたけど







まぁいっか+(・ω・0)*


Ⅳ. Closure linter使い方 -おまけ

→Closure linterがツッコミを入れる内容について書いてある. なにが突っ込まれるかチェックしたり, 突っ込まれた内容の確認にどうぞ

sinonを使ったjavascriptのテスト

前回でjavascriptの開発環境もできたので, いざコーディング!


・・・まではよかったのだが・・・
ここで課題が2つ.

1. テスト(特に通信系)どう書くの?
2. コーディング規約は?

とりあえず普通のテストはいいとして…通信…Mock?
とか調べてたら出てきたのが Sinon.js
ライブラリのように使え, いろいろと内蔵しているじゃじゃ馬
いろいろありすぎて手に負えませんorz

とりあえずjQuery.ajaxが使いたかったので, 有効そうな2つをピックアップ.

A. FakeServer
名前の通り偽者のサーバを立てる. 

var sinonTestCase = sinon.testCase({
    setUp : function() {
        this.server = sinon.fakeServer.create();
    },
    tearDown : function() {
        this.server.restore();
    },
    "test server":function () {
        this.server.respondWith("GET", "/some/article/comments.json",
                                [200, { "Content-Type": "application/json" },
                                 '[{ "id": 12, "comment": "Hey there" }]']);
        var callback = sinon.spy();
        jQuery.getJSON("/some/article/comments.json", callback);
        this.server.respond();
        sinon.assert.calledWith(callback, [{ id: 12, comment: "Hey there" }]);
    },
});

TestCase("Fakeserver test case", sinonTestCase); 

これで "Fakeserver test case" という名前のテストクラスが出来上がる.
setUp でfakeServerを立ち上げ
tearDown でその偽サーバを破棄している.
偽者とはいえ通信系, 破棄しておかないと特に通しのテストの時に…
"test server" がテストクラス名. 名前は test から始めないとテストとして認識されないので注意.
sinon.fakeServer.responsedWith で偽サーバのresponseの内容を決める.
sinon.spyは仮のcallback関数. これをテストしたい関数に組み込むことで, 後々sinon.assertが使えたりする. 詳しくはAPIで
server.respond() を呼ぶことでfakeServerが応答し, 先に設定したresponseを返す.

これにより, callbackにfakeServerからの応答が入る.

あとはsinon.assertを用いてきちんと応答が受け取れたことを確認する.


…すっごい不安だ('A`)

B. Stub
あるクラスの ある関数を 一時的に置き換える
stubのよるテスト例
var sinonTestCase = sinon.testCase({

    "test with stub" : function() {
        var json = [{"hoge":"hoge","foo":"foo","bar":"bar"},
        {"hoge2":"hoge2","foo2":"foo2","bar2":"bar2"},
        {"hoge3":"hoge3","foo3":"foo3","bar3":"bar3"}];

        var stub = sinon.stub(jQuery, "ajax");
      stub.yieldsTo("success", json);
  
        jQuery.ajax({
            success: function (data) {
                assertEquals(json, data);
            }
        });
       stub.restore();
    }
});

TestCase("Stub test case", sinonTestCase);

こちらは"Stub test case"クラス.
8行目にてstubを作成, 9行目にてjQuery.ajaxというメソッドの返り値を指定している.
11行目から実際にテストしたいメソッドを呼び, 値をチェックする.

こっちのほうが使いやすい気はした(・`ω・´) (キリッ
restore()は忘れずに.(setUp&tearDownに入れたほうがいい気がした(^ω^;).

参考:SinonAPI

明らかにAPIのが正しいのでそちらを参考に…


コーディング規約についてはまた後日…(・ω・)ノシ

2012年9月20日木曜日

aptana ~導入編~

ついにコーディング!javascript!щ(゚Д゚щ)


…java…script?('A`)


orz


まぁ嘆いていても仕方ないので. javascript開発のIDEにEclipseの弟?のAptanaを導入することに.
一緒にjavascriptのテストを行なう"JS Test Driver"を導入. 若干めんどくさいのでメモメモφ(・ω・ )




1. aptanaをインストール
2. eclipse同様help→Install New Softwareを選択
3. http://js-test-driver.googlecode.com/svn/update/から JS Test Driverインストール. JS Test Driver Plugin for Eclipse ひとつを選択. 複数選択するとNG(同じ名前をインストールしようとしてぶつかる?)

3. インストールが終わったら, 同様にWindow→Preferencesで設定を開く
4. JS Test Driverの項でブラウザ名にあわせて使うブラウザの.exeのパスを設定する.
5. Port to start server on のボックスに使用していないポートが設定してあることを確認する.

6. js(or src)ディレクトリにソースコードの.jsを置く
7. testディレクトリを作成, テストコードの.jsを置く
8. test(or conf)ディレクトリにテストの設定を書いた.confを置く

9. Run→Run Configurationsから実行の構成を開く
10. JS Test Driver Testの項をダブルクリックして新しい構成を作成
11. Projectに用いるプロジェクト名, Conf Fileに8. で置いた.confのパスを設定する
12. Run on Every Save にチェックを入れておくと保存するたびにテストが走ってくれるようになる
13. Commonは特にいじらなくていい

14. Window→ShowViewからJS Test DriverのViewを出しておく(無ければotherから選択)
15. View右上のStart Serverをクリックし, サーバを開始する.
16. Viewのグレーのアイコンの中から使いたいブラウザのアイコンをクリックし, 色がつくのを眺める. 色がつかない場合, 4. か15. をしていない/出来ていない恐れあり
17. 15. →16. の間でhttp://127.0.0.1:(ポート番号. デフォは42442)/captureが赤→黄→緑に変化するのを眺める

18. eclipse同様Run→JS Test Driver Test を選択する
19. +(・ω・0)*


6. 7. 8. については自由に構成できる…が, ソースコードに関してはjsディレクトリに置いておいたほうが, 他のツールを使う際に楽…かもしれない.

12. は便利そうで意外と鬱陶しいので注意. 自分は入れて数回で外した(・д・`)

また, 8. にある.confはテストを行なうポートやテスト対象の宣言, 使うプラグインの宣言を行なうファイル. これを読み込んでテストを実行する重要なファイル.


ex>
server: http://localhost:42442

load:
  - js/vendor/jquery-1.7.2.js
  - js/*.js

test:
  - js/vendor/sinon-1.4.2.js
  - js/vendor/sinolog.js
  - test/*.js



a. server: http://localhost:42442
テスト時に使うポートの指定. 上でちょくちょく出てくるテストの設定と同じにすること

b. load: - ソースのパス
ワンセットっぽい. ファイル名を指定してやるとそれだけを見に行ってくれる.
ディレクトリ分けを行い, *(ワイルドカード)を使うとはかどる

c. test: - テストのパス
テスト対象らしい. ここに名前を連ねておくとテストしてくれる
ディレクトリ分けを(ry



タグ(load:など)の前にはスペースを入れると読み込みがうまくいきません('A`)



これで準備は完了. あとはTestCaseを書けばおk.

TestCaseの書き方参考: http://news.mynavi.jp/column/tool/013/index.html



…これでスタート地点に立ったわけだ…( ´_ゝ`) =3

2012年9月19日水曜日

時刻とともに入力メッセージのログをとるbat

syntaxhighlighterとの戦いも終えたので投稿再開.
でもjavaじゃない(・ω・`)


とあるミッションで
「行動のログを時間つきでとっとけ」
ということがあったので, 早速そんなbatをつくってみた.


@ECHO OFF
For /F "eol=;tokens=1,2,3,4*delims=/, " %%i in ('date /t') DO SET YYYYMMDD=%%i%%j%%k
For /F "eol=;tokens=1,2,3*delims=:, " %%i in ('time /t') DO SET HHMM=%%i%%j
set YYYYMMDDHHMM=%YYYYMMDD%%HHMM%

echo 終了するときは"fin"と入力してください
setlocal enabledelayedexpansion
For /L %%o in (0,0,5) do (
 set /p INP="メッセージを入力してください>"
 if !INP!==fin (
  echo !INP!により終了!
  exit
 )
 set message=!date! !time! !INP!
 echo !message! >>record/%YYYYMMDDHHMM%.txt
)


正直2,3行目は参考サイト参照. ほぼコピペ('A`)
やってることは, ファイル名に日付 + 時刻を用いるための処理. これでうまく出てくれた.
6行目からが本体.
7行目はお決まりの宣言(らしい). これを宣言すると, 変数の値の上書きが出来るようになる(詳しい話があった気がする).
8行目からループ開始. /Lは前にも書いた単純ループ. 変数"o"が0から5の間0刻みで進む(=進まない)
9行目でメッセージを入力待ち.

10行目の"!INP!"が肝. 通常"%INP%"で読み込むところを"!"でくくることで, "INP"の内容をループの間上書きして読み込んでくれる. ここで"fin"と書き込まれたらif内へ. "exit"で終了する.

12,13行目はメッセージの設定. 書き込まれた内容に日付と時刻を足してファイルに出力している.


これを繰り返した出力結果の例


2012/09/19 19:14:15.33 test
2012/09/19 19:14:18.13 (・ω・`)
2012/09/19 19:14:34.85 20120919


入力がコマンドプロンプトでちょっと使いにくいのが難点(´-`). でもミッションでは有効だったから満足.



参考サイト:http://d.hatena.ne.jp/orangeclover/20101203/1291387934

javaなんて無かった.
((( ⊂⌒~⊃。Д。)⊃

2012年9月6日木曜日

batでファイルの削除と, テスト用ダミーファイルの作成

bakファイルをばんばん作るようになったので, 今度は作りすぎたファイルを削除する.batと, その動作をテストする用のダミーファイルを作る.batを, FOR文を用いて作成する.

まずは削除.bat本体


for /f  "skip="任意の整数"" %%"変数名" in ('dir/b /O-D "対象ファイル名"') do del %%"変数名"


削除の命令の本体は

del %%"変数名"

指定した名称のファイルを削除するコマンド
この %%"変数名" をFOR文の中で指定して, 繰り返し処理を行い削除を進める.

/f→ ファイル解析オプション. ファイルを扱うときに.

"skip="任意の整数""→ "任意の整数"で指定した数だけ処理をスキップする. すなわちforでまわすリストの先頭から"任意の整数"の数のファイルは削除しない, となる.

 %%"変数名"→ 実行するコマンド内で用いる変数. 

in ('dir/b /O-D "対象ファイル名"')→変数に入れる値. 今回はファイル名. オプションいろいろ.

  dir/b 対象ディレクトリ. 今回はこの.batのあるディレクトリ.

  /O-D ファイルの並び. 「D」が日付を示し, 「-」が降順を示す. すなわち, 新しい順に並ぶ. skipと合わせて, 新しい"任意の整数"件のファイルを残して削除する, となる.

  "対象ファイル名"→そのまま, 削除対象となるファイル. 「?」をワイルドカードとして使うことで特定のルールで作られたファイル名をまとめて対象に含むことが出来る.
(ex> 対象ファイル名 = log????.log とすれば, log0904.log,log0905.log,log0906.logと順に作成したファイルをまとめて対象に取れる.)


削除.batを作ったら, それをテストしたいところ. しかし一々メモ帳を開いてファイルを作ったり, コピーからのリネームで量産するのも芸がない.
そこで折角のfor文を用いてのダミーファイル量産計画.


for /L %%"変数名" in ("初期値","増加値","限界値") do TYPE NUL> "ファイル名"

ただループをまわすだけならこれでOK.
/L→Iではない. ただループをまわすオプション?
in ("初期値","増加値","限界値")→"変数名"に入る値. 当然数値. java等でよく見るfor文に近い内容. "初期値"から始まり, "限界値"まで, "増加値"ずつ増加していく. なお"限界値"以下である間回るので, "限界値"は含まれる.

TYPE NUL> "ファイル名"→ファイルの作成. 中身はこのままだと当然なし. ファイル名に%%"変数名"を用いることで, ファイル名を動的に変更できる.

これで量産可能. ループ中に桁がずれたときなどには注意.
(ex> …, log098.log, log099.log,log0910.logといった感じにファイル名がずれてしまう. 桁数ごとにループを作るのが無難)





…最近javaしてないなぁ…(・ω・`)

MS SQLのバックアップコマンドとbatからの呼び出し

batを叩いてでMS SQLの復旧用バックアップを取れ!

といった感じのミッション.



まずはバックアップを取り, bakファイルを作るSQL文から


BACKUP DATABASE "バックアップを取りたいDB名" TO disk='"保存先のパス"' WITH INIT



TO disk → 保存先のフルパス. ".bak"まで書く. ファイルは無くても自動で作ってくれるが, ファイルを置くディレクトリまでは作ってくれないので注意

INIT→既に指定したファイルが有った場合, 上書きする, という設定. WITH句以下に書く. ちなみに追記する場合は NOINIT.

このSQLを投げれば, 投げた時点でのフルバックアップをとる. 差分バックアップを取りたい場合は, WITH句に","で続けて, "DIFFERENTIAL"を追加する.

※フルバックアップ→DB全体のバックアップを取ること, 差分バックアップ→最後にとったフルバックアップからの更新されたデータをバックアップする. 全てフルバックアップするよりも容量を圧迫しない.
復旧時も, 復旧したい時点の差分ファイルと, その直前のフルバックアップのひとつずつ指定すれば復旧できる.

復旧用.sqlはフルバックアップファイルだけで復旧するならば


restore database "復旧するDB名" from disk='".bakファイルのパス"'



だけでOK
ただし差分バックアップファイルを用いる場合は



restore database "復旧するDB名"  from disk='"フル.bakファイルのパス" '
WITH NORECOVERY
restore database "復旧するDB名" from disk='"差分.bakファイルのパス"'



と, フル→差分の順に呼ぶことと, フルバックアップファイルを呼んだ際, WITH句で"NORECOVERY"を指定し, トランザクションのロールバックを防ぐことで, 続けて差分.bakを呼んで復旧することが出来る.





そして, これらの処理を, 叩くだけでこなしてくれるようなbatのコマンド

バックアップを取る.bat


sqlcmd  -U "ユーザID" -P "パスワード"  -v buckupdate ="%date:/=%" -i .bakまでのパス


このとき, -U -Pは大文字でないと反応してくれない点に注意.
-v で.batを叩いた時点の日付をとって, SQLファイルに投げてくれる(ex> 20120906)
こうすることで, ファイル名に日付をつけることが出来るため, 復旧時に使いやすくなる.
なおSQL文内で使うときは $(buckupdate) で投げた値を使える.
(おまけ: "%date%"と表記するとexは2012/09/06となる. また時間を使いたいときは"%time%")
(おまけ2: "%date:/=%"の「:/=」の部分で, 表記される「/」を「」へと変換している.)


そして復旧する.bat



SET /P input="復元に使うファイルの日付を入力してください"
sqlcmd -U "ユーザID" -P "パスワード" -v buckupdate =%input% -i 復旧用.sqlのパス


復旧を行なう際は, 復旧用ファイルを指定する指定しなければいけない.
そこでSET /Pコマンドでユーザーからの入力をうけつけ, それを -v に与えて.sql内で用いる.
入力のさせ方などは工夫の見せ所.
ファイル名などを工夫してやると良いかも.




長かった…('A`) -3

2012年9月3日月曜日

Loggerの設定とか

Loggerの設定ファイルを書くことがあったのでその辺りをちらほらと.

1. 設定フィルを準備
 
      設定ファイルの中身はこんな感じ
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler.level=FINEST

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

#出力の設定
#ログとして出力するログのレベル. このレベル以上のログだけ出力される.
java.util.logging.FileHandler.level=WARNING
#出力ファイル名. カレントディレクトリから見て場所を指定する.%uと%gは世代番号
#もちろん名前は自由
#この時, ディレクトリがないとエラーになるので, あらかじめ作っておくか,
#なかった場合ディレクトリを作成する処理を行うといい.
java.util.logging.FileHandler.pattern=Log/OutPut%u.%g.log
#フォーマッターの設定, 自作のフォーマッターの宣言も可能
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
#追記設定, trueなら追記, falseなら上書き
java.util.logging.FileHandler.append=true
#最大世代番号, この数だけログファイルを作る
java.util.logging.FileHandler.count=10
#一つのファイルに書き込める最大バイト数の設定
java.util.logging.FileHandler.limit=2000
3つ目のブロックで細かい設定を行う. 上の2ブロックは・・・HandlerとFormatter?


これをパスの通ったところ(src以下など)に置いておく
あとはLoggerを使う際にこの設定を呼んでやればいい

2. 設定を呼び出すクラスの作成

自分は参考にしたサイトのとおり, クラスを作ってみた

/**
 * ログ設定プロパティファイルのファイル名.
 */
protected static final String LOGGING_PROPERTIES = "logger.properties";
//Loggerのプロパティファイルの名前
//パスが通ったところに起きましょう


/**
 * static initializer によるログ設定の初期化.
 */
static {
 File directory = new File("Log");
 if (!directory.exists()) {
  Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)
    .warning("ログディレクトリがありません");
  if (directory.mkdir()) {
   Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info("Log folder was made");
  } else {
   Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).warning("Log folder couldn't make");
  }
 }
  final Logger logger = Logger.getLogger("オリジナルの名前");
 // クラスパスの中から ログ設定プロパティファイルを取得
 InputStream inStream = "".class
   .getClassLoader().getResourceAsStream(
     LOGGING_PROPERTIES);
 if (inStream != null) {
  try {
   LogManager.getLogManager().readConfiguration(inStream);
  } catch (IOException e) {
   logger.warning("ログ設定のエラー");
  } finally {
   if (inStream != null) {
    try {
     inStream.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 } else {
  logger.info("設定ファイルがありません");
 }
}
//プロパティファイルのローダ
//staticイニシャライザで設定することで, 最初の一度だけ設定を行なう

public static Logger getLogger(){
        return Logger.getLogger("オリジナルの名前");
}
これらを設定した後,
Logger.getLogger("オリジナルの名前").info/warning/severeで呼ぶと設定は反映されている
オリジナルの名前には基本このクラス名を入れるとか


使う際はこのクラスのgetLoggerを呼ぶようにすると, 最初に呼ばれた際にのみstaticイニシャライザで設定ファイルを読み込む.

AWS CDKで立てたEC2インスタンスのTimeZoneとかいじりたかった話

EC2を立てることはできたけど、立てたインスタンスは UTCのままだし設定ファイルとかいちいちscpしてくるのはダルい。 当初UserDataでなんとかしようとしたものの、「書く量がヤバいしメンテしにくい」と悩んでいたところ見かけたのが  AWS::CloudFormation:...