void
test_ofp_flow_reply_create_01(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct flow_stats *flow_stats = NULL;
  struct instruction *instruction = NULL;
  struct match *match = NULL;
  const char *require[1] = {
    "04 13 00 58 00 00 00 10 00 01 00 00 00 00 00 00 "
    "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 "
    "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 "
    "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a "
    "00 01 00 10 00 00 01 08 00 00 00 00 00 00 00 00 "
    "00 01 00 08 00 00 00 00"
  };

  TAILQ_INIT(&s_flow_stats_list);
  if ((flow_stats = s_flow_stats_alloc()) != NULL) {
    /* flow_stats = 48, match = 16, instruction = 8, sum = 72 */
    flow_stats->ofp.length = 48 + 16 + 8;
    flow_stats->ofp.table_id = 0x01;
    flow_stats->ofp.duration_sec = 0x02;
    flow_stats->ofp.duration_nsec = 0x03;
    flow_stats->ofp.priority = 0x04;
    flow_stats->ofp.idle_timeout = 0x05;
    flow_stats->ofp.hard_timeout = 0x06;
    flow_stats->ofp.flags = 0x07;
    flow_stats->ofp.cookie = 0x08;
    flow_stats->ofp.packet_count = 0x09;
    flow_stats->ofp.byte_count = 0x0a;
    if ((match = match_alloc(8)) != NULL) {
      match->oxm_class = 0x00;
      match->oxm_field = 0x01;
      match->oxm_length = 0x08;
      TAILQ_INSERT_TAIL(&(flow_stats->match_list), match, entry);
    }
    if ((instruction = instruction_alloc()) != NULL) {
      instruction->ofpit_goto_table.type = OFPIT_GOTO_TABLE;
      instruction->ofpit_goto_table.len = 0x08; /* action_list empty */
      instruction->ofpit_goto_table.table_id = 0x00;
      TAILQ_INSERT_TAIL(&(flow_stats->instruction_list), instruction, entry);
    }
    TAILQ_INSERT_TAIL(&s_flow_stats_list, flow_stats, entry);
  } else {
    TEST_FAIL_MESSAGE("allocation error.");
  }

  /* port 0 */
  ret = check_pbuf_list_packet_create(s_ofp_flow_reply_create_wrap, require, 1);
  TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret, "create port 0 error.");

  /* free */
  while ((flow_stats = TAILQ_FIRST(&s_flow_stats_list)) != NULL) {
    TAILQ_REMOVE(&s_flow_stats_list, flow_stats, entry);
    ofp_match_list_elem_free(&flow_stats->match_list);
    ofp_instruction_list_elem_free(&flow_stats->instruction_list);
    free(flow_stats);
  }
}
static struct eventq_data *
create_data(void) {
  int i;
  struct eventq_data *ed;
  struct match *match;
  int match_num = 2;
  uint16_t class = OFPXMC_OPENFLOW_BASIC;
  uint8_t field[] = {OFPXMT_OFB_IN_PORT << 1,
                     OFPXMT_OFB_ETH_SRC << 1
                    };
  uint8_t length[] = {0x04, 0x06};
  uint8_t value[2][6] = {{0x00, 0x00, 0x00, 0x10},
    {0x00, 0x0c, 0x29, 0x7a, 0x90, 0xb3}
  };
  uint64_t cookie = 0x12;
  uint16_t priority = 0x34;
  uint8_t reason = 0x02;
  uint8_t table_id = 0x30;
  uint32_t duration_sec = 0x56;
  uint32_t duration_nsec = 0x78;
  uint16_t idle_timeout = 0x90;
  uint16_t hard_timeout = 0x23;
  uint64_t packet_count = 0x45;
  uint64_t byte_count = 0x67;

  ed = (struct eventq_data *) calloc(1, sizeof(struct eventq_data));

  /* data. */
  ed->flow_removed.ofp_flow_removed.cookie = cookie;
  ed->flow_removed.ofp_flow_removed.priority = priority;
  ed->flow_removed.ofp_flow_removed.reason = reason;
  ed->flow_removed.ofp_flow_removed.table_id = table_id;
  ed->flow_removed.ofp_flow_removed.duration_sec = duration_sec;
  ed->flow_removed.ofp_flow_removed.duration_nsec = duration_nsec;
  ed->flow_removed.ofp_flow_removed.idle_timeout = idle_timeout;
  ed->flow_removed.ofp_flow_removed.hard_timeout = hard_timeout;
  ed->flow_removed.ofp_flow_removed.packet_count = packet_count;
  ed->flow_removed.ofp_flow_removed.byte_count = byte_count;


  TAILQ_INIT(&ed->flow_removed.match_list);
  for (i = 0; i < match_num; i++) {
    match = match_alloc(length[i]);
    match->oxm_class = class;
    match->oxm_field = field[i];
    match->oxm_length = length[i];
    memcpy(match->oxm_value, value[i], match->oxm_length);
    TAILQ_INSERT_TAIL(&ed->flow_removed.match_list, match, entry);
  }

  return ed;
}
void
test_ofp_flow_reply_create_02(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct flow_stats *flow_stats = NULL;
  struct match *match = NULL;
  const char *header_data[2] = {
    "04 13 ff b8 00 00 00 10 00 01 00 01 00 00 00 00 ",
    "04 13 00 58 00 00 00 10 00 01 00 00 00 00 00 00 "
  };
  const char *body_data[2] = {
    "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 "
    "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 "
    "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a "
    "00 01 00 18 00 00 01 10 00 00 00 00 00 00 00 00 "
    "00 00 00 00 00 00 00 00",
    "00 48 01 00 00 00 00 02 00 00 00 03 00 04 00 05 "
    "00 06 00 07 00 00 00 00 00 00 00 00 00 00 00 08 "
    "00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 0a "
    "00 01 00 18 00 00 01 10 00 00 00 00 00 00 00 00 "
    "00 00 00 00 00 00 00 00"
  };
  size_t nums[2] = {909, 1};
  int i;

  /* data */
  TAILQ_INIT(&s_flow_stats_list);
  for (i = 0; i < 910; i++) {
    if ((flow_stats = s_flow_stats_alloc()) != NULL) {
      /* flow_stats = 48, match = 24, sum = 72 */
      flow_stats->ofp.length = 0;
      flow_stats->ofp.table_id = 0x01;
      flow_stats->ofp.duration_sec = 0x02;
      flow_stats->ofp.duration_nsec = 0x03;
      flow_stats->ofp.priority = 0x04;
      flow_stats->ofp.idle_timeout = 0x05;
      flow_stats->ofp.hard_timeout = 0x06;
      flow_stats->ofp.flags = 0x07;
      flow_stats->ofp.cookie = 0x08;
      flow_stats->ofp.packet_count = 0x09;
      flow_stats->ofp.byte_count = 0x0a;
      if ((match = match_alloc(16)) != NULL) {
        match->oxm_class = 0x00;
        match->oxm_field = 0x01;
        match->oxm_length = 0x10;
        TAILQ_INSERT_TAIL(&(flow_stats->match_list), match, entry);
      }
      TAILQ_INSERT_TAIL(&s_flow_stats_list, flow_stats, entry);
    } else {
      TEST_FAIL_MESSAGE("allocation error.");
    }
  }

  ret = check_pbuf_list_across_packet_create(s_ofp_flow_reply_create_wrap,
        header_data, body_data, nums, 2);
  TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret, "create port 0 error.");

  /* free */
  while ((flow_stats = TAILQ_FIRST(&s_flow_stats_list)) != NULL) {
    TAILQ_REMOVE(&s_flow_stats_list, flow_stats, entry);
    ofp_match_list_elem_free(&flow_stats->match_list);
    ofp_instruction_list_elem_free(&flow_stats->instruction_list);
    free(flow_stats);
  }
}