Skip to content

Commit 4eac375

Browse files
committed
Improvements of test framework
- Ignoring on Github actions improved - fixed firebird25 connection and added new for firebird30 - Added some versions to be used in test requirements
1 parent cd6b434 commit 4eac375

5 files changed

Lines changed: 175 additions & 23 deletions

File tree

Orm/Xtensive.Orm.Tests.Framework/NUnitFrameworkExtensions/IgnoreIfGithubActionsAttribute.cs

Lines changed: 115 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,142 @@
44
namespace Xtensive.Orm.Tests
55
{
66
/// <summary>
7-
/// Ignores test if test run is in Github Action environment
7+
/// Helps to ignore flaky tests
88
/// </summary>
9-
public sealed class IgnoreIfGithubActionsAttribute : NUnitTestCustomAttribute
9+
public sealed class IgnoreOnGithubActionsIfFailedAttribute : IgnoreIfGithubActionAttributeBase
1010
{
11-
public string Reason { get; private set; }
11+
protected override bool CheckIfFailed => true;
1212

13-
public StorageProvider? Provider { get; private set; }
13+
public IgnoreOnGithubActionsIfFailedAttribute(StorageProvider provider, GithubActionsEvents triggerEvent, string reason)
14+
: base((StorageProvider?) provider, triggerEvent, reason)
15+
{
16+
}
1417

15-
protected override void OnBeforeTestCheck(ITest test)
18+
19+
public IgnoreOnGithubActionsIfFailedAttribute(GithubActionsEvents triggerEvent, string reason)
20+
: base(null, triggerEvent, reason)
21+
{
22+
}
23+
24+
public IgnoreOnGithubActionsIfFailedAttribute(GithubActionsEvents triggerEvent)
25+
: base(null, triggerEvent, null)
26+
{
27+
}
28+
29+
public IgnoreOnGithubActionsIfFailedAttribute(StorageProvider provider, string reason)
30+
: base(provider, null, reason)
31+
{
32+
}
33+
34+
public IgnoreOnGithubActionsIfFailedAttribute(StorageProvider provider)
35+
: base(provider, null, null)
36+
{
37+
}
38+
39+
public IgnoreOnGithubActionsIfFailedAttribute(string reason)
40+
: base(null, null, reason)
41+
{
42+
}
43+
44+
public IgnoreOnGithubActionsIfFailedAttribute()
45+
: base(null, null, null)
46+
{
47+
}
48+
}
49+
50+
/// <summary>
51+
/// Helps to ignore always failing tests.
52+
/// </summary>
53+
public sealed class IgnoreIfGithubActionsAttribute : IgnoreIfGithubActionAttributeBase
54+
{
55+
protected override bool CheckIfFailed => false;
56+
57+
58+
public IgnoreIfGithubActionsAttribute(StorageProvider provider, GithubActionsEvents triggerEvent, string reason)
59+
: base((StorageProvider?) provider, triggerEvent, reason)
60+
{
61+
}
62+
63+
64+
public IgnoreIfGithubActionsAttribute(GithubActionsEvents triggerEvent, string reason)
65+
: base(null, null, reason)
66+
{
67+
}
68+
69+
public IgnoreIfGithubActionsAttribute(GithubActionsEvents triggerEvent)
70+
: base(null, triggerEvent, null)
1671
{
17-
if (TestInfo.IsGitHubActions) {
18-
if (Provider.HasValue && !StorageProviderInfo.Instance.CheckProviderIs(Provider.Value))
19-
return;
20-
throw new IgnoreException(
21-
string.IsNullOrEmpty(Reason)
22-
? "Ignored due to run on Github Actions. Test is always failing."
23-
: $"Ignored due to run on Github Actions. {Reason}");
24-
}
2572
}
2673

2774
public IgnoreIfGithubActionsAttribute(StorageProvider provider, string reason)
75+
: base(provider, null, reason)
2876
{
29-
Reason = reason;
30-
Provider = provider;
3177
}
3278

3379
public IgnoreIfGithubActionsAttribute(StorageProvider provider)
80+
: base(provider, null, null)
3481
{
35-
Provider = provider;
3682
}
3783

3884
public IgnoreIfGithubActionsAttribute(string reason)
85+
: base(null, null, reason)
3986
{
40-
Reason = reason;
4187
}
4288

4389
public IgnoreIfGithubActionsAttribute()
90+
: base(null, null, null)
91+
{
92+
}
93+
}
94+
95+
public abstract class IgnoreIfGithubActionAttributeBase : NUnitTestCustomAttribute
96+
{
97+
public string Reason { get; private set; }
98+
99+
public StorageProvider? Provider { get; private set; }
100+
101+
public GithubActionsEvents? TriggerEvent { get; private set; }
102+
103+
protected abstract bool CheckIfFailed { get; }
104+
105+
protected override void OnBeforeTestCheck(ITest test)
44106
{
107+
if (TestInfo.IsGithubActions && !CheckIfFailed) {
108+
Check();
109+
}
110+
}
111+
112+
protected override void OnAfterTestCheck(ITest test)
113+
{
114+
var resultOutcome = TestContext.CurrentContext.Result.Outcome;
115+
if (TestInfo.IsGithubActions && CheckIfFailed
116+
&& (resultOutcome == ResultState.Failure || resultOutcome == ResultState.Error)) {
117+
Check();
118+
}
119+
}
120+
121+
private void Check()
122+
{
123+
if (Provider.HasValue && !StorageProviderInfo.Instance.CheckProviderIs(Provider.Value)) {
124+
return;
125+
}
126+
127+
if (TriggerEvent.HasValue && TriggerEvent != TestInfo.GithubActionTrigger) {
128+
return;
129+
}
130+
131+
throw new IgnoreException(
132+
string.IsNullOrEmpty(Reason)
133+
? $"Ignored due to run on Github Actions. {(CheckIfFailed ? "Flaky tests failed this time" : "Test is always failing")}."
134+
: $"Ignored due to run on Github Actions. {Reason}");
135+
}
136+
137+
138+
protected IgnoreIfGithubActionAttributeBase(StorageProvider? provider, GithubActionsEvents? triggerEvent, string reason)
139+
{
140+
Provider = provider;
141+
TriggerEvent = triggerEvent;
142+
Reason = reason;
45143
}
46144
}
47145
}

