提交 68c7c96e 编写于 作者: S Sebastian Florek 提交者: Sebastian Florek

Added replica set card status messages.

上级 340a7290
......@@ -159,7 +159,7 @@ func DeployApp(spec *AppDeploymentSpec, client client.Interface) error {
Containers: []api.Container{containerSpec},
}
if spec.ImagePullSecret != nil {
podSpec.ImagePullSecrets = []api.LocalObjectReference{api.LocalObjectReference{Name: *spec.ImagePullSecret}}
podSpec.ImagePullSecrets = []api.LocalObjectReference{{Name: *spec.ImagePullSecret}}
}
podTemplate := &api.PodTemplateSpec{
......
......@@ -137,19 +137,22 @@ func GetReplicationControllerPodsEvents(client *client.Client, namespace, replic
return nil, err
}
events := make([]api.Event, 0, 0)
events, err := GetPodsEvents(client, pods)
for _, pod := range pods.Items {
fieldSelector, err := fields.ParseSelector("involvedObject.name=" + pod.Name)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
return events, nil
}
list, err := client.Events(namespace).List(unversioned.ListOptions{
LabelSelector: unversioned.LabelSelector{labels.Everything()},
FieldSelector: unversioned.FieldSelector{fieldSelector},
})
// Gets events associated to given list of pods
// TODO(floreks): refactor this to make single API call instead of N api calls
func GetPodsEvents(client *client.Client, pods *api.PodList) ([]api.Event, error) {
events := make([]api.Event, 0, 0)
for _, pod := range pods.Items {
list, err := GetPodEvents(client, pod)
if err != nil {
return nil, err
......@@ -164,6 +167,26 @@ func GetReplicationControllerPodsEvents(client *client.Client, namespace, replic
return events, nil
}
// Gets events associated to given pod
func GetPodEvents(client client.Interface, pod api.Pod) (*api.EventList, error) {
fieldSelector, err := fields.ParseSelector("involvedObject.name=" + pod.Name)
if err != nil {
return nil, err
}
list, err := client.Events(pod.Namespace).List(unversioned.ListOptions{
LabelSelector: unversioned.LabelSelector{labels.Everything()},
FieldSelector: unversioned.FieldSelector{fieldSelector},
})
if err != nil {
return nil, err
}
return list, nil
}
// Appends events from source slice to target events representation.
func AppendEvents(source []api.Event, target Events) Events {
for _, event := range source {
......
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed 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.
package main
import (
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
"log"
"strings"
)
// Partial string to correctly filter warning events.
// Has to be lower case for correct case insensitive comparison.
const FAILED_REASON_PARTIAL = "failed"
// Contains basic information about event related to a pod
type PodEvent struct {
// Short, machine understandable string that gives the reason
// for this event being generated.
Reason string `json:"reason"`
// A human-readable description of the status of related pod.
Message string `json:"message"`
}
// Returns warning pod events based on given list of pods.
// TODO(floreks) : Import and use Set instead of custom function to get rid of duplicates
func GetPodsEventWarnings(client client.Interface, pods []api.Pod) (result []PodEvent, err error) {
for _, pod := range pods {
if !isRunningOrSucceeded(pod) {
log.Printf("Getting warning events from pod: %s", pod.Name)
events, err := GetPodEvents(client, pod)
if err != nil {
return nil, err
}
result = getPodsEventWarnings(events)
}
}
return removeDuplicates(result), nil
}
// Returns list of Pod Event model objects based on kubernetes API event list object
// Event list object is filtered to get only warning events.
func getPodsEventWarnings(eventList *api.EventList) []PodEvent {
result := make([]PodEvent, 0)
var events []api.Event
if isTypeFilled(eventList.Items) {
events = filterEventsByType(eventList.Items, api.EventTypeWarning)
} else {
events = filterEventsByReason(eventList.Items, FAILED_REASON_PARTIAL)
}
for _, event := range events {
result = append(result, PodEvent{
Message: event.Message,
Reason: event.Reason,
})
}
return result
}
// Filters kubernetes API event objects based on event type.
// Empty string will return all events.
func filterEventsByType(events []api.Event, eventType string) []api.Event {
if len(eventType) == 0 || len(events) == 0 {
return events
}
result := make([]api.Event, 0)
for _, event := range events {
if event.Type == eventType {
result = append(result, event)
}
}
return result
}
// Filters kubernetes API event objects based on reason property.
// Empty string will return all events.
func filterEventsByReason(events []api.Event, partial string) []api.Event {
if len(partial) == 0 || len(events) == 0 {
return events
}
result := make([]api.Event, 0)
for _, event := range events {
if strings.Contains(strings.ToLower(event.Reason), partial) {
result = append(result, event)
}
}
return result
}
// Returns true if all given events type is filled, false otherwise.
// This is needed as some older versions of kubernetes do not have Type property filled.
func isTypeFilled(events []api.Event) bool {
if len(events) == 0 {
return false
}
for _, event := range events {
if len(event.Type) == 0 {
return false
}
}
return true
}
// Removes duplicate strings from the slice
func removeDuplicates(slice []PodEvent) []PodEvent {
visited := make(map[string]bool, 0)
result := make([]PodEvent, 0)
for _, elem := range slice {
if !visited[elem.Reason] {
visited[elem.Reason] = true
result = append(result, elem)
}
}
return result
}
// Returns true if given pod is in state running or succeeded, false otherwise
func isRunningOrSucceeded(pod api.Pod) bool {
switch pod.Status.Phase {
case api.PodRunning, api.PodSucceeded:
return true
}
return false
}
......@@ -24,7 +24,7 @@ import (
type ReplicationControllerWithPods struct {
ReplicationController *api.ReplicationController
Pods *api.PodList
Pods *api.PodList
}
// ReplicationControllerPodInfo represents aggregate information about replication controller pods.
......@@ -43,6 +43,9 @@ type ReplicationControllerPodInfo struct {
// Number of pods that are failed.
Failed int `json:"failed"`
// Unique warning messages related to pods in this Replication Controller.
Warnings []PodEvent `json:"warnings"`
}
// Returns structure containing ReplicationController and Pods for the given replication controller.
......@@ -66,7 +69,7 @@ func getRawReplicationControllerWithPods(client client.Interface, namespace, nam
replicationControllerAndPods := &ReplicationControllerWithPods{
ReplicationController: replicationController,
Pods: pods,
Pods: pods,
}
return replicationControllerAndPods, nil
}
......
......@@ -24,6 +24,9 @@ import (
"k8s.io/kubernetes/pkg/labels"
)
// Callback function in order to get the pod status errors
type GetPodsEventWarningsFunc func(pods []api.Pod) ([]PodEvent, error)
// ReplicationControllerList contains a list of Replication Controllers in the cluster.
type ReplicationControllerList struct {
// Unordered list of Replication Controllers.
......@@ -45,7 +48,7 @@ type ReplicationController struct {
// Label of this Replication Controller.
Labels map[string]string `json:"labels"`
// Aggergate information about pods belonging to this repolica set.
// Aggregate information about pods belonging to this repolica set.
Pods ReplicationControllerPodInfo `json:"pods"`
// Container images of the Replication Controller.
......@@ -88,14 +91,34 @@ func GetReplicationControllerList(client *client.Client) (*ReplicationController
return nil, err
}
return getReplicationControllerList(replicationControllers.Items, services.Items, pods.Items), nil
// Anonymous callback function to get pods warnings.
// Function fulfils GetPodsEventWarningsFunc type contract.
// Based on list of api pods returns list of pod related warning events
getPodsEventWarningsFn := func(pods []api.Pod) ([]PodEvent, error) {
errors, err := GetPodsEventWarnings(client, pods)
if err != nil {
return nil, err
}
return errors, nil
}
result, err := getReplicationControllerList(replicationControllers.Items, services.Items, pods.Items, getPodsEventWarningsFn)
if err != nil {
return nil, err
}
return result, nil
}
// Returns a list of all Replication Controller model objects in the cluster, based on all Kubernetes
// Replication Controller and Service API objects.
// The function processes all Replication Controllers API objects and finds matching Services for them.
func getReplicationControllerList(replicationControllers []api.ReplicationController, services []api.Service,
pods []api.Pod) *ReplicationControllerList {
func getReplicationControllerList(replicationControllers []api.ReplicationController,
services []api.Service, pods []api.Pod, getPodsEventWarningsFn GetPodsEventWarningsFunc) (
*ReplicationControllerList, error) {
replicationControllerList := &ReplicationControllerList{ReplicationControllers: make([]ReplicationController, 0)}
......@@ -125,6 +148,13 @@ func getReplicationControllerList(replicationControllers []api.ReplicationContro
}
}
podInfo := getReplicationControllerPodInfo(&replicationController, matchingPods)
podErrors, err := getPodsEventWarningsFn(matchingPods)
if err != nil {
return nil, err
}
podInfo.Warnings = podErrors
replicationControllerList.ReplicationControllers = append(replicationControllerList.ReplicationControllers, ReplicationController{
Name: replicationController.ObjectMeta.Name,
......@@ -139,7 +169,7 @@ func getReplicationControllerList(replicationControllers []api.ReplicationContro
})
}
return replicationControllerList
return replicationControllerList, nil
}
// Returns all services that target the same Pods (or subset) as the given Replication Controller.
......
......@@ -98,13 +98,22 @@ backendApi.Event;
*/
backendApi.ReplicationControllerList;
/**
* @typedef {{
* reason: string,
* message: string
* }}
*/
backendApi.PodEvent;
/**
* @typedef {{
* current: number,
* desired: number,
* running: number,
* pending: number,
* failed: number
* failed: number,
* warnings: !Array<!backendApi.PodEvent>
* }}
*/
backendApi.ReplicationControllerPodInfo;
......
......@@ -19,11 +19,23 @@ limitations under the License.
<div layout="column">
<div flex layout="row" layout-align="space-between center"
class="kd-replicationcontroller-card-title-row">
<a ng-href="{{::ctrl.getReplicationControllerDetailHref()}}" class="kd-replicationcontroller-card-name" flex>
<h3 class="md-title kd-replicationcontroller-card-title">
<span layout="row" flex>
<a ng-href="{{::ctrl.getReplicationControllerDetailHref()}}" class="kd-replicationcontroller-card-name">
<span class="md-title kd-replicationcontroller-card-title">
{{::ctrl.replicationController.name}}
</h3>
</span>
</a>
<md-icon class="material-icons md-warn kd-replicationcontroller-card-status-icon"
ng-if="::ctrl.hasWarnings()">
error
<md-tooltip>One or more pods have errors</md-tooltip>
</md-icon>
<md-icon class="material-icons kd-replicationcontroller-card-status-icon"
ng-if="::ctrl.isPending()">
timelapse
<md-tooltip>One or more pods are in pending state</md-tooltip>
</md-icon>
</span>
<kd-replication-controller-card-menu replication-controller="::ctrl.replicationController"></kd-replication-controller-card-menu>
</div>
<div flex class="md-caption">
......@@ -33,7 +45,7 @@ limitations under the License.
<div class="md-caption">
<div layout="row" layout-align="center end">
<span flex="60">
<ng-pluralize class="kd-replicase-card-pods-stat kd-comma-separated-item"
<ng-pluralize class="kd-replicationcontroller-card-pods-stat kd-comma-separated-item"
count="::ctrl.replicationController.pods.running"
when="{'one': '1 pod running', 'other': '{} pods running'}">
</ng-pluralize>
......@@ -107,6 +119,15 @@ limitations under the License.
</div>
</div>
</div>
<div layout="column" ng-if="::ctrl.hasWarnings()">
<md-divider class="kd-replicationcontroller-card-divider"></md-divider>
<div layout-wrap>
<div flex class="kd-replicationcontroller-card-section"
ng-repeat="warning in ::ctrl.replicationController.pods.warnings">
<span class="kd-replicationcontroller-card-error">{{::warning.message}}</span>
</div>
</div>
</div>
</div>
</md-card-content>
</md-card>
......@@ -29,6 +29,10 @@
}
}
.kd-replicationcontroller-card-status-icon {
margin-left: $baseline-grid;
}
.kd-replicationcontroller-card-title {
font-weight: $regular-font-weight;
margin: 0;
......@@ -38,6 +42,12 @@
}
}
.kd-replicationcontroller-card-error {
color: $secondary;
margin-top: $baseline-grid / 2;
word-wrap: break-word;
}
.kd-replicationcontroller-card-description {
overflow: auto;
white-space: pre-wrap;
......@@ -87,6 +97,6 @@
margin-right: 2 * $baseline-grid;
}
.kd-replicase-card-pods-stat {
.kd-replicationcontroller-card-pods-stat {
white-space: nowrap;
}
......@@ -67,4 +67,19 @@ export default class ReplicationControllerCardController {
areDesiredPodsRunning() {
return this.replicationController.pods.running === this.replicationController.pods.desired;
}
/**
* Returns true if any of replication controller pods has warning, false otherwise
* @return {boolean}
* @export
*/
hasWarnings() { return this.replicationController.pods.warnings.length > 0; }
/**
* Returns true if replication controller pods have no warnings and there is at least one pod
* in pending state, false otherwise
* @return {boolean}
* @export
*/
isPending() { return !this.hasWarnings() && this.replicationController.pods.pending > 0; }
}
......@@ -25,8 +25,8 @@ import (
func TestFormatRequestLog(t *testing.T) {
cases := []struct {
request *restful.Request
expected string
request *restful.Request
expected string
}{
{
&restful.Request{
......@@ -40,7 +40,7 @@ func TestFormatRequestLog(t *testing.T) {
},
}
for _, c := range cases {
actual := FormatRequestLog(c.request,)
actual := FormatRequestLog(c.request)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("FormatRequestLog(%#v) == %#v, expected %#v", c.request, actual, c.expected)
}
......@@ -49,9 +49,9 @@ func TestFormatRequestLog(t *testing.T) {
func TestFormatResponseLog(t *testing.T) {
cases := []struct {
response *restful.Response
request *restful.Request
expected string
response *restful.Response
request *restful.Request
expected string
}{
{
&restful.Response{},
......
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed 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.
package main
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
)
func TestGetPodsEventWarningsApi(t *testing.T) {
cases := []struct {
pods []api.Pod
expectedActions []string
}{
{nil, []string{}},
{
[]api.Pod{
{
Status: api.PodStatus{
Phase: api.PodFailed,
},
},
},
[]string{"get"},
},
{
[]api.Pod{
{
Status: api.PodStatus{
Phase: api.PodRunning,
},
},
},
[]string{},
},
}
for _, c := range cases {
eventList := &api.EventList{}
fakeClient := testclient.NewSimpleFake(eventList)
GetPodsEventWarnings(fakeClient, c.pods)
actions := fakeClient.Actions()
if len(actions) != len(c.expectedActions) {
t.Errorf("Unexpected actions: %v, expected %d actions got %d", actions,
len(c.expectedActions), len(actions))
continue
}
}
}
func TestGetPodsEventWarnings(t *testing.T) {
cases := []struct {
events *api.EventList
expected []PodEvent
}{
{&api.EventList{Items: nil}, []PodEvent{}},
{
&api.EventList{
Items: []api.Event{
{
Message: "msg",
Reason: "reason",
Type: api.EventTypeWarning,
},
},
},
[]PodEvent{
{
Message: "msg",
Reason: "reason",
},
},
},
{
&api.EventList{
Items: []api.Event{
{
Message: "msg",
Reason: "failed",
},
},
},
[]PodEvent{
{
Message: "msg",
Reason: "failed",
},
},
},
{
&api.EventList{
Items: []api.Event{
{
Message: "msg",
Reason: "reason",
},
},
},
[]PodEvent{},
},
}
for _, c := range cases {
actual := getPodsEventWarnings(c.events)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getPodsEventErrors(%#v) == \n%#v\nexpected \n%#v\n",
c.events, actual, c.expected)
}
}
}
func TestFilterEventsByType(t *testing.T) {
events := []api.Event{
{Type: api.EventTypeNormal},
{Type: api.EventTypeWarning},
}
cases := []struct {
events []api.Event
eventType string
expected []api.Event
}{
{nil, "", nil},
{nil, api.EventTypeWarning, nil},
{
events,
"",
events,
},
{
events,
api.EventTypeNormal,
[]api.Event{
{Type: api.EventTypeNormal},
},
},
{
events,
api.EventTypeWarning,
[]api.Event{
{Type: api.EventTypeWarning},
},
},
}
for _, c := range cases {
actual := filterEventsByType(c.events, c.eventType)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("FilterEventsByType(%#v, %#v) == \n%#v\nexpected \n%#v\n",
c.events, c.eventType, actual, c.expected)
}
}
}
func TestRemoveDuplicates(t *testing.T) {
cases := []struct {
slice []PodEvent
expected []PodEvent
}{
{nil, []PodEvent{}},
{
[]PodEvent{
{Reason: "test"},
{Reason: "test2"},
{Reason: "test"},
},
[]PodEvent{
{Reason: "test"},
{Reason: "test2"},
},
},
{
[]PodEvent{
{Reason: "test"},
{Reason: "test"},
{Reason: "test"},
},
[]PodEvent{
{Reason: "test"},
},
},
{
[]PodEvent{
{Reason: "test"},
{Reason: "test2"},
{Reason: "test3"},
},
[]PodEvent{
{Reason: "test"},
{Reason: "test2"},
{Reason: "test3"},
},
},
}
for _, c := range cases {
actual := removeDuplicates(c.slice)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("removeDuplicates(%#v) == \n%#v\nexpected \n%#v\n",
c.slice, actual, c.expected)
}
}
}
func TestIsRunningOrSucceeded(t *testing.T) {
cases := []struct {
pod api.Pod
expected bool
}{
{
api.Pod{
Status: api.PodStatus{
Phase: api.PodRunning,
},
},
true,
},
{
api.Pod{
Status: api.PodStatus{
Phase: api.PodSucceeded,
},
},
true,
},
{
api.Pod{
Status: api.PodStatus{
Phase: api.PodFailed,
},
},
false,
},
{
api.Pod{
Status: api.PodStatus{
Phase: api.PodPending,
},
},
false,
},
}
for _, c := range cases {
actual := isRunningOrSucceeded(c.pod)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("isRunningOrSucceded(%#v) == \n%#v\nexpected \n%#v\n",
c.pod, actual, c.expected)
}
}
}
func TestFilterEventsByReason(t *testing.T) {
cases := []struct {
events []api.Event
partial string
expected []api.Event
}{
{nil, "", nil},
{nil, "failed", nil},
{
[]api.Event{
{
Message: "msg",
Reason: "reason",
},
{
Message: "msg-2",
Reason: "failed",
},
},
"failed",
[]api.Event{
{
Message: "msg-2",
Reason: "failed",
},
},
},
}
for _, c := range cases {
actual := filterEventsByReason(c.events, c.partial)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("filterEventsByReason(%#v, %#v) == \n%#v\nexpected \n%#v\n",
c.events, c.partial, actual, c.expected)
}
}
}
func TestIsTypeFilled(t *testing.T) {
cases := []struct {
events []api.Event
expected bool
}{
{nil, false},
{
[]api.Event{
{Type: api.EventTypeWarning},
},
true,
},
{
[]api.Event{},
false,
},
{
[]api.Event{
{Type: api.EventTypeWarning},
{Type: api.EventTypeNormal},
{Type: ""},
},
false,
},
}
for _, c := range cases {
actual := isTypeFilled(c.events)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("isTypeFilled(%#v) == \n%#v\nexpected \n%#v\n",
c.events, actual, c.expected)
}
}
}
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed 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.
package main
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
)
func TestGetReplicaSetPodInfo(t *testing.T) {
cases := []struct {
controller *api.ReplicationController
pods []api.Pod
expected ReplicationControllerPodInfo
}{
{
&api.ReplicationController{
Status: api.ReplicationControllerStatus{
Replicas: 5,
},
Spec: api.ReplicationControllerSpec{
Replicas: 4,
},
},
[]api.Pod{
{
Status: api.PodStatus{
Phase: api.PodRunning,
},
},
},
ReplicationControllerPodInfo{
Current: 5,
Desired: 4,
Running: 1,
Pending: 0,
Failed: 0,
},
},
}
for _, c := range cases {
actual := getReplicationControllerPodInfo(c.controller, c.pods)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getReplicaSetPodInfo(%#v, %#v) == \n%#v\nexpected \n%#v\n",
c.controller, c.pods, actual, c.expected)
}
}
}
......@@ -26,8 +26,8 @@ func TestUpdateReplicasCount(t *testing.T) {
cases := []struct {
namespace, replicationControllerName string
replicationControllerSpec *ReplicationControllerSpec
expected int
expectedActions []string
expected int
expectedActions []string
}{
{
"default-ns", "replicationController-1",
......
......@@ -24,7 +24,7 @@ import (
func TestIsLabelSelectorMatching(t *testing.T) {
cases := []struct {
serviceSelector, replicationControllerSelector map[string]string
expected bool
expected bool
}{
{nil, nil, false},
{nil, map[string]string{}, false},
......@@ -52,9 +52,9 @@ func TestIsLabelSelectorMatching(t *testing.T) {
func TestGetMatchingServices(t *testing.T) {
cases := []struct {
services []api.Service
services []api.Service
replicationController *api.ReplicationController
expected []api.Service
expected []api.Service
}{
{nil, nil, nil},
{
......@@ -83,11 +83,15 @@ func TestGetMatchingServices(t *testing.T) {
}
func TestGetReplicationControllerList(t *testing.T) {
getPodsErrorFnMock := func(pods []api.Pod) ([]PodEvent, error) {
return []PodEvent{}, nil
}
cases := []struct {
replicationControllers []api.ReplicationController
services []api.Service
pods []api.Pod
expected *ReplicationControllerList
services []api.Service
pods []api.Pod
expected *ReplicationControllerList
}{
{nil, nil, nil, &ReplicationControllerList{ReplicationControllers: []ReplicationController{}}},
{
......@@ -206,23 +210,27 @@ func TestGetReplicationControllerList(t *testing.T) {
ContainerImages: []string{"my-container-image-1"},
InternalEndpoints: []Endpoint{{Host: "my-app-1.namespace-1"}},
Pods: ReplicationControllerPodInfo{
Failed: 2,
Pending: 1,
Running: 1,
Failed: 2,
Pending: 1,
Running: 1,
Warnings: []PodEvent{},
},
}, {
Name: "my-app-2",
Namespace: "namespace-2",
ContainerImages: []string{"my-container-image-2"},
InternalEndpoints: []Endpoint{{Host: "my-app-2.namespace-2"}},
Pods: ReplicationControllerPodInfo{},
Pods: ReplicationControllerPodInfo{
Warnings: []PodEvent{},
},
},
},
},
},
}
for _, c := range cases {
actual := getReplicationControllerList(c.replicationControllers, c.services, c.pods)
actual, _ := getReplicationControllerList(c.replicationControllers, c.services, c.pods,
getPodsErrorFnMock)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getReplicationControllerList(%#v, %#v) == \n%#v\nexpected \n%#v\n",
c.replicationControllers, c.services, actual, c.expected)
......
......@@ -15,7 +15,7 @@
import ReplicationControllerCardController from 'replicationcontrollerlist/replicationcontrollercard_controller';
import replicationControllerListModule from 'replicationcontrollerlist/replicationcontrollerlist_module';
describe('Logs menu controller', () => {
describe('Replication controller card controller', () => {
/**
* @type {!ReplicationControllerCardController}
*/
......@@ -72,4 +72,73 @@ describe('Logs menu controller', () => {
// then
expect(ctrl.areDesiredPodsRunning()).toBeFalsy();
});
it('should return true when at least one replication controller pod has warning', () => {
// given
ctrl.replicationController = {
pods: {
warnings: [{
message: "test-error",
reason: "test-reason",
}],
},
};
// then
expect(ctrl.hasWarnings()).toBeTruthy();
});
it('should return false when there are no errors related to replication controller pods', () => {
// given
ctrl.replicationController = {
pods: {
warnings: [],
},
};
// then
expect(ctrl.hasWarnings()).toBeFalsy();
});
it('should return true when there are no warnings and at least one pod is in pending state',
() => {
// given
ctrl.replicationController = {
pods: {
warnings: [],
pending: 1,
},
};
// then
expect(ctrl.isPending()).toBeTruthy();
});
it('should return false when there is warning related to replication controller pods', () => {
// given
ctrl.replicationController = {
pods: {
warnings: [{
message: "test-error",
reason: "test-reason",
}],
},
};
// then
expect(ctrl.isPending()).toBeFalsy();
});
it('should return false when there are no warnings and there is no pod in pending state', () => {
// given
ctrl.replicationController = {
pods: {
warnings: [],
pending: 0,
},
};
// then
expect(ctrl.isPending()).toBeFalsy();
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册