How to use parse method of defaults Package

Best Rod code snippet using defaults.parse

defaults_test.go

Source:defaults_test.go Github

copy

Full Screen

1package defaults2import (3 "reflect"4 "testing"5 "k8s.io/api/core/v1"6 "k8s.io/apimachinery/pkg/api/resource"7 kapi "k8s.io/kubernetes/pkg/apis/core"8 kapihelper "k8s.io/kubernetes/pkg/apis/core/helper"9 buildadmission "github.com/openshift/origin/pkg/build/admission"10 u "github.com/openshift/origin/pkg/build/admission/testutil"11 buildapi "github.com/openshift/origin/pkg/build/apis/build"12 defaultsapi "github.com/openshift/origin/pkg/build/controller/build/apis/defaults"13 buildutil "github.com/openshift/origin/pkg/build/util"14 _ "github.com/openshift/origin/pkg/api/install"15)16func TestProxyDefaults(t *testing.T) {17 defaultsConfig := &defaultsapi.BuildDefaultsConfig{18 GitHTTPProxy: "http",19 GitHTTPSProxy: "https",20 GitNoProxy: "no",21 }22 admitter := BuildDefaults{defaultsConfig}23 pod := u.Pod().WithBuild(t, u.Build().WithDockerStrategy().AsBuild())24 err := admitter.ApplyDefaults((*v1.Pod)(pod))25 if err != nil {26 t.Fatalf("unexpected error: %v", err)27 }28 build, err := buildadmission.GetBuildFromPod((*v1.Pod)(pod))29 if err != nil {30 t.Fatalf("unexpected error: %v", err)31 }32 if build.Spec.Source.Git.HTTPProxy == nil || len(*build.Spec.Source.Git.HTTPProxy) == 0 || *build.Spec.Source.Git.HTTPProxy != "http" {33 t.Errorf("failed to find http proxy in git source")34 }35 if build.Spec.Source.Git.HTTPSProxy == nil || len(*build.Spec.Source.Git.HTTPSProxy) == 0 || *build.Spec.Source.Git.HTTPSProxy != "https" {36 t.Errorf("failed to find http proxy in git source")37 }38 if build.Spec.Source.Git.NoProxy == nil || len(*build.Spec.Source.Git.NoProxy) == 0 || *build.Spec.Source.Git.NoProxy != "no" {39 t.Errorf("failed to find no proxy setting in git source")40 }41}42func TestEnvDefaults(t *testing.T) {43 defaultsConfig := &defaultsapi.BuildDefaultsConfig{44 Env: []kapi.EnvVar{45 {46 Name: "VAR1",47 Value: "VALUE1",48 },49 {50 Name: "VAR2",51 Value: "VALUE2",52 },53 {54 Name: "GIT_SSL_NO_VERIFY",55 Value: "true",56 },57 },58 }59 admitter := BuildDefaults{defaultsConfig}60 pod := u.Pod().WithBuild(t, u.Build().WithSourceStrategy().AsBuild())61 err := admitter.ApplyDefaults((*v1.Pod)(pod))62 if err != nil {63 t.Fatalf("unexpected error: %v", err)64 }65 build, err := buildadmission.GetBuildFromPod((*v1.Pod)(pod))66 if err != nil {67 t.Fatalf("unexpected error: %v", err)68 }69 env := buildutil.GetBuildEnv(build)70 var1found, var2found := false, false71 for _, ev := range env {72 if ev.Name == "VAR1" {73 if ev.Value != "VALUE1" {74 t.Errorf("unexpected value %s", ev.Value)75 }76 var1found = true77 }78 if ev.Name == "VAR2" {79 if ev.Value != "VALUE2" {80 t.Errorf("unexpected value %s", ev.Value)81 }82 var2found = true83 }84 }85 if !var1found {86 t.Errorf("VAR1 not found")87 }88 if !var2found {89 t.Errorf("VAR2 not found")90 }91 gitSSL := false92 for _, ev := range pod.Spec.Containers[0].Env {93 if ev.Name == "VAR1" || ev.Name == "VAR2" {94 t.Errorf("non whitelisted key %v found", ev.Name)95 }96 if ev.Name == "GIT_SSL_NO_VERIFY" {97 gitSSL = true98 }99 }100 if !gitSSL {101 t.Errorf("GIT_SSL_NO_VERIFY key not found")102 }103}104func TestIncrementalDefaults(t *testing.T) {105 bool_t := true106 defaultsConfig := &defaultsapi.BuildDefaultsConfig{107 SourceStrategyDefaults: &defaultsapi.SourceStrategyDefaultsConfig{108 Incremental: &bool_t,109 },110 }111 admitter := BuildDefaults{defaultsConfig}112 pod := u.Pod().WithBuild(t, u.Build().WithSourceStrategy().AsBuild())113 err := admitter.ApplyDefaults((*v1.Pod)(pod))114 if err != nil {115 t.Fatalf("unexpected error: %v", err)116 }117 build, err := buildadmission.GetBuildFromPod((*v1.Pod)(pod))118 if err != nil {119 t.Fatalf("unexpected error: %v", err)120 }121 if !*build.Spec.Strategy.SourceStrategy.Incremental {122 t.Errorf("failed to default incremental to true")123 }124 build = u.Build().WithSourceStrategy().AsBuild()125 bool_f := false126 build.Spec.Strategy.SourceStrategy.Incremental = &bool_f127 pod = u.Pod().WithBuild(t, build)128 err = admitter.ApplyDefaults((*v1.Pod)(pod))129 if err != nil {130 t.Fatalf("unexpected error: %v", err)131 }132 build, err = buildadmission.GetBuildFromPod((*v1.Pod)(pod))133 if err != nil {134 t.Fatalf("unexpected error: %v", err)135 }136 if *build.Spec.Strategy.SourceStrategy.Incremental {137 t.Errorf("should not have overridden incremental to true")138 }139}140func TestLabelDefaults(t *testing.T) {141 tests := []struct {142 buildLabels []buildapi.ImageLabel143 defaultLabels []buildapi.ImageLabel144 expected []buildapi.ImageLabel145 }{146 {147 buildLabels: nil,148 defaultLabels: nil,149 expected: nil,150 },151 {152 buildLabels: nil,153 defaultLabels: []buildapi.ImageLabel{154 {155 Name: "distribution-scope",156 Value: "private",157 },158 {159 Name: "changelog-url",160 Value: "file:///dev/null",161 },162 },163 expected: []buildapi.ImageLabel{164 {165 Name: "distribution-scope",166 Value: "private",167 },168 {169 Name: "changelog-url",170 Value: "file:///dev/null",171 },172 },173 },174 {175 buildLabels: []buildapi.ImageLabel{176 {177 Name: "distribution-scope",178 Value: "private",179 },180 {181 Name: "changelog-url",182 Value: "file:///dev/null",183 },184 },185 defaultLabels: nil,186 expected: []buildapi.ImageLabel{187 {188 Name: "distribution-scope",189 Value: "private",190 },191 {192 Name: "changelog-url",193 Value: "file:///dev/null",194 },195 },196 },197 {198 buildLabels: []buildapi.ImageLabel{199 {200 Name: "distribution-scope",201 Value: "private",202 },203 },204 defaultLabels: []buildapi.ImageLabel{205 {206 Name: "distribution-scope",207 Value: "public",208 },209 {210 Name: "changelog-url",211 Value: "file:///dev/null",212 },213 },214 expected: []buildapi.ImageLabel{215 {216 Name: "distribution-scope",217 Value: "private",218 },219 {220 Name: "changelog-url",221 Value: "file:///dev/null",222 },223 },224 },225 {226 buildLabels: []buildapi.ImageLabel{227 {228 Name: "distribution-scope",229 Value: "private",230 },231 },232 defaultLabels: []buildapi.ImageLabel{233 {234 Name: "changelog-url",235 Value: "file:///dev/null",236 },237 },238 expected: []buildapi.ImageLabel{239 {240 Name: "distribution-scope",241 Value: "private",242 },243 {244 Name: "changelog-url",245 Value: "file:///dev/null",246 },247 },248 },249 }250 for i, test := range tests {251 defaultsConfig := &defaultsapi.BuildDefaultsConfig{252 ImageLabels: test.defaultLabels,253 }254 admitter := BuildDefaults{defaultsConfig}255 pod := u.Pod().WithBuild(t, u.Build().WithImageLabels(test.buildLabels).AsBuild())256 err := admitter.ApplyDefaults((*v1.Pod)(pod))257 if err != nil {258 t.Fatalf("unexpected error: %v", err)259 }260 build := pod.GetBuild(t)261 if err != nil {262 t.Fatalf("unexpected error: %v", err)263 }264 result := build.Spec.Output.ImageLabels265 if !reflect.DeepEqual(result, test.expected) {266 t.Errorf("expected[%d]: %v, got: %v", i, test.expected, result)267 }268 }269}270func TestBuildDefaultsNodeSelector(t *testing.T) {271 tests := []struct {272 name string273 build *buildapi.Build274 defaults map[string]string275 expected map[string]string276 }{277 {278 name: "build - full add",279 build: u.Build().AsBuild(),280 defaults: map[string]string{"key1": "default1", "key2": "default2"},281 expected: map[string]string{"key1": "default1", "key2": "default2"},282 },283 {284 name: "build - ignored",285 build: u.Build().WithNodeSelector(map[string]string{"key1": "value1"}).AsBuild(),286 defaults: map[string]string{"key1": "default1", "key2": "default2"},287 expected: map[string]string{"key1": "value1"},288 },289 {290 name: "build - empty(non-nil) nodeselector",291 build: u.Build().WithNodeSelector(map[string]string{}).AsBuild(),292 defaults: map[string]string{"key1": "default1"},293 expected: map[string]string{},294 },295 }296 for _, test := range tests {297 defaults := BuildDefaults{config: &defaultsapi.BuildDefaultsConfig{NodeSelector: test.defaults}}298 pod := u.Pod().WithBuild(t, test.build)299 // normally the pod will have the nodeselectors from the build, due to the pod creation logic300 // in the build controller flow. fake it out here.301 pod.Spec.NodeSelector = test.build.Spec.NodeSelector302 err := defaults.ApplyDefaults((*v1.Pod)(pod))303 if err != nil {304 t.Errorf("%s: unexpected error: %v", test.name, err)305 }306 if len(pod.Spec.NodeSelector) != len(test.expected) {307 t.Errorf("%s: incorrect number of selectors, expected %v, got %v", test.name, test.expected, pod.Spec.NodeSelector)308 }309 for k, v := range pod.Spec.NodeSelector {310 if ev, ok := test.expected[k]; !ok || ev != v {311 t.Errorf("%s: incorrect selector value for key %s, expected %s, got %s", test.name, k, ev, v)312 }313 }314 }315}316func TestBuildDefaultsAnnotations(t *testing.T) {317 tests := []struct {318 name string319 build *buildapi.Build320 annotations map[string]string321 defaults map[string]string322 expected map[string]string323 }{324 {325 name: "build - nil annotations",326 build: u.Build().AsBuild(),327 annotations: nil,328 defaults: map[string]string{"key1": "default1", "key2": "default2"},329 expected: map[string]string{"key1": "default1", "key2": "default2"},330 },331 {332 name: "build - full add",333 build: u.Build().AsBuild(),334 annotations: map[string]string{"key3": "value3"},335 defaults: map[string]string{"key1": "default1", "key2": "default2"},336 expected: map[string]string{"key1": "default1", "key2": "default2", "key3": "value3"},337 },338 {339 name: "build - partial add",340 build: u.Build().AsBuild(),341 annotations: map[string]string{"key1": "value1"},342 defaults: map[string]string{"key1": "default1", "key2": "default2"},343 expected: map[string]string{"key1": "value1", "key2": "default2"},344 },345 }346 for _, test := range tests {347 defaults := BuildDefaults{config: &defaultsapi.BuildDefaultsConfig{Annotations: test.defaults}}348 pod := u.Pod().WithBuild(t, test.build)349 pod.Annotations = test.annotations350 err := defaults.ApplyDefaults((*v1.Pod)(pod))351 if err != nil {352 t.Errorf("%s: unexpected error: %v", test.name, err)353 }354 if len(pod.Annotations) != len(test.expected) {355 t.Errorf("%s: incorrect number of annotations, expected %v, got %v", test.name, test.expected, pod.Annotations)356 }357 for k, v := range pod.Annotations {358 if ev, ok := test.expected[k]; !ok || ev != v {359 t.Errorf("%s: incorrect annotation value for key %s, expected %s, got %s", test.name, k, ev, v)360 }361 }362 }363}364func TestResourceDefaults(t *testing.T) {365 tests := map[string]struct {366 DefaultResource kapi.ResourceRequirements367 BuildResource kapi.ResourceRequirements368 ExpectedResource kapi.ResourceRequirements369 }{370 "BuildDefaults plugin and Build object both defined resource limits and requests": {371 DefaultResource: kapi.ResourceRequirements{372 Limits: kapi.ResourceList{373 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),374 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),375 },376 Requests: kapi.ResourceList{377 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),378 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),379 },380 },381 BuildResource: kapi.ResourceRequirements{382 Limits: kapi.ResourceList{383 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),384 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),385 },386 Requests: kapi.ResourceList{387 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("40"),388 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("4G"),389 },390 },391 ExpectedResource: kapi.ResourceRequirements{392 Limits: kapi.ResourceList{393 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),394 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),395 },396 Requests: kapi.ResourceList{397 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("40"),398 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("4G"),399 },400 },401 },402 "BuildDefaults plugin defined limits and requests, Build object defined resource requests": {403 DefaultResource: kapi.ResourceRequirements{404 Limits: kapi.ResourceList{405 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),406 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),407 },408 Requests: kapi.ResourceList{409 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),410 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),411 },412 },413 BuildResource: kapi.ResourceRequirements{414 Requests: kapi.ResourceList{415 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),416 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),417 },418 },419 ExpectedResource: kapi.ResourceRequirements{420 Limits: kapi.ResourceList{421 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),422 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),423 },424 Requests: kapi.ResourceList{425 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),426 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),427 },428 },429 },430 "BuildDefaults plugin defined limits and requests, Build object defined resource limits": {431 DefaultResource: kapi.ResourceRequirements{432 Limits: kapi.ResourceList{433 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),434 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),435 },436 Requests: kapi.ResourceList{437 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),438 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),439 },440 },441 BuildResource: kapi.ResourceRequirements{442 Limits: kapi.ResourceList{443 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),444 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),445 },446 },447 ExpectedResource: kapi.ResourceRequirements{448 Limits: kapi.ResourceList{449 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),450 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),451 },452 Requests: kapi.ResourceList{453 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),454 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),455 },456 },457 },458 "BuildDefaults plugin defined nothing, Build object defined resource limits": {459 DefaultResource: kapi.ResourceRequirements{},460 BuildResource: kapi.ResourceRequirements{461 Limits: kapi.ResourceList{462 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),463 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),464 },465 Requests: kapi.ResourceList{466 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),467 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),468 },469 },470 ExpectedResource: kapi.ResourceRequirements{471 Limits: kapi.ResourceList{472 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),473 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),474 },475 Requests: kapi.ResourceList{476 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),477 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),478 },479 },480 },481 "BuildDefaults plugin and Build object defined nothing": {482 DefaultResource: kapi.ResourceRequirements{},483 BuildResource: kapi.ResourceRequirements{},484 ExpectedResource: kapi.ResourceRequirements{},485 },486 "BuildDefaults plugin defined limits and requests, Build object defined nothing": {487 DefaultResource: kapi.ResourceRequirements{488 Limits: kapi.ResourceList{489 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),490 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),491 },492 Requests: kapi.ResourceList{493 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),494 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),495 },496 },497 BuildResource: kapi.ResourceRequirements{},498 ExpectedResource: kapi.ResourceRequirements{499 Limits: kapi.ResourceList{500 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),501 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),502 },503 Requests: kapi.ResourceList{504 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),505 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),506 },507 },508 },509 "BuildDefaults plugin defined part of limits and requests, Build object defined part of limits and requests": {510 DefaultResource: kapi.ResourceRequirements{511 Limits: kapi.ResourceList{512 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),513 },514 Requests: kapi.ResourceList{515 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),516 },517 },518 BuildResource: kapi.ResourceRequirements{519 Limits: kapi.ResourceList{520 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),521 },522 Requests: kapi.ResourceList{523 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),524 },525 },526 ExpectedResource: kapi.ResourceRequirements{527 Limits: kapi.ResourceList{528 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),529 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),530 },531 Requests: kapi.ResourceList{532 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),533 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),534 },535 },536 },537 }538 for name, test := range tests {539 defaults := BuildDefaults{config: &defaultsapi.BuildDefaultsConfig{Resources: test.DefaultResource}}540 build := u.Build().WithSourceStrategy().AsBuild()541 build.Spec.Resources = test.BuildResource542 pod := u.Pod().WithBuild(t, build)543 // normally the buildconfig resources would be applied to the pod544 // when it was created, but this pod didn't get created by the normal545 // pod creation flow, so fake this out.546 for i := range pod.Spec.InitContainers {547 pod.Spec.InitContainers[i].Resources = buildutil.CopyApiResourcesToV1Resources(&test.BuildResource)548 }549 for i := range pod.Spec.Containers {550 pod.Spec.Containers[i].Resources = buildutil.CopyApiResourcesToV1Resources(&test.BuildResource)551 }552 err := defaults.ApplyDefaults((*v1.Pod)(pod))553 if err != nil {554 t.Fatalf("%v :unexpected error: %v", name, err)555 }556 build, err = buildadmission.GetBuildFromPod((*v1.Pod)(pod))557 if err != nil {558 t.Fatalf("%v :unexpected error: %v", name, err)559 }560 if !kapihelper.Semantic.DeepEqual(test.ExpectedResource, build.Spec.Resources) {561 t.Fatalf("%v:Build resource expected expected=actual, %#v != %#v", name, test.ExpectedResource, build.Spec.Resources)562 }563 allContainers := append([]v1.Container{}, pod.Spec.Containers...)564 allContainers = append(allContainers, pod.Spec.InitContainers...)565 for i, c := range allContainers {566 if !kapihelper.Semantic.DeepEqual(buildutil.CopyApiResourcesToV1Resources(&test.ExpectedResource), c.Resources) {567 t.Fatalf("%v: Pod container %d resource expected expected=actual, got expected:\n%#v\nactual:\n%#v", name, i, test.ExpectedResource, c.Resources)568 }569 }570 }571}...

Full Screen

Full Screen

admission_test.go

Source:admission_test.go Github

copy

Full Screen

1package defaults2import (3 "reflect"4 "testing"5 kapi "k8s.io/kubernetes/pkg/api"6 buildadmission "github.com/openshift/origin/pkg/build/admission"7 defaultsapi "github.com/openshift/origin/pkg/build/admission/defaults/api"8 u "github.com/openshift/origin/pkg/build/admission/testutil"9 buildapi "github.com/openshift/origin/pkg/build/api"10 _ "github.com/openshift/origin/pkg/api/install"11 "k8s.io/kubernetes/pkg/api/resource"12)13func TestProxyDefaults(t *testing.T) {14 defaultsConfig := &defaultsapi.BuildDefaultsConfig{15 GitHTTPProxy: "http",16 GitHTTPSProxy: "https",17 GitNoProxy: "no",18 }19 admitter := BuildDefaults{defaultsConfig}20 pod := u.Pod().WithBuild(t, u.Build().WithDockerStrategy().AsBuild(), "v1")21 err := admitter.ApplyDefaults((*kapi.Pod)(pod))22 if err != nil {23 t.Fatalf("unexpected error: %v", err)24 }25 build, _, err := buildadmission.GetBuildFromPod((*kapi.Pod)(pod))26 if err != nil {27 t.Fatalf("unexpected error: %v", err)28 }29 if build.Spec.Source.Git.HTTPProxy == nil || len(*build.Spec.Source.Git.HTTPProxy) == 0 || *build.Spec.Source.Git.HTTPProxy != "http" {30 t.Errorf("failed to find http proxy in git source")31 }32 if build.Spec.Source.Git.HTTPSProxy == nil || len(*build.Spec.Source.Git.HTTPSProxy) == 0 || *build.Spec.Source.Git.HTTPSProxy != "https" {33 t.Errorf("failed to find http proxy in git source")34 }35 if build.Spec.Source.Git.NoProxy == nil || len(*build.Spec.Source.Git.NoProxy) == 0 || *build.Spec.Source.Git.NoProxy != "no" {36 t.Errorf("failed to find no proxy setting in git source")37 }38}39func TestEnvDefaults(t *testing.T) {40 defaultsConfig := &defaultsapi.BuildDefaultsConfig{41 Env: []kapi.EnvVar{42 {43 Name: "VAR1",44 Value: "VALUE1",45 },46 {47 Name: "VAR2",48 Value: "VALUE2",49 },50 },51 }52 admitter := BuildDefaults{defaultsConfig}53 pod := u.Pod().WithBuild(t, u.Build().WithSourceStrategy().AsBuild(), "v1")54 err := admitter.ApplyDefaults((*kapi.Pod)(pod))55 if err != nil {56 t.Fatalf("unexpected error: %v", err)57 }58 build, _, err := buildadmission.GetBuildFromPod((*kapi.Pod)(pod))59 if err != nil {60 t.Fatalf("unexpected error: %v", err)61 }62 env := getBuildEnv(build)63 var1found, var2found := false, false64 for _, ev := range *env {65 if ev.Name == "VAR1" {66 if ev.Value != "VALUE1" {67 t.Errorf("unexpected value %s", ev.Value)68 }69 var1found = true70 }71 if ev.Name == "VAR2" {72 if ev.Value != "VALUE2" {73 t.Errorf("unexpected value %s", ev.Value)74 }75 var2found = true76 }77 }78 if !var1found {79 t.Errorf("VAR1 not found")80 }81 if !var2found {82 t.Errorf("VAR2 not found")83 }84}85func TestIncrementalDefaults(t *testing.T) {86 bool_t := true87 defaultsConfig := &defaultsapi.BuildDefaultsConfig{88 SourceStrategyDefaults: &defaultsapi.SourceStrategyDefaultsConfig{89 Incremental: &bool_t,90 },91 }92 admitter := BuildDefaults{defaultsConfig}93 pod := u.Pod().WithBuild(t, u.Build().WithSourceStrategy().AsBuild(), "v1")94 err := admitter.ApplyDefaults((*kapi.Pod)(pod))95 if err != nil {96 t.Fatalf("unexpected error: %v", err)97 }98 build, _, err := buildadmission.GetBuildFromPod((*kapi.Pod)(pod))99 if err != nil {100 t.Fatalf("unexpected error: %v", err)101 }102 if !*build.Spec.Strategy.SourceStrategy.Incremental {103 t.Errorf("failed to default incremental to true")104 }105 build = u.Build().WithSourceStrategy().AsBuild()106 bool_f := false107 build.Spec.Strategy.SourceStrategy.Incremental = &bool_f108 pod = u.Pod().WithBuild(t, build, "v1")109 err = admitter.ApplyDefaults((*kapi.Pod)(pod))110 if err != nil {111 t.Fatalf("unexpected error: %v", err)112 }113 build, _, err = buildadmission.GetBuildFromPod((*kapi.Pod)(pod))114 if err != nil {115 t.Fatalf("unexpected error: %v", err)116 }117 if *build.Spec.Strategy.SourceStrategy.Incremental {118 t.Errorf("should not have overridden incremental to true")119 }120}121func TestLabelDefaults(t *testing.T) {122 tests := []struct {123 buildLabels []buildapi.ImageLabel124 defaultLabels []buildapi.ImageLabel125 expected []buildapi.ImageLabel126 }{127 {128 buildLabels: nil,129 defaultLabels: nil,130 expected: nil,131 },132 {133 buildLabels: nil,134 defaultLabels: []buildapi.ImageLabel{135 {136 Name: "distribution-scope",137 Value: "private",138 },139 {140 Name: "changelog-url",141 Value: "file:///dev/null",142 },143 },144 expected: []buildapi.ImageLabel{145 {146 Name: "distribution-scope",147 Value: "private",148 },149 {150 Name: "changelog-url",151 Value: "file:///dev/null",152 },153 },154 },155 {156 buildLabels: []buildapi.ImageLabel{157 {158 Name: "distribution-scope",159 Value: "private",160 },161 {162 Name: "changelog-url",163 Value: "file:///dev/null",164 },165 },166 defaultLabels: nil,167 expected: []buildapi.ImageLabel{168 {169 Name: "distribution-scope",170 Value: "private",171 },172 {173 Name: "changelog-url",174 Value: "file:///dev/null",175 },176 },177 },178 {179 buildLabels: []buildapi.ImageLabel{180 {181 Name: "distribution-scope",182 Value: "private",183 },184 },185 defaultLabels: []buildapi.ImageLabel{186 {187 Name: "distribution-scope",188 Value: "public",189 },190 {191 Name: "changelog-url",192 Value: "file:///dev/null",193 },194 },195 expected: []buildapi.ImageLabel{196 {197 Name: "distribution-scope",198 Value: "private",199 },200 {201 Name: "changelog-url",202 Value: "file:///dev/null",203 },204 },205 },206 {207 buildLabels: []buildapi.ImageLabel{208 {209 Name: "distribution-scope",210 Value: "private",211 },212 },213 defaultLabels: []buildapi.ImageLabel{214 {215 Name: "changelog-url",216 Value: "file:///dev/null",217 },218 },219 expected: []buildapi.ImageLabel{220 {221 Name: "distribution-scope",222 Value: "private",223 },224 {225 Name: "changelog-url",226 Value: "file:///dev/null",227 },228 },229 },230 }231 for i, test := range tests {232 defaultsConfig := &defaultsapi.BuildDefaultsConfig{233 ImageLabels: test.defaultLabels,234 }235 admitter := BuildDefaults{defaultsConfig}236 pod := u.Pod().WithBuild(t, u.Build().WithImageLabels(test.buildLabels).AsBuild(), "v1")237 err := admitter.ApplyDefaults((*kapi.Pod)(pod))238 if err != nil {239 t.Fatalf("unexpected error: %v", err)240 }241 build := pod.GetBuild(t)242 if err != nil {243 t.Fatalf("unexpected error: %v", err)244 }245 result := build.Spec.Output.ImageLabels246 if !reflect.DeepEqual(result, test.expected) {247 t.Errorf("expected[%d]: %v, got: %v", i, test.expected, result)248 }249 }250}251func TestBuildDefaultsNodeSelector(t *testing.T) {252 tests := []struct {253 name string254 build *buildapi.Build255 defaults map[string]string256 expected map[string]string257 }{258 {259 name: "build - full add",260 build: u.Build().AsBuild(),261 defaults: map[string]string{"key1": "default1", "key2": "default2"},262 expected: map[string]string{"key1": "default1", "key2": "default2"},263 },264 {265 name: "build - ignored",266 build: u.Build().WithNodeSelector(map[string]string{"key1": "value1"}).AsBuild(),267 defaults: map[string]string{"key1": "default1", "key2": "default2"},268 expected: map[string]string{"key1": "value1"},269 },270 {271 name: "build - empty(non-nil) nodeselector",272 build: u.Build().WithNodeSelector(map[string]string{}).AsBuild(),273 defaults: map[string]string{"key1": "default1"},274 expected: map[string]string{},275 },276 }277 for _, test := range tests {278 defaults := BuildDefaults{config: &defaultsapi.BuildDefaultsConfig{NodeSelector: test.defaults}}279 pod := u.Pod().WithBuild(t, test.build, "v1")280 // normally the pod will have the nodeselectors from the build, due to the pod creation logic281 // in the build controller flow. fake it out here.282 pod.Spec.NodeSelector = test.build.Spec.NodeSelector283 err := defaults.ApplyDefaults((*kapi.Pod)(pod))284 if err != nil {285 t.Errorf("%s: unexpected error: %v", test.name, err)286 }287 if len(pod.Spec.NodeSelector) != len(test.expected) {288 t.Errorf("%s: incorrect number of selectors, expected %v, got %v", test.name, test.expected, pod.Spec.NodeSelector)289 }290 for k, v := range pod.Spec.NodeSelector {291 if ev, ok := test.expected[k]; !ok || ev != v {292 t.Errorf("%s: incorrect selector value for key %s, expected %s, got %s", test.name, k, ev, v)293 }294 }295 }296}297func TestBuildDefaultsAnnotations(t *testing.T) {298 tests := []struct {299 name string300 build *buildapi.Build301 annotations map[string]string302 defaults map[string]string303 expected map[string]string304 }{305 {306 name: "build - nil annotations",307 build: u.Build().AsBuild(),308 annotations: nil,309 defaults: map[string]string{"key1": "default1", "key2": "default2"},310 expected: map[string]string{"key1": "default1", "key2": "default2"},311 },312 {313 name: "build - full add",314 build: u.Build().AsBuild(),315 annotations: map[string]string{"key3": "value3"},316 defaults: map[string]string{"key1": "default1", "key2": "default2"},317 expected: map[string]string{"key1": "default1", "key2": "default2", "key3": "value3"},318 },319 {320 name: "build - partial add",321 build: u.Build().AsBuild(),322 annotations: map[string]string{"key1": "value1"},323 defaults: map[string]string{"key1": "default1", "key2": "default2"},324 expected: map[string]string{"key1": "value1", "key2": "default2"},325 },326 }327 for _, test := range tests {328 defaults := BuildDefaults{config: &defaultsapi.BuildDefaultsConfig{Annotations: test.defaults}}329 pod := u.Pod().WithBuild(t, test.build, "v1")330 pod.Annotations = test.annotations331 err := defaults.ApplyDefaults((*kapi.Pod)(pod))332 if err != nil {333 t.Errorf("%s: unexpected error: %v", test.name, err)334 }335 if len(pod.Annotations) != len(test.expected) {336 t.Errorf("%s: incorrect number of annotations, expected %v, got %v", test.name, test.expected, pod.Annotations)337 }338 for k, v := range pod.Annotations {339 if ev, ok := test.expected[k]; !ok || ev != v {340 t.Errorf("%s: incorrect annotation value for key %s, expected %s, got %s", test.name, k, ev, v)341 }342 }343 }344}345func TestResourceDefaults(t *testing.T) {346 tests := map[string]struct {347 DefaultResource kapi.ResourceRequirements348 BuildResource kapi.ResourceRequirements349 ExpectedResource kapi.ResourceRequirements350 }{351 "BuildDefaults plugin and Build object both defined resource limits and requests": {352 DefaultResource: kapi.ResourceRequirements{353 Limits: kapi.ResourceList{354 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),355 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),356 },357 Requests: kapi.ResourceList{358 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),359 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),360 },361 },362 BuildResource: kapi.ResourceRequirements{363 Limits: kapi.ResourceList{364 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),365 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),366 },367 Requests: kapi.ResourceList{368 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("40"),369 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("4G"),370 },371 },372 ExpectedResource: kapi.ResourceRequirements{373 Limits: kapi.ResourceList{374 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),375 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),376 },377 Requests: kapi.ResourceList{378 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("40"),379 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("4G"),380 },381 },382 },383 "BuildDefaults plugin defined limits and requests, Build object defined resource requests": {384 DefaultResource: kapi.ResourceRequirements{385 Limits: kapi.ResourceList{386 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),387 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),388 },389 Requests: kapi.ResourceList{390 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),391 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),392 },393 },394 BuildResource: kapi.ResourceRequirements{395 Requests: kapi.ResourceList{396 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),397 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),398 },399 },400 ExpectedResource: kapi.ResourceRequirements{401 Limits: kapi.ResourceList{402 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),403 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),404 },405 Requests: kapi.ResourceList{406 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),407 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),408 },409 },410 },411 "BuildDefaults plugin defined limits and requests, Build object defined resource limits": {412 DefaultResource: kapi.ResourceRequirements{413 Limits: kapi.ResourceList{414 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),415 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),416 },417 Requests: kapi.ResourceList{418 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),419 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),420 },421 },422 BuildResource: kapi.ResourceRequirements{423 Limits: kapi.ResourceList{424 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),425 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),426 },427 },428 ExpectedResource: kapi.ResourceRequirements{429 Limits: kapi.ResourceList{430 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),431 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("3G"),432 },433 Requests: kapi.ResourceList{434 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),435 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),436 },437 },438 },439 "BuildDefaults plugin defined nothing, Build object defined resource limits": {440 DefaultResource: kapi.ResourceRequirements{},441 BuildResource: kapi.ResourceRequirements{442 Limits: kapi.ResourceList{443 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),444 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),445 },446 Requests: kapi.ResourceList{447 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),448 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),449 },450 },451 ExpectedResource: kapi.ResourceRequirements{452 Limits: kapi.ResourceList{453 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),454 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),455 },456 Requests: kapi.ResourceList{457 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),458 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),459 },460 },461 },462 "BuildDefaults plugin and Build object defined nothing": {463 DefaultResource: kapi.ResourceRequirements{},464 BuildResource: kapi.ResourceRequirements{},465 ExpectedResource: kapi.ResourceRequirements{},466 },467 "BuildDefaults plugin defined limits and requests, Build object defined nothing": {468 DefaultResource: kapi.ResourceRequirements{469 Limits: kapi.ResourceList{470 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),471 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),472 },473 Requests: kapi.ResourceList{474 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),475 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),476 },477 },478 BuildResource: kapi.ResourceRequirements{},479 ExpectedResource: kapi.ResourceRequirements{480 Limits: kapi.ResourceList{481 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),482 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),483 },484 Requests: kapi.ResourceList{485 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("20"),486 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),487 },488 },489 },490 "BuildDefaults plugin defined part of limits and requests, Build object defined part of limits and requests": {491 DefaultResource: kapi.ResourceRequirements{492 Limits: kapi.ResourceList{493 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),494 },495 Requests: kapi.ResourceList{496 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),497 },498 },499 BuildResource: kapi.ResourceRequirements{500 Limits: kapi.ResourceList{501 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),502 },503 Requests: kapi.ResourceList{504 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),505 },506 },507 ExpectedResource: kapi.ResourceRequirements{508 Limits: kapi.ResourceList{509 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("10"),510 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("1G"),511 },512 Requests: kapi.ResourceList{513 kapi.ResourceName(kapi.ResourceCPU): resource.MustParse("30"),514 kapi.ResourceName(kapi.ResourceMemory): resource.MustParse("2G"),515 },516 },517 },518 }519 for name, test := range tests {520 defaults := BuildDefaults{config: &defaultsapi.BuildDefaultsConfig{Resources: test.DefaultResource}}521 build := u.Build().WithSourceStrategy().AsBuild()522 build.Spec.Resources = test.BuildResource523 pod := u.Pod().WithBuild(t, build, "v1")524 err := defaults.ApplyDefaults((*kapi.Pod)(pod))525 if err != nil {526 t.Fatalf("%v :unexpected error: %v", name, err)527 }528 build, _, err = buildadmission.GetBuildFromPod((*kapi.Pod)(pod))529 if err != nil {530 t.Fatalf("%v :unexpected error: %v", name, err)531 }532 if !kapi.Semantic.DeepEqual(test.ExpectedResource, build.Spec.Resources) {533 t.Fatalf("%v:Expected expected=actual, %v != %v", name, test.ExpectedResource, build.Spec.Resources)534 }535 }536}...

Full Screen

Full Screen

parse_defaults_file.go

Source:parse_defaults_file.go Github

copy

Full Screen

...21 "github.com/percona/pmm/api/inventorypb"22 "github.com/percona/pmm/managed/models"23 "github.com/percona/pmm/managed/utils/logger"24)25// DefaultsFileParser requests from agent to parse defaultsFile.26type DefaultsFileParser struct {27 r *Registry28}29// NewDefaultsFileParser creates new ParseDefaultsFile request.30func NewDefaultsFileParser(r *Registry) *DefaultsFileParser {31 return &DefaultsFileParser{32 r: r,33 }34}35// ParseDefaultsFile sends request (with file path) to pmm-agent to parse defaults file.36func (p *DefaultsFileParser) ParseDefaultsFile(ctx context.Context, pmmAgentID, filePath string, serviceType models.ServiceType) (*models.ParseDefaultsFileResult, error) {37 l := logger.Get(ctx)38 pmmAgent, err := p.r.get(pmmAgentID)39 if err != nil {40 return nil, err41 }42 start := time.Now()43 defer func() {44 if dur := time.Since(start); dur > 5*time.Second {45 l.Warnf("ParseDefaultsFile took %s.", dur)46 }47 }()48 request, err := createRequest(filePath, serviceType)49 if err != nil {50 l.Debugf("can't create ParseDefaultsFileRequest %s", err)51 return nil, err52 }53 resp, err := pmmAgent.channel.SendAndWaitResponse(request)54 if err != nil {55 return nil, err56 }57 l.Infof("ParseDefaultsFile response from agent: %+v.", resp)58 parserResponse, ok := resp.(*agentpb.ParseDefaultsFileResponse)59 if !ok {60 return nil, errors.New("wrong response from agent (not ParseDefaultsFileResponse model)")61 }62 if parserResponse.Error != "" {63 return nil, errors.New(parserResponse.Error)64 }65 return &models.ParseDefaultsFileResult{66 Username: parserResponse.Username,67 Password: parserResponse.Password,68 Host: parserResponse.Host,69 Port: parserResponse.Port,70 Socket: parserResponse.Socket,71 }, nil72}73func createRequest(configPath string, serviceType models.ServiceType) (*agentpb.ParseDefaultsFileRequest, error) {74 if serviceType == models.MySQLServiceType {75 request := &agentpb.ParseDefaultsFileRequest{76 ServiceType: inventorypb.ServiceType_MYSQL_SERVICE,77 ConfigPath: configPath,78 }79 return request, nil80 } else {81 return nil, errors.Errorf("unhandled service type %s", serviceType)82 }83}...

Full Screen

Full Screen

parse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 p := properties.MustLoadFile("1.properties", properties.UTF8)4 fmt.Println(p.Get("name"))5 fmt.Println(p.Get("age"))6}7import (8func main() {9 p := properties.MustLoadFile("1.properties", properties.UTF8)10 m := p.Map()11 fmt.Println(m)12}13import (14func main() {15 p := properties.MustLoadFile("1.properties", properties.UTF8)16 m := p.Map()17 fmt.Println(m)18}19import (20func main() {21 p := properties.MustLoadFile("1.properties", properties.UTF8)22 m := p.Map()23 fmt.Println(m)24}25import (26func main()

Full Screen

Full Screen

parse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 flag.StringVar(&svar, "svar", "bar", "a string var")4 flag.Parse()5 fmt.Println("svar:", svar)6 fmt.Println("tail:", flag.Args())7}8import (9func main() {10 flag.StringVar(&svar, "svar", "bar", "a string var")11 flag.Parse()12 fmt.Println("svar:", svar)13 fmt.Println("tail:", flag.Args())14}15import (16func main() {17 flag.StringVar(&svar, "svar", "bar", "a string var")18 flag.Parse()19 fmt.Println("svar:", svar)20 fmt.Println("tail:", flag.Args())21}22import (23func main() {24 flag.StringVar(&svar, "svar", "bar", "a string var")25 flag.Parse()26 fmt.Println("svar:", svar)27 fmt.Println("tail:", flag.Args())28}29import (30func main() {31 flag.StringVar(&svar, "svar", "bar", "a string var")32 flag.Parse()33 fmt.Println("svar:", svar)34 fmt.Println("tail:", flag.Args())35}36import (37func main() {38 flag.StringVar(&svar, "svar", "bar", "a string var")39 flag.Parse()40 fmt.Println("svar:", svar)41 fmt.Println("tail:", flag.Args())42}

Full Screen

Full Screen

parse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 app := cli.NewApp()4 app.Action = func(c *cli.Context) error {5 fmt.Println("default values")6 }7 app.Flags = []cli.Flag {8 cli.StringFlag{9 },10 }11 app.Run(os.Args)12}

Full Screen

Full Screen

parse

Using AI Code Generation

copy

Full Screen

1import (2type Config struct {3}4func main() {5 c := Config{}6 defaults.SetDefaults(&c)7 fmt.Println(c.Host)8}

Full Screen

Full Screen

parse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 def := defaults.New()4 s := &struct {5 }{}6 def.Parse(s)7 fmt.Println("String =", s.Str)8 fmt.Println("Int =", s.Int)9 fmt.Println("Float =", s.Float)10 fmt.Println("Bool =", s.Bool)11 fmt.Println("Time =", s.Time)12 fmt.Println("Duration =", s.Duration)13}14import (15func main() {16 def := defaults.New()17 s := &struct {

Full Screen

Full Screen

parse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 flag.StringVar(&str, "str", "default value", "string variable")4 flag.Parse()5 fmt.Println("String:", str)6}7flag.Set(name, value string) error8import (9func main() {10 flag.StringVar(&str, "str", "default value", "string variable")11 flag.Parse()12 fmt.Println("String:", str)13 flag.Set("str", "new value")14 flag.Parse()15 fmt.Println("String:", str)16}17flag.Get(name string) string18import (19func main() {

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Rod automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful