xenadmin/XenAdminTests/TabsAndMenus/TabsAndMenus.cs
Konstantina Chremmou ae22560ce8 Converted all extension get properties of the API classes to methods in order to
prevent them from being serialised alongside the API properties. This will also
be useful for moving the API bindings out of XenModel.

Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
2017-09-03 03:35:30 +01:00

454 lines
19 KiB
C#

/* 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.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using NUnit.Framework;
using XenAdmin;
using XenAdmin.Controls;
using XenAdmin.Core;
using XenAPI;
namespace XenAdminTests.TabsAndMenus
{
public class TabsAndMenus : MainWindowLauncher_TestFixture
{
protected bool CheckHelp = true;
public TabsAndMenus(params string[] databases)
: base(databases)
{ }
protected void VerifyTabs(object ixmo, string[] expectedTabs)
{
string ixmoString = (ixmo == null ? "XenCenter node" : ixmo.ToString());
// Select the ixmo in the tree
Assert.IsTrue(SelectInTree(ixmo), "Couldn't find a node for " + ixmoString + " in the tree");
// Check that we have the right number of tabs
TabControl actualTabs = Program.MainWindow.TheTabControl;
Assert.AreEqual(expectedTabs.Length, actualTabs.TabPages.Count, "Didn't find the expected number of tabs for " + ixmoString);
for (int i = 0; i < expectedTabs.Length; ++i)
{
//// Select the i'th tab and check that the tab has the right name
string actualText = actualTabs.TabPages[i].Text;
Assert.AreEqual(expectedTabs[i], actualText, "Tab wrong at position " + i + " for " + ixmoString);
if (CheckHelp)
{
// Make sure we have help
bool hasHelp = MW<bool>(Program.MainWindow.HasHelp);
Assert.IsTrue(hasHelp, "No help for tab " + expectedTabs[i] + " for " + ixmoString);
}
}
}
// In the expected items, represent a separator by a null
protected void VerifyContextMenu(object ixmo, ExpectedMenuItem[] expectedItems)
{
string ixmoString = (ixmo == null ? "XenCenter node" : ixmo.ToString());
Assert.IsTrue(SelectInTree(ixmo), "Couldn't find a node for " + ixmoString + " in the tree");
MW(() =>
{
var tree = TestUtils.GetFlickerFreeTreeView(MainWindowWrapper.Item, "navigationPane.navigationView.treeView");
// Generate the TreeContextMenu
var e = new VirtualTreeNodeMouseClickEventArgs(tree.SelectedNode, MouseButtons.Right, 1, 0, 0);
var view = TestUtils.GetNavigationView(MainWindowWrapper.Item, "navigationPane.navigationView");
TestUtils.ExecuteMethod(view, "HandleNodeRightClick", new object[] { e });
});
var menu = TestUtils.GetContextMenuStrip(MainWindowWrapper.Item, "navigationPane.navigationView.TreeContextMenu");
AssertToolStripItems(ixmoString, expectedItems, menu.Items, true);
// Close the menu again
MW(menu.Close);
Thread.Sleep(100);
}
protected void VerifyToolbar(object ixmo, ExpectedMenuItem[] expectedItems)
{
string ixmoString = (ixmo == null ? "XenCenter node" : ixmo.ToString());
// Select the ixmo in the tree
Assert.IsTrue(SelectInTree(ixmo), "Couldn't find a node for " + ixmoString + " in the tree");
List<ToolStripItem> items = new List<ToolStripItem>();
// skip out forward, back and system alert buttons
for (int i = 2; i < MainWindowWrapper.MainToolStrip.Items.Count; i++)
items.Add(MainWindowWrapper.MainToolStrip.Items[i]);
AssertToolStripItems(ixmoString, expectedItems, new ToolStripItemCollection(MainWindowWrapper.MainToolStrip, items.ToArray()), false);
}
/// <summary>
/// Verifies the toolbar for the currently selected item.
/// </summary>
protected void VerifyToolbar(ExpectedMenuItem[] expectedItems)
{
List<ToolStripItem> items = new List<ToolStripItem>();
// skip out forward, back and system alert buttons
for (int i = 2; i < MainWindowWrapper.MainToolStrip.Items.Count - 1; i++)
{
items.Add(MainWindowWrapper.MainToolStrip.Items[i]);
}
AssertToolStripItems(MainWindowWrapper.TreeView.SelectedNode.Text, expectedItems, new ToolStripItemCollection(MainWindowWrapper.MainToolStrip, items.ToArray()), false);
}
protected void VerifyMainMenu(object ixmo, ExpectedMenuItem[] poolMenu, ExpectedMenuItem[] serverMenu, ExpectedMenuItem[] vmMenu, ExpectedMenuItem[] storageMenu, ExpectedMenuItem[] templatesMenu)
{
string ixmoString = (ixmo == null ? "XenCenter node" : ixmo.ToString());
// Select the ixmo in the tree
Assert.IsTrue(SelectInTree(ixmo), "Couldn't find a node for " + ixmoString + " in the tree");
Thread.Sleep(300);
MW(MainWindowWrapper.PoolMenu.Select);
MW(MainWindowWrapper.PoolMenu.ShowDropDown);
Thread.Sleep(100);
AssertToolStripItems(ixmoString, poolMenu, MainWindowWrapper.PoolMenu.DropDownItems, true);
MW(MainWindowWrapper.PoolMenu.HideDropDown);
MW(MainWindowWrapper.HostMenu.Select);
MW(MainWindowWrapper.HostMenu.ShowDropDown);
Thread.Sleep(100);
AssertToolStripItems(ixmoString, serverMenu, MainWindowWrapper.HostMenu.DropDownItems, true);
MW(MainWindowWrapper.HostMenu.HideDropDown);
MW(MainWindowWrapper.VMMenu.Select);
MW(MainWindowWrapper.VMMenu.ShowDropDown);
Thread.Sleep(100);
AssertToolStripItems(ixmoString, vmMenu, MainWindowWrapper.VMMenu.DropDownItems, true);
MW(MainWindowWrapper.VMMenu.HideDropDown);
MW(MainWindowWrapper.StorageMenu.Select);
MW(MainWindowWrapper.StorageMenu.ShowDropDown);
Thread.Sleep(100);
AssertToolStripItems(ixmoString, storageMenu, MainWindowWrapper.StorageMenu.DropDownItems, true);
MW(MainWindowWrapper.StorageMenu.HideDropDown);
MW(MainWindowWrapper.TemplatesMenu.Select);
MW(MainWindowWrapper.TemplatesMenu.ShowDropDown);
Thread.Sleep(100);
AssertToolStripItems(ixmoString, templatesMenu, MainWindowWrapper.TemplatesMenu.DropDownItems, true);
MW(MainWindowWrapper.TemplatesMenu.HideDropDown);
}
private static bool ToolStripItemsEqual(ExpectedMenuItem[] expectedItems, List<ToolStripItem> itemsList)
{
if (expectedItems.Length != itemsList.Count)
{
return false;
}
for (int i = 0; i < expectedItems.Length; i++)
{
if (expectedItems[i] is ExpectedSeparator && itemsList[i] is ToolStripSeparator)
{
continue;
}
else if (expectedItems[i] is ExpectedSeparator && !(itemsList[i] is ToolStripSeparator))
{
return false;
}
else if (!(expectedItems[i] is ExpectedSeparator) && itemsList[i] is ToolStripSeparator)
{
return false;
}
else if (((ExpectedTextMenuItem)expectedItems[i]).text != itemsList[i].Text.TrimEnd())
{
return false;
}
}
return true;
}
private void AssertToolStripItems(string ixmoString, ExpectedMenuItem[] expectedItems, ToolStripItemCollection items, bool checkMnemonics)
{
List<ToolStripItem> itemsList = GetVisibleToolStripItems(items);
// some menu items take time before they become their final value.
MWWaitFor(() => ToolStripItemsEqual(expectedItems, itemsList));
Assert.AreEqual(expectedItems.Length, itemsList.Count,
string.Format("Wrong number of items in the menu for {0}: {1} != {2}", ixmoString, GetNames(expectedItems), GetNames(itemsList)));
List<char> usedMnemonics = new List<char>();
for (int i = 0; i < expectedItems.Length; ++i)
{
ToolStripItem item = itemsList[i];
if (expectedItems[i] is ExpectedSeparator)
{
Assert.IsTrue(item is ToolStripSeparator, "At position " + i + " for " + ixmoString + ", expected separator, found " + item.Text);
}
else
{
ToolStripMenuItem menuItem = item as ToolStripMenuItem;
ExpectedTextMenuItem expected = expectedItems[i] as ExpectedTextMenuItem;
Assert.AreEqual(expected.text, item.Text.TrimEnd(), "Wrong item at position " + i + " for " + ixmoString);
Assert.AreEqual(expected.enabled, item.Enabled, "Wrong enablement for item " + item.Text + " at position " + i + " for " + ixmoString);
if (checkMnemonics && item.Text.TrimEnd() != "(empty)" && !expected.skipMnemonicCheck)
{
char c = ExtractMnemonic(item.Text.TrimEnd());
if (usedMnemonics.Contains(c))
Assert.Fail(string.Format("Item '{0}' duplicates mnemnonic '{1}'", item.Text, c));
}
if (menuItem != null && menuItem.DropDownItems.Count > 0 && menuItem.Enabled)
{
MW(menuItem.ShowDropDown);
AssertToolStripItems(ixmoString, expected.DropDownItems, menuItem.DropDownItems, checkMnemonics);
}
if (expected.chcked.HasValue)
{
ToolStripButton buttonItem = item as ToolStripButton;
if (menuItem != null)
{
Assert.AreEqual(expected.chcked.Value, menuItem.Checked, "Wrong checked state for item " + item.Text + " at position " + i + " for " + ixmoString);
}
else if (buttonItem != null)
{
Assert.AreEqual(expected.chcked.Value, buttonItem.Checked, "Wrong checked state for item " + item.Text + " at position " + i + " for " + ixmoString);
}
}
}
}
}
private char ExtractMnemonic(string p)
{
int mnemonicIndex = p.IndexOf('&');
if (mnemonicIndex == -1 || mnemonicIndex == p.Length - 1)
Assert.Fail(string.Format("Menu item '{0}' is missing a mnemonic", p));
return p[mnemonicIndex + 1];
}
protected static List<ToolStripItem> GetVisibleToolStripItems(ToolStripItemCollection items)
{
return Util.PopulateList<ToolStripItem>(items).FindAll(t => t.Available);
}
private string GetNames(ExpectedMenuItem[] items)
{
List<string> l = new List<string>();
foreach (ExpectedMenuItem i in items)
{
l.Add(i.ToString());
}
return string.Join(", ", l.ToArray());
}
private string GetNames(List<ToolStripItem> items)
{
List<string> l = new List<string>();
foreach (ToolStripItem i in items)
{
l.Add(i.Text);
}
return string.Join(", ", l.ToArray());
}
protected static bool IsMaster(Host host)
{
return host.IsMaster();
}
protected static bool IsSlave(Host host)
{
return !host.IsMaster();
}
protected static bool HasTools(VM vm)
{
var status = vm.GetVirtualisationStatus();
return !vm.is_a_template && vm.IsRunning() && status != 0 &&
!status.HasFlag(VM.VirtualisationStatus.PV_DRIVERS_OUT_OF_DATE);
}
protected static bool NoTools(VM vm)
{
return !vm.is_control_domain && !vm.is_a_template && vm.IsRunning() && !HasTools(vm);
}
protected static bool IsShutdown(VM vm)
{
return !vm.is_a_template && vm.power_state == vm_power_state.Halted;
}
protected static bool IsDefaultTemplate(VM vm)
{
return vm.is_a_template && vm.DefaultTemplate() && vm.name_label != "XenSource P2V Server";
}
protected static bool CanDetach(SR sr)
{
return sr.IsDetachable() && !HelpersGUI.GetActionInProgress(sr);
}
protected static bool CanForget(SR sr)
{
return !sr.HasRunningVMs() && sr.CanCreateWithXenCenter() && sr.allowed_operations.Contains(storage_operations.forget) && !HelpersGUI.GetActionInProgress(sr);
}
protected static bool CanDestroy(SR sr)
{
return !sr.HasRunningVMs() && sr.CanCreateWithXenCenter() && sr.allowed_operations.Contains(storage_operations.destroy) && !HelpersGUI.GetActionInProgress(sr);
}
protected static bool CanSetAsDefault(SR sr)
{
return sr.HasPBDs() && !SR.IsDefaultSr(sr) && sr.SupportsVdiCreate() && (sr.shared || sr.Connection.Cache.HostCount <= 1) && !HelpersGUI.GetActionInProgress(sr);
}
protected static bool CanConvertSR(SR sr)
{
return sr != null && Helpers.DundeeOrGreater(sr.Connection) && (sr.type == "lvmohba" || sr.type == "lvmoiscsi");
}
/// <summary>
/// Adds the "Expand All" and "Collapse Children" expected items to the specified list for the specified node.
/// </summary>
/// <param name="node">The node.</param>
/// <param name="expectedItems">The expected items to be added to.</param>
protected void AddExpectedExpandAndCollapseItems(VirtualTreeNode node, List<ExpectedMenuItem> expectedItems)
{
bool expandAll = false;
bool collapseChildren = false;
MW(delegate
{
expandAll = new List<VirtualTreeNode>(node.Descendants).Find(n => !n.IsExpanded) != null;
collapseChildren = new List<VirtualTreeNode>(node.Nodes).Find(n => n.Nodes.Count > 0 && n.IsExpanded) != null;
});
if (expandAll)
{
expectedItems.Add(new ExpectedTextMenuItem("E&xpand All", true));
}
if (collapseChildren)
{
expectedItems.Add(new ExpectedTextMenuItem("&Collapse Children", true));
}
}
protected void SetPluginCheckstate(CheckState state)
{
HandleModalDialog<OptionsDialogWrapper>("Options", MainWindowWrapper.ToolsMenuItems.OptionsToolStripMenuItem.PerformClick,
p =>
{
var grid = TestUtils.GetFieldDeep<DataGridView>(p.Item, "pluginOptionsPage1.m_gridPlugins");
foreach (DataGridViewRow row in grid.Rows)
row.Cells[0].Value = (state == CheckState.Checked);
p.OkButton.PerformClick();
});
}
protected void EnableAllPlugins()
{
SetPluginCheckstate(CheckState.Checked);
}
protected void DisableAllPlugins()
{
SetPluginCheckstate(CheckState.Unchecked);
}
public class ExpectedMenuItem { }
public class ExpectedSeparator : ExpectedMenuItem
{
public override string ToString()
{
return "<separator>";
}
}
public class ExpectedTextMenuItem : ExpectedMenuItem
{
public string text;
public bool enabled;
public bool? chcked;
public ExpectedMenuItem[] DropDownItems;
public bool skipMnemonicCheck = false;
public ExpectedTextMenuItem(string text, bool enabled)
: this(text, enabled, new ExpectedMenuItem[0])
{
}
public ExpectedTextMenuItem(string text, bool enabled, ExpectedMenuItem[] dropDownItems)
{
this.text = text;
this.enabled = enabled;
this.DropDownItems = dropDownItems;
}
public ExpectedTextMenuItem(string text, bool enabled, bool chcked, ExpectedMenuItem[] dropDownItems)
: this(text, enabled, dropDownItems)
{
this.chcked = chcked;
}
public ExpectedTextMenuItem(string text, bool enabled, bool chcked)
: this(text, enabled, chcked, new ExpectedMenuItem[0])
{
}
public ExpectedTextMenuItem(string text, bool enabled, bool chcked, bool skipMnemonicCheck)
: this(text, enabled, chcked, new ExpectedMenuItem[0])
{
this.skipMnemonicCheck = skipMnemonicCheck;
}
public override string ToString()
{
return enabled ? text : string.Format("{0} (disabled)", text);
}
}
}
}