blob: 78724900aad8eab6b859cd357bdadb5b07ceb6f0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.service.paxos;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import org.junit.Test;
import static org.apache.cassandra.service.paxos.PaxosPropose.*;
public class PaxosProposeTest
{
static class V
{
static final AtomicLongFieldUpdater<V> updater = AtomicLongFieldUpdater.newUpdater(V.class, "v");
volatile long v;
public boolean valid()
{
return v == 0;
}
}
@Test
public void testShouldSignal()
{
int[] signalledAtK = new int[12];
V[] v = new V[] { new V(), new V(), new V(), new V(), new V(), new V(), new V(), new V(), new V(), new V(), new V(), new V() };
boolean[] signalled = new boolean[12];
for (int total = 2 ; total < 16 ; ++total)
{
for (int required = (total/2) + 1 ; required < total ; ++required)
{
for (int i = 0 ; i < total ; ++i)
{
for (int j = 0 ; j < total - i ; ++j)
{
Arrays.fill(signalled, false);
Arrays.fill(signalledAtK, Integer.MAX_VALUE);
for (int x = 0 ; x < v.length ; ++x)
v[x].v = 0;
for (int k = 0 ; k <= total - (i + j) ; ++k)
{
signalled[0] = v[0].valid() && shouldSignal(responses(i, j, k), required, total, true, V.updater, v[0]);
signalled[1] = v[1].valid() && shouldSignal(responses(j, i, k), required, total, true, V.updater, v[1]);
signalled[2] = v[2].valid() && shouldSignal(responses(j, k, i), required, total, true, V.updater, v[2]);
signalled[3] = v[3].valid() && shouldSignal(responses(k, i, j), required, total, true, V.updater, v[3]);
signalled[4] = v[4].valid() && shouldSignal(responses(i, k, j), required, total, true, V.updater, v[4]);
signalled[5] = v[5].valid() && shouldSignal(responses(k, j, i), required, total, true, V.updater, v[5]);
signalled[6] = v[6].valid() && shouldSignal(responses(i, j, k), required, total, false, V.updater, v[6]);
signalled[7] = v[7].valid() && shouldSignal(responses(j, i, k), required, total, false, V.updater, v[7]);
signalled[8] = v[8].valid() && shouldSignal(responses(j, k, i), required, total, false, V.updater, v[8]);
signalled[9] = v[9].valid() && shouldSignal(responses(k, i, j), required, total, false, V.updater, v[9]);
signalled[10] = v[10].valid() && shouldSignal(responses(i, k, j), required, total, false, V.updater, v[10]);
signalled[11] = v[11].valid() && shouldSignal(responses(k, j, i), required, total, false, V.updater, v[11]);
for (int x = 0 ; x < 12 ; ++x)
{
if (signalled[x] && signalledAtK[x] < k)
throw new IllegalStateException(String.format("(%d,%d,%d): (%d,%d,%d,%d)", total, required, x, i, j, k, signalledAtK[x]));
else if (signalled[x])
signalledAtK[x] = k;
}
}
for (int x = 0 ; x < 12 ; ++x)
{
if (signalledAtK[x] == Integer.MAX_VALUE)
throw new IllegalStateException(String.format("(%d,%d,%d): (%d, %d)", total, required, x, i, j));
}
}
}
}
}
}
private static long responses(int i, int j, int k)
{
return i * ACCEPT_INCREMENT + j * REFUSAL_INCREMENT + k * FAILURE_INCREMENT;
}
}