Orm/Xtensive.Orm.Tests.Framework/NUnitFrameworkExtensions/RequireProviderAttributes.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using NUnit.Framework;
32
using NUnit.Framework.Interfaces;
43

54
namespace Xtensive.Orm.Tests

Orm/Xtensive.Orm.Tests.Framework/Orm.config

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@
6767
connectionUrl="mysql://dotest:dotest@localhost:3356/dotest" />
6868

6969
<domain name="firebird25" provider="firebird"
70-
connectionString="User=dotest;Password=dotest;Database=dotest;DataSource=localhost;Port=3050;Dialect=3;Charset=UTF8;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0" />
70+
connectionUrl="firebird://dotest:dotest@localhost:3050/dotest" />
71+
72+
<domain name="firebird30" provider="firebird"
73+
connectionUrl="firebird://dotest:dotest@localhost:3053/dotest" />
7174

7275
<domain name="sqlite3"
7376
connectionUrl="sqlite:///DO-Tests.db3" />
@@ -136,7 +139,10 @@
136139

137140
<domain name="firebird25cs" provider="firebird"
138141
connectionString="User=dotest;Password=dotest;Database=dotest;DataSource=localhost;Port=3050;Dialect=3;Charset=UTF8;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0" />
139-
142+
143+
<domain name="firebird30cs" provider="firebird"
144+
connectionString="User=dotest;Password=dotest;Database=dotest;DataSource=localhost;Port=3053;Dialect=3;Charset=UTF8;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0" />
145+
140146
<domain name="sqlite3cs" provider="sqlite"
141147
connectionString="Data Source=DO-Tests.db3" />
142148
</domains>

