Пример #1
0
func TestNewFromMethod(t *testing.T) {
	var method = &amqp.ExchangeDeclare{
		Reserved1:  0,
		Exchange:   "ex-method",
		Type:       "topic",
		Passive:    true,
		Durable:    true,
		AutoDelete: true,
		Internal:   true,
		NoWait:     false,
		Arguments:  amqp.NewTable(),
	}
	exMethod, err := NewFromMethod(method, true, make(chan *Exchange))
	if err != nil {
		t.Errorf(err.Msg)
	}
	exNormal := NewExchange("ex-method", EX_TYPE_TOPIC, true, true, true, amqp.NewTable(), true, make(chan *Exchange))
	if !exNormal.EquivalentExchanges(exMethod) {
		t.Errorf("Inconsistency between NewExchange and NewFromMethod")
	}
	// Bad exchange type
	method.Type = "headers"
	exMethod, err = NewFromMethod(method, true, make(chan *Exchange))
	if err == nil {
		t.Errorf("Parsed bad exchange method")
	}
	if err.Code != 503 {
		t.Errorf("Wrong error code on bad exchange parse")
	}
}
Пример #2
0
func (channel *Channel) startConnection() *amqp.AMQPError {
	// TODO(SHOULD): add fields: host, product, version, platform, copyright, information
	var capabilities = amqp.NewTable()
	capabilities.SetKey("publisher_confirms", false)
	capabilities.SetKey("basic.nack", true)
	var serverProps = amqp.NewTable()
	// TODO: the java rabbitmq client I'm using for load testing doesn't like these string
	//       fields even though the go/python clients do. If they are set as longstr (bytes)
	//       instead they work, so I'm doing that for now
	serverProps.SetKey("product", []byte("dispatchd"))
	serverProps.SetKey("version", []byte("0.1"))
	serverProps.SetKey("copyright", []byte("Jeffrey Jenkins, 2015"))
	serverProps.SetKey("capabilities", capabilities)
	serverProps.SetKey("platform", []byte(runtime.GOARCH))
	host, err := os.Hostname()
	if err != nil {
		serverProps.SetKey("host", []byte("UnknownHostError"))
	} else {
		serverProps.SetKey("host", []byte(host))
	}

	serverProps.SetKey("information", []byte("http://dispatchd.org"))

	channel.SendMethod(&amqp.ConnectionStart{0, 9, serverProps, []byte("PLAIN"), []byte("en_US")})
	return nil
}
Пример #3
0
func TestEquals(t *testing.T) {
	var bNil *Binding = nil
	b, _ := NewBinding("q1", "e1", "rk", amqp.NewTable(), false)
	same, _ := NewBinding("q1", "e1", "rk", amqp.NewTable(), false)
	diffQ, _ := NewBinding("DIFF", "e1", "rk", amqp.NewTable(), false)
	diffE, _ := NewBinding("q1", "DIFF", "rk", amqp.NewTable(), false)
	diffR, _ := NewBinding("q1", "e1", "DIFF", amqp.NewTable(), false)

	if b == nil || same == nil || diffQ == nil || diffE == nil || diffR == nil {
		t.Errorf("Failed to construct bindings")
	}
	if b.Equals(nil) || bNil.Equals(b) {
		t.Errorf("Comparison to nil was true!")
	}
	if !b.Equals(same) {
		t.Errorf("Equals returns false!")
	}
	if b.Equals(diffQ) {
		t.Errorf("Equals returns true on queue name diff!")
	}
	if b.Equals(diffE) {
		t.Errorf("Equals returns true on exchange name diff!")
	}
	if b.Equals(diffR) {
		t.Errorf("Equals returns true on routing key diff!")
	}

}
Пример #4
0
func TestAddBinding(t *testing.T) {
	var ex = NewExchange("ex1", EX_TYPE_TOPIC, true, true, false, amqp.NewTable(), false, make(chan *Exchange))
	ex.deleteActive = time.Now()
	// bad binding
	_, err := binding.NewBinding("q1", "ex1", "~!@", amqp.NewTable(), true)
	if err == nil {
		t.Errorf("No error with bad binding!")
	}
	if len(ex.bindings) != 0 {
		t.Errorf("Bad binding was added despite error")
	}
	// duplicate binding
	var b = bindingHelper("q1", "ex1", "a.b.c", true)
	err = ex.AddBinding(b, -1)
	if err != nil {
		t.Errorf(err.Error())
	}
	if len(ex.bindings) != 1 {
		t.Errorf("Wrong number of bindings")
	}
	err = ex.AddBinding(b, -1)
	if err != nil {
		t.Errorf(err.Error())
	}
	if len(ex.bindings) != 1 {
		t.Errorf("Wrong number of bindings")
	}
	if ex.deleteActive != time.Unix(0, 0) {
		t.Errorf("Error did not reset time")
	}

}
Пример #5
0
func TestTopicRouting(t *testing.T) {
	_, err := NewBinding("q1", "e1", "(", amqp.NewTable(), true)
	if err == nil {
		t.Errorf("Bad topic patter compiled!")
	}
	basic, _ := NewBinding("q1", "e1", "hello.world", amqp.NewTable(), true)
	singleWild, _ := NewBinding("q1", "e1", "hello.*.world", amqp.NewTable(), true)
	multiWild, _ := NewBinding("q1", "e1", "hello.#.world", amqp.NewTable(), true)
	multiWild2, _ := NewBinding("q1", "e1", "hello.#.world.#", amqp.NewTable(), true)
	if !basic.MatchTopic(basicPublish("e1", "hello.world")) {
		t.Errorf("Basic match failed")
	}
	if basic.MatchTopic(basicPublish("e1", "hello.worlds")) {
		t.Errorf("Incorrect match with suffix")
	}
	if !basic.MatchTopic(basicPublish("e1", "hello.world")) {
		t.Errorf("Match succeeded despite mismatched exchange")
	}
	if !singleWild.MatchTopic(basicPublish("e1", "hello.one.world")) {
		t.Errorf("Failed to match single wildcard")
	}
	if singleWild.MatchTopic(basicPublish("e1", "hello.world")) {
		t.Errorf("Matched without wildcard token")
	}
	if !multiWild.MatchTopic(basicPublish("e1", "hello.one.two.three.world")) {
		t.Errorf("Failed to match multi wildcard")
	}
	if !multiWild2.MatchTopic(basicPublish("e1", "hello.one.world.hi")) {
		t.Errorf("Multiple multi-wild tokens failed")
	}

}
Пример #6
0
func TestAutoDeleteTimeout(t *testing.T) {
	var deleter = make(chan *Exchange)
	var ex = NewExchange("ex1", EX_TYPE_TOPIC, true, true, false, amqp.NewTable(), false, deleter)
	ex.autodeletePeriod = 10 * time.Millisecond
	ex.AddBinding(bindingHelper("q1", "ex1", "a.b.c", true), -1)
	var b, _ = binding.NewBinding("q1", "ex1", "a.b.c", amqp.NewTable(), true)
	ex.RemoveBinding(b)
	var toDelete = <-deleter
	if ex.Name != toDelete.Name {
		t.Errorf("Integrity error in delete")
	}
}
Пример #7
0
func TestExchangeRoutingFanout(t *testing.T) {
	var exFanout = NewExchange(
		"exf",
		EX_TYPE_FANOUT,
		false,
		false,
		false,
		amqp.NewTable(),
		false,
		make(chan *Exchange),
	)
	exFanout.AddBinding(bindingHelper("q1", "exf", "rk-1", false), -1)
	exFanout.AddBinding(bindingHelper("q2", "exf", "rk-2", false), -1)

	// Create a random message, won't route by default
	var msg = amqp.RandomMessage(false)
	msg.Method.Exchange = "exf"

	res, err := exFanout.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	_, foundQ1 := res["q1"]
	_, foundQ2 := res["q2"]
	if !foundQ1 || !foundQ2 {
		t.Errorf("Failed to route fanout message %v %v", foundQ1, foundQ2)
	}
}
Пример #8
0
func bindingHelper(queue string, exchange string, key string, topic bool) *binding.Binding {
	b, err := binding.NewBinding(queue, exchange, key, amqp.NewTable(), topic)
	if err != nil {
		panic(err.Error())
	}
	return b
}
Пример #9
0
func TestRemoveBinding(t *testing.T) {
	var ex = NewExchange("ex1", EX_TYPE_TOPIC, true, true, false, amqp.NewTable(), false, make(chan *Exchange))
	var b1 = bindingHelper("q1", "ex1", "a.b.c", true)
	var b2 = bindingHelper("q1", "ex1", "d.e.f", true)
	var b3 = bindingHelper("q1", "ex1", "g.h.i", true)
	var b4 = bindingHelper("q2", "ex1", "g.h.i", true)
	var b5 = bindingHelper("q2", "ex1", "j.k.l", true)
	//
	ex.AddBinding(b1, -1)
	ex.AddBinding(b2, -1)
	ex.AddBinding(b3, -1)
	ex.AddBinding(b4, -1)
	ex.AddBinding(b5, -1)

	// Remove a binding that doesn't exist
	bNone := bindingHelper("q2", "ex1", "does.not.exist", true)
	ex.RemoveBinding(bNone)
	if len(ex.bindings) != 5 {
		t.Errorf("Wrong number of bindings: %d", len(ex.bindings))
	}

	// Remove the Q2 bindings
	ex.RemoveBinding(b4)
	if len(ex.bindings) != 4 {
		t.Errorf("Wrong number of bindings: %d", len(ex.bindings))
	}
	ex.RemoveBinding(b5)

	// Check that all q2 bindings are gone
	if len(ex.BindingsForQueue("q2")) != 0 {
		t.Errorf("Wrong number of bindings")
	}

}
Пример #10
0
func TestRemoveBindingsForQueue(t *testing.T) {
	var ex = NewExchange("ex1", EX_TYPE_TOPIC, true, true, false, amqp.NewTable(), false, make(chan *Exchange))
	var b1 = bindingHelper("q1", "ex1", "a.b.c", true)
	var b2 = bindingHelper("q1", "ex1", "d.e.f", true)
	var b3 = bindingHelper("q1", "ex1", "g.h.i", true)
	var b4 = bindingHelper("q2", "ex1", "g.h.i", true)
	var b5 = bindingHelper("q2", "ex1", "j.k.l", true)
	//
	ex.AddBinding(b1, -1)
	ex.AddBinding(b2, -1)
	ex.AddBinding(b3, -1)
	ex.AddBinding(b4, -1)
	ex.AddBinding(b5, -1)

	ex.RemoveBindingsForQueue("q0")
	if len(ex.bindings) != 5 {
		t.Errorf("Wrong number of bindings after removing q0 bindings")
	}
	ex.RemoveBindingsForQueue("q1")
	if len(ex.bindings) != 2 {
		t.Errorf("Wrong number of bindings after removing q1 bindings")
	}
	ex.RemoveBindingsForQueue("q2")
	if len(ex.bindings) != 0 {
		t.Errorf("Wrong number of bindings after removing q2 bindings: %v", ex.bindings)
	}

}
Пример #11
0
func TestFanout(t *testing.T) {
	b, _ := NewBinding("q1", "e1", "rk", amqp.NewTable(), false)
	if b.MatchFanout(basicPublish("DIFF", "asdf")) {
		t.Errorf("Fanout did not check exchanges")
	}
	if !b.MatchFanout(basicPublish("e1", "asdf")) {
		t.Errorf("Fanout didn't match regardless of key")
	}
}
Пример #12
0
func TestDirect(t *testing.T) {
	b, _ := NewBinding("q1", "e1", "rk", amqp.NewTable(), false)
	if b.MatchDirect(basicPublish("DIFF", "asdf")) {
		t.Errorf("MatchDirect did not check exchanges")
	}
	if b.MatchDirect(basicPublish("e1", "asdf")) {
		t.Errorf("MatchDirect matched even with the wrong key")
	}
	if !b.MatchDirect(basicPublish("e1", "rk")) {
		t.Errorf("MatchDirect did not match with the correct key and exchange")
	}
}
Пример #13
0
func TestExchangeRoutingTopic(t *testing.T) {
	var exTopic = NewExchange(
		"ext",
		EX_TYPE_TOPIC,
		false,
		false,
		false,
		amqp.NewTable(),
		false,
		make(chan *Exchange),
	)
	exTopic.AddBinding(bindingHelper("q1", "ext", "api.msg.*.json", true), -1)
	exTopic.AddBinding(bindingHelper("q1", "ext", "api.*.home.json", true), -1)
	exTopic.AddBinding(bindingHelper("q2", "ext", "api.msg.home.json", true), -1)
	exTopic.AddBinding(bindingHelper("q3", "ext", "log.#", true), -1)

	// Create a random message, won't route by default
	var msg = amqp.RandomMessage(false)
	msg.Method.Exchange = "ext"

	// no match
	res, err := exTopic.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	if len(res) > 0 {
		t.Errorf("Routed message which should not have routed", res)
	}

	// one match on #
	msg.Method.RoutingKey = "log.msg.home.json"
	res, err = exTopic.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	_, foundLog := res["q3"]
	if !foundLog || len(res) != 1 {
		t.Errorf("Bad results routing to # key")
	}

	// one queue on two matches
	msg.Method.RoutingKey = "api.msg.home.json"
	res, err = exTopic.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	_, foundQ1 := res["q1"]
	_, foundQ2 := res["q2"]
	if !foundQ1 || !foundQ2 || len(res) != 2 {
		t.Errorf("Bad results routing to multiply-bound * key")
	}

}
Пример #14
0
func exchangeForTest(name string, typ uint8) *Exchange {
	return NewExchange(
		name,
		typ,
		false,
		false,
		false,
		amqp.NewTable(),
		false,
		make(chan *Exchange),
	)
}
Пример #15
0
func (server *Server) addQueue(q *queue.Queue) error {
	server.serverLock.Lock()
	defer server.serverLock.Unlock()
	server.queues[q.Name] = q
	var defaultExchange = server.exchanges[""]
	var defaultBinding, err = binding.NewBinding(q.Name, "", q.Name, amqp.NewTable(), false)
	if err != nil {
		return err
	}
	defaultExchange.AddBinding(defaultBinding, q.ConnId)
	q.Start()
	return nil
}
Пример #16
0
func TestExchangeRoutingDirect(t *testing.T) {
	// Make exchange ang binding
	var exDirect = NewExchange(
		"exd",
		EX_TYPE_DIRECT,
		false,
		false,
		false,
		amqp.NewTable(),
		false,
		make(chan *Exchange),
	)
	exDirect.AddBinding(bindingHelper("q1", "exd", "rk-1", false), -1)

	// Create a random message, won't route by default
	var msg = amqp.RandomMessage(false)
	// Test wrong exchange for coverage
	res, err := exDirect.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	if len(res) > 0 {
		t.Errorf("Routed message which should not have routed", res)
	}

	// Test right exchange, wrong key
	msg.Method.Exchange = "exd"

	res, err = exDirect.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	if len(res) > 0 {
		t.Errorf("Routed message which should not have routed", res)
	}

	// Set the right values for routing
	msg.Method.RoutingKey = "rk-1"

	res, err = exDirect.QueuesForPublish(msg)
	if err != nil {
		t.Errorf(err.Msg)
	}
	if _, found := res["q1"]; !found {
		t.Errorf("Failed to route direct message: %s", res)
	}
}
Пример #17
0
func TestPersistence(t *testing.T) {
	var dbFile = "TestBindingPersistence.db"
	os.Remove(dbFile)
	defer os.Remove(dbFile)
	db, err := bolt.Open(dbFile, 0600, nil)
	if err != nil {
		t.Errorf("Failed to create db")
	}

	// Persist
	b, err := NewBinding("q1", "ex1", "rk1", amqp.NewTable(), true)
	if err != nil {
		t.Errorf("Error in NewBinding")
	}
	err = b.Persist(db)
	if err != nil {
		t.Errorf("Error in NewBinding")
	}

	// Read
	bMap, err := LoadAllBindings(db)
	if err != nil {
		t.Errorf("Error in LoadAllBindings")
	}
	if len(bMap) != 1 {
		t.Errorf("Wrong number of bindings")
	}
	for _, b2 := range bMap {
		if !b2.Equals(b) {
			t.Errorf("Did not get the same binding from the db")
		}
	}

	// Depersist
	b.Depersist(db)

	bMap, err = LoadAllBindings(db)
	if err != nil {
		t.Errorf("Error in LoadAllBindings")
	}
	if len(bMap) != 0 {
		t.Errorf("Wrong number of bindings")
	}

}
Пример #18
0
func TestPersistence(t *testing.T) {
	// Create DB
	var dbFile = "TestExchangePersistence.db"
	os.Remove(dbFile)
	defer os.Remove(dbFile)
	db, err := bolt.Open(dbFile, 0600, nil)
	if err != nil {
		t.Errorf("Failed to create db")
	}
	var ex = exchangeForTest("ex1", EX_TYPE_TOPIC)
	ex.Durable = true
	err = ex.Persist(db)
	if err != nil {
		t.Errorf("Could not persist exchange %s", ex.Name)
	}
	ex.Name = ""
	err = ex.Persist(db)
	if err != nil {
		t.Errorf(err.Error())
	}

	// Read
	deleteChan := make(chan *Exchange)
	_, err = NewFromDisk(db, "ex1", deleteChan)
	if err != nil {
		t.Errorf("Error loading persisted exchage %s", err.Error())
	}
	_, err = NewFromDisk(db, "", deleteChan)
	if err != nil {
		t.Errorf("Error loading persisted exchage %s", err.Error())
	}

	// Depersist
	realEx := NewExchange("ex1", EX_TYPE_TOPIC, true, false, false, amqp.NewTable(), false, make(chan *Exchange))
	realEx.AddBinding(bindingHelper("q1", "ex1", "api.msg.*.json", true), -1)
	realEx.Depersist(db)

	// Verify
	_, err = NewFromDisk(db, "ex1", deleteChan)
	if err == nil {
		t.Errorf("Failed to delete exchange 'ex1'")
	}
}
Пример #19
0
func TestJson(t *testing.T) {
	basic, _ := NewBinding("q1", "e1", "hello.world", amqp.NewTable(), true)
	var basicBytes, err = basic.MarshalJSON()
	if err != nil {
		t.Errorf(err.Error())
	}

	expectedBytes, err := json.Marshal(map[string]interface{}{
		"queueName":    "q1",
		"exchangeName": "e1",
		"key":          "hello.world",
		"arguments":    make(map[string]interface{}),
	})
	if string(expectedBytes) != string(basicBytes) {
		t.Logf("Expected: %s", expectedBytes)
		t.Logf("Got: %s", basicBytes)
		t.Errorf("Wrong json bytes!")
	}

}
Пример #20
0
func (server *Server) genDefaultExchange(name string, typ uint8) {
	_, hasKey := server.exchanges[name]
	if !hasKey {
		var ex = exchange.NewExchange(
			name,
			exchange.EX_TYPE_TOPIC,
			true,
			false,
			false,
			amqp.NewTable(),
			true,
			server.exchangeDeleter,
		)
		// Persist
		ex.Persist(server.db)
		err := server.addExchange(ex)
		if err != nil {
			panic(err.Error())
		}
	}
}
Пример #21
0
func TestBindingsForQueue(t *testing.T) {
	var ex = NewExchange("ex1", EX_TYPE_TOPIC, true, true, false, amqp.NewTable(), false, make(chan *Exchange))
	var b1 = bindingHelper("q1", "ex1", "a.b.c", true)
	var b2 = bindingHelper("q1", "ex1", "d.e.f", true)
	var b3 = bindingHelper("q1", "ex1", "g.h.i", true)
	var b4 = bindingHelper("q2", "ex1", "g.h.i", true)
	var b5 = bindingHelper("q2", "ex1", "j.k.l", true)
	//
	ex.AddBinding(b1, -1)
	ex.AddBinding(b2, -1)
	ex.AddBinding(b3, -1)
	ex.AddBinding(b4, -1)
	ex.AddBinding(b5, -1)

	if len(ex.BindingsForQueue("q1")) != 3 {
		t.Errorf("Wrong number of bindings for q1")
	}
	if len(ex.BindingsForQueue("q2")) != 2 {
		t.Errorf("Wrong number of bindings for q2")
	}
	if len(ex.BindingsForQueue("q0")) != 0 {
		t.Errorf("Wrong number of bindings for q0")
	}
}
Пример #22
0
func TestEquivalentExchanges(t *testing.T) {
	var ex = NewExchange(
		"ex1",
		EX_TYPE_DIRECT,
		true,
		true,
		true,
		amqp.NewTable(),
		true,
		make(chan *Exchange),
	)
	var ex2 = NewExchange(
		"ex1",
		EX_TYPE_DIRECT,
		true,
		true,
		true,
		amqp.NewTable(),
		true,
		make(chan *Exchange),
	)
	// Same
	if !ex.EquivalentExchanges(ex2) {
		t.Errorf("Same exchanges aren't equal!")
	}
	// name
	ex2.Name = "ex2"
	if ex.EquivalentExchanges(ex2) {
		t.Errorf("Different exchanges are equal!")
	}
	ex2.Name = "ex1"

	// extype
	ex2.ExType = EX_TYPE_TOPIC
	if ex.EquivalentExchanges(ex2) {
		t.Errorf("Different exchanges are equal!")
	}
	ex2.ExType = EX_TYPE_DIRECT
	// internal
	ex2.Internal = false
	if ex.EquivalentExchanges(ex2) {
		t.Errorf("Different exchanges are equal!")
	}
	ex2.Internal = true
	// durable
	ex2.Durable = false
	if ex.EquivalentExchanges(ex2) {
		t.Errorf("Different exchanges are equal!")
	}
	ex2.Durable = true
	// args
	var newTable = amqp.NewTable()
	newTable.SetKey("stuff", true)
	ex2.Arguments = newTable
	if ex.EquivalentExchanges(ex2) {
		t.Errorf("Different exchanges are equal!")
	}
	ex2.Arguments = amqp.NewTable()
	// test other diffs ok
	ex2.System = false
	ex2.AutoDelete = false
	if !ex.EquivalentExchanges(ex2) {
		t.Errorf("Same exchanges aren't equal!")
	}
}