forked from kontur-intern-2015/testing
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
164 lines (153 loc) · 4.16 KB
/
Program.cs
File metadata and controls
164 lines (153 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using Kontur.Courses.Testing.Implementations;
using NUnit.Framework;
namespace Kontur.Courses.Testing
{
class Program
{
static void Main()
{
if (!CheckTests()) return;
var implementations = GetImplementations();
CheckIncorrectImplementationsFail(implementations);
}
private static void CheckIncorrectImplementationsFail(IEnumerable<Type> implementations)
{
foreach (var implementation in implementations)
{
var isCorrectImplementation = implementation == typeof (WordsStatistics_CorrectImplementation);
var failed = GetFailedTests(implementation, isCorrectImplementation).ToList();
Console.Write(implementation.Name + "\t");
if (failed.Any())
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("fails on tests: " + string.Join(", ", failed));
Console.ForegroundColor = ConsoleColor.Gray;
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("pass all tests :(");
Console.ForegroundColor = ConsoleColor.Gray;
}
}
}
private static IEnumerable<Type> GetImplementations()
{
return
Assembly.GetExecutingAssembly().GetTypes()
.Where(typeof (IWordsStatistics).IsAssignableFrom)
.Where(t => !t.IsAbstract && !t.IsInterface)
.Where(t => t != typeof(WordsStatistics_CorrectImplementation));
}
private static bool CheckTests()
{
Console.WriteLine("Check all tests pass with correct implementation...");
var failed = GetFailedTests(typeof(WordsStatistics_CorrectImplementation), true).ToList();
if (failed.Any())
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Incorrect tests detected: " + string.Join(", ", failed));
Console.ForegroundColor = ConsoleColor.Gray;
return false;
}
else
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Tests are OK!");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Gray;
return true;
}
}
private static IEnumerable<string> GetFailedTests(Type implementationType, bool printError)
{
foreach (var testMethod in GetTestMethods())
{
if (!RunTestMethod(implementationType, testMethod, printError))
yield return testMethod.Name;
}
}
private static bool RunTestMethod(Type implementationType, MethodInfo testMethod, bool printError)
{
Func<IWordsStatistics> createImpl = () => (IWordsStatistics)Activator.CreateInstance(implementationType);
var testObj = new WordsStatistics_Tests { createStat = createImpl };
testObj.SetUp();
var timeout = GetTimeout(testMethod);
try
{
Action test = () => testMethod.Invoke(testObj, new object[0]);
if (timeout > 0)
RunTestOnOwnThread(timeout, test);
else test();
}
catch (Exception e)
{
if (printError)
Console.WriteLine(e.InnerException);
return false;
}
return true;
}
private static int GetTimeout(MethodInfo method)
{
return method.GetCustomAttributes<TimeoutAttribute>()
.Select(attr => (int)attr.Properties["Timeout"])
.FirstOrDefault();
}
private static IEnumerable<MethodInfo> GetTestMethods()
{
var testMethods = typeof(WordsStatistics_Tests).GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Where(m => m.GetCustomAttribute<TestAttribute>() != null);
return testMethods;
}
private static void RunTestOnOwnThread(int timeout, Action action)
{
Exception ex = null;
object locker = new object();
Thread thread = new Thread(() =>
{
try
{
action();
}
catch (Exception e)
{
lock(locker)
ex = e;
}
});
thread.Start();
thread.Join(timeout);
if (!thread.IsAlive)
{
lock (locker)
if (ex != null)
throw ex;
return;
}
Kill(thread);
thread.Join();
throw new TimeoutException();
}
public static void Kill(Thread thread)
{
try
{
thread.Abort();
}
catch (ThreadStateException)
{
#pragma warning disable 618
thread.Resume();
#pragma warning restore 618
}
if ((thread.ThreadState & ThreadState.WaitSleepJoin) != 0)
thread.Interrupt();
}
}
}