Ejemplo n.º 1
0
// This error will be delivered via C errno, since ZK unfortunately
// only provides the handler back from zookeeper_init().
func (s *S) TestInitErrorThroughErrno(c *C) {
	conn, watch, err := zk.Dial("bad-domain-without-port", 5e9)
	if conn != nil {
		conn.Close()
	}
	if watch != nil {
		go func() {
			for {
				_, ok := <-watch
				if !ok {
					break
				}
			}
		}()
	}
	c.Assert(conn, IsNil)
	c.Assert(watch, IsNil)
	c.Assert(err, ErrorMatches, "zookeeper: dial: invalid argument")
}
Ejemplo n.º 2
0
func (s *S) TestRecvTimeoutInitParameter(c *C) {
	conn, watch, err := zk.Dial(s.zkAddr, 0)
	c.Assert(err, IsNil)
	defer conn.Close()

	select {
	case <-watch:
		c.Fatal("Watch fired")
	default:
	}

	for i := 0; i != 1000; i++ {
		_, _, err := conn.Get("/zookeeper")
		if err != nil {
			c.Check(zk.IsError(err, zk.ZOPERATIONTIMEOUT), Equals, true, Commentf("%v", err))
			c.SucceedNow()
		}
	}

	c.Fatal("Operation didn't timeout")
}
Ejemplo n.º 3
0
func (s *S) init(c *C) (*zk.Conn, chan zk.Event) {
	c.Logf("init dialling %q", s.zkAddr)
	conn, watch, err := zk.Dial(s.zkAddr, 5e9)
	c.Assert(err, IsNil)
	s.handles = append(s.handles, conn)
	bufferedWatch := make(chan zk.Event, 256)

	select {
	case e, ok := <-watch:
		c.Assert(ok, Equals, true)
		c.Assert(e.Type, Equals, zk.EVENT_SESSION)
		c.Assert(e.State, Equals, zk.STATE_CONNECTED)
		bufferedWatch <- e
	case <-time.After(5e9):
		c.Fatalf("timeout dialling zookeeper addr %v", s.zkAddr)
	}

	s.liveWatches += 1
	go func() {
	loop:
		for {
			select {
			case event, ok := <-watch:
				if !ok {
					close(bufferedWatch)
					break loop
				}
				select {
				case bufferedWatch <- event:
				default:
					panic("Too many events in buffered watch!")
				}
			}
		}
		s.deadWatches <- true
	}()

	return conn, bufferedWatch
}
Ejemplo n.º 4
0
func (s *S) TestConcurrentClose(c *C) {
	// make sure the server is ready to receive connections.
	s.init(c)

	// Close should wait until all outstanding requests have
	// completed before returning.  The idea of this test is that
	// any request that requests or changes a zookeeper node must
	// make at least one round trip to the server, so we interpose a
	// proxy between the client and the server which can stop all
	// incoming traffic on demand, thus blocking the request until
	// we want it to unblock.
	//
	// We assume that all requests take less than 0.1s to complete,
	// thus when we wait below, neither of the above goroutines
	// should complete within the allotted time (the request because
	// it's waiting for a reply from the server and the close
	// because it's waiting for the request to complete).  If the
	// locking doesn't work, the Close will return early.  If the
	// proxy blocking doesn't work, the request will return early.
	//
	// When we reenable incoming messages from the server, both
	// goroutines should complete.  We can't tell which completes
	// first, but the fact that the close blocked is sufficient to
	// tell that the locking is working correctly.
	for i, f := range requestFuncs {
		c.Logf("iter %d", i)
		p := newProxy(c, s.zkAddr)
		conn, watch, err := zk.Dial(p.addr(), 5e9)
		c.Assert(err, IsNil)
		c.Assert((<-watch).Ok(), Equals, true)

		// sanity check that the connection is actually
		// up and running.
		_, err = conn.Exists("/nothing")
		c.Assert(err, IsNil)

		p.stopIncoming()
		reqDone := make(chan bool)
		closeDone := make(chan bool)
		go func() {
			f(conn, "/closetest")
			reqDone <- true
		}()
		go func() {
			// sleep for long enough for the request to be initiated and the read lock taken.
			time.Sleep(0.05e9)
			conn.Close()
			closeDone <- true
		}()
		select {
		case <-reqDone:
			c.Fatalf("request %d finished early", i)
		case <-closeDone:
			c.Fatalf("request %d close finished early", i)
		case <-time.After(0.1e9):
		}
		p.startIncoming()
		for reqDone != nil || closeDone != nil {
			select {
			case <-reqDone:
				reqDone = nil
			case <-closeDone:
				closeDone = nil
			case <-time.After(0.4e9):
				c.Fatalf("request %d timed out waiting for req (%p) and close(%p)", i, reqDone, closeDone)
			}
		}
		p.close()
		err = f(conn, "/closetest")
		c.Check(zk.IsError(err, zk.ZCLOSING), Equals, true, Commentf("%v", err))
	}
}