普通文本  |  224行  |  7.89 KB

//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <dhcp_client/dhcp_options_parser.h>

#include <netinet/in.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <gtest/gtest.h>
#include <shill/net/byte_string.h>

using shill::ByteString;

namespace {
const uint8_t kFakeUInt8Option[] = {0x02};
const uint8_t kFakeUInt8OptionLength = 1;
const uint8_t kFakeUInt16Option[] = {0x2a, 0x01};
const uint8_t kFakeUInt16OptionLength = 2;
const uint8_t kFakeUInt32Option[] = {0x01, 0x02, 0x00, 0xfa};
const uint8_t kFakeUInt32OptionLength = 4;
const uint8_t kFakeUInt8ListOption[] =
    {0x01, 0x02, 0x00, 0xfa, 0x23, 0xae, 0x1f, 0x00};
const uint8_t kFakeUInt8ListOptionLength = 8;

const uint8_t kFakeUInt16ListOption[] =
    {0xaa, 0x26, 0x4b, 0x00, 0xff, 0xc2, 0xcf, 0x0d, 0xe0, 0x01};
const uint8_t kFakeUInt16ListOptionLength = 10;

const uint8_t kFakeUInt32ListOption[] = {0x01, 0x02, 0x00, 0xfa,
                                         0x23, 0xae, 0x1f, 0x00,
                                         0x0c, 0x53, 0x33, 0x10,
                                         0x47, 0x80, 0xb3, 0xff};
const uint8_t kFakeUInt32ListOptionLength = 16;

const uint8_t kFakeUInt32PairListOption[] = {0x21, 0xa0, 0xeb, 0x73,
                                             0x01, 0x00, 0x1f, 0x10,
                                             0xc9, 0x22, 0x3a, 0x37,
                                             0xff, 0x00, 0xbe, 0xd0};
const uint8_t kFakeUInt32PairListOptionLength = 16;

const unsigned char kFakeStringOption[] =
    {'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g'};
const uint8_t kFakeStringOptionLength = 10;

const unsigned char kFakeByteArrayOption[] =
    {'f', 'a', 'k', 'e', 'b', 'y', 't', 'e', 'a', 'r', 'r', 'a', 'y'};

const uint8_t kFakeBoolOptionEnable[] = {0x01};
const uint8_t kFakeBoolOptionDisable[] = {0x00};
const uint8_t kFakeBoolOptionLength = 1;
}  // namespace

