// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_

// Base class for testing concrete payload decoder classes.

#include "base/logging.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "net/third_party/quiche/src/http2/decoder/decode_buffer.h"
#include "net/third_party/quiche/src/http2/decoder/decode_status.h"
#include "net/third_party/quiche/src/http2/decoder/frame_decoder_state.h"
#include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h"
#include "net/third_party/quiche/src/http2/http2_constants.h"
#include "net/third_party/quiche/src/http2/http2_constants_test_util.h"
#include "net/third_party/quiche/src/http2/http2_structures.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_reconstruct_object.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string_piece.h"
#include "net/third_party/quiche/src/http2/test_tools/frame_parts.h"
#include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h"
#include "net/third_party/quiche/src/http2/tools/random_decoder_test.h"
#include "starboard/types.h"

namespace http2 {
namespace test {

// Base class for tests of payload decoders. Below this there is a templated
// sub-class that adds a bunch of type specific features.
class PayloadDecoderBaseTest : public RandomDecoderTest {
 protected:
  PayloadDecoderBaseTest();

  // Virtual functions to be implemented by the test classes for the individual
  // payload decoders...

  // Start decoding the payload.
  virtual DecodeStatus StartDecodingPayload(DecodeBuffer* db) = 0;

  // Resume decoding the payload.
  virtual DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) = 0;

  // In support of ensuring that we're really accessing and updating the
  // decoder, prepare the decoder by, for example, overwriting the decoder.
  virtual void PreparePayloadDecoder() = 0;

  // Get the listener to be inserted into the FrameDecoderState, ready for
  // listening (e.g. reset if it is a FramePartsCollector).
  virtual Http2FrameDecoderListener* PrepareListener() = 0;

  // Record a frame header for use on each call to StartDecoding.
  void set_frame_header(const Http2FrameHeader& header) {
    EXPECT_EQ(0, InvalidFlagMaskForFrameType(header.type) & header.flags);
    if (!frame_header_is_set_ || frame_header_ != header) {
      VLOG(2) << "set_frame_header: " << frame_header_;
    }
    frame_header_ = header;
    frame_header_is_set_ = true;
  }

  FrameDecoderState* mutable_state() { return &frame_decoder_state_; }

  // Randomize the payload decoder, sets the payload decoder's frame_header_,
  // then start decoding the payload. Called by RandomDecoderTest. This method
  // is final so that we can always perform certain actions when
  // RandomDecoderTest starts the decoding of a payload, such as randomizing the
  // the payload decoder, injecting the frame header and counting fast decoding
  // cases. Sub-classes must implement StartDecodingPayload to perform their
  // initial decoding of a frame's payload.
  DecodeStatus StartDecoding(DecodeBuffer* db) final;

  // Called by RandomDecoderTest. This method is final so that we can always
  // perform certain actions when RandomDecoderTest calls it, such as counting
  // slow decode cases. Sub-classes must implement ResumeDecodingPayload to
  // continue decoding the frame's payload, which must not all be in one buffer.
  DecodeStatus ResumeDecoding(DecodeBuffer* db) final;

  // Given the specified payload (without the common frame header), decode
  // it with several partitionings of the payload.
  ::testing::AssertionResult DecodePayloadAndValidateSeveralWays(
      Http2StringPiece payload,
      Validator validator);

  // TODO(jamessynge): Add helper method for verifying these are both non-zero,
  // and call the new method from tests that expect successful decoding.
  void ResetDecodeSpeedCounters() {
    fast_decode_count_ = 0;
    slow_decode_count_ = 0;
  }

  // Count of payloads that are full decoded by StartDecodingPayload, or that
  // an error was detected by StartDecodingPayload.
  size_t fast_decode_count_ = 0;

  // Count of payloads that require calling ResumeDecodingPayload in order to
  // decode them completely (or to detect an error during decoding).
  size_t slow_decode_count_ = 0;

 private:
  bool frame_header_is_set_ = false;
  Http2FrameHeader frame_header_;
  FrameDecoderState frame_decoder_state_;
};

// Base class for payload decoders of type Decoder, with corresponding test
// peer of type DecoderPeer, and using class Listener as the implementation
// of Http2FrameDecoderListenerInterface to be used during decoding.
// Typically Listener is a sub-class of FramePartsCollector.
// SupportedFrameType is set to false only for UnknownPayloadDecoder.
template <class Decoder,
          class DecoderPeer,
          class Listener,
          bool SupportedFrameType = true>
class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest {
 protected:
  // An ApproveSize function returns true to approve decoding the specified
  // size of payload, else false to skip that size. Typically used for negative
  // tests; for example, decoding a SETTINGS frame at all sizes except for
  // multiples of 6.
  typedef std::function<bool(size_t size)> ApproveSize;

