Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,15 @@ ELSE [@採番値リセット] = "しない";
#
# 条件重複ケース(存在する場合は「結果の条件」の定義に漏れがある):
# 重複ID No maxReservedValue nextValue after_nextValue after_isStarving @isOverflow @isEmpty @採番 @after_isOverflow @after_isEmpty @採番値予約 @採番値リセット
#
# オールペア(2因子間網羅)ケース:
# No maxReservedValue nextValue after_nextValue after_isStarving @isOverflow @isEmpty @採番 @after_isOverflow @after_isEmpty @採番値予約 @採番値リセット
# 1 < 予約可能な最大値 < maxReservedValue < maxReservedValue FALSE FALSE FALSE する FALSE FALSE しない しない
# 2 < 予約可能な最大値 < maxReservedValue < maxReservedValue TRUE FALSE FALSE する FALSE FALSE する しない
# 3 < 予約可能な最大値 < maxReservedValue = maxReservedValue TRUE FALSE FALSE する FALSE FALSE する しない
# 4 < 予約可能な最大値 = maxReservedValue > maxReservedValue TRUE FALSE FALSE する FALSE TRUE する しない
# 5 < 予約可能な最大値 > maxReservedValue > maxReservedValue TRUE FALSE TRUE しない FALSE TRUE する しない
# 6 = 予約可能な最大値 < maxReservedValue < maxReservedValue FALSE FALSE FALSE する FALSE FALSE しない しない
# 7 = 予約可能な最大値 < maxReservedValue = maxReservedValue TRUE FALSE FALSE する FALSE FALSE しない しない
# 8 = 予約可能な最大値 = maxReservedValue > maxReservedValue TRUE FALSE FALSE する TRUE TRUE しない する
# 9 = 予約可能な最大値 > maxReservedValue > maxReservedValue TRUE TRUE TRUE しない TRUE TRUE しない する
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#
# SequenceFactoryWorker が SequenceStore からの応答を受け取ったときにどのように振る舞うかケースを洗い出します
# InitialSequenceReserved の応答はここでは考慮しません。
# 初期化が完了するまでの間は採番が実行されず、SequenceFactoryWorker の状態変化も少ないため
# 既存のテストケースで十分な品質が確保できていると考えたからです。
# 既に SequenceFactoryWorker が初期化済みであるという前提のもとでテストケースを洗い出します。
#
# 書き方: https://github.com/Microsoft/pict/blob/main/doc/pict.md
#
##################################################
# 条件
##################################################

# 返信を受け取る前の isEmpty
isEmpty: TRUE, FALSE

# 返信を受け取る前の isOverflow
isOverflow: TRUE, FALSE

# 受け取った返信
msg: SequenceReserved, ReservationFailed, SequenceReset

# 受け取った返信の maxReservedValue
# ReservationFailed には maxReservedValue がないので NaN を使う
msg.maxReservedValue: > ctx.maxReservedValue, = ctx.maxReservedValue, < ctx.maxReservedValue, NaN

##################################################
# 結果
##################################################

# 返信を受け取った後の SequenceContext の状態

@received.isEmpty: <isEmpty>

# 返信の直後に GenerateSequence を受け取ったときの振る舞い

@採番: できる, できない

##################################################
# 条件の制約
##################################################

# msg.maxReservedValue

# msg.maxReservedValue = NaN は ReservationFailed のときだけ
IF [msg] = "ReservationFailed"
THEN [msg.maxReservedValue] = "NaN"
ELSE [msg.maxReservedValue] <> "NaN";

# SequenceStore のコマンドに対する応答順序が前後することはないため、
# msg.maxReservedValue < ctx.maxReservedValue となるメッセージが届くことはない
IF [msg] = "SequenceReserved"
THEN [msg.maxReservedValue] <> "< ctx.maxReservedValue";

# 採番値リセットで ctx.maxReservedValue よりも大きい maxReservedValue が予約されることはない
IF [msg] = "SequenceReset"
THEN [msg.maxReservedValue] <> "> ctx.maxReservedValue";

# オーバフローしているときに、それよりも大きい採番値が予約されることはない
IF [isOverflow] = "TRUE"
THEN [msg.maxReservedValue] <> "> ctx.maxReservedValue";

# isEmpty

# オーバフローしているということは採番値がないことと同義
IF [isOverflow] = "TRUE"
THEN [isEmpty] = "TRUE";

# isOverflow

##################################################
# 結果の条件
##################################################

# @received.isEmpty

# 予約成功
IF [isOverflow] = "FALSE" AND [isEmpty] = "TRUE" AND [msg] = "SequenceReserved" AND [msg.maxReservedValue] = "> ctx.maxReservedValue"
THEN [@received.isEmpty] = "FALSE";

# 予約未成功
IF [isOverflow] = "FALSE" AND [isEmpty] = "TRUE" AND [msg] = "ReservationFailed"
THEN [@received.isEmpty] = "TRUE";

# 予約応答の重複(予約をリトライした場合に発生する可能性がある)
IF [msg] = "SequenceReserved" AND [msg.maxReservedValue] = "= ctx.maxReservedValue"
THEN [@received.isEmpty] = [isEmpty];

# リセット成功
# msg.maxReservedValue = ctx.maxReservedValue となるケースは通常考えにくいが、
# 1回目の予約で上限ギリギリまで予約してしまうような設定をしていると発生しうる(全採番値を通して 1 回しか予約が発生しないケース)
IF [isOverflow] = "TRUE" AND [msg] = "SequenceReset" AND ([msg.maxReservedValue] = "< ctx.maxReservedValue" OR [msg.maxReservedValue] = "= ctx.maxReservedValue")
THEN [@received.isEmpty] = "FALSE";

