void test_nghttp2_session_send_push_promise(void) {
  nghttp2_session *session;
  nghttp2_session_callbacks callbacks;
  nghttp2_outbound_item *item;
  nghttp2_frame *frame;
  nghttp2_stream *stream;
  nghttp2_settings_entry iv;
  my_user_data ud;
  nghttp2_mem *mem;

  mem = nghttp2_mem_default();
  memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
  callbacks.send_callback = null_send_callback;
  callbacks.on_frame_not_send_callback = on_frame_not_send_callback;

  nghttp2_session_server_new(&session, &callbacks, &ud);
  open_recv_stream(session, 1);

  item = mem->malloc(sizeof(nghttp2_outbound_item), NULL);

  nghttp2_outbound_item_init(item);

  frame = &item->frame;

  nghttp2_frame_push_promise_init(&frame->push_promise,
                                  NGHTTP2_FLAG_END_HEADERS, 1,
                                  (int32_t)session->next_stream_id, NULL, 0);

  session->next_stream_id += 2;

  nghttp2_session_add_item(session, item);

  CU_ASSERT(0 == nghttp2_session_send(session));
  stream = nghttp2_session_get_stream(session, 2);
  CU_ASSERT(NGHTTP2_STREAM_RESERVED == stream->state);

  /* Received ENABLE_PUSH = 0 */
  iv.settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
  iv.value = 0;
  frame = mem->malloc(sizeof(nghttp2_frame), NULL);
  nghttp2_frame_settings_init(&frame->settings, NGHTTP2_FLAG_NONE,
                              dup_iv(&iv, 1), 1);
  nghttp2_session_on_settings_received(session, frame, 1);
  nghttp2_frame_settings_free(&frame->settings, mem);
  mem->free(frame, NULL);

  item = mem->malloc(sizeof(nghttp2_outbound_item), NULL);

  nghttp2_outbound_item_init(item);

  frame = &item->frame;

  nghttp2_frame_push_promise_init(&frame->push_promise,
                                  NGHTTP2_FLAG_END_HEADERS, 1, -1, NULL, 0);
  nghttp2_session_add_item(session, item);

  ud.frame_not_send_cb_called = 0;
  CU_ASSERT(0 == nghttp2_session_send(session));

  CU_ASSERT(1 == ud.frame_not_send_cb_called);
  CU_ASSERT(NGHTTP2_PUSH_PROMISE == ud.not_sent_frame_type);
  CU_ASSERT(NGHTTP2_ERR_PUSH_DISABLED == ud.not_sent_error);

  nghttp2_session_del(session);

  /* PUSH_PROMISE from client is error */
  nghttp2_session_client_new(&session, &callbacks, &ud);
  open_sent_stream(session, 1);
  item = mem->malloc(sizeof(nghttp2_outbound_item), NULL);

  nghttp2_outbound_item_init(item);

  frame = &item->frame;

  nghttp2_frame_push_promise_init(&frame->push_promise,
                                  NGHTTP2_FLAG_END_HEADERS, 1, -1, NULL, 0);
  nghttp2_session_add_item(session, item);

  CU_ASSERT(0 == nghttp2_session_send(session));
  CU_ASSERT(NULL == nghttp2_session_get_stream(session, 3));

  nghttp2_session_del(session);
}
void test_nghttp2_session_send_push_promise(void) {
  nghttp2_session *session;
  nghttp2_session_callbacks callbacks;
  nghttp2_outbound_item *item;
  nghttp2_frame *frame;
  nghttp2_stream *stream;
  nghttp2_settings_entry iv;
  my_user_data ud;
  nghttp2_mem *mem;

  mem = nghttp2_mem_default();
  memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
  callbacks.send_callback = null_send_callback;
  callbacks.on_frame_not_send_callback = on_frame_not_send_callback;

  nghttp2_session_server_new(&session, &callbacks, &ud);
  open_recv_stream(session, 1);

  item = mem->malloc(sizeof(nghttp2_outbound_item), NULL);

  nghttp2_outbound_item_init(item);

  frame = &item->frame;

  nghttp2_frame_push_promise_init(&frame->push_promise,
                                  NGHTTP2_FLAG_END_HEADERS, 1,
                                  (int32_t)session->next_stream_id, NULL, 0);

  session->next_stream_id += 2;

  nghttp2_session_add_item(session, item);

  CU_ASSERT(0 == nghttp2_session_send(session));
  stream = nghttp2_session_get_stream(session, 2);
  CU_ASSERT(NGHTTP2_STREAM_RESERVED == stream->state);

   
  iv.settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
  iv.value = 0;
  frame = mem->malloc(sizeof(nghttp2_frame), NULL);
  nghttp2_frame_settings_init(&frame->settings, NGHTTP2_FLAG_NONE,
                              dup_iv(&iv, 1), 1);
  nghttp2_session_on_settings_received(session, frame, 1);
  nghttp2_frame_settings_free(&frame->settings, mem);
  mem->free(frame, NULL);

  item = mem->malloc(sizeof(nghttp2_outbound_item), NULL);

  nghttp2_outbound_item_init(item);

  frame = &item->frame;

  nghttp2_frame_push_promise_init(&frame->push_promise,
                                  NGHTTP2_FLAG_END_HEADERS, 1, -1, NULL, 0);
  nghttp2_session_add_item(session, item);

  ud.frame_not_send_cb_called = 0;
  CU_ASSERT(0 == nghttp2_session_send(session));

  CU_ASSERT(1 == ud.frame_not_send_cb_called);
  CU_ASSERT(NGHTTP2_PUSH_PROMISE == ud.not_sent_frame_type);
  CU_ASSERT(NGHTTP2_ERR_PUSH_DISABLED == ud.not_sent_error);

  nghttp2_session_del(session);

   
  nghttp2_session_client_new(&session, &callbacks, &ud);
  open_sent_stream(session, 1);
  item = mem->malloc(sizeof(nghttp2_outbound_item), NULL);

  nghttp2_outbound_item_init(item);

  frame = &item->frame;

  nghttp2_frame_push_promise_init(&frame->push_promise,
                                  NGHTTP2_FLAG_END_HEADERS, 1, -1, NULL, 0);
  nghttp2_session_add_item(session, item);

  CU_ASSERT(0 == nghttp2_session_send(session));
  CU_ASSERT(NULL == nghttp2_session_get_stream(session, 3));

  nghttp2_session_del(session);
}