...

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