Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec89acc0 authored by Ray Essick's avatar Ray Essick Committed by android-build-merger
Browse files

Merge "MediaTesting: Add ID3 Test"

am: f25ccd9e

Change-Id: I79b7dec5c53fe4fb9aeb94343e0afaa6377e5e1f
parents 2ff13bf0 f25ccd9e
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

cc_test {
    name: "ID3Test",
    gtest: true,

    srcs: ["ID3Test.cpp"],

    static_libs: [
        "libdatasource",
        "libstagefright_id3",
        "libstagefright",
        "libstagefright_foundation",
    ],

    shared_libs: [
        "libutils",
        "liblog",
        "libbinder",
    ],

    cflags: [
        "-Werror",
        "-Wall",
    ],

    sanitize: {
        cfi: true,
        misc_undefined: [
            "unsigned-integer-overflow",
            "signed-integer-overflow",
        ],
    },
}
+217 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "ID3Test"
#include <utils/Log.h>

#include <ctype.h>
#include <string>
#include <sys/stat.h>
#include <datasource/FileSource.h>

#include <media/stagefright/foundation/hexdump.h>
#include <ID3.h>

#include "ID3TestEnvironment.h"

using namespace android;

static ID3TestEnvironment *gEnv = nullptr;

class ID3tagTest : public ::testing::TestWithParam<string> {};
class ID3versionTest : public ::testing::TestWithParam<pair<string, int>> {};
class ID3textTagTest : public ::testing::TestWithParam<pair<string, int>> {};
class ID3albumArtTest : public ::testing::TestWithParam<pair<string, bool>> {};
class ID3multiAlbumArtTest : public ::testing::TestWithParam<pair<string, int>> {};

TEST_P(ID3tagTest, TagTest) {
    string path = gEnv->getRes() + GetParam();
    sp<FileSource> file = new FileSource(path.c_str());
    ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
    ID3 tag(file.get());
    ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";

    ID3::Iterator it(tag, nullptr);
    while (!it.done()) {
        String8 id;
        it.getID(&id);
        ASSERT_GT(id.length(), 0) << "No ID tag found! \n";
        ALOGV("Found ID tag: %s\n", String8(id).c_str());
        it.next();
    }
}

TEST_P(ID3versionTest, VersionTest) {
    int versionNumber = GetParam().second;
    string path = gEnv->getRes() + GetParam().first;
    sp<android::FileSource> file = new FileSource(path.c_str());
    ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";

    ID3 tag(file.get());
    ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
    ASSERT_TRUE(tag.version() >= versionNumber)
            << "Expected version: " << tag.version() << " Found version: " << versionNumber;
}

TEST_P(ID3textTagTest, TextTagTest) {
    int numTextFrames = GetParam().second;
    string path = gEnv->getRes() + GetParam().first;
    sp<android::FileSource> file = new FileSource(path.c_str());
    ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";

    ID3 tag(file.get());
    ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
    int countTextFrames = 0;
    ID3::Iterator it(tag, nullptr);
    while (!it.done()) {
        String8 id;
        it.getID(&id);
        ASSERT_GT(id.length(), 0);
        if (id[0] == 'T') {
            String8 text;
            countTextFrames++;
            it.getString(&text);
            ALOGV("Found text frame %s : %s \n", id.string(), text.string());
        }
        it.next();
    }
    ASSERT_EQ(countTextFrames, numTextFrames)
            << "Expected " << numTextFrames << " text frames, found " << countTextFrames;
}

TEST_P(ID3albumArtTest, AlbumArtTest) {
    bool albumArtPresent = GetParam().second;
    string path = gEnv->getRes() + GetParam().first;
    sp<android::FileSource> file = new FileSource(path.c_str());
    ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";

    ID3 tag(file.get());
    ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
    size_t dataSize;
    String8 mime;
    const void *data = tag.getAlbumArt(&dataSize, &mime);

    if (albumArtPresent) {
        if (data) {
            ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.string());
        }
        ASSERT_NE(data, nullptr) << "Expected album art, found none!" << path;
    } else {
        ASSERT_EQ(data, nullptr) << "Found album art when expected none!";
    }
#if (LOG_NDEBUG == 0)
    hexdump(data, dataSize > 128 ? 128 : dataSize);
#endif
}

