topgun: wait for lock before deploy operations
@@ -131,6 +131,7 @@ var _ = BeforeEach(func() {
tmp, err = ioutil.TempDir("", "topgun-tmp")
Expect(err).ToNot(HaveOccurred())
+ waitForDeploymentLock()
bosh("delete-deployment")
instances = map[string][]boshInstance{}
@@ -153,6 +154,7 @@ var _ = AfterEach(func() {
deleteAllContainers()
+ waitForDeploymentLock()
bosh("delete-deployment")
Expect(os.RemoveAll(tmp)).To(Succeed())
@@ -181,6 +183,8 @@ func requestCredsInfo(webUrl string) ([]byte, error) {
}
func StartDeploy(manifest string, args ...string) *gexec.Session {
+ waitForDeploymentLock()
+
return spawnBosh(
append([]string{
"deploy", manifest,
@@ -494,37 +498,53 @@ func flyTable(argv ...string) []map[string]string {
Expect(session.ExitCode()).To(Equal(0))
result := []map[string]string{}
- var headers []string
- rows := strings.Split(string(session.Out.Contents()), "\n")
- for i, row := range rows {
+ var headers []string
+ for i, cols := range parseTable(string(session.Out.Contents())) {
if i == 0 {
- headers = splitFlyColumns(row)
+ headers = cols
continue
}
- if row == "" {
+
+ result = append(result, map[string]string{})
+
+ for j, header := range headers {
+ if header == "" || cols[j] == "" {
continue
}
- result = append(result, map[string]string{})
- columns := splitFlyColumns(row)
+ result[i-1][header] = cols[j]
+ }
+ }
- Expect(columns).To(HaveLen(len(headers)))
+ return result
+}
- for j, header := range headers {
- if header == "" || columns[j] == "" {
+func parseTable(content string) [][]string {
+ result := [][]string{}
+
+ var expectedColumns int
+ rows := strings.Split(content, "\n")
+ for i, row := range rows {
+ if row == "" {
continue
}
- result[i-1][header] = columns[j]
+ columns := splitTableColumns(row)
+ if i == 0 {
+ expectedColumns = len(columns)
+ } else {
+ Expect(columns).To(HaveLen(expectedColumns))
}
+
+ result = append(result, columns)
}
return result
}
-func splitFlyColumns(row string) []string {
- return regexp.MustCompile(`\s{2,}`).Split(strings.TrimSpace(row), -1)
+func splitTableColumns(row string) []string {
+ return regexp.MustCompile(`(\s{2,}|\t)`).Split(strings.TrimSpace(row), -1)
}
func waitForWorkersToBeRunning() {
@@ -616,3 +636,20 @@ func deleteDeploymentWithForcedDrain() {
<-delete.Exited
Expect(delete.ExitCode()).To(Equal(0))
}
+
+func waitForDeploymentLock() {
+dance:
+ for {
+ locks := bosh("locks", "--column", "type", "--column", "resource", "--column", "task id")
+
+ for _, lock := range parseTable(string(locks.Out.Contents())) {
+ if lock[0] == "deployment" && lock[1] == deploymentName {
+ fmt.Fprintf(GinkgoWriter, "waiting for deployment lock (task id %s)...", lock[2])
+ time.Sleep(5 * time.Second)
+ continue dance
+ }
+ }
+
+ break dance
+ }
+}
