예제 #1
0
/**
 * Test multiple responders
 */
void DiscoveryAgentTest::testMultipleResponders() {
  UIDSet uids;
  ResponderList responders;
  UID uid_to_remove(0x7a70, 0x00002001);
  uids.AddUID(uid_to_remove);
  uids.AddUID(UID(0x7a70, 0x00002002));
  uids.AddUID(UID(0x7a77, 0x00002002));
  PopulateResponderListFromUIDs(uids, &responders);
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with two responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
  m_callback_run = false;

  // now try incremental, adding one uid and removing another
  UID uid_to_add(0x8080, 0x00103456);
  uids.RemoveUID(uid_to_remove);
  uids.AddUID(uid_to_add);
  // update the responder list
  target.RemoveResponder(uid_to_remove);
  target.AddResponder(new MockResponder(uid_to_add));

  OLA_INFO << "starting incremental discovery with modified responder list";
  agent.StartIncrementalDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
}
예제 #2
0
void
IMAPFolder::MessageEntriesFetched()
{
	_WaitForFolderState();

	// Synchronize all pending flags first
	UIDToFlagsMap::const_iterator pendingIterator = fPendingFlagsMap.begin();
	for (; pendingIterator != fPendingFlagsMap.end(); pendingIterator++)
		SyncMessageFlags(pendingIterator->first, pendingIterator->second);

	fPendingFlagsMap.clear();

	// Delete all local messages that are no longer found on the server

	MutexLocker locker(fLock);
	UIDSet deleteUIDs;
	UIDToRefMap::const_iterator iterator = fRefMap.begin();
	for (; iterator != fRefMap.end(); iterator++) {
		uint32 uid = iterator->first;
		if (fSynchronizedUIDsSet.find(uid) == fSynchronizedUIDsSet.end())
			deleteUIDs.insert(uid);
	}

	fSynchronizedUIDsSet.clear();
	locker.Unlock();

	UIDSet::const_iterator deleteIterator = deleteUIDs.begin();
	for (; deleteIterator != deleteUIDs.end(); deleteIterator++)
		_DeleteLocalMessage(*deleteIterator);
}
예제 #3
0
/*
 * Check that interleaving requests and discovery commands work.
 */
void QueueingRDMControllerTest::testRequestAndDiscovery() {
  MockRDMController mock_controller;
  auto_ptr<ola::rdm::DiscoverableQueueingRDMController> controller(
      new ola::rdm::DiscoverableQueueingRDMController(&mock_controller, 1));

  UIDSet uids;
  UID uid1(2, 3);
  UID uid2(10, 11);
  uids.AddUID(uid1);
  uids.AddUID(uid2);

  // Send a request, but don't run the RDM request callback
  RDMRequest *get_request = NewGetRequest(m_source, m_destination);
  mock_controller.ExpectCallAndCapture(get_request);

  RDMReply *expected_reply = new RDMReply(
      ola::rdm::RDM_COMPLETED_OK,
      NewGetResponse(m_destination, m_source));

  controller->SendRDMRequest(
      get_request,
      ola::NewSingleCallback(
          this,
          &QueueingRDMControllerTest::VerifyResponse,
          expected_reply));

  // now queue up a discovery request
  controller->RunFullDiscovery(
      NewSingleCallback(
          this,
          &QueueingRDMControllerTest::VerifyDiscoveryComplete,
          &uids));
  mock_controller.Verify();
  OLA_ASSERT_FALSE(m_discovery_complete_count);

  // now run the RDM callback, this should unblock the discovery process
  mock_controller.AddExpectedDiscoveryCall(true, NULL);
  mock_controller.RunRDMCallback(expected_reply);
  mock_controller.Verify();

  // now queue another RDM request
  RDMRequest *get_request2 = NewGetRequest(m_source, m_destination);
  RDMReply *expected_reply2 = new RDMReply(
      ola::rdm::RDM_COMPLETED_OK,
      NewGetResponse(m_destination, m_source));
  mock_controller.ExpectCallAndReplyWith(get_request2, expected_reply2);

  // discovery is still running so this won't send the request just yet.
  controller->SendRDMRequest(
      get_request2,
      ola::NewSingleCallback(
          this,
          &QueueingRDMControllerTest::VerifyResponse,
          expected_reply2));

  // now finish the discovery
  mock_controller.RunDiscoveryCallback(uids);
  OLA_ASSERT_TRUE(m_discovery_complete_count);
  mock_controller.Verify();
}
예제 #4
0
/**
 * Build a vector of MockResponder objects with the given uids.
 */