  AbstractPayloadDecoderTest() {}

  // These tests are in setup rather than the constructor for two reasons:
  // 1) Constructors are not allowed to fail, so gUnit documents that EXPECT_*
  //    and ASSERT_* are not allowed in constructors, and should instead be in
  //    SetUp if they are needed before the body of the test is executed.
  // 2) To allow the sub-class constructor to make any desired modifications to
  //    the DecoderPeer before these tests are executed; in particular,
  //    UnknownPayloadDecoderPeer has not got a fixed frame type, but it is
  //    instead set during the test's constructor.
  void SetUp() override {
    PayloadDecoderBaseTest::SetUp();

    // Confirm that DecoderPeer et al returns sensible values. Using auto as the
    // variable type so that no (narrowing) conversions take place that hide
    // problems; i.e. if someone changes KnownFlagsMaskForFrameType so that it
    // doesn't return a uint8, and has bits above the low-order 8 bits set, this
    // bit of paranoia should detect the problem before we get too far.
    auto frame_type = DecoderPeer::FrameType();
    if (SupportedFrameType) {
      EXPECT_TRUE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
    } else {
      EXPECT_FALSE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
    }

    auto known_flags = KnownFlagsMaskForFrameType(frame_type);
    EXPECT_EQ(known_flags, known_flags & 0xff);

    auto flags_to_avoid = DecoderPeer::FlagsAffectingPayloadDecoding();
    EXPECT_EQ(flags_to_avoid, flags_to_avoid & known_flags);
  }

  void PreparePayloadDecoder() override {
    Http2DefaultReconstructObject(&payload_decoder_, RandomPtr());
  }

  Http2FrameDecoderListener* PrepareListener() override {
    listener_.Reset();
    return &listener_;
  }

  // Returns random flags, but only those valid for the frame type, yet not
  // those that the DecoderPeer says will affect the decoding of the payload
  // (e.g. the PRIORTY flag on a HEADERS frame or PADDED on DATA frames).
  uint8_t RandFlags() {
    return Random().Rand8() &
           KnownFlagsMaskForFrameType(DecoderPeer::FrameType()) &
           ~DecoderPeer::FlagsAffectingPayloadDecoding();
  }

  // Start decoding the payload.
  DecodeStatus StartDecodingPayload(DecodeBuffer* db) override {
    DVLOG(2) << "StartDecodingPayload, db->Remaining=" << db->Remaining();
    return payload_decoder_.StartDecodingPayload(mutable_state(), db);
  }

  // Resume decoding the payload.
  DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) override {
    DVLOG(2) << "ResumeDecodingPayload, db->Remaining=" << db->Remaining();
    return payload_decoder_.ResumeDecodingPayload(mutable_state(), db);
  }