TEST_P(ID3multiAlbumArtTest, MultiAlbumArtTest) {
    int numAlbumArt = GetParam().second;
    string path = gEnv->getRes() + GetParam().first;
    sp<android::FileSource> file = new FileSource(path.c_str());
    ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";

    ID3 tag(file.get());
    ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
    int count = 0;
    ID3::Iterator it(tag, nullptr);
    while (!it.done()) {
        String8 id;
        it.getID(&id);
        ASSERT_GT(id.length(), 0);
        // Check if the tag is an "APIC/PIC" tag.
        if (String8(id) == "APIC" || String8(id) == "PIC") {
            count++;
            size_t dataSize;
            String8 mime;
            const void *data = tag.getAlbumArt(&dataSize, &mime);
            if (data) {
                ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.string());
#if (LOG_NDEBUG == 0)
                hexdump(data, dataSize > 128 ? 128 : dataSize);
#endif
            }
            ASSERT_NE(data, nullptr) << "Expected album art, found none!" << path;
        }
        it.next();
    }
    ASSERT_EQ(count, numAlbumArt) << "Found " << count << " album arts, expected " << numAlbumArt
                                  << " album arts! \n";
}

INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest,
                         ::testing::Values("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_5mins.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3",
                                           "bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3"));

INSTANTIATE_TEST_SUITE_P(
        id3TestAll, ID3versionTest,
        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 4),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3", 4)));

INSTANTIATE_TEST_SUITE_P(
        id3TestAll, ID3textTagTest,
        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3", 5)));

INSTANTIATE_TEST_SUITE_P(
        id3TestAll, ID3albumArtTest,
        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", false),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", true),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", true),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", false),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", true),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", true),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", true)));

INSTANTIATE_TEST_SUITE_P(
        id3TestAll, ID3multiAlbumArtTest,
        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 0),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 0),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 1),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 2),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 2),
                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 3)));

int main(int argc, char **argv) {
    gEnv = new ID3TestEnvironment();
    ::testing::AddGlobalTestEnvironment(gEnv);
    ::testing::InitGoogleTest(&argc, argv);
    int status = gEnv->initFromOptions(argc, argv);
    if (status == 0) {
        status = RUN_ALL_TESTS();
        ALOGI("ID3 Test result = %d\n", status);
    }
    return status;
}
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

#ifndef __ID3_TEST_ENVIRONMENT_H__
#define __ID3_TEST_ENVIRONMENT_H__

#include <gtest/gtest.h>

#include <getopt.h>

using namespace std;

class ID3TestEnvironment : public::testing::Environment {
  public:
    ID3TestEnvironment() : res("/data/local/tmp/") {}

    // Parses the command line arguments
    int initFromOptions(int argc, char **argv);

    void setRes(const char *_res) { res = _res; }

    const string getRes() const { return res; }

  private:
    string res;
};

int ID3TestEnvironment::initFromOptions(int argc, char **argv) {
    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};

    while (true) {
        int index = 0;
        int c = getopt_long(argc, argv, "P:", options, &index);
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'P': {
                setRes(optarg);
                break;
            }
            default:
                break;
        }
    }

    if (optind < argc) {
        fprintf(stderr,
                "unrecognized option: %s\n\n"
                "usage: %s <gtest options> <test options>\n\n"
                "test options are:\n\n"
                "-P, --path: Resource files directory location\n",
                argv[optind ?: 1], argv[0]);
        return 2;
    }
    return 0;
}

#endif  // __ID3_TEST_ENVIRONMENT_H__
+34 −0
Original line number Diff line number Diff line
## Media Testing ##
---
#### ID3 Test :
The ID3 Test Suite validates the ID3 parser available in libstagefright.

Run the following command in the id3 folder to build the test suite:
```
m ID3Test
```

The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/

The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/

To test 64-bit binary push binaries from nativetest64.
```
adb push ${OUT}/data/nativetest64/ID3Test/ID3Test /data/local/tmp/
```

To test 32-bit binary push binaries from nativetest.
```
adb push ${OUT}/data/nativetest/ID3Test/ID3Test /data/local/tmp/
```

The resource file for the tests is taken from [here](https://drive.google.com/drive/folders/1pt5HFVSysbqfyqY1sVJ9MTupZKCdqjYZ). Push these files into device for testing.
Download ID3 folder and push all the files in this folder to /data/local/tmp/ID3 on the device.
```
adb push ID3/. /data/local/tmp/ID3
```

usage: ID3Test -P \<path_to_folder\>
```
adb shell /data/local/tmp/ID3Test -P /data/local/tmp/ID3/
```