6

MbUnit を使用してマルチスレッド IO クラスをテストしようとしています。私の目標は、クラスの行ごとに 1 回ずつ、テスト フィクスチャ コンストラクターを 3 回実行させることです。次に、インスタンスごとに、並列スレッドでテストを複数回実行します。

ただし、Icarus は TaskRunner で「範囲外のインデックス」で爆発します。完全なスタックを取得できません。メッセージ ボックスの生成が速すぎます。

これは MbUnit/Gallio のバグですか?

using System;
using System.Collections.Generic;
using System.Text;
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
using System.IO;

namespace ImageResizer.Plugins.DiskCache.Tests {
    [TestFixture]
    [Row(0,50,false)]
    [Row(0,50,true)]
    [Row(8000,100,true)]
    public class CustomDiskCacheTest {

        public CustomDiskCacheTest(int subfolders, int totalFiles, bool hashModifiedDate) {
            char c = System.IO.Path.DirectorySeparatorChar;
            string folder = System.IO.Path.GetTempPath().TrimEnd(c) + c + System.IO.Path.GetRandomFileName();
            cache = new CustomDiskCache(folder,subfolders,hashModifiedDate);
            this.quantity = totalFiles;

            for (int i = 0; i < quantity;i++){
                cache.GetCachedFile(i.ToString(),"test",delegate(Stream s){
                    s.WriteByte(32); //Just one space
                },defaultDate, 10);
            }
        }
        int quantity;
        CustomDiskCache cache = null;
        DateTime defaultDate = new DateTime(2011, 1, 1);

        [ThreadedRepeat(150)]
        [Test(Order=1)]
        public void TestAccess() {
            CacheResult r = 
                cache.GetCachedFile(new Random().Next(0, quantity).ToString(), "test", 
                delegate(Stream s) { Assert.Fail("No files have been modified, this should not execute"); }, defaultDate, 100);

            Assert.IsTrue(System.IO.File.Exists(r.PhysicalPath));
            Assert.IsTrue(r.Result == CacheQueryResult.Hit);
        }

        volatile int seed = 0;
        [Test (Order=2)]
        [ThreadedRepeat(20)]
        public void TestUpdate() {
            //try to get a unique date time value
            DateTime newTime = DateTime.UtcNow.AddDays(seed++);
            CacheResult r =
                cache.GetCachedFile(new Random().Next(0, quantity).ToString(), "test",
                delegate(Stream s) {
                    s.WriteByte(32); //Just one space
                }, newTime, 100);

            Assert.AreEqual<DateTime>(newTime, System.IO.File.GetLastWriteTimeUtc(r.PhysicalPath));
            Assert.IsTrue(r.Result == CacheQueryResult.Miss);
        }


        [Test(Order=3)]
        public void TestClear() {
            System.IO.Directory.Delete(cache.PhysicalCachePath, true);
        }
    }
}
4

1 に答える 1

1

バグに関する直接の質問にはお答えしませんが、次の手順はエラーを見つけるのに役立ち、ポップメッセージボックスで迷子になることはないと思います

  • totalfiles 、 subfolders の数をはるかに低い値に減らして、2 つまたは 1 つのファイル数でもエラーが続くかどうかを確認します

    • あなたのテストコードはそれほど簡単ではありません。当然のことながら、テスト用のテストを作成して、それらが正しく実行されていることを確認してください。おそらく、これらのランダムな次が問題であり、他の何かである可能性があります。テストは簡単なはずです。

    • どのテストがシステムを壊すかを把握し、コードには 3 つのテストとコンストラクターが含まれており、他の 2 つのテストにコメントを付けて、どれがエラーを生成するかを確認します。

    • スレッド化された繰り返し 150 はかなり問題があるように見えます。エラーが基本的な場合は、2 または 3 のような小さい数を試してみてください。150 スレッドを実行すると、2 つのスレッドでも壊れる可能性があります。

    • ロギングを追加してキャッチを試してください - そのインデックス例外をキャッチし、クラスの状態を注意深く記録してください。それを調べた後、問題がより明確になると思います。

MBunit 機能が表示される前に、原因となっているいくつかの単純なエラーを含む可能性のある Cache クラスのコードを提供しなかったことは言うまでもありません。

于 2011-05-21T23:39:19.123 に答える