} }) AfterEach(func() { locksmith.FlockSyscall = syscall.Flock }) It("returns an error", func() { _, err := fileSystemLock.Lock(lockPath) Expect(err).To(MatchError(ContainSubstring("failed to lock file"))) }) }) }) Describe("Unlocker", func() { var unlocker locksmith.Unlocker Describe("Unlock", func() { Context("when the lock is held", func() { BeforeEach(func() { var err error unlocker, err = fileSystemLock.Lock(lockPath) Expect(err).NotTo(HaveOccurred()) }) It("releases the lock", func() { wentThrough := make(chan struct{}) go func() { defer GinkgoRecover() _, err := fileSystemLock.Lock(lockPath)
Eventually(func() string { buff := gbytes.NewBuffer() sess, err := gexec.Start(wrapCmdInNs(netnsName, exec.Command("iptables", "-t", table, "-S", "test-chain-1")), buff, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(gexec.Exit(0)) return string(buff.Contents()) }).ShouldNot(ContainSubstring("test-chain-2")) }) }) Describe("Locking Behaviour", func() { Context("when something is holding the lock", func() { var fakeUnlocker locksmith.Unlocker 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())