You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/04/15 16:55:07 UTC
[2/3] AMBARI-5474. Unit tests for steps 3-4. (onechiporenko)
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/templates/wizard/step3_host_warning_popup_footer.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step3_host_warning_popup_footer.hbs b/ambari-web/app/templates/wizard/step3_host_warning_popup_footer.hbs
deleted file mode 100644
index 163374c..0000000
--- a/ambari-web/app/templates/wizard/step3_host_warning_popup_footer.hbs
+++ /dev/null
@@ -1,33 +0,0 @@
-{{!
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-}}
-
-<div class="update-progress pull-left">
- {{#if view.isUpdateInProgress}}
- <div class="progress-info active progress">
- <div class="bar" {{bindAttr style="view.progressWidth"}}></div>
- </div>
- {{else}}
- <label {{bindAttr class="view.updateStatusClass"}}>{{view.updateStatus}}</label>
- {{/if}}
-</div>
-{{#if view.parentView.secondary}}
- <button type="button" class="btn btn-info" {{bindAttr disabled="view.isUpdateInProgress"}} {{action onSecondary target="view.parentView"}}><i class="icon-repeat"></i> {{view.parentView.secondary}}</button>
-{{/if}}
-{{#if view.parentView.primary}}
- <button type="button" class="btn" {{action onPrimary target="view.parentView"}}>{{view.parentView.primary}}</button>
-{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/templates/wizard/step3_host_warnings_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step3_host_warnings_popup.hbs b/ambari-web/app/templates/wizard/step3_host_warnings_popup.hbs
deleted file mode 100644
index d4fe22c..0000000
--- a/ambari-web/app/templates/wizard/step3_host_warnings_popup.hbs
+++ /dev/null
@@ -1,94 +0,0 @@
-{{!
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-}}
-
-
-<div id="host-warnings">
- <div class="notice">
- <span>{{t installer.step3.hostWarningsPopup.checks}} <b>{{view.warningsNotice}}</b>.<br>{{t installer.step3.hostWarningsPopup.notice}}</span>
- </div>
- <div class="row-fluid">
- <div class="span7">
- {{t common.hosts}} {{view view.hostSelectView}}
- </div>
- {{#if view.categoryWarnings.length}}
- <div class="span3 offset2">
- <a href="javascript:void(null)" title="Show Details" {{action openWarningsInDialog target="view"}}
- class="task-detail-open-dialog"><i
- class="icon-external-link"></i> {{t installer.step3.hostWarningsPopup.report}}</a>
- </div>
- {{/if}}
- </div>
- <div class="accordion warnings-list" id="accordion2">
- {{#each category in view.content}}
- <div class="accordion-group block">
- <div class="accordion-heading" {{action onToggleBlock category}}>
- <i {{bindAttr class=":pull-left :accordion-toggle category.isCollapsed:icon-caret-right:icon-caret-down"}}></i>
- {{#if category.warnings.length}}
- <i class="pull-right accordion-toggle icon-warning-sign"></i>
- {{else}}
- <i class="pull-right accordion-toggle icon-ok"></i>
- {{/if}}
- <a class="accordion-toggle">
- {{category.title}} ({{category.warnings.length}})
- </a>
- </div>
- <div id="{{unbound category.category}}" class="accordion-body collapse in" style="display: none">
- <div class="accordion-inner">
- {{#if category.warnings.length}}
- <table>
- <thead>
- <tr>
- <th colspan="2">{{{category.message}}}</th>
- </tr>
- <tr>
- <th colspan="2"><b>{{category.type}}</b></th>
- </tr>
- </thead>
- <tbody>
- {{#each warning in category.warnings}}
- <tr>
- <td class="warning-name" {{bindAttr data-original-title="warning.command"}} >{{{warning.name}}}</td>
- {{#if warning.version}}
- <td class="package-version">{{warning.version}}</td>
- {{/if}}
- {{#if warning.target}}
- <td class="package-version">{{warning.target}}</td>
- {{/if}}
- <td>{{category.action}}
- <a href="javascript:void(null);" rel='HostsListTooltip' {{bindAttr data-original-title="warning.hostsList"}} {{action showHostsPopup warning.hosts}}>
- {{warning.hosts.length}}
- {{#if warning.onSingleHost}}
- {{t installer.step3.hostWarningsPopup.host}}
- {{else}}
- {{t installer.step3.hostWarningsPopup.hosts}}
- {{/if}}
- </a>
- </td>
- </tr>
- {{/each}}
- </tbody>
- </table>
- {{else}}
- {{t installer.step3.hostWarningsPopup.emptyMessage}} {{category.emptyName}}
- {{/if}}
- </div>
- </div>
- </div>
- {{/each}}
- </div>
-</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/templates/wizard/step3_registered_hosts_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step3_registered_hosts_popup.hbs b/ambari-web/app/templates/wizard/step3_registered_hosts_popup.hbs
deleted file mode 100644
index c5907a7..0000000
--- a/ambari-web/app/templates/wizard/step3_registered_hosts_popup.hbs
+++ /dev/null
@@ -1,24 +0,0 @@
-{{!
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-}}
-
-<p>{{view.message}}</p>
-<ul>
- {{#each host in view.registeredHosts}}
- <li>{{host}}</li>
- {{/each}}
-</ul>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/templates/wizard/step4.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step4.hbs b/ambari-web/app/templates/wizard/step4.hbs
index 0bd10d3..cda6d39 100644
--- a/ambari-web/app/templates/wizard/step4.hbs
+++ b/ambari-web/app/templates/wizard/step4.hbs
@@ -28,9 +28,8 @@
<th class="span3">{{t common.service}}
<span style="margin-left:10px">
<a href="#" {{action selectAll target="controller"}} {{bindAttr class="isAll:selected:deselected"}}>{{t all}}</a>
- |
- <a
- href="#" {{action selectMinimum target="controller"}} {{bindAttr class="isMinimum:selected:deselected"}}>{{t none}}</a>
+ |
+ <a href="#" {{action selectMinimum target="controller"}} {{bindAttr class="isMinimum:selected:deselected"}}>{{t none}}</a>
</span>
</th>
<th>{{t common.version}}</th>
@@ -38,24 +37,22 @@
</tr>
</thead>
<tbody>
- {{#each controller}}
- {{#unless isHidden}}
- <tr {{bindAttr class="isSelected:success:"}}>
- <td><label
- class="checkbox">{{view Ember.Checkbox disabledBinding="isDisabled" checkedBinding="isSelected"}}{{displayName}}</label>
- </td>
- <td>{{version}}</td>
- <td>{{{description}}}</td>
- </tr>
- {{/unless}}
- {{/each}}
+ {{#each controller}}
+ {{#unless isHidden}}
+ <tr {{bindAttr class="isSelected:success:"}}>
+ <td><label class="checkbox">{{view Ember.Checkbox disabledBinding="isDisabled" checkedBinding="isSelected"}}{{displayName}}</label>
+ </td>
+ <td>{{version}}</td>
+ <td>{{{description}}}</td>
+ </tr>
+ {{/unless}}
+ {{/each}}
</tbody>
</table>
<div class="btn-area">
{{#unless view.parentView.controller.hideBackButton}}
- <a class="btn pull-left" {{action back}}>← {{t common.back}}
- </a>
+ <a class="btn pull-left" {{action back}}>← {{t common.back}}</a>
{{/unless}}
<a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}> {{t common.next}} →</a>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 5376166..4af6051 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -244,6 +244,9 @@ require('views/wizard/step0_view');
require('views/wizard/step1_view');
require('views/wizard/step2_view');
require('views/wizard/step3_view');
+require('views/wizard/step3/hostLogPopupBody_view');
+require('views/wizard/step3/hostWarningPopupBody_view');
+require('views/wizard/step3/hostWarningPopupFooter_view');
require('views/wizard/step4_view');
require('views/wizard/step5_view');
require('views/wizard/step6_view');
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/views/wizard/step3/hostLogPopupBody_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step3/hostLogPopupBody_view.js b/ambari-web/app/views/wizard/step3/hostLogPopupBody_view.js
new file mode 100644
index 0000000..0cca32d
--- /dev/null
+++ b/ambari-web/app/views/wizard/step3/hostLogPopupBody_view.js
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.WizardStep3HostLogPopupBody = Em.View.extend({
+
+ templateName: require('templates/wizard/step3/step3_host_log_popup'),
+
+ /**
+ * Host's boot log
+ * @type {string}
+ */
+ bootLog: function() {
+ return this.get('parentView.host.bootLog');
+ }.property('parentView.host.bootLog'),
+
+ /**
+ * Is textarea view active
+ * @type {bool}
+ */
+ isTextArea: false,
+
+ /**
+ * Textbox with host's boot log
+ * @type {Ember.TextArea}
+ */
+ textArea: Em.TextArea.extend({
+
+ didInsertElement: function () {
+ var element = $(this.get('element'));
+ element.width($(this.get('parentView').get('element')).width() - 10);
+ element.height($(this.get('parentView').get('element')).height());
+ element.select();
+ element.css('resize', 'none');
+ },
+
+ /**
+ * Edit disabled
+ * @type {bool}
+ */
+ readOnly: true,
+
+ /**
+ * <code>parentView.bootLog</code>
+ * @type {string}
+ */
+ value: function () {
+ return this.get('content');
+ }.property('content')
+
+ }),
+
+ didInsertElement: function () {
+ var self = this;
+ var button = $(this.get('element')).find('.textTrigger');
+ button.click(function () {
+ $(this).text(self.get('isTextArea') ? Em.I18n.t('installer.step3.hostLogPopup.highlight') : Em.I18n.t('installer.step3.hostLogPopup.copy'));
+ self.set('isTextArea', !self.get('isTextArea'));
+ });
+ $(this.get('element')).find('.content-area').mouseenter(
+ function () {
+ $(this).css('border', '1px solid #dcdcdc');
+ button.css('visibility', 'visible');
+ }).mouseleave(
+ function () {
+ $(this).css('border', 'none');
+ button.css('visibility', 'hidden');
+ })
+ }
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/views/wizard/step3/hostWarningPopupBody_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step3/hostWarningPopupBody_view.js b/ambari-web/app/views/wizard/step3/hostWarningPopupBody_view.js
new file mode 100644
index 0000000..036de2e
--- /dev/null
+++ b/ambari-web/app/views/wizard/step3/hostWarningPopupBody_view.js
@@ -0,0 +1,386 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var lazyloading = require('utils/lazy_loading');
+var numberUtils = require('utils/number_utils');
+
+App.WizardStep3HostWarningPopupBody = Em.View.extend({
+
+ templateName: require('templates/wizard/step3/step3_host_warnings_popup'),
+
+ classNames: ['host-check'],
+
+ bodyControllerBinding: 'App.router.wizardStep3Controller',
+
+ /**
+ * Listbox with host filters
+ * @type {Ember.Select}
+ */
+ hostSelectView: Em.Select.extend({
+
+ selectionBinding: "parentView.category",
+
+ /**
+ * Content has default value "All Hosts" to bind selection to category
+ * @type {string[]}
+ */
+ content: ['All Hosts'],
+
+ /**
+ * List of filtered hostnames
+ * @type {string[]}
+ */
+ hosts: function () {
+ return this.get('parentView.warningsByHost').mapProperty('name');
+ }.property('parentView.warningsByHost'),
+
+ /**
+ * Is data loaded
+ * @type {bool}
+ */
+ isLoaded: false,
+
+ didInsertElement: function () {
+ this.initContent();
+ },
+
+ /**
+ * Check browser and set content for listbox
+ * @method initContent
+ */
+ initContent: function () {
+ this.set('isLoaded', false);
+ //The lazy loading for select elements supported only by Firefox and Chrome
+ var isBrowserSupported = $.browser.mozilla || ($.browser.safari && navigator.userAgent.indexOf('Chrome') !== -1);
+ var isLazyLoading = isBrowserSupported && this.get('hosts').length > 100;
+ this.set('isLazyLoading', isLazyLoading);
+ if (isLazyLoading) {
+ //select need at least 30 hosts to have scrollbar
+ this.set('content', this.get('hosts').slice(0, 30));
+ } else {
+ this.set('content', this.get('hosts'));
+ this.set('isLoaded', true);
+ }
+ }.observes('parentView.warningsByHost'),
+
+ /**
+ * On click start lazy loading
+ * @method click
+ */
+ click: function () {
+ if (!this.get('isLoaded') && this.get('isLazyLoading')) {
+ //filter out hosts, which already pushed in select
+ var source = this.get('hosts').filter(function (_host) {
+ return !this.get('content').contains(_host);
+ }, this).slice();
+ lazyloading.run({
+ destination: this.get('content'),
+ source: source,
+ context: this,
+ initSize: 30,
+ chunkSize: 200,
+ delay: 50
+ });
+ }
+ }
+ }),
+
+ /**
+ * List of warnings grouped by host
+ * Same to <code>bodyController.warningsByHost</code>
+ * @type {Ember.Enumerable}
+ */
+ warningsByHost: function () {
+ return this.get('bodyController.warningsByHost');
+ }.property('bodyController.warningsByHost'),
+
+ /**
+ * List of all warnings
+ * Same to <code>bodyController.warnings</code>
+ * @type {Ember.Enumerable}
+ */
+ warnings: function () {
+ return this.get('bodyController.warnings');
+ }.property('bodyController.warnings'),
+
+ /**
+ * Selected category
+ * @type {string}
+ */
+ category: 'All Hosts',
+
+ /**
+ * List of warnings for selected <code>category</code>
+ * @type {Ember.Enumerable}
+ */
+ categoryWarnings: function () {
+ return this.get('warningsByHost').findProperty('name', this.get('category')).warnings
+ }.property('warningsByHost', 'category'),
+
+ /**
+ * List of warnings grouped by <code>category</code>
+ * @type {Ember.Object[]}
+ */
+ content: function () {
+ var repoCategoryWarnings = this.get('bodyController.repoCategoryWarnings');
+ var diskCategoryWarnings = this.get('bodyController.diskCategoryWarnings');
+ var categoryWarnings = this.get('categoryWarnings');
+ return [
+ Em.Object.create({
+ warnings: diskCategoryWarnings,
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.disk'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.disk.message'),
+ type: Em.I18n.t('common.issues'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.disk'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.exists'),
+ category: 'disk',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: repoCategoryWarnings,
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.repositories'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.repositories.message'),
+ type: Em.I18n.t('common.issues'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.repositories'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.invalid'),
+ category: 'repositories',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'firewall'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.firewall'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.firewall.message'),
+ type: Em.I18n.t('common.issues'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.firewall'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.running'),
+ category: 'firewall',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'processes'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.process'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.processes.message'),
+ type: Em.I18n.t('common.process'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.processes'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.running'),
+ category: 'process',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'packages'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.package'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.packages.message'),
+ type: Em.I18n.t('common.package'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.packages'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.installed'),
+ category: 'package',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'fileFolders'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.fileAndFolder'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.fileFolders.message'),
+ type: Em.I18n.t('common.path'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.filesAndFolders'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.exists'),
+ category: 'fileFolders',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'services'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.service'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.services.message'),
+ type: Em.I18n.t('common.service'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.services'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.notRunning'),
+ category: 'service',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'users'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.user'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.users.message'),
+ type: Em.I18n.t('common.user'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.users'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.exists'),
+ category: 'user',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'misc'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.misc'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.misc.message'),
+ type: Em.I18n.t('installer.step3.hostWarningsPopup.misc.umask'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.empty.misc'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.exists'),
+ category: 'misc',
+ isCollapsed: true
+ }),
+ Em.Object.create({
+ warnings: categoryWarnings.filterProperty('category', 'alternatives'),
+ title: Em.I18n.t('installer.step3.hostWarningsPopup.alternatives'),
+ message: Em.I18n.t('installer.step3.hostWarningsPopup.alternatives.message'),
+ type: Em.I18n.t('installer.step3.hostWarningsPopup.alternatives.umask'),
+ emptyName: Em.I18n.t('installer.step3.hostWarningsPopup.alternatives.emptyinstaller.step3.hostWarningsPopup.alternatives.empty'),
+ action: Em.I18n.t('installer.step3.hostWarningsPopup.action.exists'),
+ category: 'alternatives',
+ isCollapsed: true
+ })
+ ]
+ }.property('category', 'warningsByHost'),
+
+ /**
+ * Message with info about warnings
+ * @return {string}
+ */
+ warningsNotice: function () {
+ var issuesNumber = this.get('warnings.length') + this.get('bodyController.repoCategoryWarnings.length') + this.get('bodyController.diskCategoryWarnings.length');
+ var issues = issuesNumber + ' ' + (issuesNumber.length === 1 ? Em.I18n.t('installer.step3.hostWarningsPopup.issue') : Em.I18n.t('installer.step3.hostWarningsPopup.issues'));
+ var hostsCnt = this.warningHostsNamesCount();
+ var hosts = hostsCnt + ' ' + (hostsCnt === 1 ? Em.I18n.t('installer.step3.hostWarningsPopup.host') : Em.I18n.t('installer.step3.hostWarningsPopup.hosts'));
+ return Em.I18n.t('installer.step3.hostWarningsPopup.summary').format(issues, hosts);
+ }.property('warnings', 'warningsByHost'),
+
+ /**
+ * Detailed content to show it in new window
+ * @return {string}
+ */
+ contentInDetails: function () {
+ var content = this.get('content');
+ var warningsByHost = this.get('warningsByHost').slice();
+ warningsByHost.shift();
+ var newContent = '';
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.header') + new Date;
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.hosts');
+ newContent += warningsByHost.filterProperty('warnings.length').mapProperty('name').join(' ');
+ if (content.findProperty('category', 'firewall').warnings.length) {
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.firewall');
+ newContent += content.findProperty('category', 'firewall').warnings.mapProperty('name').join('<br>');
+ }
+ if (content.findProperty('category', 'fileFolders').warnings.length) {
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.fileFolders');
+ newContent += content.findProperty('category', 'fileFolders').warnings.mapProperty('name').join(' ');
+ }
+ if (content.findProperty('category', 'process').warnings.length) {
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.process');
+ content.findProperty('category', 'process').warnings.forEach(function (process, i) {
+ process.hosts.forEach(function (host, j) {
+ if (!!i || !!j) {
+ newContent += ',';
+ }
+ newContent += '(' + host + ',' + process.user + ',' + process.pid + ')';
+ });
+ });
+ }
+ if (content.findProperty('category', 'package').warnings.length) {
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.package');
+ newContent += content.findProperty('category', 'package').warnings.mapProperty('name').join(' ');
+ }
+ if (content.findProperty('category', 'service').warnings.length) {
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.service');
+ newContent += content.findProperty('category', 'service').warnings.mapProperty('name').join(' ');
+ }
+ if (content.findProperty('category', 'user').warnings.length) {
+ newContent += Em.I18n.t('installer.step3.hostWarningsPopup.report.user');
+ newContent += content.findProperty('category', 'user').warnings.mapProperty('name').join(' ');
+ }
+ newContent += '</p>';
+ return newContent;
+ }.property('content', 'warningsByHost'),
+
+ didInsertElement: function () {
+ Em.run.next(this, function () {
+ App.tooltip(this.$("[rel='HostsListTooltip']"), {html: true, placement: "right"});
+ App.tooltip(this.$('#process .warning-name'), {html: true, placement: "top"});
+ });
+ }.observes('content'),
+
+ /**
+ * Show popup with selected hostnames
+ * @param {object} hosts
+ * @method showHostsPopup
+ */
+ showHostsPopup: function (hosts) {
+ $('.tooltip').hide();
+ App.ModalPopup.show({
+ header: Em.I18n.t('installer.step3.hostWarningsPopup.allHosts'),
+ bodyClass: Em.View.extend({
+ hosts: hosts.context,
+ template: Em.Handlebars.compile('<ul>{{#each host in view.hosts}}<li>{{host}}</li>{{/each}}</ul>')
+ }),
+ secondary: null
+ });
+ },
+
+ /**
+ * Open/Close selected category
+ * @param {object} category
+ * @method onToggleBlock
+ */
+ onToggleBlock: function (category) {
+ this.$('#' + category.context.category).toggle('blind', 500);
+ category.context.set("isCollapsed", !category.context.get("isCollapsed"));
+ },
+
+ /**
+ * Generate number of hosts which had warnings, avoid duplicated host names in different warnings.
+ * @method warningHostsNamesCount
+ * @return {number}
+ */
+ warningHostsNamesCount: function () {
+ var hostNameMap = Em.Object.create();
+ var warningsByHost = this.get('bodyController.warningsByHost').slice();
+ warningsByHost.shift();
+ warningsByHost.forEach(function (_host) {
+ if (_host.warnings.length) {
+ hostNameMap[_host.name] = true;
+ }
+ });
+ var repoCategoryWarnings = this.get('bodyController.repoCategoryWarnings');
+ var diskCategoryWarnings = this.get('bodyController.diskCategoryWarnings');
+
+ if (repoCategoryWarnings.length) {
+ repoCategoryWarnings[0].hostsNames.forEach(function (_hostName) {
+ if (!hostNameMap[_hostName]) {
+ hostNameMap[_hostName] = true;
+ }
+ });
+ }
+ if (diskCategoryWarnings.length) {
+ diskCategoryWarnings[0].hostsNames.forEach(function (_hostName) {
+ if (!hostNameMap[_hostName]) {
+ hostNameMap[_hostName] = true;
+ }
+ });
+ }
+ return Em.keys(hostNameMap).length;
+ },
+
+ /**
+ * Open new browser tab with detailed content
+ * @method openWarningsInDialog
+ */
+ openWarningsInDialog: function () {
+ var newWindow = window.open('');
+ var newDocument = newWindow.document;
+ newDocument.write(this.get('contentInDetails'));
+ newWindow.focus();
+ }
+
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/views/wizard/step3/hostWarningPopupFooter_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step3/hostWarningPopupFooter_view.js b/ambari-web/app/views/wizard/step3/hostWarningPopupFooter_view.js
new file mode 100644
index 0000000..cc15313
--- /dev/null
+++ b/ambari-web/app/views/wizard/step3/hostWarningPopupFooter_view.js
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.WizardStep3HostWarningPopupFooter = Em.View.extend({
+
+ templateName: require('templates/wizard/step3/step3_host_warning_popup_footer'),
+
+ classNames: ['modal-footer', 'host-checks-update'],
+
+ footerControllerBinding: 'App.router.wizardStep3Controller',
+
+ progressWidth: function () {
+ return 'width:' + this.get('footerController.checksUpdateProgress') + '%';
+ }.property('footerController.checksUpdateProgress'),
+
+ isUpdateInProgress: function () {
+ return (this.get('footerController.checksUpdateProgress') > 0) &&
+ (this.get('footerController.checksUpdateProgress') < 100);
+ }.property('footerController.checksUpdateProgress'),
+
+ updateStatusClass: function () {
+ var status = this.get('footerController.checksUpdateStatus');
+ if (status === 'SUCCESS') {
+ return 'text-success';
+ }
+ else {
+ if (status === 'FAILED') {
+ return 'text-error';
+ }
+ else {
+ return null;
+ }
+ }
+ }.property('footerController.checksUpdateStatus'),
+
+ updateStatus: function () {
+ var status = this.get('footerController.checksUpdateStatus');
+ if (status === 'SUCCESS') {
+ return Em.I18n.t('installer.step3.warnings.updateChecks.success');
+ } else if (status === 'FAILED') {
+ return Em.I18n.t('installer.step3.warnings.updateChecks.failed');
+ } else {
+ return null;
+ }
+ }.property('footerController.checksUpdateStatus')
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/app/views/wizard/step3_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step3_view.js b/ambari-web/app/views/wizard/step3_view.js
index 278f8dc..f193ff7 100644
--- a/ambari-web/app/views/wizard/step3_view.js
+++ b/ambari-web/app/views/wizard/step3_view.js
@@ -23,30 +23,95 @@ App.WizardStep3View = App.TableView.extend({
templateName: require('templates/wizard/step3'),
+ /**
+ * List of hosts
+ * Same to <code>controller.hosts</code>
+ * @type {Ember.Enumerable}
+ */
content:function () {
return this.get('controller.hosts');
}.property('controller.hosts.length'),
+ /**
+ * Message with info about registration result
+ * @type {string}
+ */
message:'',
+
+ /**
+ * Text to link for hosts' warnings popup
+ * @type {string}
+ */
linkText: '',
+
+ /**
+ * Registration status
+ * @type {string}
+ */
status: '',
+ /**
+ * Active category
+ * @type {string}
+ */
selectedCategory: function() {
return this.get('categories').findProperty('isActive');
}.property('categories.@each.isActive'),
+ /**
+ * Message about other registered hosts (not included in current registration)
+ * @type {string}
+ */
registeredHostsMessage: '',
+ /**
+ * Number of visible hosts on page
+ * @type {string}
+ */
displayLength: "25",
+ /**
+ * All checkboxes on page are checked
+ * @type {bool}
+ */
+ pageChecked: false,
+
+ /**
+ * bootStatus category object
+ * @type {Ember.Object}
+ */
+ categoryObject: Em.Object.extend({
+ hostsCount: 0,
+ label: function () {
+ return "%@ (%@)".fmt(this.get('value'), this.get('hostsCount'));
+ }.property('value', 'hostsCount'),
+ isActive: false,
+ itemClass: function () {
+ return this.get('isActive') ? 'active' : '';
+ }.property('isActive')
+ }),
+
+ /**
+ * List of bootStatus categories
+ * @type {categoryObject[]}
+ */
+ categories: function () {
+ return [
+ this.categoryObject.create({value: Em.I18n.t('common.all'), hostsBootStatus: 'ALL', isActive: true}),
+ this.categoryObject.create({value: Em.I18n.t('installer.step3.hosts.status.installing'), hostsBootStatus: 'RUNNING'}),
+ this.categoryObject.create({value: Em.I18n.t('installer.step3.hosts.status.registering'), hostsBootStatus: 'REGISTERING'}),
+ this.categoryObject.create({value: Em.I18n.t('common.success'), hostsBootStatus: 'REGISTERED' }),
+ this.categoryObject.create({value: Em.I18n.t('common.fail'), hostsBootStatus: 'FAILED', last: true })
+ ];
+ }.property(),
+
didInsertElement: function () {
this.get('controller').loadStep();
},
- pageChecked: false,
-
/**
- * select checkboxes of hosts on page
+ * Select checkboxes of hosts on page
+ * @method onPageChecked
*/
onPageChecked: function () {
if (this.get('selectionInProgress')) return;
@@ -54,28 +119,37 @@ App.WizardStep3View = App.TableView.extend({
}.observes('pageChecked'),
/**
- * select checkboxes of all hosts
+ * Select checkboxes of all hosts
+ * @method selectAll
*/
selectAll: function () {
this.get('content').setEach('isChecked', true);
},
/**
- * reset checkbox of all hosts
+ * Reset checkbox of all hosts
+ * @method unSelectAll
*/
unSelectAll: function() {
this.get('content').setEach('isChecked', false);
},
+ /**
+ * Call <code>watchSelection</code> only once
+ * @method watchSelectionOnce
+ */
watchSelectionOnce: function () {
Em.run.once(this, 'watchSelection');
}.observes('content.@each.isChecked', 'pageContent'),
/**
- * watch selection and calculate such flags as:
- * - noHostsSelected
- * - selectedHostsCount
- * - pageChecked
+ * Watch selection and calculate such flags as:
+ * <ul>
+ * <li>noHostsSelected</li>
+ * <li>selectedHostsCount</li>
+ * <li>pageChecked</li>
+ * </ul>
+ * @method watchSelection
*/
watchSelection: function() {
this.set('selectionInProgress', true);
@@ -84,44 +158,35 @@ App.WizardStep3View = App.TableView.extend({
var noHostsSelected = true;
var selectedHostsCount = 0;
this.get('content').forEach(function(host){
- selectedHostsCount += ~~host.get('isChecked');
+ selectedHostsCount += host.get('isChecked') ? 1 : 0;
noHostsSelected = (noHostsSelected) ? !host.get('isChecked') : noHostsSelected;
});
this.set('noHostsSelected', noHostsSelected);
this.set('selectedHostsCount', selectedHostsCount);
},
+ /**
+ * Update <code>registeredHostsMessage</code> according to <code>controller.registeredHots.length</code>
+ * @method setRegisteredHosts
+ */
setRegisteredHosts: function(){
this.set('registeredHostsMessage',Em.I18n.t('installer.step3.warning.registeredHosts').format(this.get('controller.registeredHosts').length));
}.observes('controller.registeredHosts'),
- categoryObject: Em.Object.extend({
- hostsCount: 0,
- label: function () {
- return "%@ (%@)".fmt(this.get('value'), this.get('hostsCount'));
- }.property('value', 'hostsCount'),
- isActive: false,
- itemClass: function () {
- return this.get('isActive') ? 'active' : '';
- }.property('isActive')
- }),
-
- categories: function () {
- return [
- this.categoryObject.create({value: Em.I18n.t('common.all'), hostsBootStatus: 'ALL', isActive: true}),
- this.categoryObject.create({value: Em.I18n.t('installer.step3.hosts.status.installing'), hostsBootStatus: 'RUNNING'}),
- this.categoryObject.create({value: Em.I18n.t('installer.step3.hosts.status.registering'), hostsBootStatus: 'REGISTERING'}),
- this.categoryObject.create({value: Em.I18n.t('common.success'), hostsBootStatus: 'REGISTERED' }),
- this.categoryObject.create({value: Em.I18n.t('common.fail'), hostsBootStatus: 'FAILED', last: true })
- ];
- }.property(),
-
+ /**
+ * Call filters and counters one time
+ * @method hostBootStatusObserver
+ */
hostBootStatusObserver: function(){
- Ember.run.once(this, 'countCategoryHosts');
- Ember.run.once(this, 'filter');
- Ember.run.once(this, 'monitorStatuses');
+ Em.run.once(this, 'countCategoryHosts');
+ Em.run.once(this, 'filter');
+ Em.run.once(this, 'monitorStatuses');
}.observes('content.@each.bootStatus'),
+ /**
+ * Calculate host count grouped by <code>bootStatus</code>
+ * @method countCategoryHosts
+ */
countCategoryHosts: function () {
var counters = {
"RUNNING": 0,
@@ -130,7 +195,7 @@ App.WizardStep3View = App.TableView.extend({
"FAILED": 0
};
this.get('content').forEach(function (host) {
- if (counters[host.get('bootStatus')] !== undefined) {
+ if (!Em.isNone(counters[host.get('bootStatus')])) {
counters[host.get('bootStatus')]++;
}
}, this);
@@ -142,7 +207,8 @@ App.WizardStep3View = App.TableView.extend({
/**
- * filter hosts by category
+ * Filter hosts by category
+ * @method filter
*/
filter: function () {
var self = this;
@@ -157,13 +223,14 @@ App.WizardStep3View = App.TableView.extend({
self.set('filteredContent', result);
});
}.observes('selectedCategory'),
+
/**
* Trigger on Category click
* @param {Object} event
+ * @method selectCategory
*/
selectCategory: function (event) {
var categoryStatus = event.context.get('hostsBootStatus');
- var self = this;
this.get('categories').forEach(function (category) {
category.set('isActive', (category.get('hostsBootStatus') === categoryStatus));
});
@@ -173,6 +240,7 @@ App.WizardStep3View = App.TableView.extend({
/**
* Select "All" hosts category
* run registration of failed hosts again
+ * @method retrySelectedHosts
*/
retrySelectedHosts: function () {
var eventObject = {context: Em.Object.create({hostsBootStatus: 'ALL'})};
@@ -180,6 +248,10 @@ App.WizardStep3View = App.TableView.extend({
this.get('controller').retrySelectedHosts();
},
+ /**
+ * Update <code>status</code>, <code>linkText</code>, <code>message</code> according to hosts statuses
+ * @method monitorStatuses
+ */
monitorStatuses: function() {
var hosts = this.get('controller.bootHosts');
var failedHosts = hosts.filterProperty('bootStatus', 'FAILED').length;
@@ -188,56 +260,81 @@ App.WizardStep3View = App.TableView.extend({
this.set('status', 'alert-warn');
this.set('linkText', '');
this.set('message', Em.I18n.t('installer.step3.warnings.missingHosts'));
- } else if (!this.get('controller.isWarningsLoaded')) {
- this.set('status', 'alert-info');
- this.set('linkText', '');
- this.set('message', Em.I18n.t('installer.step3.warning.loading'));
- } else if (this.get('controller.isHostHaveWarnings') || this.get('controller.repoCategoryWarnings.length') || this.get('controller.diskCategoryWarnings.length')) {
- this.set('status', 'alert-warn');
- this.set('linkText', Em.I18n.t('installer.step3.warnings.linkText'));
- this.set('message', Em.I18n.t('installer.step3.warnings.fails').format(hosts.length - failedHosts));
- } else {
- this.set('status', 'alert-success');
- this.set('linkText', Em.I18n.t('installer.step3.noWarnings.linkText'));
- if (failedHosts == 0) {
- // all are ok
- this.set('message', Em.I18n.t('installer.step3.warnings.noWarnings').format(hosts.length));
- } else if (failedHosts == hosts.length) {
- // all failed
- this.set('status', 'alert-warn');
+ }
+ else {
+ if (!this.get('controller.isWarningsLoaded')) {
+ this.set('status', 'alert-info');
this.set('linkText', '');
- this.set('message', Em.I18n.t('installer.step3.warnings.allFailed').format(failedHosts));
- } else {
- // some failed
- this.set('message', Em.I18n.t('installer.step3.warnings.someWarnings').format((hosts.length - failedHosts), failedHosts));
+ this.set('message', Em.I18n.t('installer.step3.warning.loading'));
+ }
+ else {
+ if (this.get('controller.isHostHaveWarnings') || this.get('controller.repoCategoryWarnings.length') || this.get('controller.diskCategoryWarnings.length')) {
+ this.set('status', 'alert-warn');
+ this.set('linkText', Em.I18n.t('installer.step3.warnings.linkText'));
+ this.set('message', Em.I18n.t('installer.step3.warnings.fails').format(hosts.length - failedHosts));
+ }
+ else {
+ this.set('status', 'alert-success');
+ this.set('linkText', Em.I18n.t('installer.step3.noWarnings.linkText'));
+ if (failedHosts == 0) {
+ // all are ok
+ this.set('message', Em.I18n.t('installer.step3.warnings.noWarnings').format(hosts.length));
+ }
+ else {
+ if (failedHosts == hosts.length) {
+ // all failed
+ this.set('status', 'alert-warn');
+ this.set('linkText', '');
+ this.set('message', Em.I18n.t('installer.step3.warnings.allFailed').format(failedHosts));
+ }
+ else {
+ // some failed
+ this.set('message', Em.I18n.t('installer.step3.warnings.someWarnings').format((hosts.length - failedHosts), failedHosts));
+ }
+ }
+ }
}
}
}.observes('controller.isWarningsLoaded', 'controller.isHostHaveWarnings', 'controller.repoCategoryWarnings', 'controller.diskCategoryWarnings')
+
});
//todo: move it inside WizardStep3View
App.WizardHostView = Em.View.extend({
tagName: 'tr',
+
classNameBindings: ['hostInfo.bootStatus'],
+
+ /**
+ * Host from parent view
+ * @type {Object}
+ */
hostInfo: null,
+ /**
+ * @type {bool}
+ */
+ isRetryable: function() {
+ // return ['FAILED'].contains(this.get('hostInfo.bootStatus'));
+ return false;
+ }.property('hostInfo.bootStatus'),
+
+ /**
+ * Remove selected host
+ * @method remove
+ */
remove: function () {
this.get('controller').removeHost(this.get('hostInfo'));
},
+ /**
+ * Retry register selected host
+ * @method retry
+ */
retry: function() {
this.get('controller').retryHost(this.get('hostInfo'));
- },
-
- isRemovable: function () {
- return true;
- }.property(),
-
- isRetryable: function() {
- // return ['FAILED'].contains(this.get('hostInfo.bootStatus'));
- return false;
- }.property('hostInfo.bootStatus')
+ }
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/test/controllers/wizard/stack_upgrade/step3_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/stack_upgrade/step3_controller_test.js b/ambari-web/test/controllers/wizard/stack_upgrade/step3_controller_test.js
index e30a820..092415e 100644
--- a/ambari-web/test/controllers/wizard/stack_upgrade/step3_controller_test.js
+++ b/ambari-web/test/controllers/wizard/stack_upgrade/step3_controller_test.js
@@ -23,11 +23,13 @@ var Ember = require('ember');
require('models/host');
require('controllers/wizard/stack_upgrade/step3_controller');
-App.router = Ember.Object.create({
- stackUpgradeController: Ember.Object.create({
- save: function(val) {}
- })
-});
+if (!App.router) {
+ App.router = Em.Object.create({});
+}
+
+App.router.set('stackUpgradeController', Em.Object.create({
+ save: Em.K
+}));
describe('App.StackUpgradeStep3Controller', function() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/5ef841a0/ambari-web/test/installer/step3_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/installer/step3_test.js b/ambari-web/test/installer/step3_test.js
index 9818f40..1525080 100644
--- a/ambari-web/test/installer/step3_test.js
+++ b/ambari-web/test/installer/step3_test.js
@@ -19,12 +19,20 @@
var Ember = require('ember');
var App = require('app');
+var c;
require('utils/http_client');
require('models/host');
require('controllers/wizard/step3_controller');
describe('App.WizardStep3Controller', function () {
+ beforeEach(function() {
+ c = App.WizardStep3Controller.create({
+ wizardController: App.InstallerController.create(),
+ disablePreviousSteps: Em.K
+ });
+ });
+
describe('#getAllRegisteredHostsCallback', function () {
it('One host is already in the cluster, one host is registered', function() {
var controller = App.WizardStep3Controller.create({
@@ -114,129 +122,6 @@ describe('App.WizardStep3Controller', function () {
});
- var tests = [
- {
- bootHosts: [
- Em.Object.create({name:'wst3_host1', bootStatus: 'REGISTERED', isChecked: false}),
- Em.Object.create({name:'wst3_host2', bootStatus: 'REGISTERING', isChecked: false})
- ],
- m: 'One registered, one registering',
- visibleHosts: {
- RUNNING: {
- e: 0
- },
- REGISTERING: {
- e: 1
- },
- REGISTERED: {
- e: 1
- },
- FAILED: {
- e: 0
- }
- },
- onAllChecked: {
- e: [true, true]
- }
- },
- {
- bootHosts: [
- Em.Object.create({name:'wst3_host1', bootStatus: 'REGISTERED', isChecked: false}),
- Em.Object.create({name:'wst3_host2', bootStatus: 'REGISTERED', isChecked: false})
- ],
- m: 'Two registered',
- visibleHosts: {
- RUNNING: {
- e: 0
- },
- REGISTERING: {
- e: 0
- },
- REGISTERED: {
- e: 2
- },
- FAILED: {
- e: 0
- }
- },
- onAllChecked: {
- e: [true, true]
- }
- },
- {
- bootHosts: [
- Em.Object.create({name:'wst3_host1', bootStatus: 'FAILED', isChecked: false}),
- Em.Object.create({name:'wst3_host2', bootStatus: 'REGISTERED', isChecked: false})
- ],
- m: 'One registered, one failed',
- visibleHosts: {
- RUNNING: {
- e: 0
- },
- REGISTERING: {
- e: 0
- },
- REGISTERED: {
- e: 1
- },
- FAILED: {
- e: 1
- }
- },
- onAllChecked: {
- e: [true, true]
- }
- },
- {
- bootHosts: [
- Em.Object.create({name:'wst3_host1', bootStatus: 'FAILED', isChecked: false}),
- Em.Object.create({name:'wst3_host2', bootStatus: 'FAILED', isChecked: false})
- ],
- m: 'Two failed',
- visibleHosts: {
- RUNNING: {
- e: 0
- },
- REGISTERING: {
- e: 0
- },
- REGISTERED: {
- e: 0
- },
- FAILED: {
- e: 2
- }
- },
- onAllChecked: {
- e: [true, true]
- }
- },
- {
- bootHosts: [
- Em.Object.create({name:'wst3_host1', bootStatus: 'REGISTERING', isChecked: false}),
- Em.Object.create({name:'wst3_host2', bootStatus: 'REGISTERING', isChecked: false})
- ],
- m: 'Two registering',
- visibleHosts: {
- RUNNING: {
- e: 0
- },
- REGISTERING: {
- e: 2
- },
- REGISTERED: {
- e: 0
- },
- FAILED: {
- e: 0
- }
- },
- onAllChecked: {
- e: [true, true]
- }
- }
- ];
-
describe('#registrationTimeoutSecs', function() {
it('Manual install', function() {
var controller = App.WizardStep3Controller.create({
@@ -281,4 +166,1147 @@ describe('App.WizardStep3Controller', function () {
});
});
});
+
+ describe('#isWarningsBoxVisible', function() {
+ it('for testMode should be always true', function() {
+ App.testMode = true;
+ expect(c.get('isWarningsBoxVisible')).to.equal(true);
+ App.testMode = false;
+ });
+ it('for "real" mode should be based on isRegistrationInProgress', function() {
+ c.set('disablePreviousSteps', Em.K);
+ App.testMode = false;
+ c.set('isRegistrationInProgress', false);
+ expect(c.get('isWarningsBoxVisible')).to.equal(true);
+ c.set('isRegistrationInProgress', true);
+ expect(c.get('isWarningsBoxVisible')).to.equal(false);
+ App.testMode = true;
+ });
+ });
+
+ describe('#clearStep', function() {
+ it('should clear hosts', function() {
+ c.set('hosts', [{}, {}]);
+ c.clearStep();
+ expect(c.get('hosts')).to.eql([]);
+ });
+ it('should clear bootHosts', function() {
+ c.set('bootHosts', [{}, {}]);
+ c.clearStep();
+ expect(c.get('bootHosts').length).to.equal(0);
+ });
+ it('should set stopBootstrap to false', function() {
+ c.set('stopBootstrap', true);
+ c.clearStep();
+ expect(c.get('stopBootstrap')).to.equal(false);
+ });
+ it('should set wizardController DBProperty bootStatus to false', function() {
+ c.get('wizardController').setDBProperty('bootStatus', true);
+ c.clearStep();
+ expect(c.get('wizardController').getDBProperty('bootStatus')).to.equal(false);
+ });
+ it('should set isSubmitDisabled to true', function() {
+ c.set('isSubmitDisabled', false);
+ c.clearStep();
+ expect(c.get('isSubmitDisabled')).to.equal(true);
+ });
+ it('should set isSubmitDisabled to true', function() {
+ c.set('isRetryDisabled', false);
+ c.clearStep();
+ expect(c.get('isRetryDisabled')).to.equal(true);
+ });
+ });
+
+ describe('#loadStep', function() {
+ it('should set registrationStartedAt to null', function() {
+ c.set('disablePreviousSteps', Em.K);
+ c.set('registrationStartedAt', {});
+ c.loadStep();
+ expect(c.get('registrationStartedAt')).to.be.null;
+ });
+ it('should set isLoaded to false', function() {
+ c.set('disablePreviousSteps', Em.K);
+ c.set('clearStep', Em.K);
+ c.set('loadHosts', Em.K);
+ c.set('isLoaded', true);
+ c.loadStep();
+ expect(c.get('isLoaded')).to.equal(false);
+ });
+ it('should call clearStep', function() {
+ c.set('disablePreviousSteps', Em.K);
+ c.set('loadHosts', Em.K);
+ sinon.spy(c, 'clearStep');
+ c.loadStep();
+ expect(c.get('clearStep').calledOnce).to.equal(true);
+ c.clearStep.restore();
+ });
+ it('should call loadHosts', function() {
+ c.set('disablePreviousSteps', Em.K);
+ c.set('loadHosts', Em.K);
+ sinon.spy(c, 'loadHosts');
+ c.loadStep();
+ expect(c.get('loadHosts').calledOnce).to.equal(true);
+ c.loadHosts.restore();
+ });
+ it('should call disablePreviousSteps', function() {
+ c.set('disablePreviousSteps', Em.K);
+ c.set('loadHosts', Em.K);
+ sinon.spy(c, 'disablePreviousSteps');
+ c.loadStep();
+ expect(c.get('disablePreviousSteps').calledOnce).to.equal(true);
+ c.disablePreviousSteps.restore();
+ });
+ });
+
+ describe('#loadHosts', function() {
+ it('should set isLoaded to true', function() {
+ c.set('navigateStep', Em.K);
+ c.set('content', {hosts: {}});
+ c.loadHosts();
+ expect(c.get('isLoaded')).to.equal(true);
+ });
+ it('should set bootStatus REGISTERED on testMode', function() {
+ App.testMode = true;
+ c.set('navigateStep', Em.K);
+ c.set('content', {hosts: {c: {name: 'name'}}});
+ c.loadHosts();
+ expect(c.get('hosts').everyProperty('bootStatus', 'REGISTERED')).to.equal(true);
+ });
+ it('should set bootStatus DONE on "real" mode and when installOptions.manualInstall is selected', function() {
+ App.testMode = false;
+ c.set('navigateStep', Em.K);
+ c.set('content', {installOptions:{manualInstall: true}, hosts: {c: {name: 'name'}}});
+ c.loadHosts();
+ expect(c.get('hosts').everyProperty('bootStatus', 'DONE')).to.equal(true);
+ App.testMode = true;
+ });
+ it('should set bootStatus PENDING on "real" mode and when installOptions.manualInstall is not selected', function() {
+ App.testMode = false;
+ c.set('navigateStep', Em.K);
+ c.set('content', {installOptions:{manualInstall: false}, hosts: {c: {name: 'name'}}});
+ c.loadHosts();
+ expect(c.get('hosts').everyProperty('bootStatus', 'PENDING')).to.equal(true);
+ App.testMode = true;
+ });
+ it('should set bootStatus PENDING on "real" mode and when installOptions.manualInstall is not selected', function() {
+ c.set('navigateStep', Em.K);
+ c.set('content', {hosts: {c: {name: 'name'}, d: {name: 'name1'}}});
+ c.loadHosts();
+ expect(c.get('hosts').everyProperty('isChecked', false)).to.equal(true);
+ });
+ });
+
+ describe('#parseHostInfo', function() {
+
+ var tests = Em.A([
+ {
+ bootHosts: Em.A([
+ Em.Object.create({name: 'c1', bootStatus: 'REGISTERED', bootLog: ''}),
+ Em.Object.create({name: 'c2', bootStatus: 'REGISTERING', bootLog: ''}),
+ Em.Object.create({name: 'c3', bootStatus: 'RUNNING', bootLog: ''})
+ ]),
+ hostsStatusFromServer: Em.A([
+ {hostName: 'c1', status: 'REGISTERED', log: 'c1'},
+ {hostName: 'c2', status: 'REGISTERED', log: 'c2'},
+ {hostName: 'c3', status: 'RUNNING', log: 'c3'}
+ ]),
+ m: 'bootHosts not empty, hostsStatusFromServer not empty, one is RUNNING',
+ e: {
+ c: true,
+ r: true
+ }
+ },
+ {
+ bootHosts: Em.A([]),
+ hostsStatusFromServer: Em.A([
+ {hostName: 'c1', status: 'REGISTERED', log: 'c1'},
+ {hostName: 'c2', status: 'REGISTERED', log: 'c2'},
+ {hostName: 'c3', status: 'RUNNING', log: 'c3'}
+ ]),
+ m: 'bootHosts is empty',
+ e: {
+ c: false,
+ r: false
+ }
+ },
+ {
+ bootHosts: Em.A([
+ Em.Object.create({name: 'c1', bootStatus: 'REGISTERED', bootLog: ''}),
+ Em.Object.create({name: 'c2', bootStatus: 'REGISTERING', bootLog: ''}),
+ Em.Object.create({name: 'c3', bootStatus: 'REGISTERED', bootLog: ''})
+ ]),
+ hostsStatusFromServer: Em.A([
+ {hostName: 'c1', status: 'REGISTERED', log: 'c1'},
+ {hostName: 'c2', status: 'REGISTERED', log: 'c2'},
+ {hostName: 'c3', status: 'REGISTERED', log: 'c3'}
+ ]),
+ m: 'bootHosts not empty, hostsStatusFromServer not empty, no one is RUNNING',
+ e: {
+ c: true,
+ r: false
+ }
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ c.set('bootHosts', test.bootHosts);
+ var r = c.parseHostInfo(test.hostsStatusFromServer);
+ expect(r).to.equal(test.e.r);
+ if (test.e.c) {
+ test.hostsStatusFromServer.forEach(function(h) {
+ var r = c.get('bootHosts').findProperty('name', h.hostName);
+ if (!['REGISTERED', 'REGISTERING'].contains(r.get('bootStatus'))) {
+ expect(r.get('bootStatus')).to.equal(h.status);
+ expect(r.get('bootLog')).to.equal(h.log);
+ }
+ });
+ }
+ });
+ });
+ });
+
+ describe('#removeHosts', function() {
+ it('should call App.showConfirmationPopup', function() {
+ sinon.spy(App, 'showConfirmationPopup');
+ c.removeHosts(Em.A([]));
+ expect(App.showConfirmationPopup.calledOnce).to.equal(true);
+ App.showConfirmationPopup.restore();
+ });
+ it('primary should disable Submit if no more hosts', function() {
+ var hosts = [{}];
+ c.set('hosts', hosts);
+ var popup = c.removeHosts(hosts);
+ popup.onPrimary();
+ expect(c.get('isSubmitDisabled')).to.equal(true);
+ });
+ });
+
+ describe('#removeHost', function() {
+ it('should call removeHosts with array as arg', function() {
+ var host = {a:''};
+ sinon.spy(c, 'removeHosts');
+ c.removeHost(host);
+ expect(c.removeHosts.calledWith([host]));
+ c.removeHosts.restore();
+ });
+ });
+
+ describe('#removeSelectedHosts', function() {
+ it('should remove selected hosts', function() {
+ c = App.WizardStep3Controller.create({
+ wizardController: App.InstallerController.create(),
+ hosts: [
+ {isChecked: true, name: 'c1'},
+ {isChecked: false, name: 'c2'}
+ ]
+ });
+ c.removeSelectedHosts().onPrimary();
+ expect(c.get('hosts').mapProperty('name')).to.eql(['c2']);
+ });
+ });
+
+ describe('#selectedHostsPopup', function() {
+ it('should show App.ModalPopup', function() {
+ sinon.spy(App.ModalPopup, 'show');
+ c.selectedHostsPopup();
+ expect(App.ModalPopup.show.calledOnce).to.equal(true);
+ App.ModalPopup.show.restore();
+ });
+ });
+
+ describe('#retryHosts', function() {
+ it('should set numPolls to 0', function() {
+ var s = sinon.stub(App.router, 'get', function() {
+ return {launchBootstrap: Em.K}
+ });
+ c.set('content', {installOptions: {}});
+ c.set('doBootstrap', Em.K);
+ c.set('numPolls', 123);
+ c.retryHosts(Em.A([]));
+ expect(c.get('numPolls')).to.equal(0);
+ s.restore();
+ });
+ it('should set registrationStartedAt to null', function() {
+ var s = sinon.stub(App.router, 'get', function() {
+ return {launchBootstrap: Em.K}
+ });
+ c.set('content', {installOptions: {}});
+ c.set('doBootstrap', Em.K);
+ c.retryHosts(Em.A([]));
+ expect(c.get('registrationStartedAt')).to.be.null;
+ s.restore();
+ });
+ it('should startRegistration if installOptions.manualInstall is true', function() {
+ var s = sinon.stub(App.router, 'get', function() {
+ return {launchBootstrap: Em.K}
+ });
+ sinon.spy(c, 'startRegistration');
+ c.set('content', {installOptions: {manualInstall: true}});
+ c.set('doBootstrap', Em.K);
+ c.retryHosts(Em.A([]));
+ expect(c.startRegistration.calledOnce).to.equal(true);
+ s.restore();
+ c.startRegistration.restore();
+ });
+ it('should doBootstrap if installOptions.manualInstall is false', function() {
+ var s = sinon.stub(App.router, 'get', function() {
+ return {launchBootstrap: Em.K}
+ });
+ c.set('content', {installOptions: {manualInstall: false}});
+ c.set('doBootstrap', Em.K);
+ sinon.spy(c, 'doBootstrap');
+ c.retryHosts(Em.A([]));
+ expect(c.doBootstrap.calledOnce).to.equal(true);
+ s.restore();
+ c.doBootstrap.restore();
+ });
+ });
+
+ describe('#retryHost', function() {
+ it('should callretryHosts with array as arg', function() {
+ var host = {n: 'c'}, s = sinon.stub(App.router, 'get', function() {
+ return {launchBootstrap: Em.K}
+ });
+ sinon.spy(c, 'retryHosts');
+ c.set('content', {installOptions: {}});
+ c.set('doBootstrap', Em.K);
+ c.retryHost(host);
+ expect(c.retryHosts.calledWith([host])).to.equal(true);
+ c.retryHosts.restore();
+ s.restore();
+ });
+ });
+
+ describe('#retrySelectedHosts', function() {
+ it('shouldn\'t do nothing if isRetryDisabled is true', function() {
+ c.set('isRetryDisabled', true);
+ sinon.spy(c, 'retryHosts');
+ c.retrySelectedHosts();
+ expect(c.retryHosts.called).to.equal(false);
+ c.retryHosts.restore();
+ });
+ it('should retry hosts with FAILED bootStatus and set isRetryDisabled to true', function() {
+ var s = sinon.stub(App.router, 'get', function() {
+ return {launchBootstrap: Em.K}
+ });
+ c = App.WizardStep3Controller.create({
+ wizardController: App.InstallerController.create(),
+ bootHosts: Em.A([{name: 'c1', bootStatus: 'FAILED'}, {name: 'c2', bootStatus: 'REGISTERED'}]),
+ content: {installOptions: {}},
+ doBootstrap: Em.K
+ });
+ sinon.spy(c, 'retryHosts');
+ c.retrySelectedHosts();
+ expect(c.retryHosts.calledWith([{name: 'c1', bootStatus: 'RUNNING'}]));
+ expect(c.get('isRetryDisabled')).to.equal(true);
+ c.retryHosts.restore();
+ s.restore();
+ });
+ });
+
+ describe('#startBootstrap', function() {
+ it('should drop numPolls and registrationStartedAt', function() {
+ c.set('numPolls', 123);
+ c.set('registrationStartedAt', 1234);
+ c.set('doBootstrap', Em.K);
+ c.startBootstrap();
+ expect(c.get('numPolls')).to.equal(0);
+ expect(c.get('registrationStartedAt')).to.be.null;
+ });
+ it('should drop numPolls and registrationStartedAt', function() {
+ var hosts = Em.A([{name: 'c1'}, {name: 'c2'}]);
+ c = App.WizardStep3Controller.create({
+ wizardController: App.InstallerController.create(),
+ doBootstrap: Em.K,
+ setRegistrationInProgressOnce: Em.K,
+ hosts: hosts
+ });
+ c.startBootstrap();
+ expect(c.get('bootHosts').mapProperty('name')).to.eql(['c1','c2']);
+ });
+ });
+
+ describe('#setRegistrationInProgressOnce', function() {
+ it('should call Ember.run.once with "setRegistrationInProgress"', function() {
+ sinon.spy(Em.run, 'once');
+ c.setRegistrationInProgressOnce();
+ expect(Em.run.once.firstCall.args[1]).to.equal('setRegistrationInProgress');
+ Em.run.once.restore();
+ });
+ });
+
+ describe('#setRegistrationInProgress', function() {
+ var tests = Em.A([
+ {
+ bootHosts: [],
+ isLoaded: false,
+ e: true,
+ m: 'no bootHosts and isLoaded is false'
+ },
+ {
+ bootHosts: [],
+ isLoaded: true,
+ e: false,
+ m: 'no bootHosts and isLoaded is true'
+ },
+ {
+ bootHosts: [
+ Em.Object.create({bootStatus: 'RUNNING'}),
+ Em.Object.create({bootStatus: 'RUNNING'})
+ ],
+ isLoaded: true,
+ e: false,
+ m: 'bootHosts without REGISTERED/FAILED and isLoaded is true'
+ },
+ {
+ bootHosts: [
+ Em.Object.create({bootStatus: 'RUNNING'}),
+ Em.Object.create({bootStatus: 'RUNNING'})
+ ],
+ isLoaded: false,
+ e: true,
+ m: 'bootHosts without REGISTERED/FAILED and isLoaded is false'
+ },
+ {
+ bootHosts: [
+ Em.Object.create({bootStatus: 'REGISTERED'}),
+ Em.Object.create({bootStatus: 'RUNNING'})
+ ],
+ isLoaded: false,
+ e: true,
+ m: 'bootHosts with one REGISTERED and isLoaded is false'
+ },
+ {
+ bootHosts: [
+ Em.Object.create({bootStatus: 'FAILED'}),
+ Em.Object.create({bootStatus: 'RUNNING'})
+ ],
+ isLoaded: false,
+ e: true,
+ m: 'bootHosts with one FAILED and isLoaded is false'
+ },
+ {
+ bootHosts: [
+ Em.Object.create({bootStatus: 'REGISTERED'}),
+ Em.Object.create({bootStatus: 'RUNNING'})
+ ],
+ isLoaded: true,
+ e: false,
+ m: 'bootHosts with one REGISTERED and isLoaded is true'
+ },
+ {
+ bootHosts: [
+ Em.Object.create({bootStatus: 'FAILED'}),
+ Em.Object.create({bootStatus: 'RUNNING'})
+ ],
+ isLoaded: true,
+ e: false,
+ m: 'bootHosts with one FAILED and isLoaded is true'
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ sinon.stub(c, 'disablePreviousSteps', Em.K);
+ c.set('bootHosts', test.bootHosts);
+ c.set('isLoaded', test.isLoaded);
+ c.setRegistrationInProgress();
+ expect(c.get('isRegistrationInProgress')).to.equal(test.e);
+ c.disablePreviousSteps.restore();
+ });
+ });
+ });
+
+ describe('#doBootstrap', function() {
+ beforeEach(function() {
+ sinon.spy(App.ajax, 'send');
+ });
+ afterEach(function() {
+ App.ajax.send.restore();
+ });
+ it('shouldn\'t do nothing if stopBootstrap is true', function() {
+ c.set('stopBootstrap', true);
+ c.doBootstrap();
+ expect(App.ajax.send.called).to.equal(false);
+ });
+ it('should increment numPolls if stopBootstrap is false', function() {
+ c.set('stopBootstrap', false);
+ c.set('numPolls', 0);
+ c.doBootstrap();
+ expect(c.get('numPolls')).to.equal(1);
+ });
+ it('should do ajax call if stopBootstrap is false', function() {
+ c.set('stopBootstrap', false);
+ c.doBootstrap();
+ expect(App.ajax.send.called).to.equal(true);
+ });
+ });
+
+ describe('#startRegistration', function() {
+ it('shouldn\'t do nothing if registrationStartedAt isn\'t null', function() {
+ c.set('registrationStartedAt', 1234);
+ sinon.spy(c, 'isHostsRegistered');
+ c.startRegistration();
+ expect(c.isHostsRegistered.called).to.equal(false);
+ expect(c.get('registrationStartedAt')).to.equal(1234);
+ c.isHostsRegistered.restore();
+ });
+ it('shouldn\'t do nothing if registrationStartedAt isn\'t null', function() {
+ c.set('registrationStartedAt', null);
+ sinon.spy(c, 'isHostsRegistered');
+ c.startRegistration();
+ expect(c.isHostsRegistered.calledOnce).to.equal(true);
+ c.isHostsRegistered.restore();
+ });
+ });
+
+ describe('#isHostsRegistered', function() {
+ beforeEach(function() {
+ sinon.spy(App.ajax, 'send');
+ });
+ afterEach(function() {
+ App.ajax.send.restore();
+ });
+ it('shouldn\'t do nothing if stopBootstrap is true', function() {
+ c.set('stopBootstrap', true);
+ c.isHostsRegistered();
+ expect(App.ajax.send.called).to.equal(false);
+ });
+ it('should do ajax call if stopBootstrap is false', function() {
+ c.set('stopBootstrap', false);
+ c.isHostsRegistered();
+ expect(App.ajax.send.called).to.equal(true);
+
+ });
+ });
+
+ describe('#isHostsRegisteredSuccessCallback', function() {
+ var tests = Em.A([
+ {
+ bootHosts: Em.A([
+ Em.Object.create({bootStatus: 'DONE'})
+ ]),
+ data: {items:[]},
+ m: 'one host DONE',
+ e: {
+ bs: 'REGISTERING',
+ getHostInfoCalled: false
+ }
+ },
+ {
+ bootHosts: Em.A([
+ Em.Object.create({bootStatus: 'REGISTERING', name: 'c1'})
+ ]),
+ data: {items:[{Hosts: {host_name: 'c1'}}]},
+ m: ' one host REGISTERING',
+ e: {
+ bs: 'FAILED',
+ getHostInfoCalled: true
+ }
+ },
+ {
+ bootHosts: Em.A([
+ Em.Object.create({bootStatus: 'REGISTERING', name: 'c1'})
+ ]),
+ data: {items:[{Hosts: {host_name: 'c2'}}]},
+ m: 'one host REGISTERING but data without info about it',
+ e: {
+ bs: 'FAILED',
+ getHostInfoCalled: true
+ }
+ },
+ {
+ bootHosts: Em.A([
+ Em.Object.create({bootStatus: 'RUNNING', name: 'c1'})
+ ]),
+ data: {items:[{Hosts: {host_name: 'c1'}}]},
+ m: ' one host RUNNING',
+ e: {
+ bs: 'RUNNING',
+ getHostInfoCalled: false
+ }
+ }
+ ]);
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ sinon.spy(c, 'getHostInfo');
+ c.set('bootHosts', test.bootHosts);
+ c.isHostsRegisteredSuccessCallback(test.data);
+ expect(c.get('bootHosts')[0].get('bootStatus')).to.equal(test.e.bs);
+ expect(c.getHostInfo.called).to.equal(test.e.getHostInfoCalled);
+ c.getHostInfo.restore();
+ });
+ });
+ });
+
+ describe('#getAllRegisteredHosts', function() {
+ it('should call App.ajax.send', function() {
+ sinon.spy(App.ajax, 'send');
+ c.getAllRegisteredHosts();
+ expect(App.ajax.send.calledOnce).to.equal(true);
+ App.ajax.send.restore();
+ });
+ });
+
+ describe('#getAllRegisteredHostsCallback', function() {
+ var tests = Em.A([
+ {
+ hostsInCluster: ['c3'],
+ bootHosts: [{name:'c1'},{name:'c2'}],
+ hosts: Em.A([
+ {Hosts: {host_name:'c1'}},
+ {Hosts: {host_name:'c2'}}
+ ]),
+ m: 'No registered hosts',
+ e: {
+ hasMoreRegisteredHosts: false,
+ registeredHosts: ''
+ }
+ },
+ {
+ hostsInCluster: ['c4'],
+ bootHosts: [{name:'c3'},{name:'c5'}],
+ hosts: Em.A([
+ {Hosts: {host_name:'c1'}},
+ {Hosts: {host_name:'c2'}}
+ ]),
+ m: '2 registered hosts',
+ e: {
+ hasMoreRegisteredHosts: true,
+ registeredHosts: ['c1','c2']
+ }
+ },
+ {
+ hostsInCluster: ['c4'],
+ bootHosts: [{name:'c1'},{name:'c5'}],
+ hosts: Em.A([
+ {Hosts: {host_name:'c1'}},
+ {Hosts: {host_name:'c2'}}
+ ]),
+ m: '1 registered host',
+ e: {
+ hasMoreRegisteredHosts: true,
+ registeredHosts: ['c2']
+ }
+ },
+ {
+ hostsInCluster: ['c1'],
+ bootHosts: [{name:'c3'},{name:'c5'}],
+ hosts: Em.A([
+ {Hosts: {host_name:'c1'}},
+ {Hosts: {host_name:'c2'}}
+ ]),
+ m: '1 registered host (2)',
+ e: {
+ hasMoreRegisteredHosts: true,
+ registeredHosts: ['c2']
+ }
+ }
+ ]);
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ c.reopen({hostsInCluster: test.hostsInCluster, setRegistrationInProgress: Em.K});
+ c.set('bootHosts', test.bootHosts);
+ c.getAllRegisteredHostsCallback({items:test.hosts});
+ expect(c.get('hasMoreRegisteredHosts')).to.equal(test.e.hasMoreRegisteredHosts);
+ expect(c.get('registeredHosts')).to.eql(test.e.registeredHosts);
+ });
+ });
+ });
+
+ describe('#registerErrPopup', function() {
+ it('should call App.ModalPopup.show', function() {
+ sinon.spy(App.ModalPopup, 'show');
+ c.registerErrPopup();
+ expect(App.ModalPopup.show.calledOnce).to.equal(true);
+ App.ModalPopup.show.restore();
+ });
+ });
+
+ describe('#getHostInfo', function() {
+ it('should do ajax request', function() {
+ sinon.spy(App.ajax, 'send');
+ c.getHostInfo();
+ expect(App.ajax.send.calledOnce).to.equal(true);
+ App.ajax.send.restore();
+ });
+ });
+
+ describe('#getHostInfoErrorCallback', function() {
+ it('should call registerErrPopup', function() {
+ sinon.spy(c, 'registerErrPopup');
+ c.getHostInfoErrorCallback();
+ expect(c.registerErrPopup.calledOnce).to.equal(true);
+ c.registerErrPopup.restore();
+ });
+ });
+
+ describe('#stopRegistration', function() {
+ var tests = Em.A([
+ {
+ bootHosts: [{bootStatus: 'REGISTERED'}, {bootStatus: 'RUNNING'}],
+ e: {isSubmitDisabled: false, isRetryDisabled: true}
+ },
+ {
+ bootHosts: [{bootStatus: 'FAILED'}, {bootStatus: 'RUNNING'}],
+ e: {isSubmitDisabled: true, isRetryDisabled: false}
+ },
+ {
+ bootHosts: [{bootStatus: 'FAILED'}, {bootStatus: 'REGISTERED'}],
+ e: {isSubmitDisabled: false, isRetryDisabled: false}
+ },
+ {
+ bootHosts: [{bootStatus: 'RUNNING'}, {bootStatus: 'RUNNING'}],
+ e: {isSubmitDisabled: true, isRetryDisabled: true}
+ }
+ ]);
+ tests.forEach(function(test) {
+ it(test.bootHosts.mapProperty('bootStatus').join(', '), function() {
+ c.reopen({bootHosts: test.bootHosts});
+ c.stopRegistration();
+ expect(c.get('isSubmitDisabled')).to.equal(test.e.isSubmitDisabled);
+ expect(c.get('isRetryDisabled')).to.equal(test.e.isRetryDisabled);
+ });
+ });
+ });
+
+ describe('#submit', function() {
+ it('if isHostHaveWarnings should show confirmation popup', function() {
+ c.reopen({isHostHaveWarnings: true});
+ sinon.spy(App.ModalPopup, 'show');
+ c.submit();
+ expect(App.ModalPopup.show.calledOnce).to.equal(true);
+ App.ModalPopup.show.restore();
+ });
+ it('if isHostHaveWarnings should show confirmation popup. on Primary should set bootHosts to content.hosts', function() {
+ var bootHosts = [{name: 'c1'}];
+ c.reopen({isHostHaveWarnings: true, bootHosts: bootHosts, hosts: []});
+ c.submit().onPrimary();
+ expect(c.get('content.hosts')).to.eql(bootHosts);
+ });
+ it('if isHostHaveWarnings is false should set bootHosts to content.hosts', function() {
+ var bootHosts = [{name: 'c1'}];
+ c.reopen({isHostHaveWarnings: false, bootHosts: bootHosts, hosts: []});
+ c.submit();
+ expect(c.get('content.hosts')).to.eql(bootHosts);
+ });
+ });
+
+ describe('#hostLogPopup', function() {
+ it('should show App.ModalPopup', function() {
+ sinon.spy(App.ModalPopup, 'show');
+ c.hostLogPopup({context:Em.Object.create({})});
+ expect(App.ModalPopup.show.calledOnce).to.equal(true);
+ App.ModalPopup.show.restore();
+ });
+ });
+
+ describe('#rerunChecksSuccessCallback', function() {
+ beforeEach(function() {
+ sinon.stub(c, 'parseWarnings', Em.K);
+ });
+ afterEach(function() {
+ c.parseWarnings.restore();
+ });
+ it('should set checksUpdateProgress to 100', function() {
+ c.set('checksUpdateProgress', 0);
+ c.rerunChecksSuccessCallback({});
+ expect(c.get('checksUpdateProgress')).to.equal(100);
+ });
+ it('should set checksUpdateStatus to SUCCESS', function() {
+ c.set('checksUpdateStatus', '');
+ c.rerunChecksSuccessCallback({});
+ expect(c.get('checksUpdateStatus')).to.equal('SUCCESS');
+ });
+ it('should set call parseWarnings', function() {
+ c.rerunChecksSuccessCallback({});
+ expect(c.parseWarnings.calledOnce).to.equal(true);
+ });
+ });
+
+ describe('#rerunChecksErrorCallback', function() {
+ it('should set checksUpdateProgress to 100', function() {
+ c.set('checksUpdateProgress', 0);
+ c.rerunChecksErrorCallback({});
+ expect(c.get('checksUpdateProgress')).to.equal(100);
+ });
+ it('should set checksUpdateStatus to FAILED', function() {
+ c.set('checksUpdateStatus', '');
+ c.rerunChecksErrorCallback({});
+ expect(c.get('checksUpdateStatus')).to.equal('FAILED');
+ });
+ });
+
+ describe('#filterBootHosts', function() {
+ var tests = Em.A([
+ {
+ bootHosts: [
+ Em.Object.create({name: 'c1'}),
+ Em.Object.create({name: 'c2'})
+ ],
+ data: {
+ items: [
+ {Hosts: {host_name: 'c1'}}
+ ]
+ },
+ m: 'one host',
+ e: ['c1']
+ },
+ {
+ bootHosts: [
+ Em.Object.create({name: 'c1'}),
+ Em.Object.create({name: 'c2'})
+ ],
+ data: {
+ items: [
+ {Hosts: {host_name: 'c3'}}
+ ]
+ },
+ m: 'no hosts',
+ e: []
+ },
+ {
+ bootHosts: [
+ Em.Object.create({name: 'c1'}),
+ Em.Object.create({name: 'c2'})
+ ],
+ data: {
+ items: [
+ {Hosts: {host_name: 'c1'}},
+ {Hosts: {host_name: 'c2'}}
+ ]
+ },
+ m: 'many hosts',
+ e: ['c1', 'c2']
+ }
+ ]);
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ c.reopen({bootHosts: test.bootHosts});
+ var filteredData = c.filterBootHosts(test.data);
+ expect(filteredData.items.mapProperty('Hosts.host_name')).to.eql(test.e);
+ });
+ });
+ });
+
+ describe('#hostWarningsPopup', function() {
+ it('should show App.ModalPopup', function() {
+ sinon.spy(App.ModalPopup, 'show');
+ c.hostWarningsPopup();
+ expect(App.ModalPopup.show.calledOnce).to.equal(true);
+ App.ModalPopup.show.restore();
+ });
+ });
+
+ describe('#registeredHostsPopup', function() {
+ it('should show App.ModalPopup', function() {
+ sinon.spy(App.ModalPopup, 'show');
+ c.registeredHostsPopup();
+ expect(App.ModalPopup.show.calledOnce).to.equal(true);
+ App.ModalPopup.show.restore();
+ });
+ });
+
+ describe('#parseWarnings', function() {
+ it('no warnings if last_agent_env isn\'t specified', function() {
+ c.set('warnings', [{}]);
+ c.set('warningsByHost', [{},{}]);
+ c.parseWarnings({items:[{Hosts:{host_name:'c1'}}]});
+ expect(c.get('warnings')).to.eql([]);
+ expect(c.get('warningsByHost.length')).to.equal(1); // default group
+ expect(c.get('isWarningsLoaded')).to.equal(true);
+ });
+
+ Em.A([
+ {
+ m: 'parse stackFoldersAndFiles',
+ tests : Em.A([
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {stackFoldersAndFiles: []}}}],
+ m: 'empty stackFoldersAndFiles',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {stackFoldersAndFiles: [{name: 'n1'}]}}}],
+ m: 'not empty stackFoldersAndFiles',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1'],
+ onSingleHost: true,
+ category: 'fileFolders'
+ }],
+ warningsByHost: [1]
+ }
+ },
+ {
+ items: [
+ {Hosts:{host_name: 'c1', last_agent_env: {stackFoldersAndFiles: [{name: 'n1'}]}}},
+ {Hosts:{host_name: 'c2', last_agent_env: {stackFoldersAndFiles: [{name: 'n1'}]}}}
+ ],
+ m: 'not empty stackFoldersAndFiles on two hosts',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1', 'c2'],
+ onSingleHost: false,
+ category: 'fileFolders'
+ }],
+ warningsByHost: [1]
+ }
+ }
+ ])
+ },
+ {
+ m: 'parse installedPackages',
+ tests : Em.A([
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {installedPackages: []}}}],
+ m: 'empty installedPackages',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {installedPackages: [{name: 'n1'}]}}}],
+ m: 'not empty installedPackages',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1'],
+ onSingleHost: true,
+ category: 'packages'
+ }],
+ warningsByHost: [1]
+ }
+ },
+ {
+ items: [
+ {Hosts:{host_name: 'c1', last_agent_env: {installedPackages: [{name: 'n1'}]}}},
+ {Hosts:{host_name: 'c2', last_agent_env: {installedPackages: [{name: 'n1'}]}}}
+ ],
+ m: 'not empty installedPackages on two hosts',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1', 'c2'],
+ onSingleHost: false,
+ category: 'packages'
+ }],
+ warningsByHost: [1]
+ }
+ }
+ ])
+ },
+ {
+ m: 'parse hostHealth.liveServices',
+ tests : Em.A([
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {hostHealth: []}}}],
+ m: 'empty hostHealth',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {hostHealth:{liveServices: []}}}}],
+ m: 'empty liveServices',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {hostHealth:{liveServices: [{status: 'Unhealthy', name: 'n1'}]}}}}],
+ m: 'not empty hostHealth.liveServices',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1'],
+ onSingleHost: true,
+ category: 'services'
+ }],
+ warningsByHost: [1]
+ }
+ },
+ {
+ items: [
+ {Hosts:{host_name: 'c1', last_agent_env: {hostHealth:{liveServices: [{status: 'Unhealthy', name: 'n1'}]}}}},
+ {Hosts:{host_name: 'c2', last_agent_env: {hostHealth:{liveServices: [{status: 'Unhealthy', name: 'n1'}]}}}}
+ ],
+ m: 'not empty hostHealth.liveServices on two hosts',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1', 'c2'],
+ onSingleHost: false,
+ category: 'services'
+ }],
+ warningsByHost: [1, 1]
+ }
+ }
+ ])
+ },
+ {
+ m: 'parse existingUsers',
+ tests : Em.A([
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {existingUsers: []}}}],
+ m: 'empty existingUsers',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {existingUsers: [{userName: 'n1'}]}}}],
+ m: 'not empty existingUsers',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1'],
+ onSingleHost: true,
+ category: 'users'
+ }],
+ warningsByHost: [1]
+ }
+ },
+ {
+ items: [
+ {Hosts:{host_name: 'c1', last_agent_env: {existingUsers: [{userName: 'n1'}]}}},
+ {Hosts:{host_name: 'c2', last_agent_env: {existingUsers: [{userName: 'n1'}]}}}
+ ],
+ m: 'not empty existingUsers on two hosts',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1', 'c2'],
+ onSingleHost: false,
+ category: 'users'
+ }],
+ warningsByHost: [1, 1]
+ }
+ }
+ ])
+ },
+ {
+ m: 'parse alternatives',
+ tests : Em.A([
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {alternatives: []}}}],
+ m: 'empty alternatives',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {alternatives: [{name: 'n1'}]}}}],
+ m: 'not empty alternatives',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1'],
+ onSingleHost: true,
+ category: 'alternatives'
+ }],
+ warningsByHost: [1]
+ }
+ },
+ {
+ items: [
+ {Hosts:{host_name: 'c1', last_agent_env: {alternatives: [{name: 'n1'}]}}},
+ {Hosts:{host_name: 'c2', last_agent_env: {alternatives: [{name: 'n1'}]}}}
+ ],
+ m: 'not empty alternatives on two hosts',
+ e: {
+ warnings: [{
+ name: 'n1',
+ hosts: ['c1', 'c2'],
+ onSingleHost: false,
+ category: 'alternatives'
+ }],
+ warningsByHost: [1, 1]
+ }
+ }
+ ])
+ },
+ {
+ m: 'parse hostHealth.activeJavaProcs',
+ tests : Em.A([
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {hostHealth: [], javaProcs: []}}}],
+ m: 'empty hostHealth',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {hostHealth:{activeJavaProcs: []}}}}],
+ m: 'empty activeJavaProcs',
+ e: {
+ warnings: [],
+ warningsByHost: [0]
+ }
+ },
+ {
+ items: [{Hosts:{host_name: 'c1', last_agent_env: {hostHealth:{activeJavaProcs: [{pid: 'n1', command: ''}]}}}}],
+ m: 'not empty hostHealth.activeJavaProcs',
+ e: {
+ warnings: [{
+ pid: 'n1',
+ hosts: ['c1'],
+ onSingleHost: true,
+ category: 'processes'
+ }],
+ warningsByHost: [1]
+ }
+ },
+ {
+ items: [
+ {Hosts:{host_name: 'c1', last_agent_env: {hostHealth:{activeJavaProcs: [{pid: 'n1', command: ''}]}}}},
+ {Hosts:{host_name: 'c2', last_agent_env: {hostHealth:{activeJavaProcs: [{pid: 'n1', command: ''}]}}}}
+ ],
+ m: 'not empty hostHealth.activeJavaProcs on two hosts',
+ e: {
+ warnings: [{
+ pid: 'n1',
+ hosts: ['c1', 'c2'],
+ onSingleHost: false,
+ category: 'processes'
+ }],
+ warningsByHost: [1, 1]
+ }
+ }
+ ])
+ }
+ ]).forEach(function(category) {
+ describe(category.m, function() {
+ category.tests.forEach(function(test) {
+ it(test.m, function() {
+ c.parseWarnings({items: test.items});
+ c.get('warnings').forEach(function(w, i) {
+ Em.keys(test.e.warnings[i]).forEach(function(k) {
+ expect(w[k]).to.eql(test.e.warnings[i][k]);
+ });
+ });
+ for(var i in test.e.warningsByHost) {
+ if(test.e.warningsByHost.hasOwnProperty(i)) {
+ expect(c.get('warningsByHost')[i].warnings.length).to.equal(test.e.warningsByHost[i]);
+ }
+ }
+ });
+ });
+ });
+ });
+
+ });
+
});
\ No newline at end of file