Skip to content

Commit

Permalink
* Test refactoring
Browse files Browse the repository at this point in the history
* Use dummy head and tail also in LinkedList tests
  (preparation for more versatile InsertAfterIfEqual)
  • Loading branch information
Christoph Müller committed Apr 30, 2018
1 parent 001a878 commit 745a8d4
Show file tree
Hide file tree
Showing 22 changed files with 533 additions and 304 deletions.
23 changes: 16 additions & 7 deletions test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static void Main(string[] args)
{
Random rand = new Random();

long remainingTests = 1;
long remainingTests = 20000;
var logIntervalStopwatch = new Stopwatch();
var testBatchStopwatch = new Stopwatch();
long testBatchSize;
Expand All @@ -58,14 +58,23 @@ private static void Main(string[] args)
var test = new Test001();
test.Seed = rand.Next(int.MinValue, int.MaxValue);
//Console.WriteLine("seed: {0}", test.Seed);
Thread.Yield();
testRunsStopwatch.Start();
Thread.MemoryBarrier();

test.Main(args);
try
{
Thread.Yield();
testRunsStopwatch.Start();
Thread.MemoryBarrier();

test.Main(args);

Thread.MemoryBarrier();
testRunsStopwatch.Stop();
Thread.MemoryBarrier();
testRunsStopwatch.Stop();
}
catch
{
Console.WriteLine($"The test failed. The seed was: {test.Seed}.");
throw;
}
}
if (testBatchSize > 0)
{
Expand Down
167 changes: 15 additions & 152 deletions test/Tests/Test001.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

namespace Test.Tests
{
internal class Test001 : Test
internal partial class Test001 : Test
{
public override void Main(string[] args)
{
Expand All @@ -56,15 +56,7 @@ public override void Main(string[] args)
const int operationNumberPerSequence = 4;
const int listSize = 4;

//Seed = -1182330010;
//Seed = 1136758711;

//Seed = 2037835186;
//Seed = -1713978986;
//Seed = -61631207;
//Seed = 2078889772;
//Seed = 234923264;
//Seed = -583307162;
//Seed = 669052551;
Random rand2 = new Random(Seed);

TestIterationParameters iterationParameters =
Expand Down Expand Up @@ -134,8 +126,7 @@ IEqualityComparer<ListItemData> equalityComparer
.ToList()))
.Any(
llResult =>
llResult.SequenceEqual(
lfdllResultList, equalityComparer)
llResult.SequenceEqual(lfdllResultList, equalityComparer)
&& iterationParameters.OperationSequences.All(
os => os.Operations.All(o => o.LastResultsEqual)));
// ReSharper disable once RedundantLogicalConditionalExpressionOperand
Expand Down Expand Up @@ -517,7 +508,10 @@ private IEnumerable<ListItemData> runOnLinkedList(
new ListItemData(
i,
initializationRandom.Next(
listItemValueRange)))));
listItemValueRange)),
isDummy: false)));
list.AddFirst(new LinkedListItem(null, true));
list.AddLast(new LinkedListItem(null, true));

List<linkedListOperationExecutor> executors =
parameters.OperationSequences.Select(
Expand All @@ -529,10 +523,15 @@ private IEnumerable<ListItemData> runOnLinkedList(

foreach (int executorIndex in executorStepOrder)
{
executors[executorIndex].SingleStep();
executors[executorIndex].RunSingleOperation();
}

return list.Where(value => !value.Deleted).Select(item => item.Data);
return list
.Skip(1)
.SkipLast(1)
.Where(value => !value.Deleted)
.Select(item => item.Data)
.ToList();
}

private TestIterationParameters newIterationParameters(int listSize, int operationSequencesNumber, int operationNumberPerSequence, Random rand)
Expand All @@ -546,7 +545,7 @@ private TestIterationParameters newIterationParameters(int listSize, int operati
operationSequencesNumber,
() => new ExecutionSequenceParameters
{
StartIndex = rand.Next(listSize),
StartIndex = rand.Next(listSize + 2), // with head and tail node
Operations =
LinqHelper.Repeat(
operationNumberPerSequence,
Expand Down Expand Up @@ -576,141 +575,5 @@ private static Tuple<long, long> measureTime(Action action, Counter counter)

return new Tuple<long, long>(start, end);
}

private class operationTiming
{
public readonly IOperationResultComparer Operation;
public readonly long Start, End;

public operationTiming(IOperationResultComparer operation,
Tuple<long, long> timing)
{
Operation = operation;
Start = timing.Item1;
End = timing.Item2;
}
}

private class lfdllOperationExecutor
{
public int Name { get; }

/* Should be executed before a
* LFDLLOperationExecutor modifies list. */

public void Initialize()
{
ILockFreeDoublyLinkedListNode<ListItemData> current =
state.List.Head;
for (int i = 0; i < eParams.StartIndex + 1; i++)
current = current.Next;
state.Current = current;
}

public List<operationTiming> Run()
{
#if !RunOperationsSequentially
Thread.CurrentThread.Name = Name.ToString();
#endif
return eParams.Operations
.Select(operation =>
new operationTiming(
operation,
processOperation(operation, counter)))
.ToList();
}

public lfdllOperationExecutor(
ExecutionSequenceParameters eParams,
ILockFreeDoublyLinkedList<ListItemData> list, Counter counter,
int name)
{
this.eParams = eParams;
this.counter = counter;
Name = name;
state = new LfdllExecutionState(list);
}

#region private
private readonly ExecutionSequenceParameters eParams;
private readonly LfdllExecutionState state;
private readonly Counter counter;

private Tuple<long, long> processOperation(
IOperationResultComparer op, Counter ctr)
{
#if SynchronizedLfdll_verbose
Console.WriteLine("({0}) Nächste Operation: {1}", Name, op);
Console.WriteLine("({0}) Aktueller Knoten:", Name);
state.List.LogNode(state.Current);
#endif

Tuple<long, long> timing = measureTime(
() =>
{
op.RunOnLfdll(state);
},
ctr);

#if SynchronizedLfdll_verbose
Console.WriteLine("({0}) Beendete Operation: {1}", Name, op);
#endif

return timing;
}
#endregion
}

private class linkedListOperationExecutor
{
public void Initialize()
{
LinkedListNode<LinkedListItem> current = state.List.First;
for (int i = 0; i < eParams.StartIndex; i++)
{
// ReSharper disable once PossibleNullReferenceException
current = current.Next;
}
state.Current = current;
}

public void SingleStep()
{
IOperationResultComparer operation
= eParams.Operations[nextOperation];
operation.RunOnLinkedList(state);
nextOperation++;
}

public linkedListOperationExecutor(
ExecutionSequenceParameters eParams,
LinkedList<LinkedListItem> list)
{
state = new LinkedListExecutionState(list);
this.eParams = eParams;
}

#region private
private readonly ExecutionSequenceParameters eParams;
private readonly LinkedListExecutionState state;
private int nextOperation = 0;
#endregion
}

private class operationExecutionInfo
{
public readonly int ExecutorIndex;
public readonly IOperationResultComparer Operation;
public readonly long Start, End;

public operationExecutionInfo(
operationTiming operationTiming, int executorIndex)
{
ExecutorIndex = executorIndex;
Operation = operationTiming.Operation;
Start = operationTiming.Start;
End = operationTiming.End;
}
}
}
}
116 changes: 116 additions & 0 deletions test/Tests/Test001.lfdllOperationExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#region license
// Copyright 2016 Christoph Müller
//
// Licensed 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.
#endregion
#define CheckCorrectness
/* If a thread misses, cancel immediately
* and don’t become entangled in a deadlock.
* Additionally, output the seed number.
* May exacerbate the exception handling in the IDE, though. */
#define HandleTaskExceptionImmediately
/* PopLeft is not atomic supported by the current LFDLL implementation. */
//#define PopLeft


#if SynchronizedLfdll
#if Verbose
#define SynchronizedLfdll_verbose
#endif
#undef RunOperationsSequentially
#endif

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using LockFreeDoublyLinkedLists;
using Test.Tests.Test001_;

namespace Test.Tests
{
internal partial class Test001
{
private class lfdllOperationExecutor
{
public int Name { get; }

/* Should be executed before a
* LFDLLOperationExecutor modifies list. */

public void Initialize()
{
ILockFreeDoublyLinkedListNode<ListItemData> current =
state.List.Head;
for (int i = 0; i < eParams.StartIndex; i++)
current = current.Next;
state.Current = current;
}

public List<operationTiming> Run()
{
#if !RunOperationsSequentially
Thread.CurrentThread.Name = Name.ToString();
#endif
return eParams.Operations
.Select(operation =>
new operationTiming(
operation,
processOperation(operation, counter)))
.ToList();
}

public lfdllOperationExecutor(
ExecutionSequenceParameters eParams,
ILockFreeDoublyLinkedList<ListItemData> list, Counter counter,
int name)
{
this.eParams = eParams;
this.counter = counter;
Name = name;
state = new LfdllExecutionState(list);
state.AddToKnownNodes(list.Head);
state.AddingToKnownNodes(list.Tail);
}

#region private
private readonly ExecutionSequenceParameters eParams;
private readonly LfdllExecutionState state;
private readonly Counter counter;

private Tuple<long, long> processOperation(
IOperationResultComparer op, Counter ctr)
{
#if SynchronizedLfdll_verbose
Console.WriteLine("({0}) Nächste Operation: {1}", Name, op);
Console.WriteLine("({0}) Aktueller Knoten:", Name);
state.List.LogNode(state.Current);
#endif

Tuple<long, long> timing = measureTime(
() =>
{
op.RunOnLfdll(state);
},
ctr);

#if SynchronizedLfdll_verbose
Console.WriteLine("({0}) Beendete Operation: {1}", Name, op);
#endif

return timing;
}
#endregion
}
}
}
Loading

0 comments on commit 745a8d4

Please sign in to comment.