Orm/Xtensive.Orm.Tests.Framework/StorageProviderVersion.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,8 @@ public static class StorageProviderVersion
3636

3737
public static Version MySql55 = new Version(5, 5);
3838
public static Version MySql56 = new Version(5, 6);
39+
40+
public static Version Firebird25 = new Version(2, 5);
41+
public static Version Firebird30 = new Version(3, 0);
3942
}
4043
}

Orm/Xtensive.Orm.Tests.Framework/TestInfo.cs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 20082025 Xtensive LLC.
1+
// Copyright (C) 2008-2025 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Alex Yakunin
@@ -13,11 +13,28 @@
1313

1414
namespace Xtensive.Orm.Tests
1515
{
16+
/// <summary>
17+
/// Defines subset of Github Actions events
18+
/// which may trigger test runs
19+
/// </summary>
20+
public enum GithubActionsEvents
21+
{
22+
PullRequest,
23+
WorkflowDispatch,
24+
WorkflowCall,
25+
Push,
26+
Schedule
27+
}
28+
1629
/// <summary>
1730
/// Provides various info related to the current test.
1831
/// </summary>
1932
public static class TestInfo
2033
{
34+
private static readonly bool isBuildServer;
35+
private static readonly bool isGithubActions;
36+
private static readonly GithubActionsEvents? githubActionsTriggeredBy;
37+
2138
/// <summary>
2239
/// <see langword="true"/>, if performance test is running (i.e. a test with
2340
/// "Performance" category).
@@ -39,24 +56,53 @@ public static class TestInfo
3956
/// <summary>
4057
/// Gets a value indicating whether test is running under build server.
4158
/// </summary>
42-
public static bool IsBuildServer => Environment.GetEnvironmentVariable("TEAMCITY_VERSION") != null;
59+
public static bool IsBuildServer => isBuildServer;
4360

4461
/// <summary>
4562
/// Gets a value indicating whether test is running within GitHub Actions environment.
4663
/// </summary>
47-
public static bool IsGitHubActions => Environment.GetEnvironmentVariable("GITHUB_WORKSPACE") != null;
64+
public static bool IsGithubActions => isGithubActions;
65+
66+
/// <summary>
67+
/// Gets the event that triggered test run within Github Actions environment.
68+
/// </summary>
69+
public static GithubActionsEvents? GithubActionTrigger => githubActionsTriggeredBy;
4870

4971
private static IEnumerable<T> GetMethodAttributes<T>() where T : Attribute
5072
{
5173
var stackFrames = new StackTrace().GetFrames();
5274
foreach (var frame in stackFrames) {
5375
var method = frame.GetMethod();
5476
if (method.GetCustomAttribute<TestAttribute>(false) == null)
77+
78+
5579
continue;
5680
foreach (var ca in method.GetCustomAttributes<T>(false))
5781
yield return ca;
82+
5883
}
5984
yield break;
6085
}
86+
87+
private static GithubActionsEvents? TryParseGithubEventName(string varValue)
88+
{
89+
return varValue switch {
90+
"pull_request" => GithubActionsEvents.PullRequest,
91+
"pull_request_comment" => GithubActionsEvents.PullRequest,
92+
"pull_request_review" => GithubActionsEvents.PullRequest,
93+
"pull_request_target" => GithubActionsEvents.PullRequest,
94+
"workflow_dispatch" => GithubActionsEvents.WorkflowDispatch,
95+
"workflow_call" => GithubActionsEvents.WorkflowCall,
96+
"schedule" => GithubActionsEvents.Schedule,
97+
_ => null
98+
};
99+
}
100+
101+
static TestInfo()
102+
{
103+
isBuildServer = Environment.GetEnvironmentVariable("TEAMCITY_VERSION") != null;
104+
isGithubActions = Environment.GetEnvironmentVariable("GITHUB_WORKSPACE") != null;
105+
githubActionsTriggeredBy = TryParseGithubEventName(Environment.GetEnvironmentVariable("GITHUB_EVENT_NAME"));
106+
}
61107
}
62108
}

0 commit comments

Comments
 (0)