<commit_before>package main_test

import (
	"errors"
	"regexp"
	"strconv"
	"strings"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	plugin "hub.jazz.net/git/bluemixgarage/cf-blue-green-deploy"

	"github.com/cloudfoundry/cli/plugin/fakes"
)

var _ = Describe("BGD Plugin", func() {
	Describe("the DeleteOldAppVersions function", func() {
		Context("when there is an old version deployed", func() {
			var connection *fakes.FakeCliConnection
			apps := []plugin.Application{{Name: "app-name-20150326110000-old"}}

			BeforeEach(func() {
				connection = &fakes.FakeCliConnection{}
			})

			It("deletes the old version", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				p.DeleteOldAppVersions("app-name", apps)

				Expect(strings.Join(connection.CliCommandArgsForCall(0), " ")).
					To(Equal("delete app-name-20150326110000-old -f -r"))
			})

			Context("when the deletion of an old app fails", func() {
				BeforeEach(func() {
					connection.CliCommandStub = func(args ...string) ([]string, error) {
						return nil, errors.New("failed to delete app")
					}
				})

				It("returns an error", func() {
					p := plugin.BlueGreenDeployPlugin{Connection: connection}
					err := p.DeleteOldAppVersions("app-name", apps)

					Expect(err).To(HaveOccurred())
				})
			})
		})

		Context("when there is no old version deployed", func() {
			var connection *fakes.FakeCliConnection
			apps := []plugin.Application{}

			BeforeEach(func() {
				connection = &fakes.FakeCliConnection{}
			})

			It("succeeds", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				err := p.DeleteOldAppVersions("app-name", apps)
				Expect(err).ToNot(HaveOccurred())
			})

			It("deletes nothing", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				p.DeleteOldAppVersions("app-name", apps)
				Expect(connection.CliCommandCallCount()).To(Equal(0))
			})
		})
	})

	Describe("the PushNewAppVersion function", func() {
		It("pushes an app with the timestamp appended to its name", func() {
			connection := &fakes.FakeCliConnection{}

			p := plugin.BlueGreenDeployPlugin{Connection: connection}
			p.PushNewAppVersion("app-name")

			Expect(strings.Join(connection.CliCommandArgsForCall(0), " ")).
				To(MatchRegexp(`^push app-name-\d{14}$`))
		})

		It("returns the new app name", func() {
			connection := &fakes.FakeCliConnection{}
			p := plugin.BlueGreenDeployPlugin{Connection: connection}
			newAppName, _ := p.PushNewAppVersion("app-name")

			Expect(newAppName).To(MatchRegexp(`^app-name-\d{14}$`))
		})

		Context("when the push fails", func() {
			var connection *fakes.FakeCliConnection

			BeforeEach(func() {
				connection = &fakes.FakeCliConnection{}
				connection.CliCommandStub = func(args ...string) ([]string, error) {
					return nil, errors.New("failed to push app")
				}
			})

			It("returns an error", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				_, err := p.PushNewAppVersion("app-name")

				Expect(err).To(MatchError("failed to push app"))
			})
		})
	})

	Describe("the MapRoutesFromPreviousApp function", func() {
		Context("when there was an app previously pushed", func() {
			previousApp := plugin.Application{
				Name: "foo",
				Routes: []plugin.Route{
					{Host: "foo", Domain: plugin.Domain{Name: "example.com"}},
				},
			}

			It("maps the routes of the previous app to the new app", func() {
				connection := &fakes.FakeCliConnection{}
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				p.MapRoutesFromPreviousApp("foo-12345", previousApp)

				Expect(strings.Join(connection.CliCommandArgsForCall(0), " ")).
					To(Equal("map-route foo-12345 example.com -n foo"))
			})
		})
	})

	Describe("integration test script", func() {
		Context("when integration test flag is not provided", func() {
			It("returns empty string", func() {
				args := []string{"blue-green-deploy", "appName"}
				Expect(plugin.ExtractIntegrationTestScript(args)).To(Equal(""))
			})
		})

		Context("when integration test flag provided", func() {
			It("returns flag value", func() {
				args := []string{"blue-green-deploy", "appName", "--integration-test=script/test"}
				Expect(plugin.ExtractIntegrationTestScript(args)).To(Equal("script/test"))
			})
		})
	})

	Describe("integration test runner", func() {
		It("returns stdout", func() {
			out, _ := plugin.RunIntegrationTestScript("test/support/integration-test-script", "app.mybluemix.net")
			Expect(out).To(ContainSubstring("STDOUT"))
		})

		It("returns stderr", func() {
			out, _ := plugin.RunIntegrationTestScript("test/support/integration-test-script", "app.mybluemix.net")
			Expect(out).To(ContainSubstring("STDERR"))
		})

		It("passes app FQDN as first argument", func() {
			out, _ := plugin.RunIntegrationTestScript("test/support/integration-test-script", "app.mybluemix.net")
			Expect(out).To(ContainSubstring("App FQDN is: app.mybluemix.net"))
		})

		Context("when script doesn't exist", func() {
			It("fails with useful error", func() {
				_, err := plugin.RunIntegrationTestScript("inexistent-integration-test-script", "app.mybluemix.net")
				Expect(err.Error()).To(ContainSubstring("executable file not found in $PATH"))
			})
		})
	})

	Describe("old app filter", func() {
		Context("when there are 2 old versions and 1 non-old version", func() {
			appList := []plugin.Application{
				{Name: "foo-20150408114041-old"},
				{Name: "foo-20141234567348-old"},<commit_msg>More concise<commit_after>package main_test

import (
	"errors"
	"regexp"
	"strconv"
	"strings"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	plugin "hub.jazz.net/git/bluemixgarage/cf-blue-green-deploy"

	"github.com/cloudfoundry/cli/plugin/fakes"
)

var _ = Describe("BGD Plugin", func() {
	Describe("the DeleteOldAppVersions function", func() {
		Context("when there is an old version deployed", func() {
			var connection *fakes.FakeCliConnection
			apps := []plugin.Application{{Name: "app-name-20150326110000-old"}}

			BeforeEach(func() {
				connection = &fakes.FakeCliConnection{}
			})

			It("deletes the old version", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				p.DeleteOldAppVersions("app-name", apps)

				Expect(strings.Join(connection.CliCommandArgsForCall(0), " ")).
					To(Equal("delete app-name-20150326110000-old -f -r"))
			})

			Context("when the deletion of an old app fails", func() {
				BeforeEach(func() {
					connection.CliCommandStub = func(args ...string) ([]string, error) {
						return nil, errors.New("failed to delete app")
					}
				})

				It("returns an error", func() {
					p := plugin.BlueGreenDeployPlugin{Connection: connection}
					err := p.DeleteOldAppVersions("app-name", apps)

					Expect(err).To(HaveOccurred())
				})
			})
		})

		Context("when there is no old version deployed", func() {
			var connection *fakes.FakeCliConnection
			apps := []plugin.Application{}

			BeforeEach(func() {
				connection = &fakes.FakeCliConnection{}
			})

			It("succeeds", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				err := p.DeleteOldAppVersions("app-name", apps)
				Expect(err).ToNot(HaveOccurred())
			})

			It("deletes nothing", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				p.DeleteOldAppVersions("app-name", apps)
				Expect(connection.CliCommandCallCount()).To(Equal(0))
			})
		})
	})

	Describe("the PushNewAppVersion function", func() {
		It("pushes an app with the timestamp appended to its name", func() {
			connection := &fakes.FakeCliConnection{}

			p := plugin.BlueGreenDeployPlugin{Connection: connection}
			p.PushNewAppVersion("app-name")

			Expect(strings.Join(connection.CliCommandArgsForCall(0), " ")).
				To(MatchRegexp(`^push app-name-\d{14}$`))
		})

		It("returns the new app name", func() {
			connection := &fakes.FakeCliConnection{}
			p := plugin.BlueGreenDeployPlugin{Connection: connection}
			newAppName, _ := p.PushNewAppVersion("app-name")

			Expect(newAppName).To(MatchRegexp(`^app-name-\d{14}$`))
		})

		Context("when the push fails", func() {
			var connection *fakes.FakeCliConnection

			BeforeEach(func() {
				connection = &fakes.FakeCliConnection{}
				connection.CliCommandStub = func(args ...string) ([]string, error) {
					return nil, errors.New("failed to push app")
				}
			})

			It("returns an error", func() {
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				_, err := p.PushNewAppVersion("app-name")

				Expect(err).To(MatchError("failed to push app"))
			})
		})
	})

	Describe("the MapRoutesFromPreviousApp function", func() {
		Context("when there was an app previously pushed", func() {
			previousApp := plugin.Application{
				Name: "foo",
				Routes: []plugin.Route{
					{Host: "foo", Domain: plugin.Domain{Name: "example.com"}},
				},
			}

			It("maps the routes of the previous app to the new app", func() {
				connection := &fakes.FakeCliConnection{}
				p := plugin.BlueGreenDeployPlugin{Connection: connection}
				p.MapRoutesFromPreviousApp("foo-12345", previousApp)

				Expect(strings.Join(connection.CliCommandArgsForCall(0), " ")).
					To(Equal("map-route foo-12345 example.com -n foo"))
			})
		})
	})

	Describe("integration test script", func() {
		Context("when integration test flag is not provided", func() {
			It("returns empty string", func() {
				args := []string{"blue-green-deploy", "appName"}
				Expect(plugin.ExtractIntegrationTestScript(args)).To(Equal(""))
			})
		})

		Context("when integration test flag provided", func() {
			It("returns flag value", func() {
				args := []string{"blue-green-deploy", "appName", "--integration-test=script/test"}
				Expect(plugin.ExtractIntegrationTestScript(args)).To(Equal("script/test"))
			})
		})
	})

	Describe("integration test runner", func() {
		It("returns stdout", func() {
			out, _ := plugin.RunIntegrationTestScript("test/support/integration-test-script", "app.mybluemix.net")
			Expect(out).To(ContainSubstring("STDOUT"))
		})

		It("returns stderr", func() {
			out, _ := plugin.RunIntegrationTestScript("test/support/integration-test-script", "app.mybluemix.net")
			Expect(out).To(ContainSubstring("STDERR"))
		})

		It("passes app FQDN as first argument", func() {
			out, _ := plugin.RunIntegrationTestScript("test/support/integration-test-script", "app.mybluemix.net")
			Expect(out).To(ContainSubstring("App FQDN is: app.mybluemix.net"))
		})

		Context("when script doesn't exist", func() {
			It("fails with useful error", func() {
				_, err := plugin.RunIntegrationTestScript("inexistent-integration-test-script", "app.mybluemix.net")
				Expect(err.Error()).To(ContainSubstring("executable file not found"))
			})
		})
	})

	Describe("old app filter", func() {
		Context("when there are 2 old versions and 1 non-old version", func() {
			appList := []plugin.Application{
				{Name: "foo-20150408114041-old"},
				{Name: "foo-20141234567348-old"},
{'fraction_non_alphanumeric': 0.161716472303207, 'fraction_numerical': 0.013848396501457727, 'mean_word_length': 4.172950047125354, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7337766', 'n_tokens_mistral': 4256, 'n_tokens_neox': 3504, 'n_words': 692}