  // Decode one frame's payload and confirm that the listener recorded the
  // expected FrameParts instance, and only FrameParts instance. The payload
  // will be decoded several times with different partitionings of the payload,
  // and after each the validator will be called.
  AssertionResult DecodePayloadAndValidateSeveralWays(
      Http2StringPiece payload,
      const FrameParts& expected) {
#if defined(STARBOARD)
    NoArgValidator validator = [&expected, this]() -> AssertionResult {
#else
    auto validator = [&expected, this]() -> AssertionResult {
#endif
      VERIFY_FALSE(listener_.IsInProgress());
      VERIFY_EQ(1u, listener_.size());
      VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*listener_.frame(0)));
    };
    return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
        payload, ValidateDoneAndEmpty(validator));
  }

  // Decode one frame's payload, expecting that the final status will be
  // kDecodeError, and that OnFrameSizeError will have been called on the
  // listener. The payload will be decoded several times with different
  // partitionings of the payload. The type WrappedValidator is either
  // RandomDecoderTest::Validator, RandomDecoderTest::NoArgValidator or
  // std::nullptr_t (not extra validation).
  template <typename WrappedValidator>
  ::testing::AssertionResult VerifyDetectsFrameSizeError(
      Http2StringPiece payload,
      const Http2FrameHeader& header,
      WrappedValidator wrapped_validator) {
    set_frame_header(header);
    // If wrapped_validator is not a RandomDecoderTest::Validator, make it so.
    Validator validator = ToValidator(wrapped_validator);
    // And wrap that validator in another which will check that we've reached
    // the expected state of kDecodeError with OnFrameSizeError having been
    // called by the payload decoder.
    validator = [header, validator, this](
                    const DecodeBuffer& input,
                    DecodeStatus status) -> ::testing::AssertionResult {
      DVLOG(2) << "VerifyDetectsFrameSizeError validator; status=" << status
               << "; input.Remaining=" << input.Remaining();
      VERIFY_EQ(DecodeStatus::kDecodeError, status);
      VERIFY_FALSE(listener_.IsInProgress());
      VERIFY_EQ(1u, listener_.size());
      const FrameParts* frame = listener_.frame(0);
      VERIFY_EQ(header, frame->GetFrameHeader());
      VERIFY_TRUE(frame->GetHasFrameSizeError());
      // Verify did not get OnPaddingTooLong, as we should only ever produce
      // one of these two errors for a single frame.
      VERIFY_FALSE(frame->GetOptMissingLength());
      return validator(input, status);
    };
    VERIFY_AND_RETURN_SUCCESS(
        PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(payload,
                                                                    validator));
  }

  // Confirm that we get OnFrameSizeError when trying to decode unpadded_payload
  // at all sizes from zero to unpadded_payload.size(), except those sizes not
  // approved by approve_size.
  // If total_pad_length is greater than zero, then that amount of padding
  // is added to the payload (including the Pad Length field).
  // The flags will be required_flags, PADDED if total_pad_length > 0, and some
  // randomly selected flag bits not excluded by FlagsAffectingPayloadDecoding.
  ::testing::AssertionResult VerifyDetectsMultipleFrameSizeErrors(
      uint8_t required_flags,
      Http2StringPiece unpadded_payload,
      ApproveSize approve_size,
      int total_pad_length) {
    // required_flags should come from those that are defined for the frame
    // type AND are those that affect the decoding of the payload (otherwise,
    // the flag shouldn't be required).
    Http2FrameType frame_type = DecoderPeer::FrameType();
    VERIFY_EQ(required_flags,
              required_flags & KnownFlagsMaskForFrameType(frame_type));
    VERIFY_EQ(required_flags,
              required_flags & DecoderPeer::FlagsAffectingPayloadDecoding());

    if (0 !=
        (Http2FrameFlag::PADDED & KnownFlagsMaskForFrameType(frame_type))) {
      // Frame type supports padding.
      if (total_pad_length == 0) {
        required_flags &= ~Http2FrameFlag::PADDED;
      } else {
        required_flags |= Http2FrameFlag::PADDED;
      }
    } else {
      VERIFY_EQ(0, total_pad_length);
    }

    bool validated = false;
    for (size_t real_payload_size = 0;
         real_payload_size <= unpadded_payload.size(); ++real_payload_size) {
      if (approve_size != nullptr && !approve_size(real_payload_size)) {
        continue;
      }
      VLOG(1) << "real_payload_size=" << real_payload_size;
      uint8_t flags = required_flags | RandFlags();
      Http2FrameBuilder fb;
      if (total_pad_length > 0) {
        // total_pad_length_ includes the size of the Pad Length field, and thus
        // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
        fb.AppendUInt8(total_pad_length - 1);
      }
      // Append a subset of the unpadded_payload, which the decoder should
      // determine is not a valid amount.
      fb.Append(unpadded_payload.substr(0, real_payload_size));
      if (total_pad_length > 0) {
        fb.AppendZeroes(total_pad_length - 1);
      }
      // We choose a random stream id because the payload decoders aren't
      // checking stream ids.
      uint32_t stream_id = RandStreamId();
      Http2FrameHeader header(fb.size(), frame_type, flags, stream_id);
      VERIFY_SUCCESS(VerifyDetectsFrameSizeError(fb.buffer(), header, nullptr));
      validated = true;
    }
    VERIFY_TRUE(validated);
    return ::testing::AssertionSuccess();
  }

  // As above, but for frames without padding.
  ::testing::AssertionResult VerifyDetectsFrameSizeError(
      uint8_t required_flags,
      Http2StringPiece unpadded_payload,
      const ApproveSize& approve_size) {
    Http2FrameType frame_type = DecoderPeer::FrameType();
    uint8_t known_flags = KnownFlagsMaskForFrameType(frame_type);
    VERIFY_EQ(0, known_flags & Http2FrameFlag::PADDED);
    VERIFY_EQ(0, required_flags & Http2FrameFlag::PADDED);
    VERIFY_AND_RETURN_SUCCESS(VerifyDetectsMultipleFrameSizeErrors(
        required_flags, unpadded_payload, approve_size, 0));
  }

  Listener listener_;
  union {
    // Confirm at compile time that Decoder can be in an anonymous union,
    // i.e. complain loudly if Decoder has members that prevent this, as it
    // becomes annoying and possibly difficult to deal with non-anonymous
    // unions and such union members.
    Decoder payload_decoder_;
  };
};

