| /* |
| * Copyright (C) 2011 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 "utils.h" |
| |
| #include <libgen.h> |
| #include <stdlib.h> |
| |
| #include "base/enums.h" |
| #include "base/file_utils.h" |
| #include "base/stl_util.h" |
| #include "class_linker-inl.h" |
| #include "common_runtime_test.h" |
| #include "exec_utils.h" |
| #include "handle_scope-inl.h" |
| #include "mirror/array-inl.h" |
| #include "mirror/array.h" |
| #include "mirror/object-inl.h" |
| #include "mirror/object_array-inl.h" |
| #include "mirror/string.h" |
| #include "scoped_thread_state_change-inl.h" |
| |
| #include "base/memory_tool.h" |
| |
| namespace art { |
| |
| class UtilsTest : public CommonRuntimeTest {}; |
| |
| TEST_F(UtilsTest, PrettyTypeOf) { |
| ScopedObjectAccess soa(Thread::Current()); |
| EXPECT_EQ("null", mirror::Object::PrettyTypeOf(nullptr)); |
| |
| StackHandleScope<2> hs(soa.Self()); |
| Handle<mirror::String> s(hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), ""))); |
| EXPECT_EQ("java.lang.String", mirror::Object::PrettyTypeOf(s.Get())); |
| |
| Handle<mirror::ShortArray> a(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 2))); |
| EXPECT_EQ("short[]", mirror::Object::PrettyTypeOf(a.Get())); |
| |
| mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); |
| ASSERT_TRUE(c != nullptr); |
| mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); |
| EXPECT_EQ("java.lang.String[]", mirror::Object::PrettyTypeOf(o)); |
| EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Object::PrettyTypeOf(o->GetClass())); |
| } |
| |
| TEST_F(UtilsTest, PrettyClass) { |
| ScopedObjectAccess soa(Thread::Current()); |
| EXPECT_EQ("null", mirror::Class::PrettyClass(nullptr)); |
| mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); |
| ASSERT_TRUE(c != nullptr); |
| mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); |
| EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Class::PrettyClass(o->GetClass())); |
| } |
| |
| TEST_F(UtilsTest, PrettyClassAndClassLoader) { |
| ScopedObjectAccess soa(Thread::Current()); |
| EXPECT_EQ("null", mirror::Class::PrettyClassAndClassLoader(nullptr)); |
| mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); |
| ASSERT_TRUE(c != nullptr); |
| mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); |
| EXPECT_EQ("java.lang.Class<java.lang.String[],null>", |
| mirror::Class::PrettyClassAndClassLoader(o->GetClass())); |
| } |
| |
| TEST_F(UtilsTest, PrettyField) { |
| ScopedObjectAccess soa(Thread::Current()); |
| EXPECT_EQ("null", ArtField::PrettyField(nullptr)); |
| |
| mirror::Class* java_lang_String = class_linker_->FindSystemClass(soa.Self(), |
| "Ljava/lang/String;"); |
| |
| ArtField* f; |
| f = java_lang_String->FindDeclaredInstanceField("count", "I"); |
| EXPECT_EQ("int java.lang.String.count", f->PrettyField()); |
| EXPECT_EQ("java.lang.String.count", f->PrettyField(false)); |
| } |
| |
| TEST_F(UtilsTest, PrettySize) { |
| EXPECT_EQ("1GB", PrettySize(1 * GB)); |
| EXPECT_EQ("2GB", PrettySize(2 * GB)); |
| if (sizeof(size_t) > sizeof(uint32_t)) { |
| EXPECT_EQ("100GB", PrettySize(100 * GB)); |
| } |
| EXPECT_EQ("1024KB", PrettySize(1 * MB)); |
| EXPECT_EQ("10MB", PrettySize(10 * MB)); |
| EXPECT_EQ("100MB", PrettySize(100 * MB)); |
| EXPECT_EQ("1024B", PrettySize(1 * KB)); |
| EXPECT_EQ("10KB", PrettySize(10 * KB)); |
| EXPECT_EQ("100KB", PrettySize(100 * KB)); |
| EXPECT_EQ("0B", PrettySize(0)); |
| EXPECT_EQ("1B", PrettySize(1)); |
| EXPECT_EQ("10B", PrettySize(10)); |
| EXPECT_EQ("100B", PrettySize(100)); |
| EXPECT_EQ("512B", PrettySize(512)); |
| } |
| |
| TEST_F(UtilsTest, JniShortName_JniLongName) { |
| ScopedObjectAccess soa(Thread::Current()); |
| mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;"); |
| ASSERT_TRUE(c != nullptr); |
| ArtMethod* m; |
| |
| m = c->FindClassMethod("charAt", "(I)C", kRuntimePointerSize); |
| ASSERT_TRUE(m != nullptr); |
| ASSERT_FALSE(m->IsDirect()); |
| EXPECT_EQ("Java_java_lang_String_charAt", m->JniShortName()); |
| EXPECT_EQ("Java_java_lang_String_charAt__I", m->JniLongName()); |
| |
| m = c->FindClassMethod("indexOf", "(Ljava/lang/String;I)I", kRuntimePointerSize); |
| ASSERT_TRUE(m != nullptr); |
| ASSERT_FALSE(m->IsDirect()); |
| EXPECT_EQ("Java_java_lang_String_indexOf", m->JniShortName()); |
| EXPECT_EQ("Java_java_lang_String_indexOf__Ljava_lang_String_2I", m->JniLongName()); |
| |
| m = c->FindClassMethod("copyValueOf", "([CII)Ljava/lang/String;", kRuntimePointerSize); |
| ASSERT_TRUE(m != nullptr); |
| ASSERT_TRUE(m->IsStatic()); |
| EXPECT_EQ("Java_java_lang_String_copyValueOf", m->JniShortName()); |
| EXPECT_EQ("Java_java_lang_String_copyValueOf___3CII", m->JniLongName()); |
| } |
| |
| TEST_F(UtilsTest, Split) { |
| std::vector<std::string> actual; |
| std::vector<std::string> expected; |
| |
| expected.clear(); |
| |
| actual.clear(); |
| Split("", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split(":", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| expected.clear(); |
| expected.push_back("foo"); |
| |
| actual.clear(); |
| Split(":foo", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split("foo:", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split(":foo:", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| expected.push_back("bar"); |
| |
| actual.clear(); |
| Split("foo:bar", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split(":foo:bar", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split("foo:bar:", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split(":foo:bar:", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| expected.push_back("baz"); |
| |
| actual.clear(); |
| Split("foo:bar:baz", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split(":foo:bar:baz", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split("foo:bar:baz:", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| |
| actual.clear(); |
| Split(":foo:bar:baz:", ':', &actual); |
| EXPECT_EQ(expected, actual); |
| } |
| |
| TEST_F(UtilsTest, ArrayCount) { |
| int i[64]; |
| EXPECT_EQ(ArrayCount(i), 64u); |
| char c[7]; |
| EXPECT_EQ(ArrayCount(c), 7u); |
| } |
| |
| TEST_F(UtilsTest, BoundsCheckedCast) { |
| char buffer[64]; |
| const char* buffer_end = buffer + ArrayCount(buffer); |
| EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(nullptr, buffer, buffer_end), nullptr); |
| EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer, buffer, buffer_end), |
| reinterpret_cast<const uint64_t*>(buffer)); |
| EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer + 56, buffer, buffer_end), |
| reinterpret_cast<const uint64_t*>(buffer + 56)); |
| EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer - 1, buffer, buffer_end), nullptr); |
| EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer + 57, buffer, buffer_end), nullptr); |
| } |
| |
| } // namespace art |