It("emits a completed container event", func() { var event executor.Event Eventually(containerEventPoller(eventSource, &event), 5).Should(Equal(executor.EventTypeContainerComplete)) completeEvent := event.(executor.ContainerCompleteEvent) Expect(completeEvent.Container().State).To(Equal(executor.StateCompleted)) Expect(completeEvent.Container().RunResult.Failed).To(BeTrue()) Expect(completeEvent.Container().RunResult.FailureReason).To(Equal("Exited with status 1")) }) }) }) }) Context("when the container cannot be created", func() { BeforeEach(func() { container.RootFSPath = "gopher://example.com" }) It("does not immediately return an error", func() { Expect(runErr).NotTo(HaveOccurred()) }) Context("when listening for events", func() { It("eventually completes with failure", func() { Eventually(containerStatePoller(guid)).Should(Equal(executor.StateCompleted)) container := getContainer(guid) Expect(container.RunResult.Failed).To(BeTrue()) Expect(container.RunResult.FailureReason).To(Equal("failed to initialize container")) }) })
func garden2executor(handle string, info garden.ContainerInfo) (executor.Container, error) { executorContainer := executor.Container{ Guid: handle, Tags: executor.Tags{}, ExternalIP: info.ExternalIP, } executorContainer.Ports = make([]executor.PortMapping, len(info.MappedPorts)) for key, value := range info.Properties { switch key { case ContainerStateProperty: state := executor.State(value) if state == executor.StateReserved || state == executor.StateInitializing || state == executor.StateCreated || state == executor.StateRunning || state == executor.StateCompleted { executorContainer.State = state } else { return executor.Container{}, InvalidStateError{value} } case ContainerAllocatedAtProperty: _, err := fmt.Sscanf(value, "%d", &executorContainer.AllocatedAt) if err != nil { return executor.Container{}, MalformedPropertyError{ Property: ContainerAllocatedAtProperty, Value: value, } } case ContainerRootfsProperty: executorContainer.RootFSPath = value case ContainerLogProperty: err := json.Unmarshal([]byte(value), &executorContainer.LogConfig) if err != nil { return executor.Container{}, InvalidJSONError{ Property: key, Value: value, UnmarshalErr: err, } } case ContainerMetricsConfigProperty: err := json.Unmarshal([]byte(value), &executorContainer.MetricsConfig) if err != nil { return executor.Container{}, InvalidJSONError{ Property: key, Value: value, UnmarshalErr: err, } } case ContainerResultProperty: err := json.Unmarshal([]byte(value), &executorContainer.RunResult) if err != nil { return executor.Container{}, InvalidJSONError{ Property: key, Value: value, UnmarshalErr: err, } } case ContainerMemoryMBProperty: memoryMB, err := strconv.Atoi(value) if err != nil { return executor.Container{}, MalformedPropertyError{ Property: key, Value: value, } } executorContainer.MemoryMB = memoryMB case ContainerDiskMBProperty: diskMB, err := strconv.Atoi(value) if err != nil { return executor.Container{}, MalformedPropertyError{ Property: key, Value: value, } } executorContainer.DiskMB = diskMB case ContainerCPUWeightProperty: cpuWeight, err := strconv.Atoi(value) if err != nil { return executor.Container{}, MalformedPropertyError{ Property: key, Value: value, } } executorContainer.CPUWeight = uint(cpuWeight) case ContainerStartTimeoutProperty: startTimeout, err := strconv.Atoi(value) if err != nil { return executor.Container{}, MalformedPropertyError{ Property: key, Value: value, } } executorContainer.StartTimeout = uint(startTimeout) default: if strings.HasPrefix(key, TagPropertyPrefix) { executorContainer.Tags[key[len(TagPropertyPrefix):]] = value } } } for i, mapping := range info.MappedPorts { executorContainer.Ports[i] = executor.PortMapping{ HostPort: uint16(mapping.HostPort), ContainerPort: uint16(mapping.ContainerPort), } } return executorContainer, nil }