// PrepareAppConfig sets fields in config appropriate for running tests. It // returns two buffers bound to stdout and stderr. func PrepareAppConfig(config *cmd.AppConfig) (stdout, stderr *bytes.Buffer) { config.ExpectToBuild = true stdout, stderr = new(bytes.Buffer), new(bytes.Buffer) config.Out, config.ErrOut = stdout, stderr config.Detector = app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), } config.DockerSearcher = app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(10*time.Second, true), } config.ImageStreamByAnnotationSearcher = fakeImageStreamSearcher() config.ImageStreamSearcher = fakeImageStreamSearcher() config.OriginNamespace = "default" config.OSClient = &client.Fake{} config.RefBuilder = &app.ReferenceBuilder{} config.TemplateSearcher = app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, } config.Typer = kapi.Scheme return }
func TestNewBuildEnvVars(t *testing.T) { dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected []kapi.EnvVar expectedErr error }{ { name: "explicit environment variables for buildConfig and deploymentConfig", config: &AppConfig{ AddEnvironmentToBuild: true, SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), DockerImages: util.StringList([]string{"openshift/ruby-20-centos7", "openshift/mongodb-24-centos7"}), OutputDocker: true, Environment: util.StringList([]string{"BUILD_ENV_1=env_value_1", "BUILD_ENV_2=env_value_2"}), dockerSearcher: dockerSearcher, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: []kapi.EnvVar{ {Name: "BUILD_ENV_1", Value: "env_value_1"}, {Name: "BUILD_ENV_2", Value: "env_value_2"}, }, expectedErr: nil, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} test.config.Out, test.config.ErrOut = os.Stdout, os.Stderr res, err := test.config.RunBuilds() if err != test.expectedErr { t.Errorf("%s: Error mismatch! Expected %v, got %v", test.name, test.expectedErr, err) continue } got := []kapi.EnvVar{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got = tp.Spec.Strategy.SourceStrategy.Env break } } if !reflect.DeepEqual(test.expected, got) { t.Errorf("%s: unexpected output. Expected: %#v, Got: %#v", test.name, test.expected, got) continue } } }
// NewAppConfig returns a new AppConfig, but you must set your typer, mapper, and clientMapper after the command has been run // and flags have been parsed. func NewAppConfig() *AppConfig { return &AppConfig{ detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, refBuilder: &app.ReferenceBuilder{}, } }
// NewAppConfig returns a new AppConfig, but you must set your typer, mapper, and clientMapper after the command has been run // and flags have been parsed. func NewAppConfig() *AppConfig { return &AppConfig{ Resolvers: Resolvers{ Detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, }, } }
func TestNewAppDetectSource(t *testing.T) { skipExternalGit(t) gitLocalDir := createLocalGitDirectory(t) defer os.RemoveAll(gitLocalDir) dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(10*time.Second, true), } mocks := MockSourceRepositories(t, gitLocalDir) tests := []struct { name string cfg *cmd.AppConfig repositories []*app.SourceRepository expectedLang string expectedErr string }{ { name: "detect source - ruby", cfg: &cmd.AppConfig{ Detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, DockerSearcher: dockerSearcher, }, repositories: []*app.SourceRepository{mocks[0]}, expectedLang: "ruby", expectedErr: "", }, } for _, test := range tests { err := test.cfg.DetectSource(test.repositories) if err != nil { if !strings.Contains(err.Error(), test.expectedErr) { t.Errorf("%s: Invalid error: Expected %s, got %v", test.name, test.expectedErr, err) } } else if len(test.expectedErr) != 0 { t.Errorf("%s: Expected %s error but got none", test.name, test.expectedErr) } for _, repo := range test.repositories { info := repo.Info() if info == nil { t.Errorf("%s: expected repository info to be populated; it is nil", test.name) continue } if term := strings.Join(info.Terms(), ","); term != test.expectedLang { t.Errorf("%s: expected repository info term to be %s; got %s\n", test.name, test.expectedLang, term) } } } }
// NewAppConfig returns a new AppConfig, but you must set your typer, mapper, and clientMapper after the command has been run // and flags have been parsed. func NewAppConfig() *AppConfig { dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } return &AppConfig{ detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, dockerSearcher: dockerSearcher, refBuilder: &app.ReferenceBuilder{}, } }
func TestDetectSource(t *testing.T) { dockerResolver := app.DockerRegistryResolver{ Client: dockerregistry.NewClient(), } mocks := app.MockSourceRepositories() tests := []struct { name string cfg *AppConfig repositories []*app.SourceRepository expectedLang string expectedErr string }{ { name: "detect source - ruby", cfg: &AppConfig{ detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, dockerResolver: dockerResolver, }, repositories: []*app.SourceRepository{mocks[1]}, expectedLang: "ruby", expectedErr: "", }, } for _, test := range tests { err := test.cfg.detectSource(test.repositories) if err != nil { if !strings.Contains(err.Error(), test.expectedErr) { t.Errorf("%s: Invalid error: Expected %s, got %v", test.name, test.expectedErr, err) } } else if len(test.expectedErr) != 0 { t.Errorf("%s: Expected %s error but got none", test.name, test.expectedErr) } for _, repo := range test.repositories { info := repo.Info() if info == nil { t.Errorf("%s: expected repository info to be populated; it is nil", test.name) continue } if term := strings.Join(info.Terms(), ","); term != test.expectedLang { t.Errorf("%s: expected repository info term to be %s; got %s\n", test.name, test.expectedLang, term) } } } }
// NewAppConfig returns a new AppConfig func NewAppConfig(typer runtime.ObjectTyper, mapper meta.RESTMapper, clientMapper resource.ClientMapper) *AppConfig { dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } return &AppConfig{ detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, dockerSearcher: dockerSearcher, typer: typer, mapper: mapper, clientMapper: clientMapper, refBuilder: &app.ReferenceBuilder{}, } }
func TestRunBuild(t *testing.T) { dockerResolver := app.DockerRegistryResolver{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected map[string][]string expectedErr error }{ { name: "successful ruby app generation", config: &AppConfig{ SourceRepositories: util.StringList{"https://github.com/openshift/ruby-hello-world"}, DockerImages: util.StringList{"openshift/ruby-20-centos7", "openshift/mongodb-24-centos7"}, OutputDocker: true, dockerResolver: dockerResolver, imageStreamResolver: app.ImageStreamResolver{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationResolver: &app.ImageStreamByAnnotationResolver{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateResolver: app.TemplateResolver{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"ruby-hello-world"}, "imageStream": {"ruby-20-centos7"}, }, expectedErr: nil, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} res, err := test.config.RunBuilds(os.Stdout) if err != test.expectedErr { t.Errorf("%s: Error mismatch! Expected %v, got %v", test.name, test.expectedErr, err) continue } got := map[string][]string{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got["buildConfig"] = append(got["buildConfig"], tp.Name) case *imageapi.ImageStream: got["imageStream"] = append(got["imageStream"], tp.Name) } } if len(test.expected) != len(got) { t.Errorf("%s: Resource kind size mismatch! Expected %d, got %d", test.name, len(test.expected), len(got)) continue } for k, exp := range test.expected { g, ok := got[k] if !ok { t.Errorf("%s: Didn't find expected kind %s", test.name, k) } sort.Strings(g) sort.Strings(exp) if !reflect.DeepEqual(g, exp) { t.Errorf("%s: Resource names mismatch! Expected %v, got %v", test.name, exp, g) continue } } } }
func TestRunAll(t *testing.T) { dockerResolver := app.DockerRegistryResolver{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected map[string][]string expectedErr error expectInsecure util.StringSet }{ { name: "successful ruby app generation", config: &AppConfig{ SourceRepositories: util.StringList{"https://github.com/openshift/ruby-hello-world"}, dockerResolver: fakeDockerResolver(), imageStreamResolver: app.ImageStreamResolver{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "source", imageStreamByAnnotationResolver: app.NewImageStreamByAnnotationResolver(&client.Fake{}, &client.Fake{}, []string{"default"}), templateResolver: app.TemplateResolver{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedErr: nil, }, { name: "app generation using context dir", config: &AppConfig{ SourceRepositories: util.StringList{"https://github.com/openshift/sti-ruby"}, ContextDir: "2.0/test/rack-test-app", dockerResolver: dockerResolver, imageStreamResolver: fakeImageStreamResolver(), imageStreamByAnnotationResolver: app.NewImageStreamByAnnotationResolver(&client.Fake{}, &client.Fake{}, []string{"default"}), templateResolver: app.TemplateResolver{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"sti-ruby"}, "buildConfig": {"sti-ruby"}, "deploymentConfig": {"sti-ruby"}, "service": {"sti-ruby"}, }, expectedErr: nil, }, { name: "insecure registry generation", config: &AppConfig{ Components: util.StringList{"myrepo:5000/myco/example"}, SourceRepositories: util.StringList{"https://github.com/openshift/ruby-hello-world"}, Strategy: "source", dockerResolver: app.DockerClientResolver{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"myrepo:5000/myco/example"}}}, Image: dockerBuilderImage(), }, Insecure: true, }, imageStreamResolver: app.ImageStreamResolver{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateResolver: app.TemplateResolver{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{}, }, templateFileResolver: &app.TemplateFileResolver{}, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", InsecureRegistry: true, }, expected: map[string][]string{ "imageStream": {"example", "ruby-hello-world"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedErr: nil, expectInsecure: util.NewStringSet("example"), }, { name: "docker build", config: &AppConfig{ SourceRepositories: util.StringList{"https://github.com/openshift/ruby-hello-world"}, dockerResolver: app.DockerClientResolver{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"openshift/ruby-20-centos7"}}}, Image: dockerBuilderImage(), }, Insecure: true, }, imageStreamResolver: app.ImageStreamResolver{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationResolver: app.NewImageStreamByAnnotationResolver(&client.Fake{}, &client.Fake{}, []string{"default"}), templateResolver: app.TemplateResolver{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby-20-centos7"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedErr: nil, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} res, err := test.config.RunAll(os.Stdout) if err != test.expectedErr { t.Errorf("%s: Error mismatch! Expected %v, got %v", test.name, test.expectedErr, err) continue } imageStreams := []*imageapi.ImageStream{} got := map[string][]string{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got["buildConfig"] = append(got["buildConfig"], tp.Name) case *kapi.Service: got["service"] = append(got["service"], tp.Name) case *imageapi.ImageStream: got["imageStream"] = append(got["imageStream"], tp.Name) imageStreams = append(imageStreams, tp) case *deploy.DeploymentConfig: got["deploymentConfig"] = append(got["deploymentConfig"], tp.Name) } } if len(test.expected) != len(got) { t.Errorf("%s: Resource kind size mismatch! Expected %d, got %d", test.name, len(test.expected), len(got)) continue } for k, exp := range test.expected { g, ok := got[k] if !ok { t.Errorf("%s: Didn't find expected kind %s", test.name, k) } sort.Strings(g) sort.Strings(exp) if !reflect.DeepEqual(g, exp) { t.Errorf("%s: %s resource names mismatch! Expected %v, got %v", test.name, k, exp, g) continue } } if test.expectInsecure == nil { continue } for _, stream := range imageStreams { _, hasAnnotation := stream.Annotations[imageapi.InsecureRepositoryAnnotation] if test.expectInsecure.Has(stream.Name) && !hasAnnotation { t.Errorf("%s: Expected insecure annotation for stream: %s, but did not get one.", test.name, stream.Name) } if !test.expectInsecure.Has(stream.Name) && hasAnnotation { t.Errorf("%s: Got insecure annotation for stream: %s, and was not expecting one.", test.name, stream.Name) } } } }
func TestRunBuilds(t *testing.T) { dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected map[string][]string expectedErr func(error) bool }{ { name: "successful ruby app generation", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), DockerImages: util.StringList([]string{"openshift/ruby-20-centos7", "openshift/mongodb-24-centos7"}), OutputDocker: true, dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"ruby-hello-world"}, "imageStream": {"ruby-20-centos7"}, }, }, { name: "successful build from dockerfile", config: &AppConfig{ Dockerfile: "FROM openshift/origin-base\nUSER foo", dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"origin-base"}, "imageStream": {"origin-base"}, }, }, { name: "unsuccessful build from dockerfile due to strategy conflict", config: &AppConfig{ Dockerfile: "FROM openshift/origin-base\nUSER foo", Strategy: "source", typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expectedErr: func(err error) bool { return err.Error() == "when directly referencing a Dockerfile, the strategy must must be 'docker'" }, }, { name: "unsuccessful build from dockerfile due to missing FROM instruction", config: &AppConfig{ Dockerfile: "USER foo", Strategy: "docker", typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expectedErr: func(err error) bool { return err.Error() == "the Dockerfile in the repository \"\" has no FROM instruction" }, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} test.config.Out, test.config.ErrOut = os.Stdout, os.Stderr res, err := test.config.RunBuilds() if (test.expectedErr == nil && err != nil) || (test.expectedErr != nil && !test.expectedErr(err)) { t.Errorf("%s: unexpected error: %v", test.name, err) continue } if err != nil { continue } got := map[string][]string{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got["buildConfig"] = append(got["buildConfig"], tp.Name) case *imageapi.ImageStream: got["imageStream"] = append(got["imageStream"], tp.Name) } } if len(test.expected) != len(got) { t.Errorf("%s: Resource kind size mismatch! Expected %d, got %d", test.name, len(test.expected), len(got)) continue } for k, exp := range test.expected { g, ok := got[k] if !ok { t.Errorf("%s: Didn't find expected kind %s", test.name, k) } sort.Strings(g) sort.Strings(exp) if !reflect.DeepEqual(g, exp) { t.Errorf("%s: Resource names mismatch! Expected %v, got %v", test.name, exp, g) continue } } } }
func TestRunAll(t *testing.T) { dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected map[string][]string expectedName string expectedErr error expectInsecure sets.String expectedVolumes map[string]string checkPort string }{ { name: "successful ruby app generation", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: fakeDockerSearcher(), imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "source", imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedVolumes: nil, expectedErr: nil, }, { name: "successful ruby app generation with labels", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: fakeDockerSearcher(), imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "source", imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", Labels: map[string]string{"label1": "value1", "label2": "value2"}, }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedVolumes: nil, expectedErr: nil, }, { name: "successful docker app generation", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: fakeSimpleDockerSearcher(), imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, Strategy: "docker", imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, checkPort: "8080", expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby-20-centos7"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, }, { name: "app generation using context dir", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/sti-ruby"}), ContextDir: "2.0/test/rack-test-app", dockerSearcher: dockerSearcher, imageStreamSearcher: fakeImageStreamSearcher(), imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"sti-ruby"}, "buildConfig": {"sti-ruby"}, "deploymentConfig": {"sti-ruby"}, "service": {"sti-ruby"}, }, expectedName: "sti-ruby", expectedVolumes: nil, expectedErr: nil, }, { name: "insecure registry generation", config: &AppConfig{ Components: util.StringList([]string{"myrepo:5000/myco/example"}), SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), Strategy: "source", dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"myrepo:5000/myco/example"}}}, Image: dockerBuilderImage(), }, Insecure: true, RegistrySearcher: &ExactMatchDockerSearcher{}, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{}, }, templateFileSearcher: &app.TemplateFileSearcher{}, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", InsecureRegistry: true, }, expected: map[string][]string{ "imageStream": {"example", "ruby-hello-world"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, expectedVolumes: nil, expectInsecure: sets.NewString("example"), }, { name: "emptyDir volumes", config: &AppConfig{ DockerImages: util.StringList([]string{"mysql"}), dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"mysql"}, "deploymentConfig": {"mysql"}, "service": {"mysql"}, "volumeMounts": {"mysql-volume-1"}, }, expectedName: "mysql", expectedVolumes: map[string]string{ "mysql-volume-1": "EmptyDir", }, expectedErr: nil, }, { name: "Docker build", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"openshift/ruby-20-centos7"}}}, Image: dockerBuilderImage(), }, Insecure: true, RegistrySearcher: &ExactMatchDockerSearcher{}, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world", "ruby-20-centos7"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, }, { name: "Docker build with no registry image", config: &AppConfig{ SourceRepositories: util.StringList([]string{"https://github.com/openshift/ruby-hello-world"}), dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"openshift/ruby-20-centos7"}}}, Image: dockerBuilderImage(), }, Insecure: true, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: app.NewImageStreamByAnnotationSearcher(&client.Fake{}, &client.Fake{}, []string{"default"}), templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "imageStream": {"ruby-hello-world"}, "buildConfig": {"ruby-hello-world"}, "deploymentConfig": {"ruby-hello-world"}, "service": {"ruby-hello-world"}, }, expectedName: "ruby-hello-world", expectedErr: nil, }, { name: "custom name", config: &AppConfig{ DockerImages: util.StringList([]string{"mysql"}), dockerSearcher: app.DockerClientSearcher{ Client: &dockertools.FakeDockerClient{ Images: []docker.APIImages{{RepoTags: []string{"mysql"}}}, Image: &docker.Image{ Config: &docker.Config{ ExposedPorts: map[docker.Port]struct{}{ "8080/tcp": {}, }, }, }, }, RegistrySearcher: &ExactMatchDockerSearcher{}, }, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", Name: "custom", }, expected: map[string][]string{ "imageStream": {"custom"}, "deploymentConfig": {"custom"}, "service": {"custom"}, }, expectedName: "custom", expectedErr: nil, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} test.config.Out, test.config.ErrOut = os.Stdout, os.Stderr res, err := test.config.RunAll() if err != test.expectedErr { t.Errorf("%s: Error mismatch! Expected %v, got %v", test.name, test.expectedErr, err) continue } imageStreams := []*imageapi.ImageStream{} got := map[string][]string{} gotVolumes := map[string]string{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got["buildConfig"] = append(got["buildConfig"], tp.Name) case *kapi.Service: if test.checkPort != "" { if len(tp.Spec.Ports) == 0 { t.Errorf("%s: did not get any ports in service", test.name) break } expectedPort, _ := strconv.Atoi(test.checkPort) if tp.Spec.Ports[0].Port != expectedPort { t.Errorf("%s: did not get expected port in service. Expected: %d. Got %d\n", test.name, expectedPort, tp.Spec.Ports[0].Port) } } if test.config.Labels != nil { if !mapContains(test.config.Labels, tp.Spec.Selector) { t.Errorf("%s: did not get expected service selector. Expected: %v. Got: %v", test.name, test.config.Labels, tp.Spec.Selector) } } got["service"] = append(got["service"], tp.Name) case *imageapi.ImageStream: got["imageStream"] = append(got["imageStream"], tp.Name) imageStreams = append(imageStreams, tp) case *deployapi.DeploymentConfig: got["deploymentConfig"] = append(got["deploymentConfig"], tp.Name) if podTemplate := tp.Template.ControllerTemplate.Template; podTemplate != nil { for _, volume := range podTemplate.Spec.Volumes { if volume.VolumeSource.EmptyDir != nil { gotVolumes[volume.Name] = "EmptyDir" } else { gotVolumes[volume.Name] = "UNKNOWN" } } for _, container := range podTemplate.Spec.Containers { for _, volumeMount := range container.VolumeMounts { got["volumeMounts"] = append(got["volumeMounts"], volumeMount.Name) } } } if test.config.Labels != nil { if !mapContains(test.config.Labels, tp.Template.ControllerTemplate.Selector) { t.Errorf("%s: did not get expected deployment config rc selector. Expected: %v. Got: %v", test.name, test.config.Labels, tp.Template.ControllerTemplate.Selector) } } } } if len(test.expected) != len(got) { t.Errorf("%s: Resource kind size mismatch! Expected %d, got %d", test.name, len(test.expected), len(got)) continue } for k, exp := range test.expected { g, ok := got[k] if !ok { t.Errorf("%s: Didn't find expected kind %s", test.name, k) } sort.Strings(g) sort.Strings(exp) if !reflect.DeepEqual(g, exp) { t.Errorf("%s: %s resource names mismatch! Expected %v, got %v", test.name, k, exp, g) continue } } if len(test.expectedVolumes) != len(gotVolumes) { t.Errorf("%s: Volume count mismatch! Expected %d, got %d", test.name, len(test.expectedVolumes), len(gotVolumes)) continue } for k, exp := range test.expectedVolumes { g, ok := gotVolumes[k] if !ok { t.Errorf("%s: Didn't find expected volume %s", test.name, k) } if g != exp { t.Errorf("%s: Expected volume of type %s, got %s", test.name, g, exp) } } if test.expectedName != res.Name { t.Errorf("%s: Unexpected name: %s", test.name, test.expectedName) } if test.expectInsecure == nil { continue } for _, stream := range imageStreams { _, hasAnnotation := stream.Annotations[imageapi.InsecureRepositoryAnnotation] if test.expectInsecure.Has(stream.Name) && !hasAnnotation { t.Errorf("%s: Expected insecure annotation for stream: %s, but did not get one.", test.name, stream.Name) } if !test.expectInsecure.Has(stream.Name) && hasAnnotation { t.Errorf("%s: Got insecure annotation for stream: %s, and was not expecting one.", test.name, stream.Name) } } } }
func TestNewAppBuildConfigEnvVarsAndSecrets(t *testing.T) { skipExternalGit(t) dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(10*time.Second, true), } tests := []struct { name string config *cmd.AppConfig expected []kapi.EnvVar expectedSecrets map[string]string expectedErr error }{ { name: "explicit environment variables for buildConfig and deploymentConfig", config: &cmd.AppConfig{ SourceRepositories: []string{"https://github.com/openshift/ruby-hello-world"}, DockerImages: []string{"centos/ruby-22-centos7", "centos/mongodb-26-centos7"}, OutputDocker: true, Environment: []string{"BUILD_ENV_1=env_value_1", "BUILD_ENV_2=env_value_2"}, Secrets: []string{"foo:/var", "bar"}, DockerSearcher: dockerSearcher, Detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, Typer: kapi.Scheme, OSClient: &client.Fake{}, OriginNamespace: "default", }, expected: []kapi.EnvVar{}, expectedSecrets: map[string]string{"foo": "/var", "bar": "."}, expectedErr: nil, }, } for _, test := range tests { test.config.RefBuilder = &app.ReferenceBuilder{} test.config.Out, test.config.ErrOut = os.Stdout, os.Stderr test.config.Deploy = true res, err := test.config.Run() if err != test.expectedErr { t.Errorf("%s: Error mismatch! Expected %v, got %v", test.name, test.expectedErr, err) continue } got := []kapi.EnvVar{} gotSecrets := []buildapi.SecretBuildSource{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got = tp.Spec.Strategy.SourceStrategy.Env gotSecrets = tp.Spec.Source.Secrets break } } for secretName, destDir := range test.expectedSecrets { found := false for _, got := range gotSecrets { if got.Secret.Name == secretName && got.DestinationDir == destDir { found = true continue } } if !found { t.Errorf("expected secret %q and destination %q, got %#v", secretName, destDir, gotSecrets) continue } } if !reflect.DeepEqual(test.expected, got) { t.Errorf("%s: unexpected output. Expected: %#v, Got: %#v", test.name, test.expected, got) continue } } }
func TestRunBuilds(t *testing.T) { skipExternalGit(t) dockerSearcher := app.DockerRegistrySearcher{ Client: dockerregistry.NewClient(), } tests := []struct { name string config *AppConfig expected map[string][]string expectedErr func(error) bool checkResult func(*AppResult) error }{ { name: "successful ruby app generation", config: &AppConfig{ SourceRepositories: []string{"https://github.com/openshift/ruby-hello-world"}, DockerImages: []string{"centos/ruby-22-centos7", "centos/mongodb-26-centos7"}, OutputDocker: true, dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ // TODO: this test used to silently ignore components that were not builders (i.e. user input) // That's bad, so the code should either error in this case or be a bit smarter. "buildConfig": {"ruby-hello-world", "ruby-hello-world-1"}, "imageStream": {"mongodb-26-centos7", "ruby-22-centos7"}, }, }, { name: "successful build from dockerfile", config: &AppConfig{ Dockerfile: "FROM openshift/origin:v1.0.6\nUSER foo", dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"origin"}, // There's a single image stream, but different tags: input from // openshift/origin:v1.0.6, output to openshift/origin:latest. "imageStream": {"origin"}, }, }, { name: "successful build from dockerfile with custom name", config: &AppConfig{ Dockerfile: "FROM openshift/origin-base\nUSER foo", Name: "foobar", dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"foobar"}, "imageStream": {"origin-base", "foobar"}, }, }, { name: "successful build from dockerfile with --to", config: &AppConfig{ Dockerfile: "FROM openshift/origin-base\nUSER foo", Name: "foobar", To: "destination/reference:tag", dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"foobar"}, "imageStream": {"origin-base", "reference"}, }, }, { name: "successful build from dockerfile with --to and --to-docker=true", config: &AppConfig{ Dockerfile: "FROM openshift/origin-base\nUSER foo", Name: "foobar", To: "destination/reference:tag", OutputDocker: true, dockerSearcher: dockerSearcher, imageStreamSearcher: app.ImageStreamSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, imageStreamByAnnotationSearcher: &app.ImageStreamByAnnotationSearcher{ Client: &client.Fake{}, ImageStreamImages: &client.Fake{}, Namespaces: []string{"default"}, }, templateSearcher: app.TemplateSearcher{ Client: &client.Fake{}, TemplateConfigsNamespacer: &client.Fake{}, Namespaces: []string{"openshift", "default"}, }, detector: app.SourceRepositoryEnumerator{ Detectors: source.DefaultDetectors, Tester: dockerfile.NewTester(), }, typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expected: map[string][]string{ "buildConfig": {"foobar"}, "imageStream": {"origin-base"}, }, checkResult: func(res *AppResult) error { for _, item := range res.List.Items { switch t := item.(type) { case *buildapi.BuildConfig: got := t.Spec.Output.To want := &kapi.ObjectReference{ Kind: "DockerImage", Name: "destination/reference:tag", } if !reflect.DeepEqual(got, want) { return fmt.Errorf("build.Spec.Output.To = %v; want %v", got, want) } return nil } } return fmt.Errorf("BuildConfig not found; got %v", res.List.Items) }, }, { name: "unsuccessful build from dockerfile due to strategy conflict", config: &AppConfig{ Dockerfile: "FROM openshift/origin-base\nUSER foo", Strategy: "source", typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expectedErr: func(err error) bool { return err.Error() == "when directly referencing a Dockerfile, the strategy must must be 'docker'" }, }, { name: "unsuccessful build from dockerfile due to missing FROM instruction", config: &AppConfig{ Dockerfile: "USER foo", Strategy: "docker", typer: kapi.Scheme, osclient: &client.Fake{}, originNamespace: "default", }, expectedErr: func(err error) bool { return err.Error() == "the Dockerfile in the repository \"\" has no FROM instruction" }, }, } for _, test := range tests { test.config.refBuilder = &app.ReferenceBuilder{} test.config.Out, test.config.ErrOut = os.Stdout, os.Stderr test.config.ExpectToBuild = true res, err := test.config.Run() if (test.expectedErr == nil && err != nil) || (test.expectedErr != nil && !test.expectedErr(err)) { t.Errorf("%s: unexpected error: %v", test.name, err) continue } if err != nil { continue } got := map[string][]string{} for _, obj := range res.List.Items { switch tp := obj.(type) { case *buildapi.BuildConfig: got["buildConfig"] = append(got["buildConfig"], tp.Name) case *imageapi.ImageStream: got["imageStream"] = append(got["imageStream"], tp.Name) } } if len(test.expected) != len(got) { t.Errorf("%s: Resource kind size mismatch! Expected %d, got %d", test.name, len(test.expected), len(got)) continue } for k, exp := range test.expected { g, ok := got[k] if !ok { t.Errorf("%s: Didn't find expected kind %s", test.name, k) } sort.Strings(g) sort.Strings(exp) if !reflect.DeepEqual(g, exp) { t.Errorf("%s: Resource names mismatch! Expected %v, got %v", test.name, exp, g) continue } } if test.checkResult != nil { if err := test.checkResult(res); err != nil { t.Error(err) } } } }