# リセット未成功
IF [isOverflow] = "TRUE" AND [msg] = "ReservationFailed"
THEN [@received.isEmpty] = "TRUE";

# リセット応答の重複(リセットリトライした場合に発生する可能性がある)
IF [isOverflow] = "FALSE" AND [msg] = "SequenceReset"
THEN [@received.isEmpty] = [isEmpty];

# 採番せずに枯渇することはない
IF [isEmpty] = "FALSE"
THEN [@received.isEmpty] = "FALSE";

# @採番

# 採番値が枯渇していないときだけ採番する
IF [@received.isEmpty] = "TRUE"
THEN [@採番] = "できない"
ELSE [@採番] = "できる";

##################### OUTPUT #####################
# 全組み合わせ網羅ケース:
# No isEmpty isOverflow msg msg.maxReservedValue @received.isEmpty @採番
# 1 FALSE FALSE ReservationFailed NaN FALSE できる
# 2 FALSE FALSE SequenceReserved = ctx.maxReservedValue FALSE できる
# 3 FALSE FALSE SequenceReserved > ctx.maxReservedValue FALSE できる
# 4 FALSE FALSE SequenceReset < ctx.maxReservedValue FALSE できる
# 5 FALSE FALSE SequenceReset = ctx.maxReservedValue FALSE できる
# 6 TRUE FALSE ReservationFailed NaN TRUE できない
# 7 TRUE FALSE SequenceReserved = ctx.maxReservedValue TRUE できない
# 8 TRUE FALSE SequenceReserved > ctx.maxReservedValue FALSE できる
# 9 TRUE FALSE SequenceReset < ctx.maxReservedValue TRUE できない
# 10 TRUE FALSE SequenceReset = ctx.maxReservedValue TRUE できない
# 11 TRUE TRUE ReservationFailed NaN TRUE できない
# 12 TRUE TRUE SequenceReserved = ctx.maxReservedValue TRUE できない
# 13 TRUE TRUE SequenceReset < ctx.maxReservedValue FALSE できる
# 14 TRUE TRUE SequenceReset = ctx.maxReservedValue FALSE できる
#
# 条件重複ケース(存在する場合は「結果の条件」の定義に漏れがある):
# 重複ID No isEmpty isOverflow msg msg.maxReservedValue @received.isEmpty @採番
#
# オールペア(2因子間網羅)ケース:
# No isEmpty isOverflow msg msg.maxReservedValue @received.isEmpty @採番
# 1 FALSE FALSE ReservationFailed NaN FALSE できる
# 2 FALSE FALSE SequenceReserved = ctx.maxReservedValue FALSE できる
# 3 FALSE FALSE SequenceReserved > ctx.maxReservedValue FALSE できる
# 4 FALSE FALSE SequenceReset < ctx.maxReservedValue FALSE できる
# 5 TRUE FALSE SequenceReserved > ctx.maxReservedValue FALSE できる
# 6 TRUE FALSE SequenceReset < ctx.maxReservedValue TRUE できない
# 7 TRUE FALSE SequenceReset = ctx.maxReservedValue TRUE できない
# 8 TRUE TRUE ReservationFailed NaN TRUE できない
# 9 TRUE TRUE SequenceReserved = ctx.maxReservedValue TRUE できない
# 10 TRUE TRUE SequenceReset < ctx.maxReservedValue FALSE できる
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,48 @@ set -eu
readonly output_label='##################### OUTPUT #####################'

readonly result_file="$(mktemp)"
readonly pict_output_file="$(mktemp)"
readonly pict_all_pair_output_file="$(mktemp)"
readonly pict_cover_all_output_file="$(mktemp)"

trap on_exit EXIT
function on_exit {
rm "${result_file}" "${pict_output_file}"
rm "${result_file}" "${pict_all_pair_output_file}" "${pict_cover_all_output_file}"
}

function main {
local pict_file="$1" nr_of_column

nr_of_column="$(count_column "${pict_file}")"
cat "${pict_file}" | pict > "${pict_all_pair_output_file}"

nr_of_column="$(count_column "${pict_all_pair_output_file}")"

# -o: オプションで条件数と同じ数を指定することで全網羅パターンを出力できる。(デフォルトではペアワイズ法によりケースが絞られる)
# 参考:
# ペアワイズ法によるテストケース抽出ツール「PICT」を使ってテストケースを85%削減する - Qiita
# https://qiita.com/bremen/items/6eceddc534d87fc797cc
cat "${pict_file}" | pict -o:${nr_of_column} > "${pict_output_file}"
cat "${pict_file}" | pict -o:${nr_of_column} > "${pict_cover_all_output_file}"

{
cat "${pict_file}" | remove_output
echo "${output_label}"
} > "${result_file}"
{
echo "# 全組み合わせ網羅ケース:"
normalize_pict_output "${pict_output_file}" | decorate_table
normalize_pict_output "${pict_cover_all_output_file}" | decorate_table
echo "#"
echo "# 条件重複ケース(存在する場合は「結果の条件」の定義に漏れがある):"
normalize_pict_output "${pict_output_file}" | print_repeated_factors | decorate_table
normalize_pict_output "${pict_cover_all_output_file}" | print_repeated_factors | decorate_table
echo "#"
echo "# オールペア(2因子間網羅)ケース:"
normalize_pict_output "${pict_all_pair_output_file}" | decorate_table
} | tee -a "${result_file}"

cat "${result_file}" > "${pict_file}"
}

function count_column {
local pict_file="$1"
cat "${pict_file}" | pict | head -n 1 | awk -v FS='\t' '{ print NF }'
local pict_output_file="$1"
head -n 1 "${pict_output_file}" | awk -v FS='\t' '{ print NF }'
}

function remove_output {
Expand Down