C++程序  |  214行  |  7.39 KB

/*
 * Copyright (C) 2017 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 <algorithm>
#include <iterator>
#include <iostream>

#include <gtest/gtest.h>

#include <apdu/apdu.h>

using android::CommandApdu;
using android::ResponseApdu;

/* CommandApdu */

TEST(CommandApduTest, Case1) {
    const CommandApdu apdu{1, 2, 3, 4};
    const std::vector<uint8_t> expected{1, 2, 3, 4};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case2s) {
    const CommandApdu apdu{4, 3, 2, 1, 0, 3};
    const std::vector<uint8_t> expected{4, 3, 2, 1, 3};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case2s_maxLe) {
    const CommandApdu apdu{4, 3, 2, 1, 0, 256};
    const std::vector<uint8_t> expected{4, 3, 2, 1, 0};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case2e) {
    const CommandApdu apdu{5, 6, 7, 8, 0, 258};
    const std::vector<uint8_t> expected{5, 6, 7, 8, 0, 1, 2};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case2e_maxLe) {
    const CommandApdu apdu{5, 6, 7, 8, 0, 65536};
    const std::vector<uint8_t> expected{5, 6, 7, 8, 0, 0, 0};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case3s) {
    const CommandApdu apdu{8, 7, 6, 5, 5, 0};
    const std::vector<uint8_t> expected{8, 7, 6, 5, 5, 0, 0, 0, 0, 0};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case3s_data) {
    CommandApdu apdu{8, 7, 6, 5, 3, 0};
    auto it = apdu.dataBegin();
    *it++ = 10;
    *it++ = 11;
    *it++ = 12;
    ASSERT_EQ(apdu.dataEnd(), it);

    const std::vector<uint8_t> expected{8, 7, 6, 5, 3, 10, 11, 12};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case3e) {
    const CommandApdu apdu{8, 7, 6, 5, 256, 0};
    std::vector<uint8_t> expected{8, 7, 6, 5, 0, 1, 0};
    expected.resize(expected.size() + 256, 0);
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case3e_data) {
    CommandApdu apdu{8, 7, 6, 5, 65535, 0};
    ASSERT_EQ(size_t{65535}, apdu.dataSize());
    std::fill(apdu.dataBegin(), apdu.dataEnd(), 7);
    std::vector<uint8_t> expected{8, 7, 6, 5, 0, 255, 255};
    expected.resize(expected.size() + 65535, 7);
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case4s) {
    const CommandApdu apdu{1, 3, 5, 7, 2, 3};
    const std::vector<uint8_t> expected{1, 3, 5, 7, 2, 0, 0, 3};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case4s_data) {
    CommandApdu apdu{1, 3, 5, 7, 1, 90};
    auto it = apdu.dataBegin();
    *it++ = 8;
    ASSERT_EQ(apdu.dataEnd(), it);

    const std::vector<uint8_t> expected{1, 3, 5, 7, 1, 8, 90};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case4s_maxLe) {
    const CommandApdu apdu{1, 3, 5, 7, 2, 256};
    const std::vector<uint8_t> expected{1, 3, 5, 7, 2, 0, 0, 0};
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case4e) {
    const CommandApdu apdu{1, 3, 5, 7, 527, 349};
    std::vector<uint8_t> expected{1, 3, 5, 7, 0, 2, 15};
    expected.resize(expected.size() + 527, 0);
    expected.push_back(1);
    expected.push_back(93);
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

TEST(CommandApduTest, Case4e_maxLe) {
    const CommandApdu apdu{1, 3, 5, 7, 20, 65536};
    std::vector<uint8_t> expected{1, 3, 5, 7, 0, 0, 20};
    expected.resize(expected.size() + 20, 0);
    expected.push_back(0);
    expected.push_back(0);
    ASSERT_EQ(expected.size(), apdu.size());
    ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end()));
}

/* ResponseApdu */

TEST(ResponseApduTest, bad) {
    const std::vector<uint8_t> empty{};
    const ResponseApdu<std::vector<uint8_t>> apdu{empty};
    ASSERT_FALSE(apdu.ok());
}

TEST(ResponseApduTest, statusOnly) {
    const std::vector<uint8_t> statusOnly{0x90, 0x37};
    const ResponseApdu<std::vector<uint8_t>> apdu{statusOnly};
    ASSERT_TRUE(apdu.ok());
    ASSERT_EQ(0x90, apdu.sw1());
    ASSERT_EQ(0x37, apdu.sw2());
    ASSERT_EQ(0x9037, apdu.status());
    ASSERT_EQ(size_t{0}, apdu.dataSize());
}

TEST(ResponseApduTest, data) {
    const std::vector<uint8_t> data{1, 2, 3, 9, 8, 7, 0x3a, 0xbc};
    const ResponseApdu<std::vector<uint8_t>> apdu{data};
    ASSERT_TRUE(apdu.ok());
    ASSERT_EQ(0x3abc, apdu.status());
    ASSERT_EQ(size_t{6}, apdu.dataSize());

    const uint8_t expected[] = {1, 2, 3, 9, 8, 7};
    ASSERT_TRUE(std::equal(apdu.dataBegin(), apdu.dataEnd(),
                           std::begin(expected), std::end(expected)));
}

TEST(ResponseApduTest, remainingBytes) {
    const std::vector<uint8_t> remainingBytes{0x61, 23};
    const ResponseApdu<std::vector<uint8_t>> apdu{remainingBytes};
    ASSERT_EQ(23, apdu.remainingBytes());
    ASSERT_FALSE(apdu.isWarning());
    ASSERT_FALSE(apdu.isExecutionError());
    ASSERT_FALSE(apdu.isCheckingError());
    ASSERT_FALSE(apdu.isError());
}

TEST(ResponseApduTest, warning) {
    const std::vector<uint8_t> warning{0x62, 0};
    const ResponseApdu<std::vector<uint8_t>> apdu{warning};
    ASSERT_TRUE(apdu.isWarning());
    ASSERT_FALSE(apdu.isExecutionError());
    ASSERT_FALSE(apdu.isCheckingError());
    ASSERT_FALSE(apdu.isError());
}

TEST(ResponseApduTest, executionError) {
    const std::vector<uint8_t> executionError{0x66, 0};
    const ResponseApdu<std::vector<uint8_t>> apdu{executionError};
    ASSERT_FALSE(apdu.isWarning());
    ASSERT_TRUE(apdu.isExecutionError());
    ASSERT_FALSE(apdu.isCheckingError());
    ASSERT_TRUE(apdu.isError());
}

TEST(ResponseApduTest, checkingError) {
    const std::vector<uint8_t> checkingError{0x67, 0};
    const ResponseApdu<std::vector<uint8_t>> apdu{checkingError};
    ASSERT_FALSE(apdu.isWarning());
    ASSERT_FALSE(apdu.isExecutionError());
    ASSERT_TRUE(apdu.isCheckingError());
    ASSERT_TRUE(apdu.isError());
}