Пример #1
0
func TestMakeDirs(t *testing.T) {
	// skip exists `parent` and create `child`
	conn := &mockConn{}

	conn.On("Exists", "/parent").Return(true, nil, nil).Once()
	conn.On("Exists", "/parent/child").Return(false, nil, nil).Once()
	conn.On("Create", "/parent/child", []byte{}, int32(PERSISTENT), OPEN_ACL_UNSAFE).Return("", nil).Once()

	assert.NoError(t, MakeDirs(conn, "/parent/child/node", false, nil))

	conn.AssertExpectations(t)

	// fail to create `parent`
	conn = &mockConn{}

	conn.On("Exists", "/parent").Return(true, nil, zk.ErrAPIError).Once()

	assert.EqualError(t, MakeDirs(conn, "/parent/child/node", false, nil), zk.ErrAPIError.Error())

	conn.AssertExpectations(t)

	// create `child` which exists
	conn = &mockConn{}

	conn.On("Exists", "/parent").Return(true, nil, nil).Once()
	conn.On("Exists", "/parent/child").Return(false, nil, nil).Once()
	conn.On("Create", "/parent/child", []byte{}, int32(PERSISTENT), OPEN_ACL_UNSAFE).Return("", zk.ErrNodeExists).Once()

	assert.NoError(t, MakeDirs(conn, "/parent/child/node", false, nil))

	conn.AssertExpectations(t)

	// create `child` with default ACLs
	conn = &mockConn{}
	acls := &mockACLProvider{}

	conn.On("Exists", "/parent").Return(true, nil, nil).Once()
	conn.On("Exists", "/parent/child").Return(false, nil, nil).Once()

	acls.On("GetAclForPath", "/parent/child").Return([]zk.ACL{}).Once()
	acls.On("GetDefaultAcl").Return(zk.AuthACL(zk.PermAdmin)).Once()

	conn.On("Create", "/parent/child", []byte{}, int32(PERSISTENT), zk.AuthACL(zk.PermAdmin)).Return("", nil).Once()

	assert.NoError(t, MakeDirs(conn, "/parent/child/node", false, acls))

	conn.AssertExpectations(t)
	acls.AssertExpectations(t)
}
Пример #2
0
func TestTransaction(t *testing.T) {
	newMockContainer().WithNamespace("parent").Test(t, func(client CuratorFramework, conn *mockConn, compress *mockCompressionProvider, version int32) {
		acls := zk.AuthACL(zk.PermRead)

		compress.On("Compress", "/node1", []byte("default")).Return([]byte("compressed(default)"), nil).Once()
		compress.On("Compress", "/node3", []byte("data")).Return([]byte("compressed(data)"), nil).Once()

		conn.On("Exists", "/parent").Return(true, nil, nil).Once()
		conn.On("Multi", mock.Anything).Return([]zk.MultiResponse{
			{Stat: nil, String: "/parent/node1"},
			{Stat: nil, String: ""},
			{Stat: &zk.Stat{}, String: ""},
			{Stat: nil, String: ""},
		}, nil).Once()

		results, err := client.InTransaction().
			Create().WithMode(PERSISTENT_SEQUENTIAL).WithACL(acls...).Compressed().ForPath("/node1").
			Delete().WithVersion(version).ForPath("/node2").
			SetData().WithVersion(version+1).Compressed().ForPathWithData("/node3", []byte("data")).
			Check().WithVersion(version + 2).ForPath("/node4").
			Commit()

		assert.NoError(t, err)
		assert.Equal(t, conn.operations, []interface{}{
			&zk.CreateRequest{
				Path:  "/parent/node1",
				Data:  []byte("compressed(default)"),
				Acl:   acls,
				Flags: int32(PERSISTENT_SEQUENTIAL),
			},
			&zk.DeleteRequest{
				Path:    "/parent/node2",
				Version: version,
			},
			&zk.SetDataRequest{
				Path:    "/parent/node3",
				Data:    []byte("compressed(data)"),
				Version: version + 1,
			},
			&zk.CheckVersionRequest{
				Path:    "/parent/node4",
				Version: version + 2,
			},
		})
		assert.Equal(t, results, []TransactionResult{
			{
				Type:       OP_CREATE,
				ForPath:    "/parent/node1",
				ResultPath: "/node1",
			},
			{
				Type:    OP_DELETE,
				ForPath: "/parent/node2",
			},
			{
				Type:       OP_SET_DATA,
				ForPath:    "/parent/node3",
				ResultStat: &zk.Stat{},
			},
			{
				Type:    OP_CHECK,
				ForPath: "/parent/node4",
			},
		})
	})
}
Пример #3
0
func (c *mockContainer) Test(t *testing.T, callback interface{}) {
	var client CuratorFramework
	var events chan zk.Event
	var wg *sync.WaitGroup

	zookeeperConnection := &mockConn{log: t.Logf}
	zookeeperDialer := &mockZookeeperDialer{log: t.Logf}
	ensembleProvider := &mockEnsembleProvider{}
	compressionProvider := &mockCompressionProvider{log: t.Logf}
	retryPolicy := &mockRetryPolicy{log: t.Logf}
	aclProvider := &mockACLProvider{log: t.Logf}

	data := []byte("data")
	version := rand.Int31()
	stat := &zk.Stat{Version: version, Mtime: time.Now().Unix()}
	acls := zk.AuthACL(zk.PermRead)

	if c.builder.ZookeeperDialer == nil {
		c.builder.ZookeeperDialer = zookeeperDialer
	}

	if c.builder.EnsembleProvider == nil {
		c.builder.EnsembleProvider = ensembleProvider
	}

	if c.builder.CompressionProvider == nil {
		c.builder.CompressionProvider = compressionProvider
	}

	if c.builder.RetryPolicy == nil {
		c.builder.RetryPolicy = retryPolicy
	}

	if c.builder.AclProvider == nil {
		c.builder.AclProvider = aclProvider
	}

	fn := reflect.TypeOf(callback)

	assert.Equal(t, reflect.Func, fn.Kind())

	args := make([]reflect.Value, fn.NumIn())

	for i := 0; i < fn.NumIn(); i++ {
		switch argType := fn.In(i); argType {
		case reflect.TypeOf(c.builder):
			args[i] = reflect.ValueOf(c.builder)

		case reflect.TypeOf((*CuratorFramework)(nil)).Elem():
			client = c.builder.Build()
			args[i] = reflect.ValueOf(client)

		case reflect.TypeOf((*ZookeeperConnection)(nil)).Elem(), reflect.TypeOf(zookeeperConnection):
			args[i] = reflect.ValueOf(zookeeperConnection)

		case reflect.TypeOf((*ZookeeperDialer)(nil)).Elem(), reflect.TypeOf(zookeeperDialer):
			args[i] = reflect.ValueOf(zookeeperDialer)

		case reflect.TypeOf((*EnsembleProvider)(nil)).Elem(), reflect.TypeOf(ensembleProvider):
			args[i] = reflect.ValueOf(ensembleProvider)

		case reflect.TypeOf((*ZookeeperDialer)(nil)).Elem(), reflect.TypeOf(compressionProvider):
			args[i] = reflect.ValueOf(compressionProvider)

		case reflect.TypeOf((*RetryPolicy)(nil)).Elem(), reflect.TypeOf(retryPolicy):
			args[i] = reflect.ValueOf(retryPolicy)

		case reflect.TypeOf((*ACLProvider)(nil)).Elem(), reflect.TypeOf(aclProvider):
			args[i] = reflect.ValueOf(aclProvider)

		case reflect.TypeOf(events):
			events = make(chan zk.Event)
			args[i] = reflect.ValueOf(events)

		case reflect.TypeOf(wg):
			wg = new(sync.WaitGroup)
			args[i] = reflect.ValueOf(wg)

		case reflect.TypeOf(data):
			args[i] = reflect.ValueOf(data)

		case reflect.TypeOf(version):
			args[i] = reflect.ValueOf(version)

		case reflect.TypeOf(stat):
			args[i] = reflect.ValueOf(stat)

		case reflect.TypeOf(acls):
			args[i] = reflect.ValueOf(acls)

		default:
			t.Errorf("unknown arg type: %s", fn.In(i))
		}
	}

	if client != nil {
		if c.builder.EnsembleProvider == ensembleProvider {
			ensembleProvider.On("ConnectionString").Return("connStr").Once()
			ensembleProvider.On("Start").Return(nil).Once()
			ensembleProvider.On("Close").Return(nil).Once()
		}

		if c.builder.ZookeeperDialer == zookeeperDialer {
			zookeeperDialer.On("Dial", mock.AnythingOfType("string"), c.builder.SessionTimeout, c.builder.CanBeReadOnly).Return(zookeeperConnection, events, nil).Once()
		}

		assert.NoError(t, client.Start())
	}

	if wg != nil {
		wg.Add(1)
	}

	reflect.ValueOf(callback).Call(args)

	if wg != nil {
		wg.Wait()
	}

	if client != nil {
		if c.builder.ZookeeperDialer == zookeeperDialer {
			zookeeperConnection.On("Close").Return().Once()
		}

		assert.NoError(t, client.Close())
	}

	if events != nil {
		close(events)
	}

	zookeeperConnection.AssertExpectations(t)
	zookeeperDialer.AssertExpectations(t)
	ensembleProvider.AssertExpectations(t)
	compressionProvider.AssertExpectations(t)
	retryPolicy.AssertExpectations(t)
	aclProvider.AssertExpectations(t)
}
Пример #4
0
package curator

import (
	"github.com/samuel/go-zookeeper/zk"
)

var (
	OPEN_ACL_UNSAFE = zk.WorldACL(zk.PermAll)
	CREATOR_ALL_ACL = zk.AuthACL(zk.PermAll)
	READ_ACL_UNSAFE = zk.WorldACL(zk.PermRead)
)

type ACLProvider interface {
	// Return the ACL list to use by default
	GetDefaultAcl() []zk.ACL

	// Return the ACL list to use for the given path
	GetAclForPath(path string) []zk.ACL
}

type defaultACLProvider struct {
	defaultAcls []zk.ACL
}

func (p *defaultACLProvider) GetDefaultAcl() []zk.ACL {
	return p.defaultAcls
}

func (p *defaultACLProvider) GetAclForPath(path string) []zk.ACL {
	return p.defaultAcls
}