Index: [Article Count Order] [Thread]

Date:  Wed, 4 Oct 2000 10:08:20 +0900
From:  omura@....jp
Subject:  [XP-jp:01030] 複数プロセス間のテスト用コード ( 長くてすいません)
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <20001004100620omura@....jp>
In-Reply-To:  Your message of "Tue, 3 Oct 2000 17:20:03 +0900"             <97BA340C0480D411BDA800062939A1890607C5@....jp>
References:  <97BA340C0480D411BDA800062939A1890607C5@....jp>
Posted:  Wed, 04 Oct 2000 10:06:20 +0900
X-Mail-Count: 01030

おおむらです

ファイルロックユーティリティについていろいろ議論されているのですが、
ちゃんとフォローできてないおおむらです(なさけない)

で、みていると、ユーティリティの使い方についていろいろ議論されていて、
なかなかその真意が伝わっていない(みたい)なんですが、
それこそテストコードを先に書いて示せばよいのではないかと思います。


そこで、でしゃばりですみませんが、複数プロセスがあるときのテストの
フレームワークとして、こんなものを作ってみました。
これを使って、問題になっている点が明確に書けるとよいのですが
どうでしょう。

サンプルとして最近MLにあがっていた次の条件のテストケースを作って、
末尾にいれておきました。(LockFile_Test.java) 細部はいいかげんです。

1. プロセスAがロックを取得
2. プロセスAがロックを開放(deleteOnExit付き)
3. プロセスBがロックを取得
4. プロセスAが終了することで、プロセスBのロックファイルを削除
5. プロセスBがロック中にも関わらず、プロセスCがロックを取得し
   ようとすると成功してしまう


------ TestAgentDriver_Test.java これがテストのパターンになります
import java.io.*;
import junit.framework.*;


public class TestAgentDriver_Test extends TestCase {
    public TestAgentDriver_Test( String name ) { super( name ); }

    public static Test suite() {
        return new TestSuite( TestAgentDriver_Test.class );
    }

    public static void main(String args[]) {
        junit.textui.TestRunner.run( suite() );
    }

    public void testGo() throws Exception {
        TestAgentDriver tad = new TestAgentDriver( "java DummyTestAgent" );
        tad.begin();

       // usually, I test something here while running another process 
	// in this case the process is  "java DummyTestAgent" and
	// I check only the return value of the DummyTestAgent i.e. 1

        int r = tad.end();
        assertEquals( "proof of run", 1, r );
    }
}

------ TestAgentDriver.java 別プロセスをコントロールするためのドライバ
import java.io.*;

public class TestAgentDriver {
    private Process ps;
    private PrintWriter pw;

    public TestAgentDriver( String command ) {
        try {
            Runtime rt = Runtime.getRuntime();
            ps = rt.exec( command );
            pw = new PrintWriter( ps.getOutputStream() );
        }
        catch ( IOException ex ) {
            ex.printStackTrace();
        }
    }

    public void begin() {
        pw.println( TestAgent.START );
    }

    public int end() {
        pw.println( TestAgent.END );
        pw.close();

        try {
            return ps.waitFor();
        }
        catch ( InterruptedException ex ){
            ex.printStackTrace();
        }

        return 0;
    }
}

------ TestAgent.java TestAgentDriverとのやりとりをする部分です。

import java.io.*;

public abstract class TestAgent {

    abstract public void atBegin();
    abstract public void proc();
    abstract public int atEnd();

    final public static String START = "start";
    final public static String END = "end";
    
    public int run() {

        BufferedReader r = new BufferedReader( new InputStreamReader( System.in ) );
        int v = 0;
        try {
            atBegin();
            while( ! r.readLine().startsWith( START) ){};
            proc();
            while( ! r.readLine().startsWith( END ) ){};
            v = atEnd();
        }
        catch ( IOException ex ){
            ex.printStackTrace();
        }
        return v;
    }
}

------ DummyTestAgent.java テスト用のヘルパープロセスに相当するものです。ここではほぼ空。

public class DummyTestAgent extends TestAgent {

    public static void main( String[] args ) {
        DummyTestAgent dta = new DummyTestAgent();
        System.exit( dta.run() );
    }

    private int v;
    public void atBegin() {
        v = 0;
    }

    public void proc() {
        v = 1;
    }

    public int atEnd() {
        return v;
    }
}

---- LockFile_Test.java

package XP.jp.co.esm.wiki.extremedomo.util;

import java.io.*;
import junit.framework.*;

public class LockFile_Test extends TestCase {
    public LockFile_Test( String name ) { super( name ); }

    public static Test suite() {
        return new TestSuite( LockFile_Test.class );
    }

    public static void main(String args[]) {
        junit.textui.TestRunner.run( suite() );
    }

    public void testLockOnTheFly() throws Exception {
        TestAgentDriver pa = new TestAgentDriver( "java FileLockTestAgent" );
        pa.begin();

	/* FileLockTestAgentはこういうことをするとします 
		1. プロセスAがロックを取得
		2. プロセスAがロックを開放(deleteOnExit付き)
	*/
	
	//3. プロセスBがロックを取得
        TestAgentDriver pb = new TestAgentDriver( "java FileLockTestAgent" );
	
	//4. プロセスAが終了することで、プロセスBのロックファイルを削除
    	pa.end();
        	
	//5. プロセスBがロック中にも関わらず、プロセスCがロックを取得し
	//   ようとすると成功してしまう
	
		File lock = new File(".lck");
        assertNull( "ロックできてはいけない", r );

	pb.end();
    }
}