void test_setup(const DomainParticipant_var& dp,
  const MessageTypeSupport_var& ts, const Publisher_var& pub,
  const Subscriber_var& sub, const char* topicName, DataWriter_var& dw,
  DataReader_var& dr)
{
  Topic_var topic = dp->create_topic(topicName, ts->get_type_name(),
                                     TOPIC_QOS_DEFAULT, 0,
                                     DEFAULT_STATUS_MASK);

  DataWriterQos dw_qos;
  pub->get_default_datawriter_qos(dw_qos);
  dw_qos.history.kind = KEEP_ALL_HISTORY_QOS;
  dw = pub->create_datawriter(topic, dw_qos, 0, DEFAULT_STATUS_MASK);

  DataReaderQos dr_qos;
  sub->get_default_datareader_qos(dr_qos);
  dr_qos.history.kind = KEEP_ALL_HISTORY_QOS;
  dr = sub->create_datareader(topic, dr_qos, 0, DEFAULT_STATUS_MASK);

  StatusCondition_var dw_sc = dw->get_statuscondition();
  dw_sc->set_enabled_statuses(PUBLICATION_MATCHED_STATUS);
  WaitSet_var ws = new WaitSet;
  ws->attach_condition(dw_sc);
  Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC};
  ConditionSeq active;
  ws->wait(active, infinite);
  ws->detach_condition(dw_sc);
}
void wait_match(const DataReader_var& dr, int n)
{
  StatusCondition_var condition = dr->get_statuscondition();
  condition->set_enabled_statuses(SUBSCRIPTION_MATCHED_STATUS);
  WaitSet_var ws = new DDS::WaitSet;
  ws->attach_condition(condition);
  ConditionSeq conditions;
  SubscriptionMatchedStatus ms = {0, 0, 0, 0, 0};
  const Duration_t timeout = {1, 0};
  while (dr->get_subscription_matched_status(ms) == RETCODE_OK
         && ms.current_count != n) {
    ws->wait(conditions, timeout);
  }
  ws->detach_condition(condition);
}
Beispiel #3
0
void waitForMatch(const DataWriter_var& dw, int count = 1)
{
  StatusCondition_var sc = dw->get_statuscondition();
  sc->set_enabled_statuses(PUBLICATION_MATCHED_STATUS);
  WaitSet_var ws = new WaitSet;
  ws->attach_condition(sc);
  const Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC};
  ConditionSeq active;
  PublicationMatchedStatus pubmatched;
  while (dw->get_publication_matched_status(pubmatched) == RETCODE_OK
         && pubmatched.current_count != count) {
    ws->wait(active, infinite);
  }
  ws->detach_condition(sc);
}
bool waitForSample(const DataReader_var& dr)
{
  ReadCondition_var dr_rc = dr->create_readcondition(ANY_SAMPLE_STATE,
    ANY_VIEW_STATE, ALIVE_INSTANCE_STATE);
  WaitSet_var ws = new WaitSet;
  ws->attach_condition(dr_rc);
  Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC};
  ConditionSeq active;
  ReturnCode_t ret = ws->wait(active, infinite);
  ws->detach_condition(dr_rc);
  dr->delete_readcondition(dr_rc);
  if (ret != RETCODE_OK) {
    cout << "ERROR: wait(rc) failed" << endl;
    return false;
  }
  return true;
}
int run_test(int argc, ACE_TCHAR *argv[])
{
  using namespace DDS;
  using namespace OpenDDS::DCPS;
  WaitSet_var ws = new WaitSet;
  DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv);
  DomainParticipant_var dp = dpf->create_participant(23,
    PARTICIPANT_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  Messenger::MessageTypeSupport_var ts = new Messenger::MessageTypeSupportImpl;
  ts->register_type(dp, ts->get_type_name());
  Topic_var topic = dp->create_topic("MyTopic", ts->get_type_name(),
    TOPIC_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

  Publisher_var pub = dp->create_publisher(PUBLISHER_QOS_DEFAULT, 0,
                                           ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  TransportImpl_rch pub_tport =
    TheTransportFactory->create_transport_impl(1, AUTO_CONFIG);
  PublisherImpl* pub_impl = dynamic_cast<PublisherImpl*> (pub.in());
  pub_impl->attach_transport(pub_tport.in());
  DataWriter_var dw = pub->create_datawriter(topic, DATAWRITER_QOS_DEFAULT, 0,
                                             ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  StatusCondition_var cond = dw->get_statuscondition();
  cond->set_enabled_statuses(OFFERED_INCOMPATIBLE_QOS_STATUS);
  ws->attach_condition(cond);

  Subscriber_var sub = dp->create_subscriber(SUBSCRIBER_QOS_DEFAULT, 0,
                                             ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  TransportImpl_rch sub_tport =
    TheTransportFactory->create_transport_impl(2, AUTO_CONFIG);
  SubscriberImpl* sub_impl = dynamic_cast<SubscriberImpl*> (sub.in());
  sub_impl->attach_transport(sub_tport.in());
  DataReaderQos dr_qos;
  sub->get_default_datareader_qos(dr_qos);
  dr_qos.durability.kind = PERSISTENT_DURABILITY_QOS;
  Waiter w(ws);
  w.activate();
  DataReader_var dr = sub->create_datareader(topic, dr_qos, 0,
                                             ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  w.wait();
  bool passed = (w.result() == RETCODE_OK);
  ws->detach_condition(cond);

  dp->delete_contained_entities();
  dpf->delete_participant(dp);
  return passed ? 0 : 1;
}
Beispiel #6
0
int
main (
    int ,
    char *[])
{
    /* Generic DDS entities */
    DomainParticipant_var           participant;
    Topic_var                       chatMessageTopic;
    Topic_var                       nameServiceTopic;
    Subscriber_var                  chatSubscriber;
    DataReader_ptr                  parentReader;
    QueryCondition_var              singleUser;
    ReadCondition_var               newUser;
    StatusCondition_var             leftUser;
    WaitSet_var                     userLoadWS;
    LivelinessChangedStatus         livChangStatus;

    /* QosPolicy holders */
    TopicQos                        setting_topic_qos;
    TopicQos                        reliable_topic_qos;
    SubscriberQos                   sub_qos;
    DataReaderQos                   message_qos;

    /* DDS Identifiers */
    DomainId_t                      domain = NULL;
    ReturnCode_t                    status;
    ConditionSeq                    guardList;

    /* Type-specific DDS entities */
    ChatMessageTypeSupport_var      chatMessageTS;
    NameServiceTypeSupport_var      nameServiceTS;
    NameServiceDataReader_var       nameServer;
    ChatMessageDataReader_var       loadAdmin;
    ChatMessageSeq                  msgList;
    NameServiceSeq                  nsList;
    SampleInfoSeq                   infoSeq;
    SampleInfoSeq                   infoSeq2;

    /* Others */
    StringSeq                       args;
    char *                          chatMessageTypeName = NULL;
    char *                          nameServiceTypeName = NULL;

    bool                            closed = false;
    CORBA::Long                     prevCount = 0;
    DWORD                           tid;
    HANDLE                          tHandle = INVALID_HANDLE_VALUE;

    /* Create a DomainParticipant (using the 'TheParticipantFactory' convenience macro). */
    participant = TheParticipantFactory->create_participant (
        domain,
        PARTICIPANT_QOS_DEFAULT,
        NULL,
        STATUS_MASK_NONE);
    checkHandle(participant.in(), "DDS::DomainParticipantFactory::create_participant");

    /* Register the required datatype for ChatMessage. */
    chatMessageTS = new ChatMessageTypeSupport();
    checkHandle(chatMessageTS.in(), "new ChatMessageTypeSupport");
    chatMessageTypeName = chatMessageTS->get_type_name();
    status = chatMessageTS->register_type(participant.in(), chatMessageTypeName);
    checkStatus(status, "Chat::ChatMessageTypeSupport::register_type");

    /* Register the required datatype for NameService. */
    nameServiceTS = new NameServiceTypeSupport();
    checkHandle(nameServiceTS.in(), "new NameServiceTypeSupport");
    nameServiceTypeName =  nameServiceTS->get_type_name();
    status = nameServiceTS->register_type(participant.in(), nameServiceTypeName);
    checkStatus(status, "Chat::NameServiceTypeSupport::register_type");

    /* Set the ReliabilityQosPolicy to RELIABLE. */
    status = participant->get_default_topic_qos(reliable_topic_qos);
    checkStatus(status, "DDS::DomainParticipant::get_default_topic_qos");
    reliable_topic_qos.reliability.kind = RELIABLE_RELIABILITY_QOS;

    /* Make the tailored QoS the new default. */
    status = participant->set_default_topic_qos(reliable_topic_qos);
    checkStatus(status, "DDS::DomainParticipant::set_default_topic_qos");

    /* Use the changed policy when defining the ChatMessage topic */
    chatMessageTopic = participant->create_topic(
        "Chat_ChatMessage",
        chatMessageTypeName,
        reliable_topic_qos,
        NULL,
        STATUS_MASK_NONE);
    checkHandle(chatMessageTopic.in(), "DDS::DomainParticipant::create_topic (ChatMessage)");

    /* Set the DurabilityQosPolicy to TRANSIENT. */
    status = participant->get_default_topic_qos(setting_topic_qos);
    checkStatus(status, "DDS::DomainParticipant::get_default_topic_qos");
    setting_topic_qos.durability.kind = TRANSIENT_DURABILITY_QOS;

    /* Create the NameService Topic. */
    nameServiceTopic = participant->create_topic(
        "Chat_NameService",
        nameServiceTypeName,
        setting_topic_qos,
        NULL,
        STATUS_MASK_NONE);
    checkHandle(nameServiceTopic.in(), "DDS::DomainParticipant::create_topic");

    /* Adapt the default SubscriberQos to read from the "ChatRoom" Partition. */
    status = participant->get_default_subscriber_qos (sub_qos);
    checkStatus(status, "DDS::DomainParticipant::get_default_subscriber_qos");
    sub_qos.partition.name.length(1);
    sub_qos.partition.name[0UL] = "ChatRoom";

    /* Create a Subscriber for the UserLoad application. */
    chatSubscriber = participant->create_subscriber(sub_qos, NULL, STATUS_MASK_NONE);
    checkHandle(chatSubscriber.in(), "DDS::DomainParticipant::create_subscriber");

    /* Create a DataReader for the NameService Topic (using the appropriate QoS). */
    parentReader = chatSubscriber->create_datareader(
        nameServiceTopic.in(),
        DATAREADER_QOS_USE_TOPIC_QOS,
        NULL,
        STATUS_MASK_NONE);
    checkHandle(parentReader, "DDS::Subscriber::create_datareader (NameService)");

    /* Narrow the abstract parent into its typed representative. */
    nameServer = NameServiceDataReader::_narrow(parentReader);
    checkHandle(nameServer.in(), "Chat::NameServiceDataReader::_narrow");

    /* Adapt the DataReaderQos for the ChatMessageDataReader to keep track of all messages. */
    status = chatSubscriber->get_default_datareader_qos(message_qos);
    checkStatus(status, "DDS::Subscriber::get_default_datareader_qos");
    status = chatSubscriber->copy_from_topic_qos(message_qos, reliable_topic_qos);
    checkStatus(status, "DDS::Subscriber::copy_from_topic_qos");
    message_qos.history.kind = KEEP_ALL_HISTORY_QOS;

    /* Create a DataReader for the ChatMessage Topic (using the appropriate QoS). */
    parentReader = chatSubscriber->create_datareader(
        chatMessageTopic.in(),
        message_qos,
        NULL,
        STATUS_MASK_NONE);
    checkHandle(parentReader, "DDS::Subscriber::create_datareader (ChatMessage)");

    /* Narrow the abstract parent into its typed representative. */
    loadAdmin = ChatMessageDataReader::_narrow(parentReader);
    checkHandle(loadAdmin.in(), "Chat::ChatMessageDataReader::_narrow");

    /* Initialize the Query Arguments. */
    args.length(1);
    args[0UL] = "0";

    /* Create a QueryCondition that will contain all messages with userID=ownID */
    singleUser = loadAdmin->create_querycondition(
        ANY_SAMPLE_STATE,
        ANY_VIEW_STATE,
        ANY_INSTANCE_STATE,
        "userID=%0",
        args);
    checkHandle(singleUser.in(), "DDS::DataReader::create_querycondition");

    /* Create a ReadCondition that will contain new users only */
    newUser = nameServer->create_readcondition(
        NOT_READ_SAMPLE_STATE,
        NEW_VIEW_STATE,
        ALIVE_INSTANCE_STATE);
    checkHandle(newUser.in(), "DDS::DataReader::create_readcondition");

    /* Obtain a StatusCondition that triggers only when a Writer changes Liveliness */
    leftUser = loadAdmin->get_statuscondition();
    checkHandle(leftUser.in(), "DDS::DataReader::get_statuscondition");
    status = leftUser->set_enabled_statuses(LIVELINESS_CHANGED_STATUS);
    checkStatus(status, "DDS::StatusCondition::set_enabled_statuses");

    /* Create a bare guard which will be used to close the room */
    escape = new GuardCondition();

    /* Create a waitset and add the ReadConditions */
    userLoadWS = new WaitSet();
    status = userLoadWS->attach_condition(newUser.in());
    checkStatus(status, "DDS::WaitSet::attach_condition (newUser)");
    status = userLoadWS->attach_condition(leftUser.in());
    checkStatus(status, "DDS::WaitSet::attach_condition (leftUser)");
    status = userLoadWS->attach_condition(escape.in());
    checkStatus(status, "DDS::WaitSet::attach_condition (escape)");

    /* Initialize and pre-allocate the GuardList used to obtain the triggered Conditions. */
    guardList.length(3);

    /* Remove all known Users that are not currently active. */
    status = nameServer->take(
        nsList,
        infoSeq,
        LENGTH_UNLIMITED,
        ANY_SAMPLE_STATE,
        ANY_VIEW_STATE,
        NOT_ALIVE_INSTANCE_STATE);
    checkStatus(status, "Chat::NameServiceDataReader::take");
    status = nameServer->return_loan(nsList, infoSeq);
    checkStatus(status, "Chat::NameServiceDataReader::return_loan");

    /* Start the sleeper thread. */
    tHandle = CreateThread(NULL, 0, delayedEscape, NULL, 0, &tid);

    while (!closed) {
        /* Wait until at least one of the Conditions in the waitset triggers. */
        status = userLoadWS->wait(guardList, DURATION_INFINITE);
        checkStatus(status, "DDS::WaitSet::wait");

        /* Walk over all guards to display information */
        for (CORBA::ULong i = 0; i < guardList.length(); i++) {
            if ( guardList[i].in() == newUser.in() ) {
                /* The newUser ReadCondition contains data */
                status = nameServer->read_w_condition(
                    nsList,
                    infoSeq,
                    LENGTH_UNLIMITED,
                    newUser.in() );
                checkStatus(status, "Chat::NameServiceDataReader::read_w_condition");

                for (CORBA::ULong j = 0; j < nsList.length(); j++) {
                    cout << "New user: "******"Chat::NameServiceDataReader::return_loan");

            } else if ( guardList[i].in() == leftUser.in() ) {
                /* Some liveliness has changed (either a DataWriter joined or a DataWriter left) */
                status = loadAdmin->get_liveliness_changed_status(livChangStatus);
                checkStatus(status, "DDS::DataReader::get_liveliness_changed_status");
                if (livChangStatus.alive_count < prevCount) {
                    /* A user has left the ChatRoom, since a DataWriter lost its liveliness */
                    /* Take the effected users so tey will not appear in the list later on. */
                    status = nameServer->take(
                        nsList,
                        infoSeq,
                        LENGTH_UNLIMITED,
                        ANY_SAMPLE_STATE,
                        ANY_VIEW_STATE,
                        NOT_ALIVE_NO_WRITERS_INSTANCE_STATE);
                    checkStatus(status, "Chat::NameServiceDataReader::take");

                    for (CORBA::ULong j = 0; j < nsList.length(); j++) {
                        /* re-apply query arguments */
                        ostringstream numberString;
                        numberString << nsList[j].userID;
                        args[0UL] = numberString.str().c_str();
                        status = singleUser->set_query_parameters(args);
                        checkStatus(status, "DDS::QueryCondition::set_query_parameters");

                        /* Read this users history */
                        status = loadAdmin->take_w_condition(
                            msgList,
                            infoSeq2,
                            LENGTH_UNLIMITED,
                            singleUser.in() );
                        checkStatus(status, "Chat::ChatMessageDataReader::take_w_condition");

                        /* Display the user and his history */
                        cout << "Departed user " << nsList[j].name << " has sent " <<
                            msgList.length() << " messages." << endl;
                        status = loadAdmin->return_loan(msgList, infoSeq2);
                        checkStatus(status, "Chat::ChatMessageDataReader::return_loan");
                    }
                    status = nameServer->return_loan(nsList, infoSeq);
                    checkStatus(status, "Chat::NameServiceDataReader::return_loan");
                }
                prevCount = livChangStatus.alive_count;

            } else if ( guardList[i].in() == escape.in() ) {
                cout << "UserLoad has terminated." << endl;
                closed = true;
            }
            else
            {
                assert(0);
            };
        } /* for */
    } /* while (!closed) */

    /* Remove all Conditions from the WaitSet. */
    status = userLoadWS->detach_condition( escape.in() );
    checkStatus(status, "DDS::WaitSet::detach_condition (escape)");
    status = userLoadWS->detach_condition( leftUser.in() );
    checkStatus(status, "DDS::WaitSet::detach_condition (leftUser)");
    status = userLoadWS->detach_condition( newUser.in() );
    checkStatus(status, "DDS::WaitSet::detach_condition (newUser)");

    /* Remove the type-names. */
    CORBA::string_free(chatMessageTypeName);
    CORBA::string_free(nameServiceTypeName);

    /* Free all resources */
    status = participant->delete_contained_entities();
    checkStatus(status, "DDS::DomainParticipant::delete_contained_entities");
    status = TheParticipantFactory->delete_participant( participant.in() );
    checkStatus(status, "DDS::DomainParticipantFactory::delete_participant");

    CloseHandle(tHandle);

    return 0;
}
bool run_filtering_test(const DomainParticipant_var& dp,
  const MessageTypeSupport_var& ts, const Publisher_var& pub,
  const Subscriber_var& sub)
{
  DataWriter_var dw;
  DataReader_var dr;
  test_setup(dp, ts, pub, sub, "MyTopic2", dw, dr);

  MessageDataWriter_var mdw = MessageDataWriter::_narrow(dw);
  Message sample;
  sample.key = 1;
  ReturnCode_t ret = mdw->write(sample, HANDLE_NIL);
  if (ret != RETCODE_OK) return false;
  if (!waitForSample(dr)) return false;

  ReadCondition_var dr_qc = dr->create_querycondition(ANY_SAMPLE_STATE,
    ANY_VIEW_STATE, ALIVE_INSTANCE_STATE, "key > 1", DDS::StringSeq());
  if (!dr_qc.in()) {
    cout << "ERROR: failed to create QueryCondition" << endl;
    return false;
  }
  WaitSet_var ws = new WaitSet;
  ws->attach_condition(dr_qc);
  ConditionSeq active;
  Duration_t three_sec = {3, 0};
  ret = ws->wait(active, three_sec);
  // expect a timeout because the sample doesn't match the query string
  if (ret != RETCODE_TIMEOUT) {
    cout << "ERROR: wait(qc) should have timed out" << endl;
    return false;
  }
  ws->detach_condition(dr_qc);

  MessageDataReader_var mdr = MessageDataReader::_narrow(dr);
  MessageSeq data;
  SampleInfoSeq infoseq;
  ret = mdr->take_w_condition(data, infoseq, LENGTH_UNLIMITED, dr_qc);
  if (ret != RETCODE_NO_DATA) {
    cout << "ERROR: take_w_condition(qc) shouldn't have returned data" << endl;
    return false;
  }

  SampleInfo info;
  if (mdr->take_next_sample(sample, info) != RETCODE_OK) {
    cout << "ERROR: take_next_sample() should have returned data" << endl;
    return false;
  }

  sample.key = 2;
  if (mdw->write(sample, HANDLE_NIL) != RETCODE_OK) return false;
  if (!waitForSample(dr)) return false;

  ws->attach_condition(dr_qc);
  ret = ws->wait(active, three_sec);
  if (ret != RETCODE_OK) {
    cout << "ERROR: wait(qc) should not time out" << endl;
    return false;
  }
  ws->detach_condition(dr_qc);

  ret = mdr->take_w_condition(data, infoseq, LENGTH_UNLIMITED, dr_qc);
  if (ret != RETCODE_OK) {
    cout << "ERROR: take_w_condition(qc) should have returned data" << endl;
    return false;
  }

  dr->delete_readcondition(dr_qc);
  return true;
}
bool run_sorting_test(const DomainParticipant_var& dp,
  const MessageTypeSupport_var& ts, const Publisher_var& pub,
  const Subscriber_var& sub)
{
  DataWriter_var dw;
  DataReader_var dr;
  test_setup(dp, ts, pub, sub, "MyTopic", dw, dr);

  ReturnCode_t ret = RETCODE_OK;
  MessageDataWriter_var mdw = MessageDataWriter::_narrow(dw);
  Message sample;
  sample.key = 0;
  sample.name = "data_X";
  sample.nest.value = B;
  for (int i(0); i < 20; ++i, ++sample.key) {
    //replace the 'X' with a random letter
    sample.name.inout()[5] = static_cast<char>((rand() % 26) + 'A');
    ret = mdw->write(sample, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    if (!(i % 4)) { //once in a while write more than 1 sample per instance
      Message sample2(sample);
      sample2.nest.value = A;
      sample2.name.inout()[5] = static_cast<char>((rand() % 26) + 'A');
      ret = mdw->write(sample2, HANDLE_NIL);
      if (ret != RETCODE_OK) return false;
      sample2.nest.value = C;
      ret = mdw->write(sample2, HANDLE_NIL);
      if (ret != RETCODE_OK) return false;
    }
  }

  DDS::StringSeq empty_query_params;
  ReadCondition_var dr_qc = dr->create_querycondition(ANY_SAMPLE_STATE,
    ANY_VIEW_STATE, ALIVE_INSTANCE_STATE, "ORDER BY name, nest.value",
    empty_query_params);
  WaitSet_var ws = new WaitSet;
  ws->attach_condition(dr_qc);
  MessageDataReader_var mdr = MessageDataReader::_narrow(dr);
  Duration_t five_seconds = {5, 0};
  bool passed = true, done = false;
  while (!done) {
    ConditionSeq active;
    ret = ws->wait(active, five_seconds);
    if (ret == RETCODE_TIMEOUT) {
      cout << "timeout ";
      done = true; //continue to try and read
    } else if (ret != RETCODE_OK) {
      passed = false;
      break;
    }
    cout << "wait returned" << endl;
    MessageSeq data;
    SampleInfoSeq info;
    ret = mdr->take_w_condition(data, info, LENGTH_UNLIMITED, dr_qc);
    if (ret == RETCODE_NO_DATA) {
      // fall-through
    } else if (ret != RETCODE_OK) {
      cout << "ERROR: take_w_condition returned " << ret << endl;
      passed = false;
      done = true;
    } else {
      char largest = 0;
      for (CORBA::ULong i(0); i < data.length(); ++i)  {
        cout << "Info:\tinstance_handle = " << info[i].instance_handle <<
          "\tsample_rank = " << info[i].sample_rank << '\n';
        if (info[i].valid_data) {
          cout << "Data:\tkey = " << data[i].key <<
            " \tname = " << data[i].name <<
            "\tnest.value = " << data[i].nest.value <<
            '\n';
          if (data[i].name[5] >= largest) {
            largest = data[i].name[5];
          } else {
            cout << "ERROR: data is not sorted for key: " <<
              data[i].key << endl;
            passed = false;
          }
        }
        cout << endl;
      }
    }
  }

  MessageSeq data;
  SampleInfoSeq info;
  ret = mdr->take_w_condition(data, info, LENGTH_UNLIMITED, dr_qc);
  if (ret != RETCODE_NO_DATA) {
    cout << "WARNING: there is still data in the reader\n";
  }

  ws->detach_condition(dr_qc);
  dr->delete_readcondition(dr_qc);
  return passed;
}
int run_test_instance(DDS::DomainParticipant_ptr dp)
{
  using namespace DDS;
  using namespace OpenDDS::DCPS;
  using namespace Messenger;
  WaitSet_var ws = new WaitSet;
  MessageTypeSupport_var ts = new MessageTypeSupportImpl;
  ts->register_type(dp, "");
  CORBA::String_var type_name = ts->get_type_name();
  Topic_var topic = dp->create_topic("MyTopic", type_name,
    TOPIC_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

  Publisher_var pub = dp->create_publisher(PUBLISHER_QOS_DEFAULT, 0,
    ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  DataWriter_var dw = pub->create_datawriter(topic, DATAWRITER_QOS_DEFAULT, 0,
    ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

  Subscriber_var sub = dp->create_subscriber(SUBSCRIBER_QOS_DEFAULT, 0,
    ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
  DataReader_var dr = sub->create_datareader(topic, DATAREADER_QOS_DEFAULT, 0,
    ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

  StatusCondition_var dw_sc = dw->get_statuscondition();
  dw_sc->set_enabled_statuses(PUBLICATION_MATCHED_STATUS);
  ws->attach_condition(dw_sc);
  Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC};
  ConditionSeq active;

  ReturnCode_t ret = ws->wait(active, infinite);
  if (ret != RETCODE_OK) return ret;

  ret = ws->detach_condition(dw_sc);
  if (ret != RETCODE_OK) return ret;

  MessageDataWriter_var mdw = MessageDataWriter::_narrow(dw);
  Message msg = {0};
  for (int i(0); i < 12; ++i) {
    ++msg.subject_id;
    ret = mdw->write(msg, HANDLE_NIL);
    if (ret != RETCODE_OK) return ret;
  }

  ReadCondition_var dr_rc = dr->create_readcondition(NOT_READ_SAMPLE_STATE,
    NEW_VIEW_STATE, ALIVE_INSTANCE_STATE);
  ReadCondition_var dr_rc2 = dr->create_readcondition(ANY_SAMPLE_STATE,
    ANY_VIEW_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE);
  ws->attach_condition(dr_rc);
  ws->attach_condition(dr_rc2);
  MessageDataReader_var mdr = MessageDataReader::_narrow(dr);
  bool passed = true, done = false;
  while (!done) {
    ret = ws->wait(active, infinite);
    if (ret != RETCODE_OK) {
      passed = false;
      break;
    }
    cout << "wait returned" << endl;
    for (CORBA::ULong i(0); i < active.length(); ++i) {
      if (active[i] == dr_rc) {
        // To test both take_w_condition and
        // take_next_instance_w_condition, we'll limit the "take" to 3
        // samples and then use take_next_instance_w_condition.
        MessageSeq data;
        SampleInfoSeq info;
        ret = mdr->take_w_condition(data, info, 3, dr_rc);
        if (ret == RETCODE_NO_DATA) break;
        if (ret != RETCODE_OK) {
          cout << "ERROR: take_w_condition returned " << ret << endl;
          passed = false;
          done = true;
        }
        InstanceHandle_t handle = HANDLE_NIL;
        received_data(data, mdw, msg);
        handle = info[info.length() - 1].instance_handle;
        if (handle == HANDLE_NIL) {
          cout << "ERROR: instance handle is nil" << endl;
          passed = false;
          done = true;
          break;
        }
        cout << "testing take_instance_w_condition" << endl;
        while (true) {
          ret = mdr->take_instance_w_condition(data, info, 1,
                                               handle, dr_rc);
          if (ret == RETCODE_NO_DATA) break;
          if (ret != RETCODE_OK) {
            cout << "ERROR: take_instance_w_condition returned "
                 << ret << endl;
            passed = false;
            done = true;
            break;
          }
          received_data(data, mdw, msg);
        }
      } else if (active[i] == dr_rc2) {
        cout << "an instance has been disposed, exiting" << endl;
        done = true;
      }
    }
  }
  ws->detach_condition(dr_rc);
  ws->detach_condition(dr_rc2);

  dp->delete_contained_entities();
  return passed ? 0 : 1;
}
bool run_multitopic_test(const Publisher_var& pub, const Subscriber_var& sub)
{
  DomainParticipant_var sub_dp = sub->get_participant();

  // Writer-side setup

  Writer<LocationInfo> location(pub, "Location", sub_dp);
  Writer<PlanInfo> flightplan(pub, "FlightPlan", sub_dp);
  Writer<MoreInfo> more(pub, "More", sub_dp);
  Writer<UnrelatedInfo> unrelated(pub, "Unrelated", sub_dp);
  MoreInfoDataWriter_var midw = MoreInfoDataWriter::_narrow(more.dw_);

  // Reader-side setup

  ResultingTypeSupport_var ts_res = new ResultingTypeSupportImpl;
  check(ts_res->register_type(sub_dp, ""));
  CORBA::String_var type_name = ts_res->get_type_name();
  MoreInfo mi;
  DDS::DataReader_var dr;

  for (int i = 0; i < N_ITERATIONS; ++i) {

    MultiTopic_var mt = sub_dp->create_multitopic("MyMultiTopic", type_name,
      "SELECT flight_name, x, y, z AS height, more, misc "
      "FROM Location NATURAL JOIN FlightPlan NATURAL JOIN More NATURAL JOIN "
      "Unrelated WHERE height < 1000 AND x<23", StringSeq());
    if (!mt) return false;
    dr = sub->create_datareader(mt, DATAREADER_QOS_DEFAULT,
                                0, DEFAULT_STATUS_MASK);

    // Write samples (Location)

    waitForMatch(location.dw_);
    LocationInfoDataWriter_var locdw =
      LocationInfoDataWriter::_narrow(location.dw_);
    LocationInfo sample = {100, 97, 23, 2, 3}; // filtered out (x < 23)
    ReturnCode_t ret = locdw->write(sample, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    LocationInfo sample2 = {100, 96, 1, 2, 3000}; // filtered out (height < 1000)
    ret = locdw->write(sample2, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    LocationInfo sample3 = {100, 99, 1, 2, 3};
    ret = locdw->write(sample3, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    LocationInfo sample3_5 = {100, 98, 4, 5, 6};
    ret = locdw->write(sample3_5, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;

    // Write samples (FlightPlan)

    waitForMatch(flightplan.dw_);
    PlanInfoDataWriter_var pidw = PlanInfoDataWriter::_narrow(flightplan.dw_);
    PlanInfo sample4;
    sample4.flight_id1 = 100;
    sample4.flight_id2 = 99;
    sample4.flight_name = "Flight 100-99";
    sample4.tailno = "N12345";
    ret = pidw->write(sample4, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    PlanInfo sample4_1(sample4);
    sample4_1.flight_id2 = 97;
    sample4_1.flight_name = "Flight 100-97";
    ret = pidw->write(sample4_1, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    PlanInfo sample4_2(sample4);
    sample4_2.flight_id2 = 96;
    sample4_2.flight_name = "Flight 100-96";
    ret = pidw->write(sample4_2, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;

    // Write samples (More)

    waitForMatch(more.dw_);
    mi.flight_id1 = 12345;
    mi.more = "Shouldn't see this";
    ret = midw->write(mi, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;
    mi.flight_id1 = 100;
    mi.more = "Extra info for all flights with id1 == 100";
    ret = midw->write(mi, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;

    // Write samples (Unrelated)

    waitForMatch(unrelated.dw_);
    UnrelatedInfoDataWriter_var uidw =
      UnrelatedInfoDataWriter::_narrow(unrelated.dw_);
    UnrelatedInfo ui;
    ui.misc = "Misc";
    ret = uidw->write(ui, HANDLE_NIL);
    if (ret != RETCODE_OK) return false;

    // Read resulting samples

    WaitSet_var ws = new WaitSet;
    ReadCondition_var rc = dr->create_readcondition(ANY_SAMPLE_STATE,
      ANY_VIEW_STATE, ANY_INSTANCE_STATE);
    ws->attach_condition(rc);
    Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC};
    ConditionSeq active;
    ret = ws->wait(active, infinite);
    if (ret != RETCODE_OK) return false;
    ws->detach_condition(rc);
    ResultingDataReader_var res_dr = ResultingDataReader::_narrow(dr);
    ResultingSeq data;
    SampleInfoSeq info;
    ret = res_dr->take_w_condition(data, info, LENGTH_UNLIMITED, rc);
    if (ret != RETCODE_OK) return false;
    if (data.length() > 1 || !info[0].valid_data) return false;
    std::cout << "Received: " << data[0].flight_id1 << '-' <<
      data[0].flight_id2 << " \"" << data[0].flight_name << "\" " << data[0].x <<
      " " << data[0].y << " " << data[0].height << " \"" << data[0].more <<
      "\" \"" << data[0].misc << "\"" << std::endl;
    if (data[0].flight_id1 != sample4.flight_id1 || data[0].flight_id2 !=
        sample4.flight_id2 || strcmp(data[0].flight_name, sample4.flight_name) ||
        data[0].x != sample3.x || data[0].y != sample3.y ||
        data[0].height != sample3.z || strcmp(data[0].more, mi.more) ||
        strcmp(data[0].misc, ui.misc)) {
      return false;
    }
    // Check return get_key_value
    Resulting resulting_value;
    ret = res_dr->get_key_value(resulting_value, DDS::HANDLE_NIL);
    if (ret != RETCODE_BAD_PARAMETER) return false;

    data.length(0);
    info.length(0);
    ret = res_dr->read_w_condition(data, info, LENGTH_UNLIMITED, rc);
    dr->delete_readcondition(rc);
    if (ret != RETCODE_NO_DATA) return false;

    // Reader cleanup
    if (i != N_ITERATIONS - 1) {
      sub->delete_datareader(dr);
      waitForMatch(location.dw_, 0);
      waitForMatch(flightplan.dw_, 0);
      waitForMatch(more.dw_, 0);
      waitForMatch(unrelated.dw_, 0);
      sub_dp->delete_multitopic(mt);
    }
  }

  // Dispose

  ReturnCode_t ret = midw->dispose(mi, HANDLE_NIL);
  if (ret != RETCODE_OK) return false;
  ReadCondition_var rc =
    dr->create_readcondition(ANY_SAMPLE_STATE, ANY_VIEW_STATE,
                             NOT_ALIVE_DISPOSED_INSTANCE_STATE);
  WaitSet_var ws = new WaitSet;
  ws->attach_condition(rc);
  const Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC};
  ConditionSeq active;
  ret = ws->wait(active, infinite);
  if (ret != RETCODE_OK) return false;
  ws->detach_condition(rc);
  ResultingDataReader_var res_dr = ResultingDataReader::_narrow(dr);
  ResultingSeq data;
  SampleInfoSeq info;
  ret = res_dr->read_w_condition(data, info, LENGTH_UNLIMITED, rc);
  dr->delete_readcondition(rc);
  if (ret != RETCODE_OK) return false;
  if (info[0].valid_data ||
      info[0].instance_state != NOT_ALIVE_DISPOSED_INSTANCE_STATE) return false;
  return true;
}
Beispiel #11
0
bool run_test(DomainParticipant_var& dp_sub,
              DomainParticipant_var& dp_pub)
{
  OpenDDS::DCPS::RepoId sub_repo_id, pub_repo_id;

  {
    OpenDDS::DCPS::DomainParticipantImpl* dp_impl =
      dynamic_cast<OpenDDS::DCPS::DomainParticipantImpl*>(dp_sub.in());
    sub_repo_id = dp_impl->get_id ();
    OpenDDS::DCPS::GuidConverter converter(sub_repo_id);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT("%P ")
                ACE_TEXT("Sub Domain Participant GUID=%C\n"),
                std::string(converter).c_str()));
  }

  {
    OpenDDS::DCPS::DomainParticipantImpl* dp_impl =
      dynamic_cast<OpenDDS::DCPS::DomainParticipantImpl*>(dp_pub.in());
    pub_repo_id = dp_impl->get_id ();
    OpenDDS::DCPS::GuidConverter converter(pub_repo_id);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT("%P ")
                ACE_TEXT("Pub Domain Participant GUID=%C\n"),
                std::string(converter).c_str()));
  }

  // If we are running with an rtps_udp transport, it can't be shared between
  // participants.
  TransportConfig_rch cfg = TheTransportRegistry->get_config("dp1");
  if (!cfg.is_nil()) {
    TheTransportRegistry->bind_config(cfg, dp_sub);
  }
  cfg = TheTransportRegistry->get_config("dp2");
  if (!cfg.is_nil()) {
    TheTransportRegistry->bind_config(cfg, dp_pub);
  }

  Subscriber_var bit_sub = dp_sub->get_builtin_subscriber();

  if (!read_participant_bit(bit_sub, dp_sub, pub_repo_id, TestConfig::PARTICIPANT_USER_DATA())) {
    return false;
  }

  // Each domain participant's handle to the other
  InstanceHandle_t dp_sub_ih, dp_pub_ih;
  InstanceHandle_t pub_ih, sub_ih, ig_ih;

  if (!(check_discovered_participants(dp_sub, dp_pub_ih) &&
        check_discovered_participants(dp_pub, dp_sub_ih)))
  {
    return false;
  }

  DataWriter_var dw = create_data_writer(dp_pub);
  if (!dw) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P could not create Data Writer (participant 2)\n"));
    return false;
  }

  if (!read_publication_bit(bit_sub, dp_sub, pub_repo_id, pub_ih, TestConfig::DATA_WRITER_USER_DATA(), TestConfig::TOPIC_DATA(), 1, 1)) {
    return false;
  }

  DataReader_var dr = create_data_reader(dp_sub);
  if (!dr) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P could not create Data Reader (participant 1)\n"));
    return false;
  }
  if (!read_subscription_bit(dp_pub->get_builtin_subscriber(), dp_pub, sub_repo_id, sub_ih, TestConfig::DATA_READER_USER_DATA(), TestConfig::TOPIC_DATA())) {
    return false;
  }

  // Wait for the reader to associate with the writer.
  WriterSync::wait_match(dw);

  // Remove the writer and its topic, then re-create them.  The writer's
  // participant should still have discovery info about the reader so that
  // the association between the new writer and old reader can be established.
  recreate_data_writer_and_topic(dw, dr);

  // Wait for the reader to associate with the writer.
  WriterSync::wait_match(dw);

  // The new writer is associated with the reader, but the reader may still
  // also be associated with the old writer.
  wait_match(dr, 1);

  // Get the new instance handle as pub_ih
  if (!read_publication_bit(bit_sub, dp_sub, pub_repo_id, pub_ih, TestConfig::DATA_WRITER_USER_DATA(), TestConfig::TOPIC_DATA(), 1, 2)) {
    return false;
  }

  TestMsgDataWriter_var tmdw = TestMsgDataWriter::_narrow(dw);
  const TestMsg msg = {42};
  tmdw->write(msg, HANDLE_NIL);

  ReadCondition_var rc = dr->create_readcondition(ANY_SAMPLE_STATE,
                                                  ANY_VIEW_STATE,
                                                  ALIVE_INSTANCE_STATE);
  WaitSet_var waiter = new WaitSet;
  waiter->attach_condition(rc);
  ConditionSeq activeConditions;
  const Duration_t timeout = { 90, 0 };
  ReturnCode_t result = waiter->wait(activeConditions, timeout);
  waiter->detach_condition(rc);
  if (result != RETCODE_OK) {
    ACE_DEBUG((LM_ERROR,
      "ERROR: %P TestMsg reader could not wait for condition: %d\n", result));
    return false;
  }

  TestMsgDataReader_var tmdr = TestMsgDataReader::_narrow(dr);

  TestMsgSeq data;
  SampleInfoSeq infos;
  ReturnCode_t ret = tmdr->read_w_condition(data, infos, LENGTH_UNLIMITED, rc);
  if (ret != RETCODE_OK) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P could not read TestMsg: %d\n", ret));
    return false;
  }

  bool ok = false;
  for (CORBA::ULong i = 0; i < data.length(); ++i) {
    if (infos[i].valid_data) {
      ok = true;
      ACE_DEBUG((LM_DEBUG, "%P Read data sample: %d\n", data[i].value));
    }
  }

  if (!ok) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P no valid data from TestMsg data reader\n"));
  }

  // Change dp qos
  {
    DomainParticipantQos dp_qos;
    dp_pub->get_qos(dp_qos);
    set_qos(dp_qos.user_data.value, TestConfig::PARTICIPANT_USER_DATA2());
    dp_pub->set_qos(dp_qos);
  }
  // Change dw qos
  {
    DataWriterQos dw_qos;
    dw->get_qos(dw_qos);
    set_qos(dw_qos.user_data.value, TestConfig::DATA_WRITER_USER_DATA2());
    dw->set_qos(dw_qos);
  }
  // Change dr qos
  {
    DataReaderQos dr_qos;
    dr->get_qos(dr_qos);
    set_qos(dr_qos.user_data.value, TestConfig::DATA_READER_USER_DATA2());
    dr->set_qos(dr_qos);
  }
  // Wait for propagation
  ACE_OS::sleep(3);
  if (!read_participant_bit(bit_sub, dp_sub, pub_repo_id, TestConfig::PARTICIPANT_USER_DATA2())) {
    return false;
  }
  if (!read_publication_bit(bit_sub, dp_sub, pub_repo_id, ig_ih, TestConfig::DATA_WRITER_USER_DATA2(), TestConfig::TOPIC_DATA(), 1, 1)) {
    return false;
  }
  if (!read_subscription_bit(dp_pub->get_builtin_subscriber(), dp_pub, sub_repo_id, ig_ih, TestConfig::DATA_READER_USER_DATA2(), TestConfig::TOPIC_DATA())) {
    return false;
  }

  // Set dw topic qos
  Topic_var topic = dw->get_topic();
  TopicQos topic_qos;
  topic->get_qos(topic_qos);
  set_qos(topic_qos.topic_data.value, TestConfig::TOPIC_DATA2());
  topic->set_qos(topic_qos);

  // Set dr topic qos
  TopicDescription_var topic_desc = dr->get_topicdescription();
  topic = Topic::_narrow(topic_desc);
  topic->get_qos(topic_qos);
  set_qos(topic_qos.topic_data.value, TestConfig::TOPIC_DATA2());
  topic->set_qos(topic_qos);

  // Wait for propagation
  ACE_OS::sleep(3);
  if (!read_publication_bit(bit_sub, dp_sub, pub_repo_id, ig_ih, TestConfig::DATA_WRITER_USER_DATA2(), TestConfig::TOPIC_DATA2(), 1, 1)) {
    return false;
  }
  if (!read_subscription_bit(dp_pub->get_builtin_subscriber(), dp_pub, sub_repo_id, ig_ih, TestConfig::DATA_READER_USER_DATA2(), TestConfig::TOPIC_DATA2())) {
    return false;
  }

  // Test ignore
  dp_sub->ignore_publication(pub_ih);
  if (!read_publication_bit(bit_sub, dp_sub, pub_repo_id, pub_ih, TestConfig::DATA_WRITER_USER_DATA2(), TestConfig::TOPIC_DATA2(), 0, 0)) {
    ACE_ERROR_RETURN((LM_ERROR,
                     ACE_TEXT("ERROR: %P Could not ignore publication\n")), false);
  }

  dp_pub->ignore_subscription(sub_ih);
  if (!read_subscription_bit(dp_pub->get_builtin_subscriber(), dp_pub, sub_repo_id, sub_ih, TestConfig::DATA_READER_USER_DATA2(), TestConfig::TOPIC_DATA2(), true)) {
    ACE_ERROR_RETURN((LM_ERROR,
                     ACE_TEXT("ERROR: %P Could not ignore subscription\n")), false);
  }

  dp_sub->ignore_participant(dp_pub_ih);
  InstanceHandleSeq handles;
  dp_sub->get_discovered_participants(handles);
  // Check that the handle is no longer in the sequence.
  for (CORBA::ULong i = 0; i < handles.length (); ++i) {
    if (handles[i] == dp_pub_ih) {
      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT("ERROR: %P Could not ignore participant\n")), false);

    }
  }

  return ok;
}
Beispiel #12
0
bool read_subscription_bit(const Subscriber_var& bit_sub,
                           const DomainParticipant_var& publisher,
                           const OpenDDS::DCPS::RepoId& subscriber_repo_id,
                           InstanceHandle_t& handle,
                           int user_data,
                           int topic_data,
                           bool ignored_subscription = false)
{
  OpenDDS::DCPS::Discovery_rch disc =
    TheServiceParticipant->get_discovery(publisher->get_domain_id());
  OpenDDS::DCPS::DomainParticipantImpl* publisher_impl =
    dynamic_cast<OpenDDS::DCPS::DomainParticipantImpl*>(publisher.in());

  DataReader_var dr = bit_sub->lookup_datareader(BUILT_IN_SUBSCRIPTION_TOPIC);
  if (!ignored_subscription) {
    ReadCondition_var rc = dr->create_readcondition(ANY_SAMPLE_STATE,
                                                    ANY_VIEW_STATE,
                                                    ALIVE_INSTANCE_STATE);
    WaitSet_var waiter = new WaitSet;
    waiter->attach_condition(rc);
    ConditionSeq activeConditions;
    Duration_t forever = { DURATION_INFINITE_SEC,
                           DURATION_INFINITE_NSEC };
    ReturnCode_t result = waiter->wait(activeConditions, forever);
    waiter->detach_condition(rc);
    if (result != RETCODE_OK) {
      ACE_DEBUG((LM_ERROR,
        "ERROR: %P (subscription BIT) could not wait for condition: %d\n", result));
      return false;
    }
  } else {
    ACE_OS::sleep(1);
  }
  SubscriptionBuiltinTopicDataDataReader_var pub_bit =
    SubscriptionBuiltinTopicDataDataReader::_narrow(dr);

  SubscriptionBuiltinTopicDataSeq data;
  SampleInfoSeq infos;
  ReturnCode_t ret =
    pub_bit->read(data, infos, LENGTH_UNLIMITED,
                  ANY_SAMPLE_STATE, ANY_VIEW_STATE, ALIVE_INSTANCE_STATE);
  if (ignored_subscription && (ret != RETCODE_NO_DATA)) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P could not read ignored subscription BIT: %d\n",
               ret));
    return false;
  } else if (ret != RETCODE_OK && ret != RETCODE_NO_DATA) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P could not read subscription BIT: %d\n", ret));
    return false;
  }

  int num_valid = 0;
  bool found_subscriber = false;
  for (CORBA::ULong i = 0; i < data.length(); ++i) {
    if (infos[i].valid_data) {
      ++num_valid;

      OpenDDS::DCPS::RepoId repo_id =
        disc->bit_key_to_repo_id(publisher_impl,
                                 OpenDDS::DCPS::BUILT_IN_PARTICIPANT_TOPIC,
                                 data[i].participant_key);

      OpenDDS::DCPS::GuidConverter converter(repo_id);

      ACE_DEBUG((LM_DEBUG,
                 "%P Read Subscription BIT with key: %x %x %x and handle %d\n"
                 "\tParticipant's GUID=%C\n\tTopic: %C\tType: %C\n",
                 data[i].key.value[0], data[i].key.value[1],
                 data[i].key.value[2], infos[i].instance_handle,
                 std::string(converter).c_str (), data[i].topic_name.in(),
                 data[i].type_name.in()));
      if (repo_id == subscriber_repo_id) {
        found_subscriber = true;
        if (data[i].user_data.value.length() != 1) {
          ACE_ERROR_RETURN((LM_ERROR,
                            "ERROR: %P subscription [%d] user data length %d "
                            "not expected length of 1\n",
                            i,
                            data[i].user_data.value.length()),
                           false);
        }
        if (data[i].topic_data.value.length() != 1) {
          ACE_ERROR_RETURN((LM_ERROR,
                            "ERROR: %P subscription [%d] topic data length %d "
                            "not expected length of 1\n",
                            i,
                            data[i].topic_data.value.length()),
                           false);
        }
        if (data[i].user_data.value[0] != user_data) {
          ACE_ERROR_RETURN((LM_ERROR,
                            "ERROR: %P subscription [%d] user data value %d "
                            "not expected value %d\n",
                            i,
                            data[i].user_data.value[0],
                            user_data),
                           false);
        }
        if (data[i].topic_data.value[0] != topic_data) {
          ACE_ERROR_RETURN((LM_ERROR,
                            "ERROR: %P subscription [%d] topic data value %d "
                            "not expected value %d\n",
                            i,
                            data[i].topic_data.value[0],
                            topic_data),
                           false);
        }
      }
      handle = infos[i].instance_handle;
    }
  }
  if (ignored_subscription) {
    if (num_valid != 0) {
      ACE_ERROR_RETURN((LM_ERROR, "ERROR: %P expected 0 discovered "
                        "subscriptions, found %d\n",
                        num_valid), false);
    }
  }
  else {
    if (num_valid != 1) {
      ACE_ERROR_RETURN((LM_ERROR, "ERROR: %P expected 1 discovered "
                        "subscriptions, found %d\n",
                        num_valid), false);
    }
    if (!found_subscriber) {
      ACE_ERROR_RETURN((LM_ERROR, "ERROR: %P did not find expected subscription\n"), false);
    }
  }

  return true;
}
Beispiel #13
0
bool read_participant_bit(const Subscriber_var& bit_sub,
                          const DomainParticipant_var& dp,
                          const OpenDDS::DCPS::RepoId& other_dp_repo_id,
                          int user_data)
{
  OpenDDS::DCPS::Discovery_rch disc =
    TheServiceParticipant->get_discovery(dp->get_domain_id());
  OpenDDS::DCPS::DomainParticipantImpl* dp_impl =
    dynamic_cast<OpenDDS::DCPS::DomainParticipantImpl*>(dp.in());

  DataReader_var dr = bit_sub->lookup_datareader(BUILT_IN_PARTICIPANT_TOPIC);
  ReadCondition_var rc = dr->create_readcondition(ANY_SAMPLE_STATE,
                                                  ANY_VIEW_STATE,
                                                  ALIVE_INSTANCE_STATE);
  WaitSet_var waiter = new WaitSet;
  waiter->attach_condition(rc);
  ConditionSeq activeConditions;
  Duration_t forever = { DURATION_INFINITE_SEC,
                         DURATION_INFINITE_NSEC };
  ReturnCode_t result = waiter->wait(activeConditions, forever);
  waiter->detach_condition(rc);
  if (result != RETCODE_OK) {
    ACE_ERROR_RETURN((LM_ERROR, "ERROR: %P could not wait for condition: %d\n", result), false);
  }

  ParticipantBuiltinTopicDataDataReader_var part_bit =
    ParticipantBuiltinTopicDataDataReader::_narrow(dr);

  ParticipantBuiltinTopicDataSeq data;
  SampleInfoSeq infos;
  ReturnCode_t ret =
    part_bit->read_w_condition(data, infos, LENGTH_UNLIMITED, rc);
  if (ret != RETCODE_OK) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P could not read participant BIT: %d\n", ret));
    return false;
  }

  bool found_other_dp = false;
  int num_valid = 0;

  for (CORBA::ULong i = 0; i < data.length(); ++i) {
    if (infos[i].valid_data) {
      ++num_valid;
      OpenDDS::DCPS::RepoId repo_id =
        disc->bit_key_to_repo_id(dp_impl,
                                 OpenDDS::DCPS::BUILT_IN_PARTICIPANT_TOPIC,
                                 data[i].key);

      OpenDDS::DCPS::GuidConverter converter(repo_id);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("%P ")
                 ACE_TEXT("Read Participant BIT GUID=%C handle=%d\n"),
                 std::string(converter).c_str(), infos[i].instance_handle));

      if (repo_id == other_dp_repo_id) {
        if (data[i].user_data.value.length() != 1) {
          ACE_ERROR_RETURN((LM_ERROR,
                            "ERROR: %P participant[%d] user data length %d "
                            "not expected length of 1\n",
                            i,
                            data[i].user_data.value.length()),
                           false);
        }

        if (data[i].user_data.value[0] != user_data) {
          ACE_ERROR_RETURN((LM_ERROR,
                            "ERROR: %P participant[%d] user data value %d "
                            "not expected value %d\n",
                            i,
                            data[i].user_data.value[0],
                            user_data),
                           false);
        }

        found_other_dp = true;
      }
    }
  }

  if (num_valid != 1) {
    ACE_DEBUG((LM_ERROR, "ERROR: %P expected to discover 1 other participant, found %d\n", data.length ()));
  }

  part_bit->return_loan(data, infos);

  if (!found_other_dp) {
    ACE_ERROR_RETURN((LM_ERROR, "ERROR: %P did not find expected participant\n"), false);
  }

  return true;
}
bool run_change_parameter_test(const DomainParticipant_var& dp,
  const MessageTypeSupport_var& ts, const Publisher_var& pub,
  const Subscriber_var& sub)
{
  DataWriter_var dw;
  DataReader_var dr;
  test_setup(dp, ts, pub, sub, "MyTopic3", dw, dr);

  MessageDataWriter_var mdw = MessageDataWriter::_narrow(dw);
  Message sample;
  sample.key = 3;
  ReturnCode_t ret = mdw->write(sample, HANDLE_NIL);
  if (ret != RETCODE_OK) return false;
  if (!waitForSample(dr)) return false;

  DDS::StringSeq params(1);
  params.length(1);
  params[0] = "2";
  ReadCondition_var dr_qc = dr->create_querycondition(ANY_SAMPLE_STATE,
    ANY_VIEW_STATE, ALIVE_INSTANCE_STATE, "key = %0", params);
  if (!dr_qc.in()) {
    cout << "ERROR: failed to create QueryCondition" << endl;
    return false;
  }

  QueryCondition_var query_cond = QueryCondition::_narrow(dr_qc);
  CORBA::String_var expr = query_cond->get_query_expression();
  if (std::string("key = %0") != expr.in()) {
    cout << "ERROR: get_query_expression() query expression should match " << endl;
    return false;
  }

  params = DDS::StringSeq();
  ret = query_cond->get_query_parameters(params);
  if (ret != RETCODE_OK) {
    cout << "ERROR: get_query_parameters() failed " << endl;
    return false;
  } else if (params.length() != 1 || std::string(params[0]) != "2") {
    cout << "ERROR: get_query_parameters() query parameters doesn't match " << endl;
    return false;
  }

  WaitSet_var ws = new WaitSet;
  ws->attach_condition(dr_qc);
  ConditionSeq active;
  Duration_t three_sec = {3, 0};
  ret = ws->wait(active, three_sec);
  // expect a timeout because the sample doesn't match the query string
  if (ret != RETCODE_TIMEOUT) {
    cout << "ERROR: wait(qc) should have timed out" << endl;
    return false;
  }
  ws->detach_condition(dr_qc);

  MessageDataReader_var mdr = MessageDataReader::_narrow(dr);
  MessageSeq data;
  SampleInfoSeq infoseq;
  ret = mdr->take_w_condition(data, infoseq, LENGTH_UNLIMITED, dr_qc);
  if (ret != RETCODE_NO_DATA) {
    cout << "ERROR: take_w_condition(qc) shouldn't have returned data" << endl;
    return false;
  }

  params = DDS::StringSeq(1);
  params.length(1);
  params[0] = "3";
  ret = query_cond->set_query_parameters(params);

  params = DDS::StringSeq();
  ret = query_cond->get_query_parameters(params);
  if (ret != RETCODE_OK) {
    cout << "ERROR: get_query_parameters() failed " << endl;
    return false;
  } else if (params.length() != 1 || std::string(params[0]) != "3") {
    cout << "ERROR: get_query_parameters() query parameters doesn't match " << endl;
    return false;
  }

  ws->attach_condition(dr_qc);
  ret = ws->wait(active, three_sec);
  if (ret != RETCODE_OK) {
    cout << "ERROR: wait(qc) should not time out" << endl;
    return false;
  }
  ws->detach_condition(dr_qc);

  ret = mdr->take_w_condition(data, infoseq, LENGTH_UNLIMITED, dr_qc);
  if (ret != RETCODE_OK) {
    cout << "ERROR: take_w_condition(qc) should have returned data" << endl;
    return false;
  }

  dr->delete_readcondition(dr_qc);
  return true;
}