namespace dhcp_client {

class ParserTest : public testing::Test {
 protected:
  std::unique_ptr<DHCPOptionsParser> parser_;
};

TEST_F(ParserTest, ParseUInt8) {
  parser_.reset(new UInt8Parser());
  uint8_t value;
  EXPECT_TRUE(parser_->GetOption(kFakeUInt8Option,
                                 kFakeUInt8OptionLength,
                                 &value));
  EXPECT_EQ(*kFakeUInt8Option, value);
}

TEST_F(ParserTest, ParseUInt16) {
  parser_.reset(new UInt16Parser());
  uint16_t value;
  uint16_t target_value =
      *reinterpret_cast<const uint16_t*>(kFakeUInt16Option);
  target_value = ntohs(target_value);
  EXPECT_TRUE(parser_->GetOption(kFakeUInt16Option,
                                 kFakeUInt16OptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseUInt32) {
  parser_.reset(new UInt32Parser());
  uint32_t value;
  uint32_t target_value =
      *reinterpret_cast<const uint32_t*>(kFakeUInt32Option);
  target_value = ntohl(target_value);
  EXPECT_TRUE(parser_->GetOption(kFakeUInt32Option,
                                 kFakeUInt32OptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseUInt8List) {
  parser_.reset(new UInt8ListParser());
  std::vector<uint8_t> value;
  std::vector<uint8_t> target_value;
  uint8_t length = kFakeUInt8ListOptionLength;
  const uint8_t* uint8_list =
      reinterpret_cast<const uint8_t*>(kFakeUInt8ListOption);
  target_value = std::vector<uint8_t>(uint8_list, uint8_list + length);
  EXPECT_TRUE(parser_->GetOption(kFakeUInt8ListOption,
                                 kFakeUInt8ListOptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseUInt16List) {
  parser_.reset(new UInt16ListParser());
  std::vector<uint16_t> value;
  std::vector<uint16_t> target_value;
  std::vector<uint16_t> target_value_net_order;
  int length = kFakeUInt16ListOptionLength / sizeof(uint16_t);
  const uint16_t* uint16_list =
      reinterpret_cast<const uint16_t*>(kFakeUInt16ListOption);
  target_value_net_order =
      std::vector<uint16_t>(uint16_list, uint16_list + length);
  for (uint16_t element : target_value_net_order) {
    target_value.push_back(ntohs(element));
  }
  EXPECT_TRUE(parser_->GetOption(kFakeUInt16ListOption,
                                 kFakeUInt16ListOptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseUInt32List) {
  parser_.reset(new UInt32ListParser());
  std::vector<uint32_t> value;
  std::vector<uint32_t> target_value;
  std::vector<uint32_t> target_value_net_order;
  int length = kFakeUInt32ListOptionLength / sizeof(uint32_t);
  const uint32_t* uint32_list =
      reinterpret_cast<const uint32_t*>(kFakeUInt32ListOption);
  target_value_net_order =
      std::vector<uint32_t>(uint32_list, uint32_list + length);
  for (uint32_t element : target_value_net_order) {
    target_value.push_back(ntohl(element));
  }
  EXPECT_TRUE(parser_->GetOption(kFakeUInt32ListOption,
                                 kFakeUInt32ListOptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseUInt32PairList) {
  parser_.reset(new UInt32PairListParser());
  int length = kFakeUInt32PairListOptionLength / (2 * sizeof(uint32_t));
  const uint32_t* uint32_array =
      reinterpret_cast<const uint32_t*>(kFakeUInt32PairListOption);
  std::vector<uint32_t> uint32_vector =
      std::vector<uint32_t>(uint32_array, uint32_array + length * 2);
  std::vector<std::pair<uint32_t, uint32_t>> target_value;
  for (int i = 0; i < length; i++) {
    target_value.push_back(
        std::pair<uint32_t, uint32_t>(ntohl(uint32_vector[2 * i]),
                                      ntohl(uint32_vector[2 * i + 1])));
  }
  std::vector<std::pair<uint32_t, uint32_t>> value;
  EXPECT_TRUE(parser_->GetOption(kFakeUInt32PairListOption,
                                 kFakeUInt32PairListOptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseBoolEnable) {
  parser_.reset(new BoolParser());
  bool value;
  EXPECT_TRUE(parser_->GetOption(kFakeBoolOptionEnable,
                                 kFakeBoolOptionLength,
                                 &value));
  EXPECT_TRUE(value);
}

TEST_F(ParserTest, ParseBoolDisable) {
  parser_.reset(new BoolParser());
  bool value;
  EXPECT_TRUE(parser_->GetOption(kFakeBoolOptionDisable,
                                 kFakeBoolOptionLength,
                                 &value));
  EXPECT_FALSE(value);
}

TEST_F(ParserTest, ParseString) {
  parser_.reset(new StringParser());
  std::string value;
  std::string target_value;
  target_value.assign(reinterpret_cast<const char*>(kFakeStringOption),
                      kFakeStringOptionLength);
  EXPECT_TRUE(parser_->GetOption(kFakeStringOption,
                                 kFakeStringOptionLength,
                                 &value));
  EXPECT_EQ(target_value, value);
}

TEST_F(ParserTest, ParseByteArray) {
  parser_.reset(new ByteArrayParser());
  ByteString value;
  ByteString target_value(reinterpret_cast<const char*>(kFakeByteArrayOption),
                          sizeof(kFakeByteArrayOption));
  EXPECT_TRUE(parser_->GetOption(kFakeByteArrayOption,
                                 sizeof(kFakeByteArrayOption),
                                 &value));
  EXPECT_TRUE(target_value.Equals(value));
}

}  // namespace dhcp_client