...

Source file src/github.com/chaos-mesh/chaos-mesh/e2e-test/pkg/fixture/fixture.go

Documentation: github.com/chaos-mesh/chaos-mesh/e2e-test/pkg/fixture

     1  // Copyright 2020 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package fixture
    15  
    16  import (
    17  	"sort"
    18  
    19  	appsv1 "k8s.io/api/apps/v1"
    20  	corev1 "k8s.io/api/core/v1"
    21  	"k8s.io/apimachinery/pkg/api/resource"
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  	"k8s.io/apimachinery/pkg/util/intstr"
    24  	"k8s.io/utils/pointer"
    25  
    26  	"github.com/chaos-mesh/chaos-mesh/e2e-test/e2e/config"
    27  )
    28  
    29  // NewCommonNginxPod describe that we use common nginx pod to be tested in our chaos-operator test
    30  func NewCommonNginxPod(name, namespace string) *corev1.Pod {
    31  	return &corev1.Pod{
    32  		ObjectMeta: metav1.ObjectMeta{
    33  			Name:      name,
    34  			Namespace: namespace,
    35  			Labels: map[string]string{
    36  				"app": "nginx",
    37  			},
    38  		},
    39  		Spec: corev1.PodSpec{
    40  			Containers: []corev1.Container{
    41  				{
    42  					Image:           "nginx:latest",
    43  					ImagePullPolicy: corev1.PullIfNotPresent,
    44  					Name:            "nginx",
    45  				},
    46  			},
    47  		},
    48  	}
    49  }
    50  
    51  // NewCommonNginxDeployment would create a nginx deployment
    52  func NewCommonNginxDeployment(name, namespace string, replicas int32) *appsv1.Deployment {
    53  	return &appsv1.Deployment{
    54  		ObjectMeta: metav1.ObjectMeta{
    55  			Name:      name,
    56  			Namespace: namespace,
    57  			Labels: map[string]string{
    58  				"app": "nginx",
    59  			},
    60  		},
    61  		Spec: appsv1.DeploymentSpec{
    62  			Replicas: &replicas,
    63  			Selector: &metav1.LabelSelector{
    64  				MatchLabels: map[string]string{
    65  					"app": "nginx",
    66  				},
    67  			},
    68  			Template: corev1.PodTemplateSpec{
    69  				ObjectMeta: metav1.ObjectMeta{
    70  					Labels: map[string]string{
    71  						"app": "nginx",
    72  					},
    73  				},
    74  				Spec: corev1.PodSpec{
    75  					Containers: []corev1.Container{
    76  						{
    77  							Image:           "nginx:latest",
    78  							ImagePullPolicy: corev1.PullIfNotPresent,
    79  							Name:            "nginx",
    80  						},
    81  					},
    82  				},
    83  			},
    84  		},
    85  	}
    86  }
    87  
    88  // NewTimerDeployment creates a timer deployment
    89  func NewTimerDeployment(name, namespace string) *appsv1.Deployment {
    90  	return &appsv1.Deployment{
    91  		ObjectMeta: metav1.ObjectMeta{
    92  			Name:      name,
    93  			Namespace: namespace,
    94  			Labels: map[string]string{
    95  				"app": name,
    96  			},
    97  		},
    98  		Spec: appsv1.DeploymentSpec{
    99  			Replicas: pointer.Int32Ptr(1),
   100  			Selector: &metav1.LabelSelector{
   101  				MatchLabels: map[string]string{
   102  					"app": name,
   103  				},
   104  			},
   105  			Template: corev1.PodTemplateSpec{
   106  				ObjectMeta: metav1.ObjectMeta{
   107  					Labels: map[string]string{
   108  						"app": name,
   109  					},
   110  				},
   111  				Spec: corev1.PodSpec{
   112  					Containers: []corev1.Container{
   113  						{
   114  							Image:           config.TestConfig.E2EImage,
   115  							ImagePullPolicy: corev1.PullIfNotPresent,
   116  							Name:            name,
   117  							Command:         []string{"/bin/test"},
   118  						},
   119  					},
   120  				},
   121  			},
   122  		},
   123  	}
   124  }
   125  
   126  // NewNetworkTestDeployment creates a deployment for e2e test
   127  func NewNetworkTestDeployment(name, namespace string, extraLabels map[string]string) *appsv1.Deployment {
   128  	labels := map[string]string{
   129  		"app": name,
   130  	}
   131  	for key, val := range extraLabels {
   132  		labels[key] = val
   133  	}
   134  	return &appsv1.Deployment{
   135  		ObjectMeta: metav1.ObjectMeta{
   136  			Name:      name,
   137  			Namespace: namespace,
   138  			Labels:    labels,
   139  		},
   140  		Spec: appsv1.DeploymentSpec{
   141  			Replicas: pointer.Int32Ptr(1),
   142  			Selector: &metav1.LabelSelector{
   143  				MatchLabels: labels,
   144  			},
   145  			Template: corev1.PodTemplateSpec{
   146  				ObjectMeta: metav1.ObjectMeta{
   147  					Labels: labels,
   148  				},
   149  				Spec: corev1.PodSpec{
   150  					Containers: []corev1.Container{
   151  						{
   152  							Image:           config.TestConfig.E2EImage,
   153  							ImagePullPolicy: corev1.PullIfNotPresent,
   154  							Name:            "network",
   155  							Command:         []string{"/bin/test"},
   156  						},
   157  					},
   158  				},
   159  			},
   160  		},
   161  	}
   162  }
   163  
   164  // NewStressTestDeployment creates a deployment for e2e test
   165  func NewStressTestDeployment(name, namespace string, extraLabels map[string]string) *appsv1.Deployment {
   166  	labels := map[string]string{
   167  		"app": name,
   168  	}
   169  	for key, val := range extraLabels {
   170  		labels[key] = val
   171  	}
   172  	return &appsv1.Deployment{
   173  		ObjectMeta: metav1.ObjectMeta{
   174  			Name:      name,
   175  			Namespace: namespace,
   176  			Labels:    labels,
   177  		},
   178  		Spec: appsv1.DeploymentSpec{
   179  			Replicas: pointer.Int32Ptr(1),
   180  			Selector: &metav1.LabelSelector{
   181  				MatchLabels: labels,
   182  			},
   183  			Template: corev1.PodTemplateSpec{
   184  				ObjectMeta: metav1.ObjectMeta{
   185  					Labels: labels,
   186  				},
   187  				Spec: corev1.PodSpec{
   188  					Containers: []corev1.Container{
   189  						{
   190  							Image:           config.TestConfig.E2EImage,
   191  							ImagePullPolicy: corev1.PullIfNotPresent,
   192  							Name:            "stress",
   193  							Command:         []string{"/bin/test"},
   194  							Resources: corev1.ResourceRequirements{
   195  								Requests: corev1.ResourceList{
   196  									corev1.ResourceCPU:    resource.MustParse("0"),
   197  									corev1.ResourceMemory: resource.MustParse("0"),
   198  								},
   199  								Limits: corev1.ResourceList{
   200  									corev1.ResourceCPU:    resource.MustParse("1"),
   201  									corev1.ResourceMemory: resource.MustParse("150M"),
   202  								},
   203  							},
   204  							VolumeMounts: []corev1.VolumeMount{
   205  								{
   206  									Name:      "sys",
   207  									MountPath: "/sys",
   208  								},
   209  							},
   210  						},
   211  					},
   212  					Volumes: []corev1.Volume{
   213  						{
   214  							Name: "sys",
   215  							VolumeSource: corev1.VolumeSource{
   216  								HostPath: &corev1.HostPathVolumeSource{
   217  									Path: "/sys",
   218  								},
   219  							},
   220  						},
   221  					},
   222  				},
   223  			},
   224  		},
   225  	}
   226  }
   227  
   228  // NewIOTestDeployment creates a deployment for e2e test
   229  func NewIOTestDeployment(name, namespace string) *appsv1.Deployment {
   230  	return &appsv1.Deployment{
   231  		ObjectMeta: metav1.ObjectMeta{
   232  			Name:      name,
   233  			Namespace: namespace,
   234  			Labels: map[string]string{
   235  				"app": "io",
   236  			},
   237  		},
   238  		Spec: appsv1.DeploymentSpec{
   239  			Replicas: pointer.Int32Ptr(1),
   240  			Selector: &metav1.LabelSelector{
   241  				MatchLabels: map[string]string{
   242  					"app": "io",
   243  				},
   244  			},
   245  			Template: corev1.PodTemplateSpec{
   246  				ObjectMeta: metav1.ObjectMeta{
   247  					Labels: map[string]string{
   248  						"app": "io",
   249  					},
   250  					Annotations: map[string]string{
   251  						"admission-webhook.chaos-mesh.org/request": "chaosfs-io",
   252  					},
   253  				},
   254  				Spec: corev1.PodSpec{
   255  					Containers: []corev1.Container{
   256  						{
   257  							Image:           config.TestConfig.E2EImage,
   258  							ImagePullPolicy: corev1.PullIfNotPresent,
   259  							Name:            "io",
   260  							Command:         []string{"/bin/test"},
   261  							VolumeMounts: []corev1.VolumeMount{
   262  								{
   263  									Name:      "datadir",
   264  									MountPath: "/var/run/data",
   265  								},
   266  							},
   267  						},
   268  					},
   269  					Volumes: []corev1.Volume{
   270  						{
   271  							Name: "datadir",
   272  							VolumeSource: corev1.VolumeSource{
   273  								EmptyDir: &corev1.EmptyDirVolumeSource{},
   274  							},
   275  						},
   276  					},
   277  				},
   278  			},
   279  		},
   280  	}
   281  }
   282  
   283  // NewHTTPTestDeployment creates a deployment for e2e test
   284  func NewHTTPTestDeployment(name, namespace string) *appsv1.Deployment {
   285  	return &appsv1.Deployment{
   286  		ObjectMeta: metav1.ObjectMeta{
   287  			Name:      name,
   288  			Namespace: namespace,
   289  			Labels: map[string]string{
   290  				"app": "http",
   291  			},
   292  		},
   293  		Spec: appsv1.DeploymentSpec{
   294  			Replicas: pointer.Int32Ptr(1),
   295  			Selector: &metav1.LabelSelector{
   296  				MatchLabels: map[string]string{
   297  					"app": "http",
   298  				},
   299  			},
   300  			Template: corev1.PodTemplateSpec{
   301  				ObjectMeta: metav1.ObjectMeta{
   302  					Labels: map[string]string{
   303  						"app": "http",
   304  					},
   305  				},
   306  				Spec: corev1.PodSpec{
   307  					Containers: []corev1.Container{
   308  						{
   309  							Image:           config.TestConfig.E2EImage,
   310  							ImagePullPolicy: corev1.PullIfNotPresent,
   311  							Name:            "http",
   312  							Command:         []string{"/bin/test"},
   313  						},
   314  					},
   315  				},
   316  			},
   317  		},
   318  	}
   319  }
   320  
   321  // NewE2EService creates a service for the E2E helper deployment
   322  func NewE2EService(name, namespace string) *corev1.Service {
   323  	return &corev1.Service{
   324  		ObjectMeta: metav1.ObjectMeta{
   325  			Namespace: namespace,
   326  			Name:      name,
   327  		},
   328  		Spec: corev1.ServiceSpec{
   329  			Type: corev1.ServiceTypeNodePort,
   330  			Selector: map[string]string{
   331  				"app": name,
   332  			},
   333  			Ports: []corev1.ServicePort{
   334  				{
   335  					Name:       "http",
   336  					Port:       8080,
   337  					TargetPort: intstr.IntOrString{IntVal: 8080},
   338  				},
   339  				// Only used in network chaos
   340  				{
   341  					Name:       "nc-port",
   342  					Port:       1070,
   343  					TargetPort: intstr.IntOrString{IntVal: 8000},
   344  				},
   345  				// Only used in io chaos
   346  				{
   347  					Name:       "chaosfs",
   348  					Port:       65534,
   349  					TargetPort: intstr.IntOrString{IntVal: 65534},
   350  				},
   351  			},
   352  		},
   353  	}
   354  }
   355  
   356  // HaveSameUIDs returns if pods1 and pods2 are same based on their UIDs
   357  func HaveSameUIDs(pods1 []corev1.Pod, pods2 []corev1.Pod) bool {
   358  	count := len(pods1)
   359  	if count != len(pods2) {
   360  		return false
   361  	}
   362  	ids1, ids2 := make([]string, count), make([]string, count)
   363  	for i := 0; i < count; i++ {
   364  		ids1[i], ids2[i] = string(pods1[i].UID), string(pods2[i].UID)
   365  	}
   366  	sort.Strings(ids1)
   367  	sort.Strings(ids2)
   368  	for i := 0; i < count; i++ {
   369  		if ids1[i] != ids2[i] {
   370  			return false
   371  		}
   372  	}
   373  	return true
   374  }
   375