void DiscoveryAgentTest::PopulateResponderListFromUIDs(
    const UIDSet &uids,
    ResponderList *responders) {
  UIDSet::Iterator iter = uids.Begin();
  for (; iter != uids.End(); iter++)
    responders->push_back(new MockResponder(*iter));
}
예제 #5
0
/**
 * Test a responder that can't make up it's mind about it's UID
 */
void DiscoveryAgentTest::testBipolarResponder() {
  UIDSet uids;
  ResponderList responders;
  uids.AddUID(UID(0x7a70, 0x00002002));
  PopulateResponderListFromUIDs(uids, &responders);
  // add the BiPolarResponders
  UID bipolar_uid = UID(0x7a77, 0x00002002);
  UID bipolar_uid2 = UID(0x7a77, 0x00003030);
  responders.push_back(new BiPolarResponder(bipolar_uid));
  responders.push_back(new BiPolarResponder(bipolar_uid2));
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with BiPolarResponder responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoveryFailed,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
  m_callback_run = false;

  // now try incremental, adding one uid and removing another
  OLA_INFO << "starting incremental discovery with modified responder list";
  agent.StartIncrementalDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoveryFailed,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
}
예제 #6
0
/*
 * Verify reentrant discovery works
 */
void QueueingRDMControllerTest::testReentrantDiscovery() {
  MockRDMController mock_controller;
  auto_ptr<ola::rdm::DiscoverableQueueingRDMController> controller(
      new ola::rdm::DiscoverableQueueingRDMController(&mock_controller, 1));

  UIDSet uids;
  UID uid1(2, 3);
  UID uid2(10, 11);
  uids.AddUID(uid1);
  uids.AddUID(uid2);

  // trigger discovery, the ReentrantDiscovery starts a new discovery from
  // within the callback of the first.
  mock_controller.AddExpectedDiscoveryCall(true, NULL);
  controller->RunFullDiscovery(
      NewSingleCallback(
          this,
          &QueueingRDMControllerTest::ReentrantDiscovery,
          controller.get(),
          &uids));
  mock_controller.Verify();

  // this will finish the first discovery attempt, and start the second
  mock_controller.AddExpectedDiscoveryCall(true, NULL);
  mock_controller.RunDiscoveryCallback(uids);
  OLA_ASSERT_TRUE(m_discovery_complete_count);
  m_discovery_complete_count = 0;
  mock_controller.Verify();

  // now unblock the second
  mock_controller.RunDiscoveryCallback(uids);
  OLA_ASSERT_TRUE(m_discovery_complete_count);
  m_discovery_complete_count = 0;
  mock_controller.Verify();
}
예제 #7
0
 void ShowUIDs() {
   UIDSet::Iterator iter = m_uids.Begin();
   cout << "---------- " << m_uids.Size() << " UIDs -------" << endl;
   char c = 'A';
   for (; iter != m_uids.End(); ++iter) {
     if (c <= 'Z') {
       cout << *iter << " (" << c++ << ")" << endl;
     } else {
       cout << *iter << endl;
     }
   }
   cout << "-------------------------" << endl;
 }
예제 #8
0
/**
 * Called when RDM discovery completes
 */
void OlaServerServiceImpl::RDMDiscoveryComplete(
    unsigned int universe_id,
    ola::rpc::RpcService::CompletionCallback* done,
    ola::proto::UIDListReply *response,
    const UIDSet &uids) {
  ClosureRunner runner(done);

  response->set_universe(universe_id);
  UIDSet::Iterator iter = uids.Begin();
  for (; iter != uids.End(); ++iter) {
    ola::proto::UID *uid = response->add_uid();
    SetProtoUID(*iter, uid);
  }
}
예제 #9
0
/**
 * Called when RDM discovery completes
 */
