...

Source file src/github.com/chaos-mesh/chaos-mesh/api/v1alpha1/physical_machine_chaos_webhook_test.go

Documentation: github.com/chaos-mesh/chaos-mesh/api/v1alpha1

     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 v1alpha1
    17  
    18  import (
    19  	"strings"
    20  
    21  	. "github.com/onsi/ginkgo/v2"
    22  	. "github.com/onsi/gomega"
    23  )
    24  
    25  var _ = Describe("physicalmachinechaos_webhook", func() {
    26  	Context("webhook.Defaultor of physicalmachinechaos", func() {
    27  		It("Default", func() {
    28  			physicalMachineChaos := &PhysicalMachineChaos{
    29  				Spec: PhysicalMachineChaosSpec{
    30  					Action: "stress-cpu",
    31  					PhysicalMachineSelector: PhysicalMachineSelector{
    32  						Address: []string{
    33  							"123.123.123.123:123",
    34  							"234.234.234.234:234",
    35  						},
    36  					},
    37  					ExpInfo: ExpInfo{
    38  						UID: "",
    39  						StressCPU: &StressCPUSpec{
    40  							Load:    10,
    41  							Workers: 1,
    42  						},
    43  					},
    44  				},
    45  			}
    46  			physicalMachineChaos.Default()
    47  			Expect(physicalMachineChaos.Spec.UID).ToNot(Equal(""))
    48  			Expect(physicalMachineChaos.Spec.Address).To(BeEquivalentTo([]string{
    49  				"http://123.123.123.123:123",
    50  				"http://234.234.234.234:234",
    51  			}))
    52  		})
    53  	})
    54  	Context("webhook.Validator of physicalmachinechaos", func() {
    55  		It("Validate common", func() {
    56  			testCases := []struct {
    57  				chaos PhysicalMachineChaos
    58  				err   string
    59  			}{
    60  				{
    61  					PhysicalMachineChaos{
    62  						Spec: PhysicalMachineChaosSpec{
    63  							PhysicalMachineSelector: PhysicalMachineSelector{
    64  								Address: []string{
    65  									"123.123.123.123:123",
    66  									"234.234.234.234:234",
    67  								},
    68  							},
    69  							Action:  "stress-cpu",
    70  							ExpInfo: ExpInfo{},
    71  						},
    72  					},
    73  					"the configuration corresponding to action is required",
    74  				},
    75  			}
    76  
    77  			for _, testCase := range testCases {
    78  				_, err := testCase.chaos.ValidateCreate()
    79  				Expect(strings.Contains(err.Error(), testCase.err)).To(BeTrue())
    80  			}
    81  		})
    82  
    83  		It("Validate selector", func() {
    84  			testCases := []struct {
    85  				chaos PhysicalMachineChaos
    86  				err   string
    87  			}{
    88  				{
    89  					PhysicalMachineChaos{
    90  						Spec: PhysicalMachineChaosSpec{
    91  							Action: "stress-cpu",
    92  							PhysicalMachineSelector: PhysicalMachineSelector{
    93  								Address: []string{
    94  									"123.123.123.123:123",
    95  									"234.234.234.234:234",
    96  								},
    97  								Selector: PhysicalMachineSelectorSpec{
    98  									PhysicalMachines: map[string][]string{
    99  										"default": {"physical-machine1"},
   100  									},
   101  								},
   102  							},
   103  							ExpInfo: ExpInfo{
   104  								UID: "",
   105  								StressCPU: &StressCPUSpec{
   106  									Load:    10,
   107  									Workers: 1,
   108  								},
   109  							},
   110  						},
   111  					},
   112  					"only one of address or selector could be specified",
   113  				},
   114  				{
   115  					PhysicalMachineChaos{
   116  						Spec: PhysicalMachineChaosSpec{
   117  							Action: "stress-cpu",
   118  							PhysicalMachineSelector: PhysicalMachineSelector{
   119  								Selector: PhysicalMachineSelectorSpec{
   120  									PhysicalMachines: map[string][]string{
   121  										"default": {"physical-machine1"},
   122  									},
   123  								},
   124  							},
   125  							ExpInfo: ExpInfo{
   126  								UID: "",
   127  								StressCPU: &StressCPUSpec{
   128  									Load:    10,
   129  									Workers: 1,
   130  								},
   131  							},
   132  						},
   133  					},
   134  					"",
   135  				},
   136  				{
   137  					PhysicalMachineChaos{
   138  						Spec: PhysicalMachineChaosSpec{
   139  							Action: "stress-cpu",
   140  							PhysicalMachineSelector: PhysicalMachineSelector{
   141  								Address: []string{
   142  									"123.123.123.123:123",
   143  									"234.234.234.234:234",
   144  								},
   145  							},
   146  							ExpInfo: ExpInfo{
   147  								UID: "",
   148  								StressCPU: &StressCPUSpec{
   149  									Load:    10,
   150  									Workers: 1,
   151  								},
   152  							},
   153  						},
   154  					},
   155  					"",
   156  				},
   157  				{
   158  					PhysicalMachineChaos{
   159  						Spec: PhysicalMachineChaosSpec{
   160  							Action:                  "stress-cpu",
   161  							PhysicalMachineSelector: PhysicalMachineSelector{},
   162  							ExpInfo: ExpInfo{
   163  								UID: "",
   164  								StressCPU: &StressCPUSpec{
   165  									Load:    10,
   166  									Workers: 1,
   167  								},
   168  							},
   169  						},
   170  					},
   171  					"one of address or selector should be specified",
   172  				},
   173  			}
   174  
   175  			for _, testCase := range testCases {
   176  				_, err := testCase.chaos.ValidateCreate()
   177  				if len(testCase.err) != 0 {
   178  					Expect(err).To(HaveOccurred())
   179  					Expect(strings.Contains(err.Error(), testCase.err)).To(BeTrue())
   180  				} else {
   181  					Expect(err).ToNot(HaveOccurred())
   182  				}
   183  			}
   184  		})
   185  
   186  		It("Validate config for specified action", func() {
   187  			testCases := []struct {
   188  				action  PhysicalMachineChaosAction
   189  				expInfo ExpInfo
   190  				err     string
   191  			}{
   192  				{
   193  					PMStressCPUAction,
   194  					ExpInfo{
   195  						StressCPU: &StressCPUSpec{
   196  							Load: 0,
   197  						},
   198  					},
   199  					"load can't be 0",
   200  				},
   201  				{
   202  					PMStressCPUAction,
   203  					ExpInfo{
   204  						StressCPU: &StressCPUSpec{
   205  							Load:    1,
   206  							Workers: 0,
   207  						},
   208  					},
   209  					"workers can't be 0",
   210  				},
   211  				{
   212  					PMStressCPUAction,
   213  					ExpInfo{
   214  						StressCPU: &StressCPUSpec{
   215  							Load:    1,
   216  							Workers: 1,
   217  						},
   218  					},
   219  					"",
   220  				},
   221  				{
   222  					PMStressMemAction,
   223  					ExpInfo{
   224  						StressMemory: &StressMemorySpec{
   225  							Size: "",
   226  						},
   227  					},
   228  					"size is required",
   229  				},
   230  				{
   231  					PMStressMemAction,
   232  					ExpInfo{
   233  						StressMemory: &StressMemorySpec{
   234  							Size: "123HB",
   235  						},
   236  					},
   237  					"unknown unit",
   238  				},
   239  				{
   240  					PMStressMemAction,
   241  					ExpInfo{
   242  						StressMemory: &StressMemorySpec{
   243  							Size: "123MB",
   244  						},
   245  					},
   246  					"",
   247  				},
   248  				{
   249  					PMDiskReadPayloadAction,
   250  					ExpInfo{
   251  						DiskReadPayload: &DiskPayloadSpec{
   252  							PayloadProcessNum: 0,
   253  						},
   254  					},
   255  					"payload-process-num can't be 0",
   256  				},
   257  				{
   258  					PMDiskReadPayloadAction,
   259  					ExpInfo{
   260  						DiskReadPayload: &DiskPayloadSpec{
   261  							PayloadProcessNum: 1,
   262  							DiskFileSpec: DiskFileSpec{
   263  								Size: "",
   264  							},
   265  						},
   266  					},
   267  					"size is required",
   268  				},
   269  				{
   270  					PMDiskReadPayloadAction,
   271  					ExpInfo{
   272  						DiskReadPayload: &DiskPayloadSpec{
   273  							PayloadProcessNum: 1,
   274  							DiskFileSpec: DiskFileSpec{
   275  								Size: "100HB",
   276  							},
   277  						},
   278  					},
   279  					"unknown unit",
   280  				},
   281  				{
   282  					PMDiskReadPayloadAction,
   283  					ExpInfo{
   284  						DiskReadPayload: &DiskPayloadSpec{
   285  							PayloadProcessNum: 1,
   286  							DiskFileSpec: DiskFileSpec{
   287  								Size: "100MB",
   288  							},
   289  						},
   290  					},
   291  					"",
   292  				},
   293  				{
   294  					PMDiskWritePayloadAction,
   295  					ExpInfo{
   296  						DiskWritePayload: &DiskPayloadSpec{
   297  							PayloadProcessNum: 0,
   298  						},
   299  					},
   300  					"payload-process-num can't be 0",
   301  				},
   302  				{
   303  					PMDiskWritePayloadAction,
   304  					ExpInfo{
   305  						DiskWritePayload: &DiskPayloadSpec{
   306  							PayloadProcessNum: 1,
   307  							DiskFileSpec: DiskFileSpec{
   308  								Size: "",
   309  							},
   310  						},
   311  					},
   312  					"size is required",
   313  				},
   314  				{
   315  					PMDiskWritePayloadAction,
   316  					ExpInfo{
   317  						DiskWritePayload: &DiskPayloadSpec{
   318  							PayloadProcessNum: 1,
   319  							DiskFileSpec: DiskFileSpec{
   320  								Size: "100HB",
   321  							},
   322  						},
   323  					},
   324  					"unknown unit",
   325  				},
   326  				{
   327  					PMDiskWritePayloadAction,
   328  					ExpInfo{
   329  						DiskWritePayload: &DiskPayloadSpec{
   330  							PayloadProcessNum: 1,
   331  							DiskFileSpec: DiskFileSpec{
   332  								Size: "100MB",
   333  							},
   334  						},
   335  					},
   336  					"",
   337  				},
   338  				{
   339  					PMDiskFillAction,
   340  					ExpInfo{
   341  						DiskFill: &DiskFillSpec{
   342  							DiskFileSpec: DiskFileSpec{
   343  								Size: "",
   344  							},
   345  						},
   346  					},
   347  					"size is required",
   348  				},
   349  				{
   350  					PMDiskFillAction,
   351  					ExpInfo{
   352  						DiskFill: &DiskFillSpec{
   353  							DiskFileSpec: DiskFileSpec{
   354  								Size: "100HB",
   355  							},
   356  						},
   357  					},
   358  					"unknown unit",
   359  				},
   360  				{
   361  					PMDiskFillAction,
   362  					ExpInfo{
   363  						DiskFill: &DiskFillSpec{
   364  							DiskFileSpec: DiskFileSpec{
   365  								Size: "100MB",
   366  							},
   367  						},
   368  					},
   369  					"",
   370  				},
   371  				{
   372  					PMNetworkCorruptAction,
   373  					ExpInfo{
   374  						NetworkCorrupt: &NetworkCorruptSpec{
   375  							NetworkCommonSpec: NetworkCommonSpec{
   376  								Correlation: "-1",
   377  							},
   378  						},
   379  					},
   380  					"correlation -1 is invalid",
   381  				},
   382  				{
   383  					PMNetworkCorruptAction,
   384  					ExpInfo{
   385  						NetworkCorrupt: &NetworkCorruptSpec{
   386  							NetworkCommonSpec: NetworkCommonSpec{
   387  								Correlation: "100",
   388  								Device:      "",
   389  							},
   390  						},
   391  					},
   392  					"device is required",
   393  				},
   394  				{
   395  					PMNetworkCorruptAction,
   396  					ExpInfo{
   397  						NetworkCorrupt: &NetworkCorruptSpec{
   398  							NetworkCommonSpec: NetworkCommonSpec{
   399  								Correlation: "100",
   400  								Device:      "eth0",
   401  								IPAddress:   "123.123.123.123",
   402  							},
   403  							Percent: "0",
   404  						},
   405  					},
   406  					"percent is invalid",
   407  				},
   408  				{
   409  					PMNetworkCorruptAction,
   410  					ExpInfo{
   411  						NetworkCorrupt: &NetworkCorruptSpec{
   412  							NetworkCommonSpec: NetworkCommonSpec{
   413  								Correlation: "100",
   414  								Device:      "eth0",
   415  								IPAddress:   "123.123.123.123",
   416  							},
   417  							Percent: "10",
   418  						},
   419  					},
   420  					"",
   421  				},
   422  				{
   423  					PMNetworkDuplicateAction,
   424  					ExpInfo{
   425  						NetworkDuplicate: &NetworkDuplicateSpec{
   426  							NetworkCommonSpec: NetworkCommonSpec{
   427  								Correlation: "-1",
   428  							},
   429  						},
   430  					},
   431  					"correlation -1 is invalid",
   432  				},
   433  				{
   434  					PMNetworkDuplicateAction,
   435  					ExpInfo{
   436  						NetworkDuplicate: &NetworkDuplicateSpec{
   437  							NetworkCommonSpec: NetworkCommonSpec{
   438  								Correlation: "100",
   439  								Device:      "",
   440  							},
   441  						},
   442  					},
   443  					"device is required",
   444  				},
   445  				{
   446  					PMNetworkDuplicateAction,
   447  					ExpInfo{
   448  						NetworkDuplicate: &NetworkDuplicateSpec{
   449  							NetworkCommonSpec: NetworkCommonSpec{
   450  								Correlation: "100",
   451  								Device:      "eth0",
   452  								IPAddress:   "123.123.123.123",
   453  							},
   454  							Percent: "0",
   455  						},
   456  					},
   457  					"percent is invalid",
   458  				},
   459  				{
   460  					PMNetworkDuplicateAction,
   461  					ExpInfo{
   462  						NetworkDuplicate: &NetworkDuplicateSpec{
   463  							NetworkCommonSpec: NetworkCommonSpec{
   464  								Correlation: "100",
   465  								Device:      "eth0",
   466  								IPAddress:   "123.123.123.123",
   467  							},
   468  							Percent: "10",
   469  						},
   470  					},
   471  					"",
   472  				},
   473  				{
   474  					PMNetworkLossAction,
   475  					ExpInfo{
   476  						NetworkLoss: &NetworkLossSpec{
   477  							NetworkCommonSpec: NetworkCommonSpec{
   478  								Correlation: "100",
   479  								Device:      "",
   480  							},
   481  						},
   482  					},
   483  					"device is required",
   484  				},
   485  				{
   486  					PMNetworkLossAction,
   487  					ExpInfo{
   488  						NetworkLoss: &NetworkLossSpec{
   489  							NetworkCommonSpec: NetworkCommonSpec{
   490  								Correlation: "100",
   491  								Device:      "eth0",
   492  								IPAddress:   "123.123.123.123",
   493  							},
   494  							Percent: "0",
   495  						},
   496  					},
   497  					"percent is invalid",
   498  				},
   499  				{
   500  					PMNetworkLossAction,
   501  					ExpInfo{
   502  						NetworkLoss: &NetworkLossSpec{
   503  							NetworkCommonSpec: NetworkCommonSpec{
   504  								Correlation: "100",
   505  								Device:      "eth0",
   506  								IPAddress:   "123.123.123.123",
   507  							},
   508  							Percent: "10",
   509  						},
   510  					},
   511  					"",
   512  				},
   513  				{
   514  					PMNetworkDelayAction,
   515  					ExpInfo{
   516  						NetworkDelay: &NetworkDelaySpec{
   517  							NetworkCommonSpec: NetworkCommonSpec{
   518  								Correlation: "-1",
   519  							},
   520  						},
   521  					},
   522  					"correlation -1 is invalid",
   523  				},
   524  				{
   525  					PMNetworkDelayAction,
   526  					ExpInfo{
   527  						NetworkDelay: &NetworkDelaySpec{
   528  							NetworkCommonSpec: NetworkCommonSpec{
   529  								Correlation: "100",
   530  								Device:      "",
   531  							},
   532  						},
   533  					},
   534  					"device is required",
   535  				},
   536  				{
   537  					PMNetworkDelayAction,
   538  					ExpInfo{
   539  						NetworkDelay: &NetworkDelaySpec{
   540  							NetworkCommonSpec: NetworkCommonSpec{
   541  								Correlation: "100",
   542  								Device:      "eth0",
   543  								Hostname:    "chaos-mesh.org",
   544  							},
   545  						},
   546  					},
   547  					"latency is invalid",
   548  				},
   549  				{
   550  					PMNetworkDelayAction,
   551  					ExpInfo{
   552  						NetworkDelay: &NetworkDelaySpec{
   553  							NetworkCommonSpec: NetworkCommonSpec{
   554  								Correlation: "100",
   555  								Device:      "eth0",
   556  								Hostname:    "chaos-mesh.org",
   557  							},
   558  							Latency: "10ms",
   559  						},
   560  					},
   561  					"",
   562  				},
   563  				{
   564  					PMNetworkPartitionAction,
   565  					ExpInfo{
   566  						NetworkPartition: &NetworkPartitionSpec{
   567  
   568  							Device: "",
   569  						},
   570  					},
   571  					"device is required",
   572  				},
   573  				{
   574  					PMNetworkPartitionAction,
   575  					ExpInfo{
   576  						NetworkPartition: &NetworkPartitionSpec{
   577  							Device: "eth0",
   578  						},
   579  					},
   580  					"one of ip-address and hostname is required",
   581  				},
   582  				{
   583  					PMNetworkPartitionAction,
   584  					ExpInfo{
   585  						NetworkPartition: &NetworkPartitionSpec{
   586  							Device:    "eth0",
   587  							Hostname:  "chaos-mesh.org",
   588  							Direction: "nil",
   589  						},
   590  					},
   591  					"direction should be one of 'to' and 'from'",
   592  				},
   593  				{
   594  					PMNetworkPartitionAction,
   595  					ExpInfo{
   596  						NetworkPartition: &NetworkPartitionSpec{
   597  							Device:         "eth0",
   598  							Hostname:       "chaos-mesh.org",
   599  							Direction:      "to",
   600  							AcceptTCPFlags: "SYN,ACK SYN,ACK",
   601  							IPProtocol:     "udp",
   602  						},
   603  					},
   604  					"protocol should be 'tcp' when set accept-tcp-flags",
   605  				},
   606  				{
   607  					PMNetworkPartitionAction,
   608  					ExpInfo{
   609  						NetworkPartition: &NetworkPartitionSpec{
   610  							Device:         "eth0",
   611  							Hostname:       "chaos-mesh.org",
   612  							Direction:      "to",
   613  							AcceptTCPFlags: "SYN,ACK SYN,ACK",
   614  							IPProtocol:     "tcp",
   615  						},
   616  					},
   617  					"",
   618  				},
   619  				{
   620  					PMNetworkDNSAction,
   621  					ExpInfo{
   622  						NetworkDNS: &NetworkDNSSpec{
   623  							DNSDomainName: "chaos-mesh.org",
   624  							DNSIp:         "",
   625  						},
   626  					},
   627  					"DNS host chaos-mesh.org must match a DNS ip",
   628  				},
   629  				{
   630  					PMNetworkDNSAction,
   631  					ExpInfo{
   632  						NetworkDNS: &NetworkDNSSpec{
   633  							DNSDomainName: "",
   634  							DNSIp:         "123.123.123.123",
   635  						},
   636  					},
   637  					"DNS host  must match a DNS ip 123.123.123.123",
   638  				},
   639  				{
   640  					PMNetworkDNSAction,
   641  					ExpInfo{
   642  						NetworkDNS: &NetworkDNSSpec{
   643  							DNSDomainName: "chaos-mesh.org",
   644  							DNSIp:         "123.123.123.123",
   645  						},
   646  					},
   647  					"",
   648  				},
   649  				{
   650  					PMProcessAction,
   651  					ExpInfo{
   652  						Process: &ProcessSpec{
   653  							Process: "",
   654  						},
   655  					},
   656  					"process is required",
   657  				},
   658  				{
   659  					PMProcessAction,
   660  					ExpInfo{
   661  						Process: &ProcessSpec{
   662  							Process: "123",
   663  							Signal:  0,
   664  						},
   665  					},
   666  					"signal is required",
   667  				},
   668  				{
   669  					PMProcessAction,
   670  					ExpInfo{
   671  						Process: &ProcessSpec{
   672  							Process: "123",
   673  							Signal:  19,
   674  						},
   675  					},
   676  					"",
   677  				},
   678  				{
   679  					PMJVMExceptionAction,
   680  					ExpInfo{
   681  						JVMException: &JVMExceptionSpec{
   682  							JVMCommonSpec: JVMCommonSpec{
   683  								Pid: 0,
   684  							},
   685  						},
   686  					},
   687  					"pid is required",
   688  				},
   689  				{
   690  					PMJVMExceptionAction,
   691  					ExpInfo{
   692  						JVMException: &JVMExceptionSpec{
   693  							JVMCommonSpec: JVMCommonSpec{
   694  								Pid: 123,
   695  							},
   696  							JVMClassMethodSpec: JVMClassMethodSpec{
   697  								Class: "",
   698  							},
   699  						},
   700  					},
   701  					"class is required",
   702  				},
   703  				{
   704  					PMJVMExceptionAction,
   705  					ExpInfo{
   706  						JVMException: &JVMExceptionSpec{
   707  							JVMCommonSpec: JVMCommonSpec{
   708  								Pid: 123,
   709  							},
   710  							JVMClassMethodSpec: JVMClassMethodSpec{
   711  								Class:  "Main",
   712  								Method: "",
   713  							},
   714  						},
   715  					},
   716  					"method is required",
   717  				},
   718  				{
   719  					PMJVMExceptionAction,
   720  					ExpInfo{
   721  						JVMException: &JVMExceptionSpec{
   722  							JVMCommonSpec: JVMCommonSpec{
   723  								Pid: 123,
   724  							},
   725  							JVMClassMethodSpec: JVMClassMethodSpec{
   726  								Class:  "Main",
   727  								Method: "test",
   728  							},
   729  							ThrowException: "",
   730  						},
   731  					},
   732  					"exception is required",
   733  				},
   734  				{
   735  					PMJVMExceptionAction,
   736  					ExpInfo{
   737  						JVMException: &JVMExceptionSpec{
   738  							JVMCommonSpec: JVMCommonSpec{
   739  								Pid: 123,
   740  							},
   741  							JVMClassMethodSpec: JVMClassMethodSpec{
   742  								Class:  "Main",
   743  								Method: "test",
   744  							},
   745  							ThrowException: "java.io.IOException(\"BOOM\")",
   746  						},
   747  					},
   748  					"",
   749  				},
   750  				{
   751  					PMJVMGCAction,
   752  					ExpInfo{
   753  						JVMGC: &JVMGCSpec{
   754  							JVMCommonSpec: JVMCommonSpec{
   755  								Pid: 0,
   756  							},
   757  						},
   758  					},
   759  					"pid is required",
   760  				},
   761  				{
   762  					PMJVMGCAction,
   763  					ExpInfo{
   764  						JVMGC: &JVMGCSpec{
   765  							JVMCommonSpec: JVMCommonSpec{
   766  								Pid: 10,
   767  							},
   768  						},
   769  					},
   770  					"",
   771  				},
   772  				{
   773  					PMJVMLatencyAction,
   774  					ExpInfo{
   775  						JVMLatency: &JVMLatencySpec{
   776  							JVMCommonSpec: JVMCommonSpec{
   777  								Pid: 0,
   778  							},
   779  						},
   780  					},
   781  					"pid is required",
   782  				},
   783  				{
   784  					PMJVMLatencyAction,
   785  					ExpInfo{
   786  						JVMLatency: &JVMLatencySpec{
   787  							JVMCommonSpec: JVMCommonSpec{
   788  								Pid: 123,
   789  							},
   790  							JVMClassMethodSpec: JVMClassMethodSpec{
   791  								Class: "",
   792  							},
   793  						},
   794  					},
   795  					"class is required",
   796  				},
   797  				{
   798  					PMJVMLatencyAction,
   799  					ExpInfo{
   800  						JVMLatency: &JVMLatencySpec{
   801  							JVMCommonSpec: JVMCommonSpec{
   802  								Pid: 123,
   803  							},
   804  							JVMClassMethodSpec: JVMClassMethodSpec{
   805  								Class:  "Main",
   806  								Method: "",
   807  							},
   808  						},
   809  					},
   810  					"method is required",
   811  				},
   812  				{
   813  					PMJVMLatencyAction,
   814  					ExpInfo{
   815  						JVMLatency: &JVMLatencySpec{
   816  							JVMCommonSpec: JVMCommonSpec{
   817  								Pid: 123,
   818  							},
   819  							JVMClassMethodSpec: JVMClassMethodSpec{
   820  								Class:  "Main",
   821  								Method: "test",
   822  							},
   823  							LatencyDuration: 0,
   824  						},
   825  					},
   826  					"latency is required",
   827  				},
   828  				{
   829  					PMJVMLatencyAction,
   830  					ExpInfo{
   831  						JVMLatency: &JVMLatencySpec{
   832  							JVMCommonSpec: JVMCommonSpec{
   833  								Pid: 123,
   834  							},
   835  							JVMClassMethodSpec: JVMClassMethodSpec{
   836  								Class:  "Main",
   837  								Method: "test",
   838  							},
   839  							LatencyDuration: 1000,
   840  						},
   841  					},
   842  					"",
   843  				},
   844  				{
   845  					PMJVMReturnAction,
   846  					ExpInfo{
   847  						JVMReturn: &JVMReturnSpec{
   848  							JVMCommonSpec: JVMCommonSpec{
   849  								Pid: 0,
   850  							},
   851  						},
   852  					},
   853  					"pid is required",
   854  				},
   855  				{
   856  					PMJVMReturnAction,
   857  					ExpInfo{
   858  						JVMReturn: &JVMReturnSpec{
   859  							JVMCommonSpec: JVMCommonSpec{
   860  								Pid: 123,
   861  							},
   862  							JVMClassMethodSpec: JVMClassMethodSpec{
   863  								Class: "",
   864  							},
   865  						},
   866  					},
   867  					"class is required",
   868  				},
   869  				{
   870  					PMJVMReturnAction,
   871  					ExpInfo{
   872  						JVMReturn: &JVMReturnSpec{
   873  							JVMCommonSpec: JVMCommonSpec{
   874  								Pid: 123,
   875  							},
   876  							JVMClassMethodSpec: JVMClassMethodSpec{
   877  								Class:  "Main",
   878  								Method: "",
   879  							},
   880  						},
   881  					},
   882  					"method is required",
   883  				},
   884  				{
   885  					PMJVMReturnAction,
   886  					ExpInfo{
   887  						JVMReturn: &JVMReturnSpec{
   888  							JVMCommonSpec: JVMCommonSpec{
   889  								Pid: 123,
   890  							},
   891  							JVMClassMethodSpec: JVMClassMethodSpec{
   892  								Class:  "Main",
   893  								Method: "test",
   894  							},
   895  							ReturnValue: "",
   896  						},
   897  					},
   898  					"value is required",
   899  				},
   900  				{
   901  					PMJVMReturnAction,
   902  					ExpInfo{
   903  						JVMReturn: &JVMReturnSpec{
   904  							JVMCommonSpec: JVMCommonSpec{
   905  								Pid: 123,
   906  							},
   907  							JVMClassMethodSpec: JVMClassMethodSpec{
   908  								Class:  "Main",
   909  								Method: "test",
   910  							},
   911  							ReturnValue: "123",
   912  						},
   913  					},
   914  					"",
   915  				},
   916  				{
   917  					PMJVMStressAction,
   918  					ExpInfo{
   919  						JVMStress: &JVMStressSpec{
   920  							JVMCommonSpec: JVMCommonSpec{
   921  								Pid: 0,
   922  							},
   923  						},
   924  					},
   925  					"pid is required",
   926  				},
   927  				{
   928  					PMJVMStressAction,
   929  					ExpInfo{
   930  						JVMStress: &JVMStressSpec{
   931  							JVMCommonSpec: JVMCommonSpec{
   932  								Pid: 10,
   933  							},
   934  
   935  							CPUCount:   0,
   936  							MemoryType: "",
   937  						},
   938  					},
   939  					"one of cpu-count and mem-type is required",
   940  				},
   941  				{
   942  					PMJVMStressAction,
   943  					ExpInfo{
   944  						JVMStress: &JVMStressSpec{
   945  							JVMCommonSpec: JVMCommonSpec{
   946  								Pid: 10,
   947  							},
   948  							CPUCount:   1,
   949  							MemoryType: "heap",
   950  						},
   951  					},
   952  					"inject stress on both CPU and memory is not support",
   953  				},
   954  				{
   955  					PMJVMStressAction,
   956  					ExpInfo{
   957  						JVMStress: &JVMStressSpec{
   958  							JVMCommonSpec: JVMCommonSpec{
   959  								Pid: 10,
   960  							},
   961  							CPUCount:   0,
   962  							MemoryType: "heap",
   963  						},
   964  					},
   965  					"",
   966  				},
   967  				{
   968  					PMJVMRuleDataAction,
   969  					ExpInfo{
   970  						JVMRuleData: &JVMRuleDataSpec{
   971  							JVMCommonSpec: JVMCommonSpec{
   972  								Pid: 0,
   973  							},
   974  						},
   975  					},
   976  					"pid is required",
   977  				},
   978  				{
   979  					PMJVMRuleDataAction,
   980  					ExpInfo{
   981  						JVMRuleData: &JVMRuleDataSpec{
   982  							JVMCommonSpec: JVMCommonSpec{
   983  								Pid: 10,
   984  							},
   985  							RuleData: "",
   986  						},
   987  					},
   988  					"rule-data is required",
   989  				},
   990  				{
   991  					PMJVMRuleDataAction,
   992  					ExpInfo{
   993  						JVMRuleData: &JVMRuleDataSpec{
   994  							JVMCommonSpec: JVMCommonSpec{
   995  								Pid: 10,
   996  							},
   997  							RuleData: "RULE modify return value\nCLASS Main\nMETHOD getnum\nAT ENTRY\nIF true\nDO\n    return 9999\nENDRULE",
   998  						},
   999  					},
  1000  					"",
  1001  				},
  1002  				{
  1003  					PMClockAction,
  1004  					ExpInfo{
  1005  						Clock: &ClockSpec{
  1006  							Pid: 0,
  1007  						},
  1008  					},
  1009  					"pid is required",
  1010  				},
  1011  				{
  1012  					PMClockAction,
  1013  					ExpInfo{
  1014  						Clock: &ClockSpec{
  1015  							Pid:        123,
  1016  							TimeOffset: "",
  1017  						},
  1018  					},
  1019  					"time-offset is required",
  1020  				},
  1021  				{
  1022  					PMClockAction,
  1023  					ExpInfo{
  1024  						Clock: &ClockSpec{
  1025  							Pid:        123,
  1026  							TimeOffset: "10m",
  1027  						},
  1028  					},
  1029  					"",
  1030  				},
  1031  			}
  1032  
  1033  			for _, testCase := range testCases {
  1034  				chaos := PhysicalMachineChaos{
  1035  					Spec: PhysicalMachineChaosSpec{
  1036  						PhysicalMachineSelector: PhysicalMachineSelector{
  1037  							Address: []string{
  1038  								"123.123.123.123:123",
  1039  								"234.234.234.234:234",
  1040  							},
  1041  						},
  1042  						Action:  testCase.action,
  1043  						ExpInfo: testCase.expInfo,
  1044  					},
  1045  				}
  1046  				_, err := chaos.ValidateCreate()
  1047  				if len(testCase.err) != 0 {
  1048  					Expect(err).To(HaveOccurred())
  1049  					Expect(strings.Contains(err.Error(), testCase.err)).To(BeTrue())
  1050  				} else {
  1051  					Expect(err).ToNot(HaveOccurred())
  1052  				}
  1053  			}
  1054  		})
  1055  	})
  1056  	Context("webhook.Validator of bandwidth physicalmachinechaos", func() {
  1057  		It("Validate", func() {
  1058  			testCases := []struct {
  1059  				chaos PhysicalMachineChaos
  1060  				err   string
  1061  			}{
  1062  				{
  1063  					PhysicalMachineChaos{
  1064  						Spec: PhysicalMachineChaosSpec{
  1065  							PhysicalMachineSelector: PhysicalMachineSelector{
  1066  								Address: []string{
  1067  									"123.123.123.123:123",
  1068  									"234.234.234.234:234",
  1069  								},
  1070  							},
  1071  							Action: "network",
  1072  							ExpInfo: ExpInfo{
  1073  								NetworkBandwidth: &NetworkBandwidthSpec{
  1074  									Rate:   "",
  1075  									Limit:  0,
  1076  									Buffer: 0,
  1077  								},
  1078  							},
  1079  						},
  1080  					},
  1081  					"rate is required",
  1082  				},
  1083  			}
  1084  
  1085  			for _, testCase := range testCases {
  1086  				_, err := testCase.chaos.ValidateCreate()
  1087  				Expect(strings.Contains(err.Error(), testCase.err)).To(BeTrue())
  1088  			}
  1089  		})
  1090  	})
  1091  })
  1092