C# Client Library
A C# Client Library for the AnalyzeRe REST API
Loading...
Searching...
No Matches
BaseServerAPITestSuite.cs
Go to the documentation of this file.
1using System;
2using System.Diagnostics;
3using System.Net;
4using System.Threading;
5
6using AnalyzeRe;
10#if MSTEST
11using Microsoft.VisualStudio.TestTools.UnitTesting;
12#elif NUNIT
13using NUnit.Framework;
14using TestClass = NUnit.Framework.TestFixtureAttribute;
15using AssemblyCleanup = NUnit.Framework.OneTimeTearDownAttribute;
16#endif
17
19{
22 [TestClass]
24 {
25 #region Static Properties
28 public static string API_URL { get; set; }
29
32 public static IAccessToken API_AuthenticationToken { get; set; }
33
34 private static bool? _lastTestCleanupSucceeded;
35
37 private static readonly object SuiteInitializeLock = new object();
38
40 private static volatile int _suiteInitializeCalled = 0;
41 #endregion Static Properties
42
43 #region Instance Properties
46 public bool DeletingResourcesBetweenTests { get; private set; }
47 #endregion Instance Properties
48
49 #region Static Test Suite Constructor
52 static BaseServerTestSuite()
53 {
55 // Create the authentication token (it will only be used if the server requires authentication)
58
59 // Apply the configured properties to the API
61 API.DefaultRequestTimeout = EnvironmentSettings.REQUEST_TIMEOUT;
62 API.DefaultRequestTimeoutCollections = EnvironmentSettings.COLLECTION_REQUEST_TIMEOUT;
63
64 // Optionally ignore SSL certificate errors since we often test against servers with
65 // self-signed certificates
67 {
68 ServicePointManager.ServerCertificateValidationCallback =
69 (sender, certificate, chain, errors) => true;
70 }
71 }
72
77#if NUNIT
78 [OneTimeSetUp]
79 public void TestSuiteInitialize() => TestSuiteInitialize(new FakeTestContext());
80#elif MSTEST
82 [AssemblyInitialize]
83#endif
84 public static void TestSuiteInitialize(TestContext context)
85 {
86 lock (SuiteInitializeLock)
87 {
88 if (_suiteInitializeCalled != 0)
89 {
90 Console.WriteLine("WARNING: Tried to initialize the test suite on thread " +
91 Thread.CurrentThread.ManagedThreadId + " but another test thread (" +
92 _suiteInitializeCalled + ") has already invoked TestSuiteInitialize.");
93 return;
94 }
95 _suiteInitializeCalled = Thread.CurrentThread.ManagedThreadId;
96 }
97
98 // Log the test settings.
99 context.WriteLine("Test Settings:");
100 context.WriteLine("Connecting to server at " + EnvironmentSettings.API_URL +
101 " with username " + EnvironmentSettings.HTTPS_USER);
103 context.WriteLine("Tests will be run in parallel.");
104
105 context.WriteLine("Polling Interval: " + EnvironmentSettings.POLLING_INTERVAL);
106 context.WriteLine("Request Timeout: " + EnvironmentSettings.REQUEST_TIMEOUT);
107 context.WriteLine("Collection Request Timeout: " + EnvironmentSettings.COLLECTION_REQUEST_TIMEOUT);
108 context.WriteLine("Data Upload Timeout: " + EnvironmentSettings.DATA_UPLOAD_TIMEOUT);
109 context.WriteLine("Simulation Timeout: " + EnvironmentSettings.SIMULATION_TIMEOUT);
110 context.WriteLine("Optimization Timeout: " + EnvironmentSettings.OPTIMIZATION_TIMEOUTS);
111
113 context.WriteLine("Root DELETE is set to \"not supported\". Root DELETE will not be called.");
114 else
115 {
116 context.WriteLine("DELETE Timeout: " + EnvironmentSettings.DELETE_TIMEOUT);
118 context.WriteLine("Root DELETE will be called " +
119 (EnvironmentSettings.EXECUTING_IN_PARALLEL ? "once before tests begin." :
120 "before each test is run."));
122 context.WriteLine("Root DELETE will be called " +
123 (EnvironmentSettings.EXECUTING_IN_PARALLEL ? "once after tests finish running." :
124 "after each test is run."));
125 }
127 context.WriteLine("Certificate Verification has been Disabled.");
129 context.WriteLine("Randomized Tests have been Disabled.");
131 context.WriteLine("Skipping tests has been Disabled, skipped tests will be run.");
133 context.WriteLine("Any skipped tests past their expiry will raise an error.");
134 else
135 context.WriteLine("Any skipped tests past their expiry will be run.");
136#if DEBUG
138 {
139 context.WriteLine("Debug logs for all API requests have been enabled.");
140 API.RequestLogging = true;
141 }
142 else
143 API.RequestLogging = false;
144#else
146 context.WriteLine("Debug logs for all API requests is unavailable in Release mode.");
147#endif
148
149 // Setup the server
153 {
154 ForceServerCleanupAction();
155 }
156 }
157
162 [AssemblyCleanup]
163 public static void TestSuiteCleanup()
164 {
167 {
168 ForceServerCleanupAction();
169 }
170 }
171 #endregion Static Test Suite Constructor
172
173 #region Constructor
179 protected BaseServerTestSuite(bool? CleanBeforeEveryTest = null,
180 bool? CleanAfterEveryTest = null)
181 {
182 if (CleanBeforeEveryTest ?? EnvironmentSettings.ENFORCE_CLEANUP_BEFORE_RUN &&
185 {
186 AddCommonTestInitializeAction(DeleteAllResources);
187 }
189 {
190 if (_lastTestCleanupSucceeded == false &&
191 TestContext.CurrentTestOutcome != UnitTestOutcome.Passed)
192 {
193 // Add a message to the failed test output to indicate that the test may have
194 // failed for reasons outside of its control.
195 Assert.Fail("Warning: This test did not pass, but this may have been " +
196 "due to the fact that the previous test failed to successfully clean " +
197 "up after itself, so the server was not clean when this test started.");
198 }
199 });
200 if (CleanAfterEveryTest ?? EnvironmentSettings.ENFORCE_CLEANUP_AFTER_RUN &&
203 {
204 AddCommonTestCleanupAction(DeleteAllResources);
205 }
206
207 // Determine whether we are deleting resources between tests based on the settings.
209 (CleanBeforeEveryTest ?? EnvironmentSettings.ENFORCE_CLEANUP_BEFORE_RUN &&
210 EnvironmentSettings.ROOT_DELETE_SUPPORTED &&
212 (CleanAfterEveryTest ?? EnvironmentSettings.ENFORCE_CLEANUP_AFTER_RUN &&
215
216 // It doesn't make sense to create a new samples class on each new test if
217 // we aren't cleaning up between tests.
219 Samples.Reset();
220 }
221 #endregion Constructor
222
223 #region Setup/Teardown methods
226 public static void ApplyConfiguredCredentials()
227 {
228 // Don't override local default setting on this machine.
229 API.ManagedSettingsEnabled = false;
230 API.ServerURL = API_URL;
231 API.AuthenticationToken = API_AuthenticationToken;
232 }
233
235 public static void CheckConnection()
236 {
238 DateTime start = DateTime.UtcNow;
239 // Check whether this server is responding to OPTIONS requests as expected
240 try
241 {
242 API.Options();
243 }
244 catch (Exception ex)
245 {
247 {
248 // If we have no connection and RUN_OFFLINE is enabled, shrink the timeouts
249 // to allow tests that require a connection to fail faster.
250 API.DefaultRequestTimeout = API.DefaultRequestTimeoutCollections =
251 Settings.Default.REQUEST_TIMEOUT = Settings.Default.COLLECTION_REQUEST_TIMEOUT =
252 Settings.Default.DATA_UPLOAD_TIMEOUT = Settings.Default.DELETE_TIMEOUT =
253 Settings.Default.OPTIMIZATION_TIMEOUTS = Settings.Default.POLLING_INTERVAL =
254 Settings.Default.SIMULATION_TIMEOUT = 1;
255 API.MaxRequestRetries = 0;
257 return;
258 }
259 Assert.Fail("Could not communicate with server at " + API_URL +
260 ". Test cannot run. (" + (DateTime.UtcNow - start).TotalSeconds +
261 " seconds)\nError Details: " + ex);
262 }
263 }
264
266 private void DeleteAllResources()
267 {
268 // Reset the samples class because the previously injected resources will be deleted.
269 Samples.Reset();
270 ForceServerCleanupAction();
271 }
272
274 private static void ForceServerCleanupAction()
275 {
276 Debug.WriteLine("LastTestCleanupSucceeded: " + (_lastTestCleanupSucceeded ?? (object)"(null)"));
277 // Force cleanup of the server (tries to get it to DELETE for a while).
278 _lastTestCleanupSucceeded = CleanUp.ForceCleanServer(
279 // If the cleanup fails (times out) fail this test, but if the last test
280 // failed cleanup, don't fail this one because of it. Just try to clean up the
281 // test again and move on if cleanup is still not working.
282 _lastTestCleanupSucceeded == false,
283 // Give the server some time to perform the delete, but if the last delete
284 // timeout or otherwise failed, it's probably broken for all future tests,
285 // so use a reduced timeout to avoid dragging out the tests.
286 _lastTestCleanupSucceeded == false ? 1 : EnvironmentSettings.DELETE_TIMEOUT);
287 }
288 #endregion Setup/Teardown methods
289 }
290}
Create a test class that takes care of setting the server URL and cleaning up after each unit test.
bool DeletingResourcesBetweenTests
Determines based on the EnvironmentSettings whether injected resources (such as Samples) are being de...
static string API_URL
Location of the REST API being tested against. This can be set using the API_URL environment variable...
static void CheckConnection()
Set the Client API Server URL to the configured API_URL.
static void ApplyConfiguredCredentials()
Apply the current configured API_URL and API_AuthenticationToken credentials to the static API.
static IAccessToken API_AuthenticationToken
Set the AuthenticationToken to supply to the server before every test (if applicable).
static void TestSuiteInitialize(TestContext context)
Actions to run once when the C# Unit Tests initialize. Note: This method will not automatically be in...
static void TestSuiteCleanup()
Actions to run once when the C# Unit Tests finish. Note: This method will not automatically be inheri...
BaseServerTestSuite(bool? CleanBeforeEveryTest=null, bool? CleanAfterEveryTest=null)
BaseServerAPITest Constructor. MSTest runs this constructor for each test.
void AddCommonTestCleanupAction(Action action)
void AddCommonTestInitializeAction(Action action)
Exposes sample resource objects, with built-in methods for injecting dependencies.
Definition Samples.cs:14
void Reset()
Reset all cached injected resources.
Utilities for cleaning up the server.
Definition CleanUp.cs:19
static bool ForceCleanServer(bool ignoreExceptions=false, int? timeout=null)
Invoke the DELETE method on the root of the server. Will wait for the DELETE to complete successfully...
Definition CleanUp.cs:63
Retrieve settings from environment variables if they exist, or the project settings file otherwise.
static void Reload()
Read all settings and environment variables again and re-assign all properties.
static int DATA_UPLOAD_TIMEOUT
Amount of time to wait for data upload requests to complete (in milliseconds).
static string API_URL
The URL against which server tests are run.
static bool ENABLE_REQUEST_DEBUG_LOGGING
Controls whenther AnalyzeRe.Client.API.DebugLogging is enabled.
static int COLLECTION_REQUEST_TIMEOUT
Amount of time to wait for requests on collection endpoints to complete (in milliseconds).
static bool ENFORCE_CLEANUP_BEFORE_RUN
Indicates whether the server should be wiped clean before every unit test is run.
static int OPTIMIZATION_TIMEOUTS
Amount of time to wait for optimization engine requests to complete (in milliseconds).
static bool FAIL_ON_EXPIRED_SKIP
If true, expired SkipUntils will raise an exception saying they are expired. If false,...
static bool RUN_OFFLINE
Controls whether tests that normally require a connection to the server should be allowed to try to r...
static int REQUEST_TIMEOUT
Amount of time to wait for requests to complete (in milliseconds).
static int DELETE_TIMEOUT
Amount of time to wait for DELETE to complete (in milliseconds).
static bool ROOT_DELETE_SUPPORTED
Indicates whether the server currently supports the DELETE method on the server root to wipe out all ...
static bool RANDOMIZED_TESTS_ENABLED
If false, tests that involve random generation of resources (which can be unstable) will be skipped.
static int POLLING_INTERVAL
Frequency with which to poll the server for updates during tests (in milliseconds).
static int SIMULATION_TIMEOUT
Amount of time to wait for simulations to complete (in milliseconds).
static bool VALIDATE_SERVER_CERTIFICATE
Indicates whether the SSL/TLS certificate for the HTTPS server should be validated.
static bool SKIPS_ENABLED
If true, SkipUntils can be used to skip tests. If false, SkipUntils will be ignored and all tests wil...
static bool ENFORCE_CLEANUP_AFTER_RUN
Indicates whether the server should be wiped clean after every unit test is run.
static string HTTPS_USER
The username for the HTTPS server authentication.
static string HTTPS_PASSWORD
The password for the HTTPS server authentication.
static bool EXECUTING_IN_PARALLEL
If true, tests are being run in parallel, so certain assumptions about the state of the server after ...
API methods / requests made available to the user.
static OptionsResponse Options(IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Perform an OPTIONS request on the API, which returns a list of features supported for the current aut...
An AccessToken storing basic authentication information for requests made to the server.
An AccessToken storing authentication information for requests made to the server.