func TestImageStreamDelete(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } stream := mockImageStream() if err := clusterAdminClient.ImageStreams(testutil.Namespace()).Delete(stream.Name); err == nil || !errors.IsNotFound(err) { t.Fatalf("Unxpected non-error or type: %v", err) } actual, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } if err := clusterAdminClient.ImageStreams(testutil.Namespace()).Delete(actual.Name); err != nil { t.Fatalf("Unxpected error: %v", err) } }
func TestTriggers_manual(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestDeployOpenshift(t) defer openshift.Close() config := deploytest.OkDeploymentConfig(0) config.Namespace = testutil.Namespace() config.Triggers = []deployapi.DeploymentTriggerPolicy{ { Type: deployapi.DeploymentTriggerManual, }, } var err error dc, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Create(config) if err != nil { t.Fatalf("Couldn't create DeploymentConfig: %v %#v", err, config) } watch, err := openshift.KubeClient.ReplicationControllers(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), dc.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Deployments: %v", err) } defer watch.Stop() config, err = openshift.Client.DeploymentConfigs(testutil.Namespace()).Generate(config.Name) if err != nil { t.Fatalf("Error generating config: %v", err) } if config.LatestVersion != 1 { t.Fatalf("Generated deployment should have version 1: %#v", config) } glog.Infof("config(1): %#v", config) new, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Update(config) if err != nil { t.Fatalf("Couldn't create updated DeploymentConfig: %v %#v", err, config) } glog.Infof("config(2): %#v", new) event := <-watch.ResultChan() if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } deployment := event.Object.(*kapi.ReplicationController) if e, a := config.Name, deployutil.DeploymentConfigNameFor(deployment); e != a { t.Fatalf("Expected deployment annotated with deploymentConfig '%s', got '%s'", e, a) } if e, a := 1, deployutil.DeploymentVersionFor(deployment); e != a { t.Fatalf("Deployment annotation version does not match: %#v", deployment) } }
func runBuildRunningPodDeleteTest(t *testing.T, clusterAdminClient *client.Client, clusterAdminKubeClient *kclient.Client) { buildWatch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } defer buildWatch.Stop() created, err := clusterAdminClient.Builds(testutil.Namespace()).Create(mockBuild()) if err != nil { t.Fatalf("Couldn't create Build: %v", err) } podWatch, err := clusterAdminKubeClient.Pods(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Pods %v", err) } defer podWatch.Stop() // wait for initial build event from the creation of the imagerepo with tag latest event := waitForWatch(t, "initial build added", buildWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild := event.Object.(*buildapi.Build) // initial pod creation for build event = waitForWatch(t, "build pod created", podWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } event = waitForWatch(t, "build updated to pending", buildWatch) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) if newBuild.Status != buildapi.BuildStatusPending { t.Fatalf("expected build status to be marked pending, but was marked %s", newBuild.Status) } clusterAdminKubeClient.Pods(testutil.Namespace()).Delete(buildutil.GetBuildPodName(newBuild), kapi.NewDeleteOptions(0)) event = waitForWatch(t, "build updated to error", buildWatch) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) if newBuild.Status != buildapi.BuildStatusError { t.Fatalf("expected build status to be marked error, but was marked %s", newBuild.Status) } }
func TestDeleteBuildConfig(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() buildConfig := mockBuildConfig() actual, err := openshift.Client.BuildConfigs(testutil.Namespace()).Create(buildConfig) if err != nil { t.Fatalf("Unexpected error: %v", err) } if err := openshift.Client.BuildConfigs(testutil.Namespace()).Delete(actual.Name); err != nil { t.Fatalf("Unxpected error: %v", err) } }
func imageChangeBuildConfig(name string, strategy buildapi.BuildStrategy) *buildapi.BuildConfig { return &buildapi.BuildConfig{ ObjectMeta: kapi.ObjectMeta{ Name: name, Namespace: testutil.Namespace(), Labels: map[string]string{"testlabel": "testvalue"}, }, Parameters: buildapi.BuildParameters{ Source: buildapi.BuildSource{ Type: "Git", Git: &buildapi.GitBuildSource{ URI: "git://github.com/openshift/ruby-hello-world.git", }, ContextDir: "contextimage", }, Strategy: strategy, Output: buildapi.BuildOutput{ To: &kapi.ObjectReference{ Name: "test-image-trigger-repo", }, Tag: "outputtag", }, }, Triggers: []buildapi.BuildTriggerPolicy{ { Type: buildapi.ImageChangeBuildTriggerType, ImageChange: &buildapi.ImageChangeTrigger{}, }, }, } }
func TestImageStreamCreate(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } stream := mockImageStream() if _, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(&imageapi.ImageStream{}); err == nil || !errors.IsInvalid(err) { t.Fatalf("Unexpected error: %v", err) } expected, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } if expected.Name == "" { t.Errorf("Unexpected empty image Name %v", expected) } actual, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(stream.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if !reflect.DeepEqual(expected, actual) { t.Errorf("unexpected object: %s", util.ObjectDiff(expected, actual)) } streams, err := clusterAdminClient.ImageStreams(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(streams.Items) != 1 { t.Errorf("Expected one image, got %#v", streams.Items) } }
func runBuildDeleteTest(t *testing.T, clusterAdminClient *client.Client, clusterAdminKubeClient *kclient.Client) { buildWatch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } defer buildWatch.Stop() created, err := clusterAdminClient.Builds(testutil.Namespace()).Create(mockBuild()) if err != nil { t.Fatalf("Couldn't create Build: %v", err) } podWatch, err := clusterAdminKubeClient.Pods(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Pods %v", err) } defer podWatch.Stop() // wait for initial build event from the creation of the imagerepo with tag latest event := waitForWatch(t, "initial build added", buildWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild := event.Object.(*buildapi.Build) // initial pod creation for build event = waitForWatch(t, "build pod created", podWatch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } clusterAdminClient.Builds(testutil.Namespace()).Delete(newBuild.Name) event = waitForWatch(t, "pod deleted due to build deleted", podWatch) if e, a := watchapi.Deleted, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } pod := event.Object.(*kapi.Pod) if expected := buildutil.GetBuildPodName(newBuild); pod.Name != expected { t.Fatalf("Expected pod %s to be deleted, but pod %s was deleted", expected, pod.Name) } }
func putManifest(name, user, token string) (digest.Digest, error) { putUrl := fmt.Sprintf("http://127.0.0.1:5000/v2/%s/%s/manifests/%s", testutil.Namespace(), name, imageapi.DefaultImageTag) signedManifest, dgst, err := signedManifest(fmt.Sprintf("%s/%s", testutil.Namespace(), name)) if err != nil { return "", err } req, err := http.NewRequest("PUT", putUrl, bytes.NewReader(signedManifest)) if err != nil { return "", fmt.Errorf("error creating put request: %s", err) } req.SetBasicAuth(user, token) client := http.DefaultClient resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("error putting manifest: %s", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusAccepted { return "", fmt.Errorf("unexpected put status code: %d", resp.StatusCode) } return dgst, nil }
func TestCreateBuildConfig(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() buildConfig := mockBuildConfig() expected, err := openshift.Client.BuildConfigs(testutil.Namespace()).Create(buildConfig) if err != nil { t.Fatalf("Unexpected error: %v", err) } if expected.Name == "" { t.Errorf("Unexpected empty buildConfig ID %v", expected) } buildConfigs, err := openshift.Client.BuildConfigs(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(buildConfigs.Items) != 1 { t.Errorf("Expected one buildConfig, got %#v", buildConfigs.Items) } }
func TestListBuildConfigs(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() buildConfigs, err := openshift.Client.BuildConfigs(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(buildConfigs.Items) != 0 { t.Errorf("Expected no buildConfigs, got %#v", buildConfigs.Items) } }
func TestWebhookGitHubPing(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() openshift.KubeClient.Namespaces().Create(&kapi.Namespace{ ObjectMeta: kapi.ObjectMeta{Name: testutil.Namespace()}, }) // create buildconfig buildConfig := mockBuildConfigImageParms("originalImage", "imageStream", "validTag") if _, err := openshift.Client.BuildConfigs(testutil.Namespace()).Create(buildConfig); err != nil { t.Fatalf("Unexpected error: %v", err) } watch, err := openshift.Client.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to builds: %v", err) } defer watch.Stop() for _, s := range []string{ "/oapi/v1/namespaces/" + testutil.Namespace() + "/buildconfigs/pushbuild/webhooks/secret101/github", } { // trigger build event sending push notification postFile(&http.Client{}, "ping", "pingevent.json", openshift.server.URL+s, http.StatusOK, t) // TODO: improve negative testing timer := time.NewTimer(time.Second / 2) select { case <-timer.C: // nothing should happen case event := <-watch.ResultChan(): build := event.Object.(*buildapi.Build) t.Fatalf("Unexpected build created: %#v", build) } } }
func TestImageStreamList(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } builds, err := clusterAdminClient.ImageStreams(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("Unexpected error %v", err) } if len(builds.Items) != 0 { t.Errorf("Expected no builds, got %#v", builds.Items) } }
func setupBuildControllerTest(additionalBuildControllers, additionalBuildPodControllers, additionalImageChangeControllers int, t *testing.T) (*client.Client, *kclient.Client) { master, clusterAdminKubeConfig, err := testutil.StartTestMaster() checkErr(t, err) clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) checkErr(t, err) clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) checkErr(t, err) _, err = clusterAdminKubeClient.Namespaces().Create(&kapi.Namespace{ ObjectMeta: kapi.ObjectMeta{Name: testutil.Namespace()}, }) checkErr(t, err) if err := testutil.WaitForServiceAccounts(clusterAdminKubeClient, testutil.Namespace(), []string{bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DefaultServiceAccountName}); err != nil { t.Errorf("unexpected error: %v", err) } openshiftConfig, err := origin.BuildMasterConfig(*master) checkErr(t, err) // Get the build controller clients, since those rely on service account tokens // We don't want to proceed with the rest of the test until those are available openshiftConfig.BuildControllerClients() for i := 0; i < additionalBuildControllers; i++ { openshiftConfig.RunBuildController() } for i := 0; i < additionalBuildPodControllers; i++ { openshiftConfig.RunBuildPodController() } for i := 0; i < additionalImageChangeControllers; i++ { openshiftConfig.RunBuildImageChangeTriggerController() } return clusterAdminClient, clusterAdminKubeClient }
func TestWatchBuildConfigs(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() buildConfig := mockBuildConfig() watch, err := openshift.Client.BuildConfigs(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Unexpected error: %v", err) } defer watch.Stop() expected, err := openshift.Client.BuildConfigs(testutil.Namespace()).Create(buildConfig) if err != nil { t.Fatalf("Unexpected error: %v", err) } event := <-watch.ResultChan() actual := event.Object.(*buildapi.BuildConfig) if e, a := expected.Name, actual.Name; e != a { t.Errorf("Expected buildConfig Name %s, got %s", e, a) } }
func setup(t *testing.T) *client.Client { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminKubeClient.Namespaces().Create(&kapi.Namespace{ ObjectMeta: kapi.ObjectMeta{Name: testutil.Namespace()}, }) return clusterAdminClient }
func getTags(streamName, user, token string) ([]string, error) { url := fmt.Sprintf("http://127.0.0.1:5000/v2/%s/%s/tags/list", testutil.Namespace(), streamName) client := http.DefaultClient req, err := http.NewRequest("GET", url, nil) if err != nil { return []string{}, fmt.Errorf("error creating request: %v", err) } req.SetBasicAuth(user, token) resp, err := client.Do(req) if err != nil { return []string{}, fmt.Errorf("error retrieving tags from registry: %s", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return []string{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } body, err := ioutil.ReadAll(resp.Body) m := make(map[string]interface{}) err = json.Unmarshal(body, &m) if err != nil { return []string{}, fmt.Errorf("error unmarhsaling response %q: %s", body, err) } arr, ok := m["tags"].([]interface{}) if !ok { return []string{}, fmt.Errorf("couldn't convert tags") } tags := []string{} for _, value := range arr { tag, ok := value.(string) if !ok { return []string{}, fmt.Errorf("tag %#v is not a string", value) } tags = append(tags, tag) } return tags, nil }
func TestImageStreamMappingCreate(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } stream := mockImageStream() expected, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } if expected.Name == "" { t.Errorf("Unexpected empty image Name %v", expected) } // create a mapping to an image that doesn't exist mapping := &imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{Name: stream.Name}, Tag: "newer", Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: "image1", }, DockerImageReference: "some/other/name", }, } if err := clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(mapping); err != nil { t.Fatalf("unexpected error: %v", err) } // verify we can tag a second time with the same data, and nothing changes if err := clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(mapping); err != nil { t.Fatalf("unexpected non-error or type: %v", err) } // create an image directly image := &imageapi.Image{ ObjectMeta: kapi.ObjectMeta{Name: "image2"}, DockerImageMetadata: imageapi.DockerImage{ Config: imageapi.DockerConfig{ Env: []string{"A=B"}, }, }, } if _, err := clusterAdminClient.Images().Create(image); err == nil { t.Error("unexpected non-error") } image.DockerImageReference = "some/other/name" // can reuse references across multiple images actual, err := clusterAdminClient.Images().Create(image) if err != nil { t.Fatalf("unexpected error: %v", err) } if actual == nil || actual.Name != image.Name { t.Errorf("unexpected object: %#v", actual) } // verify that image stream mappings cannot mutate / overwrite the image (images are immutable) mapping = &imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{Name: stream.Name}, Tag: "newest", Image: *image, } mapping.Image.DockerImageReference = "different" if err := clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(mapping); err != nil { t.Fatalf("unexpected error: %v", err) } image, err = clusterAdminClient.Images().Get(image.Name) if err != nil { t.Fatalf("unexpected error: %v", err) } if image.DockerImageReference != "some/other/name" { t.Fatalf("image was unexpectedly mutated: %#v", image) } // ensure the correct tags are set updated, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(stream.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if updated.Spec.Tags != nil && len(updated.Spec.Tags) > 0 { t.Errorf("unexpected object: %#v", updated.Spec.Tags) } fromTag, err := clusterAdminClient.ImageStreamTags(testutil.Namespace()).Get(stream.Name, "newer") if err != nil { t.Fatalf("Unexpected error: %v", err) } if fromTag.Name != "test:newer" || fromTag.Image.UID == "" || fromTag.Image.DockerImageReference != "some/other/name" { t.Errorf("unexpected object: %#v", fromTag) } fromTag, err = clusterAdminClient.ImageStreamTags(testutil.Namespace()).Get(stream.Name, "newest") if err != nil { t.Fatalf("Unexpected error: %v", err) } if fromTag.Name != "test:newest" || fromTag.Image.UID == "" || fromTag.Image.DockerImageReference != "some/other/name" { t.Errorf("unexpected object: %#v", fromTag) } // verify that image stream mappings can use the same image for different tags image.ResourceVersion = "" mapping = &imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{Name: stream.Name}, Tag: "anothertag", Image: *image, } if err := clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(mapping); err != nil { t.Fatalf("unexpected error: %v", err) } // ensure the correct tags are set updated, err = clusterAdminClient.ImageStreams(testutil.Namespace()).Get(stream.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if updated.Spec.Tags != nil && len(updated.Spec.Tags) > 0 { t.Errorf("unexpected object: %#v", updated.Spec.Tags) } fromTag, err = clusterAdminClient.ImageStreamTags(testutil.Namespace()).Get(stream.Name, "newer") if err != nil { t.Fatalf("Unexpected error: %v", err) } if fromTag.Name != "test:newer" || fromTag.Image.UID == "" || fromTag.Image.DockerImageReference != "some/other/name" { t.Errorf("unexpected object: %#v", fromTag) } fromTag, err = clusterAdminClient.ImageStreamTags(testutil.Namespace()).Get(stream.Name, "newest") if err != nil { t.Fatalf("Unexpected error: %v", err) } if fromTag.Name != "test:newest" || fromTag.Image.UID == "" || fromTag.Image.DockerImageReference != "some/other/name" { t.Errorf("unexpected object: %#v", fromTag) } fromTag, err = clusterAdminClient.ImageStreamTags(testutil.Namespace()).Get(stream.Name, "anothertag") if err != nil { t.Fatalf("Unexpected error: %v", err) } if fromTag.Name != "test:anothertag" || fromTag.Image.UID == "" || fromTag.Image.DockerImageReference != "some/other/name" { t.Errorf("unexpected object: %#v", fromTag) } }
func TestTriggers_configChange(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestDeployOpenshift(t) defer openshift.Close() config := deploytest.OkDeploymentConfig(0) config.Namespace = testutil.Namespace() config.Triggers[0] = deploytest.OkConfigChangeTrigger() var err error watch, err := openshift.KubeClient.ReplicationControllers(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to Deployments %v", err) } defer watch.Stop() // submit the initial deployment config if _, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Create(config); err != nil { t.Fatalf("Couldn't create DeploymentConfig: %v", err) } // verify the initial deployment exists event := <-watch.ResultChan() if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } deployment := event.Object.(*kapi.ReplicationController) if e, a := config.Name, deployutil.DeploymentConfigNameFor(deployment); e != a { t.Fatalf("Expected deployment annotated with deploymentConfig '%s', got '%s'", e, a) } assertEnvVarEquals("ENV1", "VAL1", deployment, t) // submit a new config with an updated environment variable if config, err = openshift.Client.DeploymentConfigs(testutil.Namespace()).Generate(config.Name); err != nil { t.Fatalf("Error generating config: %v", err) } config.Template.ControllerTemplate.Template.Spec.Containers[0].Env[0].Value = "UPDATED" // before we update the config, we need to update the state of the existing deployment // this is required to be done manually since the deployment and deployer pod controllers are not run in this test deployment.Annotations[deployapi.DeploymentStatusAnnotation] = string(deployapi.DeploymentStatusComplete) // update the deployment if _, err = openshift.KubeClient.ReplicationControllers(testutil.Namespace()).Update(deployment); err != nil { t.Fatalf("Error updating existing deployment: %v", err) } event = <-watch.ResultChan() if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } if _, err := openshift.Client.DeploymentConfigs(testutil.Namespace()).Update(config); err != nil { t.Fatalf("Couldn't create updated DeploymentConfig: %v", err) } event = <-watch.ResultChan() if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newDeployment := event.Object.(*kapi.ReplicationController) assertEnvVarEquals("ENV1", "UPDATED", newDeployment, t) if newDeployment.Name == deployment.Name { t.Fatalf("expected new deployment; old=%s, new=%s", deployment.Name, newDeployment.Name) } }
func TestTriggers_imageChange(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("error starting master: %v", err) } openshiftClusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("error getting OpenShift cluster admin client: %v", err) } openshiftClusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Fatalf("error getting cluster admin client config: %v", err) } openshiftProjectAdminClient, err := testutil.CreateNewProject(openshiftClusterAdminClient, *openshiftClusterAdminClientConfig, testutil.Namespace(), "bob") if err != nil { t.Fatalf("error creating project: %v", err) } imageStream := &imageapi.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "test-image-stream"}} config := deploytest.OkDeploymentConfig(0) config.Namespace = testutil.Namespace() configWatch, err := openshiftProjectAdminClient.DeploymentConfigs(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to Deployments %v", err) } defer configWatch.Stop() if imageStream, err = openshiftProjectAdminClient.ImageStreams(testutil.Namespace()).Create(imageStream); err != nil { t.Fatalf("Couldn't create ImageStream: %v", err) } imageWatch, err := openshiftProjectAdminClient.ImageStreams(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to ImageStreams: %s", err) } defer imageWatch.Stop() // Make a function which can create a new tag event for the image stream and // then wait for the stream status to be asynchronously updated. createTagEvent := func(image string) { mapping := &imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{Name: imageStream.Name}, Tag: "latest", Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: image, }, DockerImageReference: fmt.Sprintf("registry:8080/openshift/test-image@%s", image), }, } if err := openshiftProjectAdminClient.ImageStreamMappings(testutil.Namespace()).Create(mapping); err != nil { t.Fatalf("unexpected error: %v", err) } t.Log("Waiting for image stream mapping to be reflected in the IS status...") statusLoop: for { select { case event := <-imageWatch.ResultChan(): stream := event.Object.(*imageapi.ImageStream) if _, ok := stream.Status.Tags["latest"]; ok { t.Logf("ImageStream %s now has Status with tags: %#v", stream.Name, stream.Status.Tags) break statusLoop } else { t.Logf("Still waiting for latest tag status on ImageStream %s", stream.Name) } } } } if config, err = openshiftProjectAdminClient.DeploymentConfigs(testutil.Namespace()).Create(config); err != nil { t.Fatalf("Couldn't create DeploymentConfig: %v", err) } createTagEvent("sha256:00000000000000000000000000000001") var newConfig *deployapi.DeploymentConfig t.Log("Waiting for a new deployment config in response to ImageStream update") waitForNewConfig: for { select { case event := <-configWatch.ResultChan(): if event.Type == watchapi.Modified { newConfig = event.Object.(*deployapi.DeploymentConfig) break waitForNewConfig } } } if e, a := 1, newConfig.LatestVersion; e != a { t.Fatalf("expected config version %d, got %d", e, a) } }
func TestV2RegistryGetTags(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("error starting master: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("error getting cluster admin client: %v", err) } clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Fatalf("error getting cluster admin client config: %v", err) } user := "******" adminClient, err := testutil.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, testutil.Namespace(), user) if err != nil { t.Fatalf("error creating project: %v", err) } token, err := tokencmd.RequestToken(clusterAdminClientConfig, nil, user, "password") if err != nil { t.Fatalf("error requesting token: %v", err) } config := `version: 0.1 loglevel: debug http: addr: 127.0.0.1:5000 storage: inmemory: {} auth: openshift: middleware: repository: - name: openshift ` os.Setenv("OPENSHIFT_CA_DATA", string(clusterAdminClientConfig.CAData)) os.Setenv("OPENSHIFT_CERT_DATA", string(clusterAdminClientConfig.CertData)) os.Setenv("OPENSHIFT_KEY_DATA", string(clusterAdminClientConfig.KeyData)) os.Setenv("OPENSHIFT_MASTER", clusterAdminClientConfig.Host) os.Setenv("REGISTRY_URL", "127.0.0.1:5000") go dockerregistry.Execute(strings.NewReader(config)) stream := imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Namespace: testutil.Namespace(), Name: "test", }, } if _, err := adminClient.ImageStreams(testutil.Namespace()).Create(&stream); err != nil { t.Fatalf("error creating image stream: %s", err) } tags, err := getTags(stream.Name, user, token) if err != nil { t.Fatal(err) } if len(tags) > 0 { t.Fatalf("expected 0 tags, got: %#v", tags) } dgst, err := putManifest(stream.Name, user, token) if err != nil { t.Fatal(err) } tags, err = getTags(stream.Name, user, token) if err != nil { t.Fatal(err) } if len(tags) != 1 { t.Fatalf("expected 1 tag, got %d: %v", len(tags), tags) } if tags[0] != imageapi.DefaultImageTag { t.Fatalf("expected latest, got %q", tags[0]) } // test get by tag url := fmt.Sprintf("http://127.0.0.1:5000/v2/%s/%s/manifests/%s", testutil.Namespace(), stream.Name, imageapi.DefaultImageTag) req, err := http.NewRequest("GET", url, nil) if err != nil { t.Fatalf("error creating request: %v", err) } req.SetBasicAuth(user, token) resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("error retrieving manifest from registry: %s", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected status code: %d", resp.StatusCode) } body, err := ioutil.ReadAll(resp.Body) var retrievedManifest manifest.Manifest if err := json.Unmarshal(body, &retrievedManifest); err != nil { t.Fatalf("error unmarshaling retrieved manifest") } if retrievedManifest.Name != fmt.Sprintf("%s/%s", testutil.Namespace(), stream.Name) { t.Fatalf("unexpected manifest name: %s", retrievedManifest.Name) } if retrievedManifest.Tag != imageapi.DefaultImageTag { t.Fatalf("unexpected manifest tag: %s", retrievedManifest.Tag) } // test get by digest url = fmt.Sprintf("http://127.0.0.1:5000/v2/%s/%s/manifests/%s", testutil.Namespace(), stream.Name, dgst.String()) req, err = http.NewRequest("GET", url, nil) if err != nil { t.Fatalf("error creating request: %v", err) } req.SetBasicAuth(user, token) resp, err = http.DefaultClient.Do(req) if err != nil { t.Fatalf("error retrieving manifest from registry: %s", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected status code: %d", resp.StatusCode) } body, err = ioutil.ReadAll(resp.Body) if err := json.Unmarshal(body, &retrievedManifest); err != nil { t.Fatalf("error unmarshaling retrieved manifest") } if retrievedManifest.Name != fmt.Sprintf("%s/%s", testutil.Namespace(), stream.Name) { t.Fatalf("unexpected manifest name: %s", retrievedManifest.Name) } if retrievedManifest.Tag != imageapi.DefaultImageTag { t.Fatalf("unexpected manifest tag: %s", retrievedManifest.Tag) } image, err := adminClient.ImageStreamImages(testutil.Namespace()).Get(stream.Name, dgst.String()) if err != nil { t.Fatalf("error getting imageStreamImage: %s", err) } if e, a := fmt.Sprintf("test@%s", dgst.Hex()[:7]), image.Name; e != a { t.Errorf("image name: expected %q, got %q", e, a) } if e, a := dgst.String(), image.Image.Name; e != a { t.Errorf("image name: expected %q, got %q", e, a) } if e, a := fmt.Sprintf("127.0.0.1:5000/%s/%s@%s", testutil.Namespace(), stream.Name, dgst.String()), image.Image.DockerImageReference; e != a { t.Errorf("image dockerImageReference: expected %q, got %q", e, a) } if e, a := "foo", image.Image.DockerImageMetadata.ID; e != a { t.Errorf("image dockerImageMetadata.ID: expected %q, got %q", e, a) } // test auto provisioning otherStream, err := adminClient.ImageStreams(testutil.Namespace()).Get("otherrepo") t.Logf("otherStream=%#v, err=%v", otherStream, err) if err == nil { t.Fatalf("expected error getting otherrepo") } otherDigest, err := putManifest("otherrepo", user, token) if err != nil { t.Fatal(err) } otherStream, err = adminClient.ImageStreams(testutil.Namespace()).Get("otherrepo") if err != nil { t.Fatalf("unexpected error getting otherrepo: %s", err) } if otherStream == nil { t.Fatalf("unexpected nil otherrepo") } if len(otherStream.Status.Tags) != 1 { t.Errorf("expected 1 tag, got %#v", otherStream.Status.Tags) } history, ok := otherStream.Status.Tags[imageapi.DefaultImageTag] if !ok { t.Fatal("unable to find 'latest' tag") } if len(history.Items) != 1 { t.Errorf("expected 1 tag event, got %#v", history.Items) } if e, a := otherDigest.String(), history.Items[0].Image; e != a { t.Errorf("digest: expected %q, got %q", e, a) } }
// TestConcurrentBuildPodControllers tests the lifecycle of a build pod when running multiple controllers. func TestConcurrentBuildPodControllers(t *testing.T) { // Start a master with multiple BuildPodControllers osClient, kClient := setupBuildControllerTest(0, 5, 0, t) ns := testutil.Namespace() waitTime := ConcurrentBuildPodControllersTestWait tests := []buildControllerPodTest{ { Name: "running state test", States: []buildControllerPodState{ { PodPhase: kapi.PodRunning, BuildStatus: buildapi.BuildStatusRunning, }, }, }, { Name: "build succeeded", States: []buildControllerPodState{ { PodPhase: kapi.PodRunning, BuildStatus: buildapi.BuildStatusRunning, }, { PodPhase: kapi.PodSucceeded, BuildStatus: buildapi.BuildStatusComplete, }, }, }, { Name: "build failed", States: []buildControllerPodState{ { PodPhase: kapi.PodRunning, BuildStatus: buildapi.BuildStatusRunning, }, { PodPhase: kapi.PodFailed, BuildStatus: buildapi.BuildStatusFailed, }, }, }, } for _, test := range tests { // Setup communications channels podReadyChan := make(chan *kapi.Pod) // Will receive a value when a build pod is ready errChan := make(chan error) // Will receive a value when an error occurs stateReached := int32(0) // Create a build b, err := osClient.Builds(ns).Create(mockBuild()) checkErr(t, err) // Watch build pod for transition to pending podWatch, err := kClient.Pods(ns).Watch(labels.Everything(), fields.OneTermEqualSelector("metadata.name", buildutil.GetBuildPodName(b)), "") checkErr(t, err) go func() { for e := range podWatch.ResultChan() { pod, ok := e.Object.(*kapi.Pod) if !ok { checkErr(t, fmt.Errorf("%s: unexpected object received: %#v\n", test.Name, e.Object)) } if pod.Status.Phase == kapi.PodPending { podReadyChan <- pod break } } }() var pod *kapi.Pod select { case pod = <-podReadyChan: if pod.Status.Phase != kapi.PodPending { t.Errorf("Got wrong pod phase: %s", pod.Status.Phase) podWatch.Stop() continue } case <-time.After(BuildControllersWatchTimeout): t.Errorf("Timed out waiting for build pod to be ready") podWatch.Stop() continue } podWatch.Stop() for _, state := range test.States { // Update pod state and verify that corresponding build state happens accordingly pod, err := kClient.Pods(ns).Get(pod.Name) checkErr(t, err) pod.Status.Phase = state.PodPhase _, err = kClient.Pods(ns).UpdateStatus(pod) checkErr(t, err) buildWatch, err := osClient.Builds(ns).Watch(labels.Everything(), fields.OneTermEqualSelector("name", b.Name), b.ResourceVersion) checkErr(t, err) defer buildWatch.Stop() go func() { done := false for e := range buildWatch.ResultChan() { var ok bool b, ok = e.Object.(*buildapi.Build) if !ok { errChan <- fmt.Errorf("%s: unexpected object received: %#v", test.Name, e.Object) } if e.Type != watchapi.Modified { errChan <- fmt.Errorf("%s: unexpected event received: %s, object: %#v", e.Type, e.Object) } if done { errChan <- fmt.Errorf("%s: unexpected build state: %#v", test.Name, e.Object) } else if b.Status == state.BuildStatus { done = true atomic.StoreInt32(&stateReached, 1) } } }() select { case err := <-errChan: buildWatch.Stop() t.Errorf("Error: %v\n", test.Name, err) break case <-time.After(waitTime): buildWatch.Stop() if atomic.LoadInt32(&stateReached) != 1 { t.Errorf("%s: Did not reach desired build state: %s", test.Name, state.BuildStatus) break } } } } }
func TestBuildConfigClient(t *testing.T) { testutil.DeleteAllEtcdKeys() openshift := NewTestBuildOpenshift(t) defer openshift.Close() buildConfigs, err := openshift.Client.BuildConfigs(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("unexpected error %v", err) } if len(buildConfigs.Items) != 0 { t.Errorf("expected no buildConfigs, got %#v", buildConfigs) } // get a validation error buildConfig := &buildapi.BuildConfig{ ObjectMeta: kapi.ObjectMeta{ GenerateName: "mock-build", Labels: map[string]string{ "label1": "value1", "label2": "value2", }, }, Parameters: buildapi.BuildParameters{ Source: buildapi.BuildSource{ Type: buildapi.BuildSourceGit, Git: &buildapi.GitBuildSource{ URI: "http://my.docker/build", }, ContextDir: "context", }, Strategy: buildapi.BuildStrategy{ Type: buildapi.DockerBuildStrategyType, DockerStrategy: &buildapi.DockerBuildStrategy{}, }, Output: buildapi.BuildOutput{ DockerImageReference: "namespace/builtimage", }, }, } // get a created buildConfig got, err := openshift.Client.BuildConfigs(testutil.Namespace()).Create(buildConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } if got.Name == "" { t.Errorf("unexpected empty buildConfig ID %v", got) } // get a list of buildConfigs buildConfigs, err = openshift.Client.BuildConfigs(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(buildConfigs.Items) != 1 { t.Errorf("expected one buildConfig, got %#v", buildConfigs) } actual := buildConfigs.Items[0] if actual.Name != got.Name { t.Errorf("expected buildConfig %#v, got %#v", got, actual) } // delete a buildConfig err = openshift.Client.BuildConfigs(testutil.Namespace()).Delete(got.Name) if err != nil { t.Fatalf("unexpected error %v", err) } buildConfigs, err = openshift.Client.BuildConfigs(testutil.Namespace()).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("unexpected error %v", err) } if len(buildConfigs.Items) != 0 { t.Errorf("expected no buildConfigs, got %#v", buildConfigs) } }
func TestWebhookGitHubPushWithImage(t *testing.T) { _, clusterAdminKubeConfig, err := testutil.StartTestMaster() if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Errorf("unexpected error: %v", err) } err = testutil.CreateNamespace(clusterAdminKubeConfig, testutil.Namespace()) if err != nil { t.Errorf("unexpected error: %v", err) } clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig) checkErr(t, err) if err := testutil.WaitForServiceAccounts(clusterAdminKubeClient, testutil.Namespace(), []string{bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DefaultServiceAccountName}); err != nil { t.Errorf("unexpected error: %v", err) } // create imagerepo imageStream := &imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{Name: "image-stream"}, Spec: imageapi.ImageStreamSpec{ DockerImageRepository: "registry:3000/integration/imageStream", Tags: map[string]imageapi.TagReference{ "validTag": { From: &kapi.ObjectReference{ Kind: "DockerImage", Name: "registry:3000/integration/imageStream:success", }, }, }, }, } if _, err := clusterAdminClient.ImageStreams(testutil.Namespace()).Create(imageStream); err != nil { t.Fatalf("Unexpected error: %v", err) } ism := &imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{Name: "image-stream"}, Tag: "validTag", Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: "myimage", }, DockerImageReference: "registry:3000/integration/imageStream:success", }, } if err := clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(ism); err != nil { t.Fatalf("Unexpected error: %v", err) } // create buildconfig buildConfig := mockBuildConfigImageParms("originalImage", "imageStream", "validTag") if _, err := clusterAdminClient.BuildConfigs(testutil.Namespace()).Create(buildConfig); err != nil { t.Fatalf("Unexpected error: %v", err) } watch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to builds: %v", err) } defer watch.Stop() for _, s := range []string{ "/oapi/v1/namespaces/" + testutil.Namespace() + "/buildconfigs/pushbuild/webhooks/secret101/github", } { // trigger build event sending push notification postFile(clusterAdminClient.RESTClient.Client, "push", "pushevent.json", clusterAdminClientConfig.Host+s, http.StatusOK, t) event := <-watch.ResultChan() actual := event.Object.(*buildapi.Build) // FIXME: I think the build creation is fast and in some situlation we miss // the BuildStatusNew here. Note that this is not a bug, in future we should // move this to use go routine to capture all events. if actual.Status != buildapi.BuildStatusNew && actual.Status != buildapi.BuildStatusPending { t.Errorf("Expected %s or %s, got %s", buildapi.BuildStatusNew, buildapi.BuildStatusPending, actual.Status) } if actual.Parameters.Strategy.DockerStrategy.From.Name != "originalImage" { t.Errorf("Expected %s, got %s", "originalImage", actual.Parameters.Strategy.DockerStrategy.From.Name) } } }
// TestConcurrentBuildControllers tests the transition of a build from new to pending. Ensures that only a single New -> Pending // transition happens and that only a single pod is created during a set period of time. func TestConcurrentBuildControllers(t *testing.T) { // Start a master with multiple BuildControllers osClient, kClient := setupBuildControllerTest(5, 0, 0, t) // Setup an error channel errChan := make(chan error) // go routines will send a message on this channel if an error occurs. Once this happens the test is over // Create a build ns := testutil.Namespace() b, err := osClient.Builds(ns).Create(mockBuild()) checkErr(t, err) // Start watching builds for New -> Pending transition buildWatch, err := osClient.Builds(ns).Watch(labels.Everything(), fields.OneTermEqualSelector("name", b.Name), b.ResourceVersion) checkErr(t, err) defer buildWatch.Stop() buildModifiedCount := int32(0) go func() { for e := range buildWatch.ResultChan() { if e.Type != watchapi.Modified { errChan <- fmt.Errorf("received an unexpected event of type: %s with object: %#v", e.Type, e.Object) } build, ok := e.Object.(*buildapi.Build) if !ok { errChan <- fmt.Errorf("received something other than build: %#v", e.Object) break } // If unexpected status, throw error if build.Status != buildapi.BuildStatusPending { errChan <- fmt.Errorf("received unexpected build status: %s", build.Status) break } else { atomic.AddInt32(&buildModifiedCount, 1) } } }() // Watch build pods as they are created podWatch, err := kClient.Pods(ns).Watch(labels.Everything(), fields.OneTermEqualSelector("metadata.name", buildutil.GetBuildPodName(b)), "") checkErr(t, err) defer podWatch.Stop() podAddedCount := int32(0) go func() { for e := range podWatch.ResultChan() { // Look for creation events if e.Type == watchapi.Added { atomic.AddInt32(&podAddedCount, 1) } } }() select { case err := <-errChan: t.Errorf("Error: %v", err) case <-time.After(ConcurrentBuildControllersTestWait): if atomic.LoadInt32(&buildModifiedCount) != 1 { t.Errorf("The build was modified an unexpected number of times. Got: %d, Expected: 1", buildModifiedCount) } if atomic.LoadInt32(&podAddedCount) != 1 { t.Errorf("The build pod was created an unexpected number of times. Got: %d, Expected: 1", podAddedCount) } } }
func runImageChangeTriggerTest(t *testing.T, clusterAdminClient *client.Client, imageStream *imageapi.ImageStream, imageStreamMapping *imageapi.ImageStreamMapping, config *buildapi.BuildConfig, tag string) { created, err := clusterAdminClient.BuildConfigs(testutil.Namespace()).Create(config) if err != nil { t.Fatalf("Couldn't create BuildConfig: %v", err) } watch, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } watch2, err := clusterAdminClient.BuildConfigs(testutil.Namespace()).Watch(labels.Everything(), fields.Everything(), created.ResourceVersion) if err != nil { t.Fatalf("Couldn't subscribe to BuildConfigs %v", err) } defer watch2.Stop() imageStream, err = clusterAdminClient.ImageStreams(testutil.Namespace()).Create(imageStream) if err != nil { t.Fatalf("Couldn't create ImageStream: %v", err) } err = clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(imageStreamMapping) if err != nil { t.Fatalf("Couldn't create Image: %v", err) } // wait for initial build event from the creation of the imagerepo with tag latest event := waitForWatch(t, "initial build added", watch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild := event.Object.(*buildapi.Build) switch newBuild.Parameters.Strategy.Type { case buildapi.SourceBuildStrategyType: if newBuild.Parameters.Strategy.SourceStrategy.From.Name != "registry:8080/openshift/test-image-trigger:"+tag { i, _ := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(imageStream.Name) bc, _ := clusterAdminClient.BuildConfigs(testutil.Namespace()).Get(config.Name) t.Fatalf("Expected build with base image %s, got %s\n, imagerepo is %v\ntrigger is %s\n", "registry:8080/openshift/test-image-trigger:"+tag, newBuild.Parameters.Strategy.DockerStrategy.From.Name, i, bc.Triggers[0].ImageChange) } case buildapi.DockerBuildStrategyType: if newBuild.Parameters.Strategy.DockerStrategy.From.Name != "registry:8080/openshift/test-image-trigger:"+tag { i, _ := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(imageStream.Name) bc, _ := clusterAdminClient.BuildConfigs(testutil.Namespace()).Get(config.Name) t.Fatalf("Expected build with base image %s, got %s\n, imagerepo is %v\ntrigger is %s\n", "registry:8080/openshift/test-image-trigger:"+tag, newBuild.Parameters.Strategy.DockerStrategy.From.Name, i, bc.Triggers[0].ImageChange) } case buildapi.CustomBuildStrategyType: if newBuild.Parameters.Strategy.CustomStrategy.From.Name != "registry:8080/openshift/test-image-trigger:"+tag { i, _ := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(imageStream.Name) bc, _ := clusterAdminClient.BuildConfigs(testutil.Namespace()).Get(config.Name) t.Fatalf("Expected build with base image %s, got %s\n, imagerepo is %v\ntrigger is %s\n", "registry:8080/openshift/test-image-trigger:"+tag, newBuild.Parameters.Strategy.DockerStrategy.From.Name, i, bc.Triggers[0].ImageChange) } } // Wait for an update on the specific build that was added watch3, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.OneTermEqualSelector("name", newBuild.Name), newBuild.ResourceVersion) defer watch3.Stop() if err != nil { t.Fatalf("Couldn't subscribe to Builds %v", err) } event = waitForWatch(t, "initial build update", watch3) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) // Make sure the resolution of the build's docker image pushspec didn't mutate the persisted API object if newBuild.Parameters.Output.To.Name != "test-image-trigger-repo" || newBuild.Parameters.Output.Tag != "outputtag" || newBuild.Parameters.Output.DockerImageReference != "" { t.Fatalf("unexpected build output: %#v %#v", newBuild.Parameters.Output.To, newBuild.Parameters.Output) } if newBuild.Labels["testlabel"] != "testvalue" { t.Fatalf("Expected build with label %s=%s from build config got %s=%s", "testlabel", "testvalue", "testlabel", newBuild.Labels["testlabel"]) } // wait for build config to be updated WaitLoop: for { select { case e := <-watch2.ResultChan(): event = &e continue case <-time.After(BuildControllersWatchTimeout): break WaitLoop } } updatedConfig := event.Object.(*buildapi.BuildConfig) if err != nil { t.Fatalf("Couldn't get BuildConfig: %v", err) } // the first tag did not have an image id, so the last trigger field is the pull spec if updatedConfig.Triggers[0].ImageChange.LastTriggeredImageID != "registry:8080/openshift/test-image-trigger:"+tag { t.Fatalf("Expected imageID equal to pull spec, got %#v", updatedConfig.Triggers[0].ImageChange) } // clear out the build/buildconfig watches before triggering a new build WaitLoop2: for { select { case <-watch.ResultChan(): continue case <-watch2.ResultChan(): continue case <-time.After(BuildControllersWatchTimeout): break WaitLoop2 } } // trigger a build by posting a new image if err := clusterAdminClient.ImageStreamMappings(testutil.Namespace()).Create(&imageapi.ImageStreamMapping{ ObjectMeta: kapi.ObjectMeta{ Namespace: testutil.Namespace(), Name: imageStream.Name, }, Tag: tag, Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: "ref-2-random", }, DockerImageReference: "registry:8080/openshift/test-image-trigger:ref-2-random", }, }); err != nil { t.Fatalf("unexpected error: %v", err) } event = waitForWatch(t, "second build created", watch) if e, a := watchapi.Added, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) switch newBuild.Parameters.Strategy.Type { case buildapi.SourceBuildStrategyType: if newBuild.Parameters.Strategy.SourceStrategy.From.Name != "registry:8080/openshift/test-image-trigger:ref-2-random" { i, _ := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(imageStream.Name) bc, _ := clusterAdminClient.BuildConfigs(testutil.Namespace()).Get(config.Name) t.Fatalf("Expected build with base image %s, got %s\n, imagerepo is %v\trigger is %s\n", "registry:8080/openshift/test-image-trigger:ref-2-random", newBuild.Parameters.Strategy.DockerStrategy.From.Name, i, bc.Triggers[3].ImageChange) } case buildapi.DockerBuildStrategyType: if newBuild.Parameters.Strategy.DockerStrategy.From.Name != "registry:8080/openshift/test-image-trigger:ref-2-random" { i, _ := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(imageStream.Name) bc, _ := clusterAdminClient.BuildConfigs(testutil.Namespace()).Get(config.Name) t.Fatalf("Expected build with base image %s, got %s\n, imagerepo is %v\trigger is %s\n", "registry:8080/openshift/test-image-trigger:ref-2-random", newBuild.Parameters.Strategy.DockerStrategy.From.Name, i, bc.Triggers[3].ImageChange) } case buildapi.CustomBuildStrategyType: if newBuild.Parameters.Strategy.CustomStrategy.From.Name != "registry:8080/openshift/test-image-trigger:ref-2-random" { i, _ := clusterAdminClient.ImageStreams(testutil.Namespace()).Get(imageStream.Name) bc, _ := clusterAdminClient.BuildConfigs(testutil.Namespace()).Get(config.Name) t.Fatalf("Expected build with base image %s, got %s\n, imagerepo is %v\trigger is %s\n", "registry:8080/openshift/test-image-trigger:ref-2-random", newBuild.Parameters.Strategy.DockerStrategy.From.Name, i, bc.Triggers[3].ImageChange) } } // Listen to events on specific build watch4, err := clusterAdminClient.Builds(testutil.Namespace()).Watch(labels.Everything(), fields.OneTermEqualSelector("name", newBuild.Name), newBuild.ResourceVersion) defer watch4.Stop() event = waitForWatch(t, "update on second build", watch4) if e, a := watchapi.Modified, event.Type; e != a { t.Fatalf("expected watch event type %s, got %s", e, a) } newBuild = event.Object.(*buildapi.Build) // Make sure the resolution of the build's docker image pushspec didn't mutate the persisted API object if newBuild.Parameters.Output.To.Name != "test-image-trigger-repo" || newBuild.Parameters.Output.Tag != "outputtag" || newBuild.Parameters.Output.DockerImageReference != "" { t.Fatalf("unexpected build output: %#v %#v", newBuild.Parameters.Output.To, newBuild.Parameters.Output) } if newBuild.Labels["testlabel"] != "testvalue" { t.Fatalf("Expected build with label %s=%s from build config got %s=%s", "testlabel", "testvalue", "testlabel", newBuild.Labels["testlabel"]) } WaitLoop3: for { select { case e := <-watch2.ResultChan(): event = &e continue case <-time.After(BuildControllersWatchTimeout): break WaitLoop3 } } updatedConfig = event.Object.(*buildapi.BuildConfig) if e, a := "registry:8080/openshift/test-image-trigger:ref-2-random", updatedConfig.Triggers[0].ImageChange.LastTriggeredImageID; e != a { t.Errorf("unexpected trigger id: expected %v, got %v", e, a) } }