void OlaServerServiceImpl::RDMDiscoveryComplete(
    unsigned int universe_id,
    google::protobuf::Closure* done,
    ola::proto::UIDListReply *response,
    const UIDSet &uids) {
  ClosureRunner runner(done);

  response->set_universe(universe_id);
  UIDSet::Iterator iter = uids.Begin();
  for (; iter != uids.End(); ++iter) {
    ola::proto::UID *uid = response->add_uid();
    uid->set_esta_id(iter->ManufacturerId());
    uid->set_device_id(iter->DeviceId());
  }
}
int main(int argc, char* argv[]) {
    UIDSet uids;

    if (argc < 3) {
        std::cerr << "ERROR: Must have at least two arguments: basename and a UID"
                  << std::endl;
        return -1;
    }

    try {
        stoi(argv[1], NULL, 10);
        std::cerr << "ERROR: First argument must not be an integer"
                  << std::endl;
        return -1;
    } catch (...) {}

    std::string basename(std::string(argv[1]) + "_mixed");

    if (basename.find("/") != std::string::npos) {
        std::cerr << "ERROR: Basename may not contain path separator"
                  << std::endl;
        return -1;
    }

    for (int i = 2; i < argc; ++i) {
        uids.insert(stoi(argv[i], NULL, 10));
    }
    ParamSet extraParams;
    extraParams.insert(-1); // Don't-care value
    SetuidState startState = SetuidState::get();
    Explorer explorer(
        Graph(VG(), uids, startState),
        EG(),
        uids,
        extraParams);

    explorer.exploreAll();

    Graph const& graph = explorer.getGraph();
    GraphName name(basename, uids, extraParams);
    ArchiveWriter<Graph>().write(graph, name);
    DotWriter<Graph>().write(graph, name);

    return 0;
}
예제 #11
0
/**
 * Called when discovery completes and fails for some reason.
 */
void DiscoveryAgentTest::DiscoveryFailed(const UIDSet *expected,
                                         bool successful,
                                         const UIDSet &received) {
  OLA_INFO << "in discovery callback, size is " << received.Size() <<
      ", state: " << successful;
  OLA_ASSERT_FALSE(successful);
  OLA_ASSERT_EQ(*expected, received);
  m_callback_run = true;
}
예제 #12
0
/**
 * Test a responder that replies with too little data.
 */
void DiscoveryAgentTest::testBriefResponder() {
  UIDSet uids;
  ResponderList responders;
  uids.AddUID(UID(0x7a70, 0x00002002));
  PopulateResponderListFromUIDs(uids, &responders);
  // add the BriefResponder
  UID brief_uid = UID(0x7a77, 0x00002002);
  responders.push_back(new BriefResponder(brief_uid));
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with brief responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoveryFailed,
                             static_cast<const UIDSet*>(&uids)));
  OLA_ASSERT_TRUE(m_callback_run);
}
예제 #13
0
/**
 * Called when discovery completes
 */
void DiscoveryAgentTest::DiscoverySuccessful(const UIDSet *expected,
                                             bool successful,
                                             const UIDSet &received) {
  OLA_INFO << "in discovery callback, size is " << received.Size() <<
      ", state: " << successful;
  CPPUNIT_ASSERT(successful);
  CPPUNIT_ASSERT_EQUAL(*expected, received);
  m_callback_run = true;
}
예제 #14
0
/**
 * Test a proxy.
 */
