Expect(err).NotTo(HaveOccurred()) }) It("releases the lock", func() { wentThrough := make(chan struct{}) go func() { defer GinkgoRecover() _, err := fileSystemLock.Lock(lockPath) Expect(err).NotTo(HaveOccurred()) close(wentThrough) }() Consistently(wentThrough).ShouldNot(BeClosed()) Expect(unlocker.Unlock()).To(Succeed()) Eventually(wentThrough).Should(BeClosed()) }) Context("when unlocking a file descriptor fails", func() { BeforeEach(func() { locksmith.FlockSyscall = func(_ int, _ int) error { return errors.New("failed to unlock file") } }) AfterEach(func() { locksmith.FlockSyscall = syscall.Flock }) It("returns an error", func() {
BeforeEach(func() { var err error fakeUnlocker, err = fakeLocksmith.Lock("/foo/bar") Expect(err).NotTo(HaveOccurred()) }) It("blocks on any iptables operations until the lock is freed", func() { done := make(chan struct{}) go func() { defer GinkgoRecover() Expect(iptablesController.CreateChain("filter", "test-chain")).To(Succeed()) close(done) }() Consistently(done).ShouldNot(BeClosed()) fakeUnlocker.Unlock() Eventually(done).Should(BeClosed()) }) }) It("should unlock, ensuring future commands can get the lock", func(done Done) { Expect(iptablesController.CreateChain("filter", "test-chain-1")).To(Succeed()) Expect(iptablesController.CreateChain("filter", "test-chain-2")).To(Succeed()) close(done) }, 2.0) It("should lock to correct key", func() { Expect(iptablesController.CreateChain("filter", "test-chain-1")).To(Succeed()) Expect(fakeLocksmith.KeyForLastLock()).To(Equal(iptables.LockKey)) })