// A base class for tests parameterized by the total number of bytes of
// padding, including the Pad Length field (i.e. a total_pad_length of 0
// means unpadded as there is then no room for the Pad Length field).
// The frame type must support padding.
template <class Decoder, class DecoderPeer, class Listener>
class AbstractPaddablePayloadDecoderTest
    : public AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener>,
      public ::testing::WithParamInterface<int> {
  typedef AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener> Base;

 protected:
  using Base::listener_;
  using Base::Random;
  using Base::RandStreamId;
  using Base::set_frame_header;
  typedef typename Base::Validator Validator;

  AbstractPaddablePayloadDecoderTest() : total_pad_length_(GetParam()) {
    LOG(INFO) << "total_pad_length_ = " << total_pad_length_;
  }

  // Note that total_pad_length_ includes the size of the Pad Length field,
  // and thus ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
  bool IsPadded() const { return total_pad_length_ > 0; }

  // Value of the Pad Length field. Only call if IsPadded.
  size_t pad_length() const {
    EXPECT_TRUE(IsPadded());
    return total_pad_length_ - 1;
  }

  // Clear the frame builder and add the Pad Length field if appropriate.
  void Reset() {
    frame_builder_ = Http2FrameBuilder();
    if (IsPadded()) {
      frame_builder_.AppendUInt8(pad_length());
    }
  }

  void MaybeAppendTrailingPadding() {
    if (IsPadded()) {
      frame_builder_.AppendZeroes(pad_length());
    }
  }

  uint8_t RandFlags() {
    uint8_t flags = Base::RandFlags();
    if (IsPadded()) {
      flags |= Http2FrameFlag::PADDED;
    } else {
      flags &= ~Http2FrameFlag::PADDED;
    }
    return flags;
  }

  // Verify that we get OnPaddingTooLong when decoding payload, and that the
  // amount of missing padding is as specified. header.IsPadded must be true,
  // and the payload must be empty or the PadLength field must be too large.
  ::testing::AssertionResult VerifyDetectsPaddingTooLong(
      Http2StringPiece payload,
      const Http2FrameHeader& header,
      size_t expected_missing_length) {
    set_frame_header(header);
    auto& listener = listener_;
    Validator validator =
        [header, expected_missing_length, &listener](
            const DecodeBuffer& input,
            DecodeStatus status) -> ::testing::AssertionResult {
      VERIFY_EQ(DecodeStatus::kDecodeError, status);
      VERIFY_FALSE(listener.IsInProgress());
      VERIFY_EQ(1u, listener.size());
      const FrameParts* frame = listener.frame(0);
      VERIFY_EQ(header, frame->GetFrameHeader());
      VERIFY_TRUE(frame->GetOptMissingLength());
      VERIFY_EQ(expected_missing_length, frame->GetOptMissingLength().value());
      // Verify did not get OnFrameSizeError.
      VERIFY_FALSE(frame->GetHasFrameSizeError());
      return ::testing::AssertionSuccess();
    };
    VERIFY_AND_RETURN_SUCCESS(
        PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(payload,
                                                                    validator));
  }

  // Verifies that we get OnPaddingTooLong for a padded frame payload whose
  // (randomly selected) payload length is less than total_pad_length_.
  // Flags will be selected at random, except PADDED will be set and
  // flags_to_avoid will not be set. The stream id is selected at random.
  ::testing::AssertionResult VerifyDetectsPaddingTooLong() {
    uint8_t flags = RandFlags() | Http2FrameFlag::PADDED;

    // Create an all padding payload for total_pad_length_.
    int payload_length = 0;
    Http2FrameBuilder fb;
    if (IsPadded()) {
      fb.AppendUInt8(pad_length());
      fb.AppendZeroes(pad_length());
      VLOG(1) << "fb.size=" << fb.size();
      // Pick a random length for the payload that is shorter than neccesary.
      payload_length = Random().Uniform(fb.size());
    }

    VLOG(1) << "payload_length=" << payload_length;
    Http2String payload = fb.buffer().substr(0, payload_length);

    // The missing length is the amount we cut off the end, unless
    // payload_length is zero, in which case the decoder knows only that 1
    // byte, the Pad Length field, is missing.
    size_t missing_length =
        payload_length == 0 ? 1 : fb.size() - payload_length;
    VLOG(1) << "missing_length=" << missing_length;

    const Http2FrameHeader header(payload_length, DecoderPeer::FrameType(),
                                  flags, RandStreamId());
    VERIFY_AND_RETURN_SUCCESS(
        VerifyDetectsPaddingTooLong(payload, header, missing_length));
  }

  // total_pad_length_ includes the size of the Pad Length field, and thus
  // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
  const size_t total_pad_length_;
  Http2FrameBuilder frame_builder_;
};

}  // namespace test
}  // namespace http2

#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