void DiscoveryAgentTest::testProxy() {
  UIDSet proxied_uids, proxied_uids2;
  ResponderList proxied_responders, proxied_responders2, responders;
  proxied_uids.AddUID(UID(0x7a70, 0x00002002));
  proxied_uids.AddUID(UID(0x8080, 0x00001234));
  proxied_uids.AddUID(UID(0x9000, 0x00005678));
  proxied_uids.AddUID(UID(0x1020, 0x00005678));
  PopulateResponderListFromUIDs(proxied_uids, &proxied_responders);
  proxied_uids2.AddUID(UID(0x7a71, 0x00002002));
  proxied_uids2.AddUID(UID(0x8081, 0x00001234));
  proxied_uids2.AddUID(UID(0x9001, 0x00005678));
  proxied_uids2.AddUID(UID(0x1021, 0x00005678));
  PopulateResponderListFromUIDs(proxied_uids2, &proxied_responders2);
  // add the two proxies
  UIDSet uids = proxied_uids.Union(proxied_uids2);
  UID proxy_uid = UID(0x1010, 0x00002002);
  uids.AddUID(proxy_uid);
  responders.push_back(new ProxyResponder(proxy_uid, proxied_responders));
  UID proxy_uid2 = UID(0x1010, 0x00001999);
  uids.AddUID(proxy_uid2);
  responders.push_back(new ProxyResponder(proxy_uid2, proxied_responders2));

  // add some other responders
  UID responder(0x0001, 0x00000001);
  UID responder2(0x0001, 0x10000001);
  uids.AddUID(responder);
  uids.AddUID(responder2);
  responders.push_back(new MockResponder(responder));
  responders.push_back(new MockResponder(responder2));

  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with Proxy responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  OLA_ASSERT_TRUE(m_callback_run);
  m_callback_run = false;
}
예제 #15
0
/**
 * Test a responder that doesn't respond to a mute message.
 */
void DiscoveryAgentTest::testNonMutingResponder() {
  UIDSet uids;
  ResponderList responders;
  uids.AddUID(UID(0x7a70, 0x00002002));
  PopulateResponderListFromUIDs(uids, &responders);
  // add the NonMutingResponders
  UID non_muting_uid = UID(0x7a77, 0x00002002);
  UID non_muting_uid2 = UID(0x7a77, 0x00003030);
  responders.push_back(new NonMutingResponder(non_muting_uid));
  responders.push_back(new NonMutingResponder(non_muting_uid2));
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with NonMutingResponder responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoveryFailed,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
  m_callback_run = false;
}
예제 #16
0
/**
 * Test a responder that replies with responses larger than the DUB size
 */
void DiscoveryAgentTest::testRamblingResponder() {
  const UID normal_responder_uid(0x7a70, 0x00002002);
  const UID rambling_responder_uid(0x7a77, 0x0002002);

  UIDSet uids;
  ResponderList responders;
  uids.AddUID(normal_responder_uid);
  PopulateResponderListFromUIDs(uids, &responders);
  // add the RamblingResponder
  responders.push_back(new RamblingResponder(rambling_responder_uid));
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  uids.AddUID(rambling_responder_uid);
  OLA_INFO << "starting discovery with rambling responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  OLA_ASSERT_TRUE(m_callback_run);
}
예제 #17
0
/**
 * Test single responder with a broadcast UID
 */
void DiscoveryAgentTest::testResponderWithBroadcastUID() {
  UIDSet uids;
  ResponderList responders;
  uids.AddUID(UID(0xffff, 0xffffffff));
  PopulateResponderListFromUIDs(uids, &responders);
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  OLA_ASSERT_TRUE(m_callback_run);
  m_callback_run = false;

  // now try incremental
  agent.StartIncrementalDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  OLA_ASSERT_TRUE(m_callback_run);
}
예제 #18
0
파일: UIDTest.cpp 프로젝트: basileus/ola
/*
 * Test the UIDSet
 */
void UIDTest::testUIDSet() {
  UIDSet set1;
  OLA_ASSERT_EQ(0u, set1.Size());

  UID uid(1, 2);
  UID uid2(2, 10);
  set1.AddUID(uid);
  OLA_ASSERT_EQ(1u, set1.Size());
  OLA_ASSERT_EQ(string("0001:00000002"), set1.ToString());
  OLA_ASSERT_TRUE(set1.Contains(uid));
  OLA_ASSERT_FALSE(set1.Contains(uid2));
  set1.AddUID(uid);
  OLA_ASSERT_EQ(1u, set1.Size());

  set1.AddUID(uid2);
  OLA_ASSERT_EQ(2u, set1.Size());
  OLA_ASSERT_EQ(string("0001:00000002,0002:0000000a"), set1.ToString());
  OLA_ASSERT_TRUE(set1.Contains(uid));
  OLA_ASSERT_TRUE(set1.Contains(uid2));

  UIDSet set2(set1);
  OLA_ASSERT_EQ(set1, set2);
  UIDSet set3;
  OLA_ASSERT_EQ(0u, set3.Size());
  set3 = set2;
  OLA_ASSERT_EQ(set1, set2);

  set3.RemoveUID(uid2);
  OLA_ASSERT_EQ(1u, set3.Size());
  OLA_ASSERT_EQ(string("0001:00000002"), set3.ToString());

  UIDSet difference = set1.SetDifference(set3);
  OLA_ASSERT_EQ(1u, difference.Size());
  OLA_ASSERT_TRUE(set1.Contains(uid));
  OLA_ASSERT_TRUE(set1.Contains(uid2));

  difference = set3.SetDifference(set1);
  OLA_ASSERT_EQ(0u, difference.Size());
}
예제 #19
0
/*
 * This is called when we receive uids for a universe
 * @param universes a vector of OlaUniverses
 */
