xenadmin/XenAdminTests/TabsAndMenus/TabsAndMenus.cs

453 lines
19 KiB
C#
Raw Normal View History

/* Copyright (c) Cloud Software Group, Inc.
*
* 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);
}
}
}
}