Merge pull request #526 from cheng--zhang/CP-12769

CP-12769: Fix issue when integration test with CIS
This commit is contained in:
Mihaela Stoica 2015-07-02 11:10:01 +01:00
commit 9b7cfb018e
9 changed files with 341 additions and 249 deletions

View File

@ -313,7 +313,7 @@ namespace XenAdmin.Dialogs.CallHome
var callHomeSettings = poolRow.Pool.CallHomeSettings;
if (callHomeSettings.CanRequestNewUpload)
{
callHomeSettings.NewUploadRequest = DateTime.UtcNow.ToString();
callHomeSettings.NewUploadRequest = CallHomeSettings.DateTimeToString(DateTime.UtcNow);
new SaveCallHomeSettingsAction(poolRow.Pool, callHomeSettings, null, null, null, false).RunAsync();
}
}

View File

@ -36,6 +36,7 @@ using System.Net;
using XenAdmin;
using XenAdmin.Core;
using XenAdmin.Network;
using System.Globalization;
namespace XenAPI
{
@ -559,6 +560,21 @@ namespace XenAPI
{
return new Random().Next(1, 5);
}
public static string DateTimeToString(DateTime dateTime)
{
// Round-trip format time
DateTime rtime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
return rtime.ToString("o");
}
public static DateTime StringToDateTime(string dateTimeString)
{
// Round-trip format time
DateTime dateTime = DateTime.ParseExact(dateTimeString, "o", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
return dateTime;
}
#endregion
public string GetSecretyInfo(IXenConnection connection, string secretType)

View File

@ -51,8 +51,11 @@ namespace XenServerHealthCheck
{
lock (pipeServerLock)
{
pipeServer.Close();
pipeServer = null;
if (pipeServer != null)
{
pipeServer.Close();
pipeServer = null;
}
}
}

View File

@ -58,7 +58,7 @@ namespace XenServerHealthCheck
}
private static double DueAfterHour = 24;
private static bool CanLock(string UploadLock)
private static bool CanLock(string UploadLock, bool onDemand)
{
if (UploadLock.Length == 0)
return true;
@ -67,6 +67,9 @@ namespace XenServerHealthCheck
DateTime currentTime = DateTime.UtcNow;
DateTime lockTime = DateTime.Parse(currentLock[1]);
if (currentLock[0] == Properties.Settings.Default.UUID && onDemand)
return true;
if (currentLock[0] == Properties.Settings.Default.UUID)
{
if ((DateTime.Compare(lockTime.AddHours(DueAfterHour), currentTime) <= 0))
@ -80,9 +83,9 @@ namespace XenServerHealthCheck
private static int SleepForLockConfirm = 10 * 1000; // 10 seconds
private static bool getLock(IXenConnection connection, Session session)
{
Dictionary<string, string> config = new Dictionary<string, string>();
Dictionary<string, string> config = Pool.get_health_check_config(session, connection.Cache.Pools[0].opaque_ref);
string newUploadLock = Properties.Settings.Default.UUID;
newUploadLock += "|" + DateTime.UtcNow.ToString();
newUploadLock += "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow);
config[CallHomeSettings.UPLOAD_LOCK] = newUploadLock;
Pool.set_health_check_config(session, connection.Cache.Pools[0].opaque_ref, config);
System.Threading.Thread.Sleep(SleepForLockConfirm);
@ -101,7 +104,7 @@ namespace XenServerHealthCheck
return false;
}
//Check if there already some service doing the uploading already
if (CanLock(Get(config, CallHomeSettings.UPLOAD_LOCK)) == false)
if (CanLock(Get(config, CallHomeSettings.UPLOAD_LOCK), false) == false)
{
log.InfoFormat("Will not report for XenServer {0} that already locked", connection.Hostname);
return false;
@ -115,7 +118,8 @@ namespace XenServerHealthCheck
{
try
{
lastSuccessfulUpload = DateTime.Parse(Get(config, CallHomeSettings.LAST_SUCCESSFUL_UPLOAD));
lastSuccessfulUpload = CallHomeSettings.StringToDateTime(Get(config, CallHomeSettings.LAST_SUCCESSFUL_UPLOAD));
haveSuccessfulUpload = true;
}
catch (Exception exn)
@ -137,7 +141,7 @@ namespace XenServerHealthCheck
{
try
{
DateTime LastFailedUpload = DateTime.Parse(Get(config, CallHomeSettings.LAST_FAILED_UPLOAD));
DateTime LastFailedUpload = CallHomeSettings.StringToDateTime(Get(config, CallHomeSettings.LAST_FAILED_UPLOAD));
if (haveSuccessfulUpload)
{
@ -199,7 +203,7 @@ namespace XenServerHealthCheck
}
//Check if there already some service doing the uploading already
if (CanLock(Get(config, CallHomeSettings.UPLOAD_LOCK)) == false)
if (CanLock(Get(config, CallHomeSettings.UPLOAD_LOCK), true) == false)
{
log.InfoFormat("Will not report for XenServer {0} that already locked", connection.Hostname);
return false;
@ -207,7 +211,8 @@ namespace XenServerHealthCheck
if (config.ContainsKey(CallHomeSettings.NEW_UPLOAD_REQUEST))
{
DateTime newUploadRequestDueTime = DateTime.Parse(Get(config, CallHomeSettings.NEW_UPLOAD_REQUEST)).AddMinutes(DemandTimeOutMinutes);
DateTime newUploadRequestDueTime = CallHomeSettings.StringToDateTime(Get(config, CallHomeSettings.NEW_UPLOAD_REQUEST)).AddMinutes(DemandTimeOutMinutes);;
if (DateTime.Compare(newUploadRequestDueTime, DateTime.UtcNow) >= 0)
{
return getLock(connection, session);

View File

@ -1,210 +1,256 @@
/* Copyright (c) Citrix Systems Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using XenAdmin.Core;
using XenAdmin.Network;
using XenAPI;
namespace XenServerHealthCheck
{
public class XenServerHealthCheckBundleUpload
{
public XenServerHealthCheckBundleUpload(IXenConnection _connection)
{
connection = _connection;
}
private IXenConnection connection;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public const int TIMEOUT = 24 * 60 * 60 * 1000;
public const int VERBOSITY_LEVEL = 2;
public void runUpload()
{
DateTime startTime = DateTime.UtcNow;
string uploadToken = "";
Session session = new Session(connection.Hostname, 80);
session.APIVersion = API_Version.LATEST;
try
{
session.login_with_password(connection.Username, connection.Password);
connection.LoadCache(session);
var pool = Helpers.GetPoolOfOne(connection);
if (pool != null)
{
uploadToken = pool.CallHomeSettings.GetSecretyInfo(connection, CallHomeSettings.UPLOAD_TOKEN_SECRET);
}
if (string.IsNullOrEmpty(uploadToken))
{
if (session != null)
session.logout();
session = null;
log.ErrorFormat("The upload token is not retrieved for {0}", connection.Hostname);
updateCallHomeSettings(false, startTime);
return;
}
}
catch (Exception e)
{
if (session != null)
session.logout();
session = null;
log.Error(e, e);
updateCallHomeSettings(false, startTime);
return;
}
try
{
CancellationTokenSource cts = new CancellationTokenSource();
Func<string> upload = delegate()
{
try
{
return bundleUpload(connection, session, uploadToken, cts.Token);
}
catch (OperationCanceledException)
{
return "";
}
};
System.Threading.Tasks.Task<string> task = new System.Threading.Tasks.Task<string>(upload);
task.Start();
if (!task.Wait(TIMEOUT))
{
cts.Cancel();
updateCallHomeSettings(false, startTime);
task.Wait();
return;
}
if (task.Status == System.Threading.Tasks.TaskStatus.RanToCompletion)
{
string upload_uuid = task.Result;
if(!string.IsNullOrEmpty(upload_uuid))
updateCallHomeSettings(true, startTime, upload_uuid);
else
updateCallHomeSettings(false, startTime);
}
else
updateCallHomeSettings(false, startTime);
}
catch (Exception e)
{
if (session != null)
session.logout();
session = null;
log.Error(e, e);
updateCallHomeSettings(false, startTime);
}
}
public void updateCallHomeSettings(bool success, DateTime time, string uploadUuid = "")
{
Session session = new Session(connection.Hostname, 80);
session.login_with_password(connection.Username, connection.Password);
connection.LoadCache(session);
// Round-trip format time
DateTime rtime = DateTime.SpecifyKind(time, DateTimeKind.Utc);
string stime = rtime.ToString("o");
// record upload_uuid,
// release the lock,
// set the time of LAST_SUCCESSFUL_UPLOAD or LAST_FAILED_UPLOAD
Dictionary<string, string> config = Pool.get_health_check_config(session, connection.Cache.Pools[0].opaque_ref);
config[CallHomeSettings.UPLOAD_LOCK] = "";
if (success)
{
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = stime;
config[CallHomeSettings.UPLOAD_UUID] = uploadUuid;
}
else
config[CallHomeSettings.LAST_FAILED_UPLOAD] = stime;
Pool.set_health_check_config(session, connection.Cache.Pools[0].opaque_ref, config);
if (session != null)
session.logout();
session = null;
}
public string bundleUpload(IXenConnection connection, Session session, string uploadToken, System.Threading.CancellationToken cancel)
{
// Collect the server status report and generate zip file to upload.
XenServerHealthCheckBugTool bugTool = new XenServerHealthCheckBugTool();
try
{
bugTool.RunBugtool(connection, session);
}
catch (Exception e)
{
if (session != null)
session.logout();
session = null;
log.Error(e, e);
return "";
}
string bundleToUpload = bugTool.outputFile;
if(string.IsNullOrEmpty(bundleToUpload) || !File.Exists(bundleToUpload))
{
log.ErrorFormat("Server Status Report is NOT collected");
return "";
}
// Upload the zip file to CIS uploading server.
XenServerHealthCheckUpload upload = new XenServerHealthCheckUpload(uploadToken, VERBOSITY_LEVEL);
string upload_uuid = upload.UploadZip(bundleToUpload, cancel);
if (File.Exists(bundleToUpload))
File.Delete(bundleToUpload);
// Return the uuid of upload.
if(string.IsNullOrEmpty(upload_uuid))
{
// Fail to upload the zip to CIS server.
log.ErrorFormat("Fail to upload the Server Status Report {0} to CIS server", bundleToUpload);
return "";
}
return upload_uuid;
}
}
}
/* Copyright (c) Citrix Systems Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using XenAdmin.Core;
using XenAdmin.Network;
using XenAPI;
namespace XenServerHealthCheck
{
public class XenServerHealthCheckBundleUpload
{
public XenServerHealthCheckBundleUpload(IXenConnection _connection)
{
connection = _connection;
server.HostName = connection.Hostname;
server.UserName = connection.Username;
server.Password = connection.Password;
}
private IXenConnection connection;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public const int TIMEOUT = 24 * 60 * 60 * 1000;
public const int INTERVAL = 10 * 1000;
public const int VERBOSITY_LEVEL = 2;
private ServerInfo server = new ServerInfo();
public void runUpload(System.Threading.CancellationToken serviceStop)
{
DateTime startTime = DateTime.UtcNow;
string uploadToken = "";
Session session = new Session(connection.Hostname, 80);
session.APIVersion = API_Version.LATEST;
try
{
session.login_with_password(connection.Username, connection.Password);
connection.LoadCache(session);
var pool = Helpers.GetPoolOfOne(connection);
if (pool != null)
{
try
{
string opaqueref = Secret.get_by_uuid(session, pool.CallHomeSettings.UploadTokenSecretUuid);
uploadToken = Secret.get_value(session, opaqueref);
}
catch (Exception e)
{
log.Error("Exception getting the upload token from the xapi secret", e);
uploadToken = null;
}
}
if (string.IsNullOrEmpty(uploadToken))
{
if (session != null)
session.logout();
session = null;
log.ErrorFormat("The upload token is not retrieved for {0}", connection.Hostname);
updateCallHomeSettings(false, startTime);
server.task = null;
ServerListHelper.instance.UpdateServerInfo(server);
return;
}
}
catch (Exception e)
{
if (session != null)
session.logout();
session = null;
log.Error(e, e);
updateCallHomeSettings(false, startTime);
server.task = null;
ServerListHelper.instance.UpdateServerInfo(server);
return;
}
try
{
CancellationTokenSource cts = new CancellationTokenSource();
Func<string> upload = delegate()
{
try
{
return bundleUpload(connection, session, uploadToken, cts.Token);
}
catch (OperationCanceledException)
{
return "";
}
};
System.Threading.Tasks.Task<string> task = new System.Threading.Tasks.Task<string>(upload);
task.Start();
// Check if the task runs to completion before timeout.
for (int i = 0; i < TIMEOUT; i += INTERVAL)
{
// If the task finishes, set CallHomeSettings accordingly.
if (task.IsCompleted || task.IsCanceled || task.IsFaulted)
{
if (task.Status == System.Threading.Tasks.TaskStatus.RanToCompletion)
{
string upload_uuid = task.Result;
if (!string.IsNullOrEmpty(upload_uuid))
updateCallHomeSettings(true, startTime, upload_uuid);
else
updateCallHomeSettings(false, startTime);
}
else
updateCallHomeSettings(false, startTime);
server.task = null;
ServerListHelper.instance.UpdateServerInfo(server);
return;
}
// If the main thread (XenServerHealthCheckService) stops,
// set the cancel token to notify the working task to return.
if (serviceStop.IsCancellationRequested)
{
cts.Cancel();
updateCallHomeSettings(false, startTime);
task.Wait();
server.task = null;
ServerListHelper.instance.UpdateServerInfo(server);
return;
}
System.Threading.Thread.Sleep(INTERVAL);
}
// The task has run for 24h, cancel the task and mark it as a failure upload.
cts.Cancel();
updateCallHomeSettings(false, startTime);
task.Wait();
server.task = null;
ServerListHelper.instance.UpdateServerInfo(server);
return;
}
catch (Exception e)
{
if (session != null)
session.logout();
session = null;
log.Error(e, e);
server.task = null;
ServerListHelper.instance.UpdateServerInfo(server);
}
}
public void updateCallHomeSettings(bool success, DateTime time, string uploadUuid = "")
{
Session session = new Session(connection.Hostname, 80);
session.login_with_password(connection.Username, connection.Password);
connection.LoadCache(session);
// Round-trip format time
DateTime rtime = DateTime.SpecifyKind(time, DateTimeKind.Utc);
string stime = CallHomeSettings.DateTimeToString(rtime);
// record upload_uuid,
// release the lock,
// set the time of LAST_SUCCESSFUL_UPLOAD or LAST_FAILED_UPLOAD
Dictionary<string, string> config = Pool.get_health_check_config(session, connection.Cache.Pools[0].opaque_ref);
config[CallHomeSettings.UPLOAD_LOCK] = "";
if (success)
{
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = stime;
config[CallHomeSettings.UPLOAD_UUID] = uploadUuid;
}
else
config[CallHomeSettings.LAST_FAILED_UPLOAD] = stime;
Pool.set_health_check_config(session, connection.Cache.Pools[0].opaque_ref, config);
if (session != null)
session.logout();
session = null;
}
public string bundleUpload(IXenConnection connection, Session session, string uploadToken, System.Threading.CancellationToken cancel)
{
// Collect the server status report and generate zip file to upload.
XenServerHealthCheckBugTool bugTool = new XenServerHealthCheckBugTool();
try
{
bugTool.RunBugtool(connection, session);
}
catch (Exception e)
{
if (session != null)
session.logout();
session = null;
log.Error(e, e);
return "";
}
string bundleToUpload = bugTool.outputFile;
if(string.IsNullOrEmpty(bundleToUpload) || !File.Exists(bundleToUpload))
{
log.ErrorFormat("Server Status Report is NOT collected");
return "";
}
// Upload the zip file to CIS uploading server.
XenServerHealthCheckUpload upload = new XenServerHealthCheckUpload(uploadToken, VERBOSITY_LEVEL);
string upload_uuid = upload.UploadZip(bundleToUpload, cancel);
if (File.Exists(bundleToUpload))
File.Delete(bundleToUpload);
// Return the uuid of upload.
if(string.IsNullOrEmpty(upload_uuid))
{
// Fail to upload the zip to CIS server.
log.ErrorFormat("Fail to upload the Server Status Report {0} to CIS server", bundleToUpload);
return "";
}
return upload_uuid;
}
}
}

View File

@ -42,6 +42,7 @@ namespace XenServerHealthCheck
public partial class XenServerHealthCheckService : ServiceBase
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private CancellationTokenSource cts = new CancellationTokenSource();
public XenServerHealthCheckService()
{
@ -91,6 +92,7 @@ namespace XenServerHealthCheck
{
log.Info("XenServer Health Check Service stopping...");
CredentialReceiver.instance.UnInit();
cts.Cancel();
bool canStop;
do
{
@ -115,7 +117,7 @@ namespace XenServerHealthCheck
List<ServerInfo> servers = ServerListHelper.instance.GetServerList();
foreach (ServerInfo server in servers)
{
if(server.task != null)
if (server.task != null && (!server.task.IsCompleted || !server.task.IsCanceled || !server.task.IsFaulted))
{
continue;
}
@ -139,10 +141,13 @@ namespace XenServerHealthCheck
XenServerHealthCheckBundleUpload upload = new XenServerHealthCheckBundleUpload(connectionInfo);
Action uploadAction = delegate()
{
upload.runUpload();
upload.runUpload(cts.Token);
};
System.Threading.Tasks.Task task = new System.Threading.Tasks.Task(uploadAction);
task.Start();
server.task = task;
ServerListHelper.instance.UpdateServerInfo(server);
}
session.logout();
session = null;

View File

@ -195,8 +195,11 @@ namespace XenServerHealthCheck
}
// Fail to upload the chunk for 3 times so fail the bundle upload.
log.ErrorFormat("Fail to upload the chunk");
return "";
if (i == 2)
{
log.ErrorFormat("Fail to upload the chunk");
return "";
}
}
}
catch (Exception e)

View File

@ -90,19 +90,33 @@ namespace XenServerHealthCheckTests
Assert.IsTrue(con.Count == conSize);
//6. semd 2 credential
//7. semd 2 credential
pipeClient = new NamedPipeClientStream(".", CallHomeSettings.HEALTH_CHECK_PIPE, PipeDirection.Out);
pipeClient.Connect();
HostName = "host1";
HostName = "host3";
credential = EncryptionUtils.ProtectForLocalMachine(String.Join(SEPARATOR.ToString(), new[] { HostName, UserName, Password }));
pipeClient.Write(Encoding.UTF8.GetBytes(credential), 0, credential.Length);
HostName = "host2";
HostName = "host4";
credential = EncryptionUtils.ProtectForLocalMachine(String.Join(SEPARATOR.ToString(), new[] { HostName, UserName, Password }));
pipeClient.Write(Encoding.UTF8.GetBytes(credential), 0, credential.Length);
pipeClient.Close();
System.Threading.Thread.Sleep(1000);
con = ServerListHelper.instance.GetServerList();
Assert.IsTrue(con.Count == conSize + 2);
//8. remove 2 credential
pipeClient = new NamedPipeClientStream(".", CallHomeSettings.HEALTH_CHECK_PIPE, PipeDirection.Out);
pipeClient.Connect();
HostName = "host3";
credential = EncryptionUtils.ProtectForLocalMachine(String.Join(SEPARATOR.ToString(), new[] { HostName }));
pipeClient.Write(Encoding.UTF8.GetBytes(credential), 0, credential.Length);
HostName = "host4";
credential = EncryptionUtils.ProtectForLocalMachine(String.Join(SEPARATOR.ToString(), new[] { HostName }));
pipeClient.Write(Encoding.UTF8.GetBytes(credential), 0, credential.Length);
pipeClient.Close();
System.Threading.Thread.Sleep(1000);
con = ServerListHelper.instance.GetServerList();
Assert.IsTrue(con.Count == conSize);
}
catch (Exception)
{ }

View File

@ -90,20 +90,20 @@ namespace XenServerHealthCheckTests
//2.If the lock has already set by current service and not due, the lock should not been set again.
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + DateTime.UtcNow.ToString();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow);
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.Request(connection, _session));
//3. If the lock already due or no one set the lock, but current schedule DayOfWeek and TimeOfDay is not correct, the lock should not been set.
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.Request(connection, _session));
//4. For lock due or not set by others and schedule meet, lock should be set.
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
config[CallHomeSettings.DAY_OF_WEEK] = DateTime.UtcNow.DayOfWeek.ToString();
config[CallHomeSettings.TIME_OF_DAY] = DateTime.UtcNow.Hour.ToString();
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
@ -111,13 +111,13 @@ namespace XenServerHealthCheckTests
//5. For Lock set by other service and not due, the lock should not been set by us.
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + DateTime.UtcNow.ToString();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow);
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.Request(connection, _session));
//6. For Lock set by other service but already due, the lock can be set by current service
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
config[CallHomeSettings.DAY_OF_WEEK] = DateTime.UtcNow.DayOfWeek.ToString();
config[CallHomeSettings.TIME_OF_DAY] = DateTime.UtcNow.Hour.ToString();
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
@ -125,27 +125,27 @@ namespace XenServerHealthCheckTests
//7 Check LastFailedUpload is not empty and > LastSuccessfulUpload && INTERVAL_IN_DAYS using default, lock can be set
config = cleanStack();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.LAST_FAILED_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(8)).ToString();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
config[CallHomeSettings.LAST_FAILED_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(8)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsTrue(RequestUploadTask.Request(connection, _session));
//8 For not due uploading, lock should not been set
config = cleanStack();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(6)).ToString();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(6)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.Request(connection, _session));
//9 For failed upload, retry was needed but not meet RetryIntervalInDays, lock should not been set
config = cleanStack();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.LAST_FAILED_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(5)).ToString();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
config[CallHomeSettings.LAST_FAILED_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(5)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.Request(connection, _session));
//10 For failed upload, retry was needed and meet RetryIntervalInDays, lock should be set
config = cleanStack();
config[CallHomeSettings.LAST_FAILED_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)).ToString();
config[CallHomeSettings.LAST_FAILED_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsTrue(RequestUploadTask.Request(connection, _session));
@ -153,13 +153,13 @@ namespace XenServerHealthCheckTests
//11 Retry needed because no LAST_SUCCESSFUL_UPLOAD but not meet RetryIntervalInDays, lock should not be set
config = cleanStack();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = "";
config[CallHomeSettings.LAST_FAILED_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(8)).ToString();
config[CallHomeSettings.LAST_FAILED_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(8)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsTrue(RequestUploadTask.Request(connection, _session));
//12 For no LAST_FAILED_UPLOAD or invalid LAST_FAILED_UPLOAD, lock should not be set if not due
config = cleanStack();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = DateTime.UtcNow.Subtract(TimeSpan.FromDays(13)).ToString();
config[CallHomeSettings.LAST_SUCCESSFUL_UPLOAD] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(13)));
config[CallHomeSettings.LAST_FAILED_UPLOAD] = "asd";
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse (RequestUploadTask.Request(connection, _session));
@ -180,29 +180,29 @@ namespace XenServerHealthCheckTests
connection.LoadCache(_session);
//1 Uploading is inprocess by current service, demand will be ignore
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + DateTime.UtcNow.ToString();
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = DateTime.UtcNow.ToString();
config[CallHomeSettings.UPLOAD_LOCK] = UUID + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow);
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = CallHomeSettings.DateTimeToString(DateTime.UtcNow);
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.OnDemandRequest(connection, _session));
//2 Uploading is inprocess by other service, demand will be ignore
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + DateTime.UtcNow.ToString();
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = DateTime.UtcNow.ToString();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow);
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = CallHomeSettings.DateTimeToString(DateTime.UtcNow);
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.OnDemandRequest(connection, _session));
//3 Uploading is not due and demand due, demand will be ignore
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(31)).ToString();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(31)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsFalse(RequestUploadTask.OnDemandRequest(connection, _session));
//4 Uploading is due and demand not due, lock will be set
config = cleanStack();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)).ToString();
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(28)).ToString();
config[CallHomeSettings.UPLOAD_LOCK] = "test2-test2" + "|" + CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromDays(14)));
config[CallHomeSettings.NEW_UPLOAD_REQUEST] = CallHomeSettings.DateTimeToString(DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(28)));
Pool.set_health_check_config(_session, connection.Cache.Pools[0].opaque_ref, config);
Assert.IsTrue(RequestUploadTask.OnDemandRequest(connection, _session));
}