void UIDList(const ola::rdm::UIDSet &uids,
             const string &error) {
  UIDSet vendorcast;
  if (error.empty()) {
    UIDSet::Iterator iter = uids.Begin();
    for (; iter != uids.End(); ++iter) {
      cout << *iter << endl;
      vendorcast.AddUID(UID::VendorcastAddress(*iter));
    }
    if (opts.vendorcast) {
      iter = vendorcast.Begin();
      for (; iter != vendorcast.End(); ++iter) {
        cout << *iter << endl;
      }
    }
    if (opts.broadcast) {
      cout << UID::AllDevices().ToString() << endl;
    }
  } else {
    cerr << error << endl;
  }
  ss->Terminate();
}
예제 #20
0
/**
 * Test a responder that only acks a mute request after N attempts.
 */
void DiscoveryAgentTest::testFlakeyResponder() {
  UIDSet uids;
  ResponderList responders;
  uids.AddUID(UID(0x7a70, 0x00002002));
  PopulateResponderListFromUIDs(uids, &responders);
  // add the NonMutingResponders
  UID flakey_uid = UID(0x7a77, 0x00002002);
  UID flakey_uid2 = UID(0x7a77, 0x00003030);
  uids.AddUID(flakey_uid);
  uids.AddUID(flakey_uid2);
  FlakeyMutingResponder *flakey_responder1 = new FlakeyMutingResponder(
      flakey_uid);
  FlakeyMutingResponder *flakey_responder2 = new FlakeyMutingResponder(
      flakey_uid2);
  responders.push_back(flakey_responder1);
  responders.push_back(flakey_responder2);
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with flakey responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
  m_callback_run = false;

  // now try incremental
  flakey_responder1->Reset();
  flakey_responder2->Reset();
  OLA_INFO << "starting incremental discovery with flakey responder list";
  agent.StartIncrementalDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
}
예제 #21
0
GraphName::GraphName(
    std::string const& basename,
    UIDSet const& uidSet,
    ParamSet const& paramSet) {
    std::vector<int> uids, params;
    for (UIDSet::const_iterator it = uidSet.begin(), ie = uidSet.end();
         it != ie; ++it) {
        uids.push_back(static_cast<int>(*it));
    }
    std::sort(uids.begin(), uids.end());
    for (ParamSet::const_iterator it = paramSet.begin(), ie = paramSet.end();
         it != ie; ++it) {
        params.push_back(*it);
    }
    std::sort(params.begin(), params.end());

    std::stringstream ss;
    ss << basename << "__u_";
    for (std::vector<int>::iterator it = uids.begin(), ie = uids.end();
         it != ie; ++it) {
        ss << *it;
        if (it +1 != uids.end()) {
            ss << "_";
        }
    }
    ss << "__p_";
    for (std::vector<int>::iterator it = params.begin(), ie = params.end();
         it != ie; ++it) {
        ss << *it;
        if (it +1 != params.end()) {
            ss << "_";
        }
    }

    name = ss.str();
}
예제 #22
0
/**
 * Test single responder
 */
void DiscoveryAgentTest::testSingleResponder() {
  UIDSet uids;
  ResponderList responders;
  uids.AddUID(UID(1, 10));
  PopulateResponderListFromUIDs(uids, &responders);
  MockDiscoveryTarget target(responders);

  DiscoveryAgent agent(&target);
  OLA_INFO << "starting discovery with one responder";
  agent.StartFullDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
  m_callback_run = false;

  // now try incremental
  OLA_INFO << "starting incremental discovery with one responder";
  agent.StartIncrementalDiscovery(
      ola::NewSingleCallback(this,
                             &DiscoveryAgentTest::DiscoverySuccessful,
                             static_cast<const UIDSet*>(&uids)));
  CPPUNIT_ASSERT(m_callback_run);
}
예제 #23
0
  void SetIdentify(bool identify_on) {
    JaRuleWidget *widget = m_widget_manager->GetWidget();
    if (!widget) {
      return;
    }

    if (m_uids.Size() == 0) {
      OLA_WARN << "No UIDs";
      return;
    }

    uint8_t param_data = identify_on;
    RDMSetRequest *request = new RDMSetRequest(
        m_widget_uid, m_selected_uid, 0, 0, 0, ola::rdm::PID_IDENTIFY_DEVICE,
        &param_data, sizeof(param_data));
    widget->SendRDMRequest(request, NULL);
  }
예제 #24
0
/**
 * Check that interleaving requests and discovery commands work.
 */
void QueueingRDMControllerTest::testRequestAndDiscovery() {
  MockRDMController mock_controller;
  auto_ptr<ola::rdm::DiscoverableQueueingRDMController> controller(
      new ola::rdm::DiscoverableQueueingRDMController(&mock_controller, 1));

  UIDSet uids;
  UID uid1(2, 3);
  UID uid2(10, 11);
  uids.AddUID(uid1);
  uids.AddUID(uid2);

  UID source(1, 2);
  UID destination(3, 4);

  // Send a request, but don't run the RDM request callback
  RDMRequest *get_request = NewGetRequest(source, destination);

  RDMGetResponse expected_command(destination,
                                  source,
                                  0,  // transaction #
                                  RDM_ACK,
                                  0,  // message count
                                  10,  // sub device
                                  296,  // param id
                                  NULL,  // data
                                  0);  // data length

  mock_controller.AddExpectedCall(get_request,
                                  ola::rdm::RDM_COMPLETED_OK,
                                  NULL,
                                  "",
                                  false);

  vector<string> packets;
  packets.push_back("foo");
  controller->SendRDMRequest(
      get_request,
      ola::NewSingleCallback(
          this,
          &QueueingRDMControllerTest::VerifyResponse,
          ola::rdm::RDM_COMPLETED_OK,
          static_cast<const RDMResponse*>(&expected_command),
          packets,
          false));

  // now queue up a discovery request
  controller->RunFullDiscovery(
      NewSingleCallback(
          this,
          &QueueingRDMControllerTest::VerifyDiscoveryComplete,
          &uids));
  mock_controller.Verify();
  CPPUNIT_ASSERT(!m_discovery_complete_count);

  // now run the RDM callback, this should unblock the discovery process
  mock_controller.AddExpectedDiscoveryCall(true, NULL);
  mock_controller.RunRDMCallback(ola::rdm::RDM_COMPLETED_OK,
                                 &expected_command,
                                 "foo");
  mock_controller.Verify();

  // now queue another RDM request
  RDMRequest *get_request2 = NewGetRequest(source, destination);

  RDMGetResponse expected_command2(destination,
                                   source,
                                   0,  // transaction #
                                   RDM_ACK,
                                   0,  // message count
                                   10,  // sub device
                                   296,  // param id
                                   NULL,  // data
                                   0);  // data length

  controller->SendRDMRequest(
      get_request2,
      ola::NewSingleCallback(
          this,
          &QueueingRDMControllerTest::VerifyResponse,
          ola::rdm::RDM_COMPLETED_OK,
          static_cast<const RDMResponse*>(&expected_command2),
          packets,
          false));
  // discovery is still running so this won't send the request
  mock_controller.Verify();

  // now finish the discovery
  mock_controller.AddExpectedCall(get_request2,
                                  ola::rdm::RDM_COMPLETED_OK,
                                  &expected_command,
                                  "foo");
  mock_controller.RunDiscoveryCallback(uids);
  CPPUNIT_ASSERT(m_discovery_complete_count);
  mock_controller.Verify();
}