1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

Tuesday, November 9, 2010

Effective Java Programming

3. Avoid creating unnecessary objects
Reuse a single object instead of creating a functionally equivalent object each time is needed.
• Reuse immutable objects, such as String objects
 Avoid statements like String s = new String("abc") as this will create a copy of the String object “abc” every time it is executed. Instead, use String s = "abc";
• Beware about the performance of string concatenation: when two strings are concatenated, a new String object is allocated and the contents of both strings are copied into the new String object. Do not use string concatenation to combine more than a few strings (as the time required is quadratic to the number of strings to combine). As an alternative:
 Use the StringBuilder (which replaces StringBuffer in release 1.5) or
 Use a character array or
 Process the strings one at a time instead of combining them
Note: StringBuilder objects are like String objects, except that they can be modified. Internally, these objects are treated like variable-length arrays that contain a sequence of characters.
• Prefer static factory methods to constructors in classes that provide both; for example, the static factory method Boolean.valueOf(String) is preferable to the constructor Boolean(String) which always creates a new object.
Boolean b = Boolean.valueOf("abc"); //good
Boolean b = new Boolean ("abc"); //bad
• Prefer primitive types to boxed primitives & watch for unintentional autoboxing
public static void main(String[] args) {
Long sum =0L;
for (long i=0; i<=Integer.MAX_VALUE; i++)
sum = sum + i;
System.out.println(sum);
}
// a new object of type Long is created each time the long i is added to the Long sum (autoboxing); sum should be declared of type long (primitive type)
• Prefer multiple parallel one-dimensional arrays to one multi-dimensional array (e.g., multiple parallel arrays of ints are a lot more efficient than an array of (int,int) objects)
• Avoid creating short-lifetime objects to avoid frequent garbage collection
 If you have a method returning a string, and you know that its result will always be appended to a StringBuilder anyway, change your method so that it does the append directly, instead of creating a short-lived temporary object.
String m1()
{
String s1 = …;
… return s1;
}
… StringBuilder sb = new StringBuilder();
sb.append(m1());
void m1(StringBuilder sb)
{
String s1 = …;
… sb.append(s1);
}
… StringBuilder sb = new StringBuilder();
m1(sb);
 Avoid creating objects in a user interface loop, as it will force a periodic garbage collection, creating little "hiccups" in the user experience.
class MyFirstView extends View
{
protected void onDraw(Canvas canvas)
{
Object obj1;
for (int i=0; i<1000; obj1 =" new" start =" start;" end =" end;">0)
throw new IllegalArgumentException (start+" after"+end);
}
public Date start() {return start;}
public Date end() {return end;}
}
The above class appears to be immutable and to enforce the constraint that the end date follows the start date. However it can be broken by exploiting the fact that the Date is mutable.
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78); //Modifies the state of p
The solution is to make defensive copies of each mutable parameter in the constructor. Note that defensive copies are made before checking the validity of the parameters, and the validity check is performed on copies rather than on the originals. This is necessary to protect the class against changes to the parameters from another thread, between the time the parameters are checked and the time they are copied.
public Period(Date start, Date end) {
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
if (start.compareTo(end) >0)
throw new IllegalArgumentException (start+" after"+end);
}
However, the internal state of p can still be modified through the accessors.
p.end().setYear(78); //Modifies the state of p
The solution is to make the accessors return defensive copies of the mutable internal fields.
public Date start()
{
return new Date(start.getTime());
}
public Date end()
{
return new Date(end.getTime());
}

Effective Java Programming

Best practices and guidelines for writing efficient, well-designed programs
1. Minimize mutability :
An immutable class is a class whose objects cannot be modified (e.g., String, BigInteger, BigDecimal, Boolean, Integer, …). Immutable classes are: easier to design, implement and use, less prone to error and more secure. Disadvantage: they require a separate object for each distinct value (and object creation can be expensive especially for large objects).
Immutable objects: are simple (can only have one state, the state in which they were created), are inherently thread-safe (they require no synchronization, can be shared freely) and make great building blocks for other objects.
To make a class immutable:
- don’t provide any mutators
- make all fields final and private
- ensure the class cannot be extended (for example, make it final, or make its constructor private and provide public static factory methods in place of constructors)
- ensure exclusive access to any mutable components, such as fields that refer to mutable objects
//class is declared final to prevent it from being subclassed
public final class Complex {
private final double re;
private final double im;
public Complex (double re, double im) {
this.re = re;
this.im = im
}
//…other methods (but no mutators)
}
or
public class Complex {
private final double re;
private final double im;
//constructor is private to prevent the class from being subclasses
private Complex (double re, double im) {
this.re = re;
this.im = im
}
//public static factory method for object construction
public static Complex valueOf(double re, double im) {
return new Complex(re, im);
}
//…other methods (but no mutators)
}
If a class cannot be made immutable, limit its mutability as much as possible. Make every field final unless there is a compelling reason to make it non-final.
2. Declare constants final :
Declaring fields final makes them accessible faster, especially is they are also static.
For classes that involve static fields, the compiler generates a class initializer method, called , which is executed when the class is first used. This method creates (and initializes) the static fields. When these fields are referenced later on, they are accessed with field lookups (just like non-static fields).
class SomeClass {
static int intVal = 42;
}
If the static fields are also declared as final, the class no longer requires a method, because the constants go into classfile static field initializers, which are handled directly by the virtual machine. Code accessing these variables will use their values directly (instead of a field lookup).
class SomeClass {
static final int intVal = 42;
}
Declaring a method or class final does not confer any immediate performance benefits, but it does allow certain optimizations. For example, if the compiler knows that a "getter" method can't be overridden by a subclass, it can inline the method call.
You can also declare local variables final, but this has no definitive performance benefits (it might make the code clearer).

Sunday, November 7, 2010

Signals In Linux Kernel

Check for Signals in kernel implementation and user programming below link.

http://www.mediafire.com/?ta78amq6bxpmuy2

Tuesday, November 2, 2010

The sysfs Filesystem

sysfs is a feature of the Linux 2.6 kernel that allows kernel code to export information to user processes via an in-memory filesystem. The organization of the filesystem directory hierarchy is strict, and based the internal organization of kernel data structures. The files that are created in the filesystem are (mostly) ASCII files with (usually) one value per file. These features ensure that the information exported is accurate and easily accessible, making sysfs one of the
most intuitive and useful features of the 2.6 kernel.

Introduction
sysfs is a mechanism for representing kernel objects, their attributes, and their relationships with each other. It provides two components:a kernel programming interface for exporting these items via sysfs, and a user interface to view and manipulate these items that maps back to the kernel objects which they represent. The table below shows the mapping between internel (kernel) constructs and their external (userspace) sysfs mappings.

First, a short but touching history describes its origins. Then crucial information about mounting and accessing sysfs is included. Next, the directory organization and layout of subsystems in sysfs is described. This provides enough information for a user to understand the organization and content of the information that is exported through sysfs, though for reasons of time and space constraints, not every object and its attributes are described.
The primary goal of this paper is to provide a technical overview of the internal sysfs interface—the data structures and the functions that are used to export kernel constructs to userspace. It describes the functions among the three concepts mentioned above Kernel Objects, Object Attributes, and Object Relationships—and dedicates a section to each one. It also provides a section for each of the two additional regular file interfaces created to simplify some common operations—Attribute Groups and Binary Attributes.sysfs is a conduit of information between the kernel and user space. There are many opportunities for user space applications to leverage this information. Some existing uses are the ability to I/O Scheduler parameters and the udev program. The final section describes a sampling of the current applications that use sysfs and attempts to provide enough inspira-
tion to spawn more development in this area.Because it is a simple and mostly abstract interface, much time can be spent describing its interactions with each subsystem that uses it.This is especially true for the kobject and driver models, which are both new features of the 2.6 kernel and heavily intertwined with sysfs. It would be impossible to do those topics justice in such a medium and are left as subjects for other documents.

The History of sysfs
sysfs is an in-memory filesystem that was originally based on ramfs. ramfs was written around the time the 2.4.0 kernel was being stabilized. It was an exercise in elegance, as it showed just how easy it was to write a simple filesystem using the then-new VFS layer. Because of its simplicity and use of the VFS, it provided a good base from which to derive other in-memory based filesystems. sysfs was originally called ddfs (Device Driver Filesystem) and was written to debug the new driver model as it was being written. That debug code had originally used procfs to export a device tree, but under strict urging from Linus Torvalds, it was converted to use a new filesystem based on ramfs.By the time the new driver model was merged into the kernel around 2.5.1, it had changed names to driverfs to be a little more descriptive.During the next year of 2.5 development, the infrastructural capabilities of the driver model and driverfs began to prove useful to other sub- systems. kobjects were developed to provide a central object management mechanism and driverfs was converted to sysfs to represent its subsystem agnosticism.
Mounting sysfs
sysfs can be mounted from userspace just like any other memory-based filesystem. The command for doing so is listed in Table 1. sysfs can also be mounted automatically on
boot using the file /etc/fstab. Most distributions that support the 2.6 kernel have entries for sysfs in /etc/fstab. An example entry is shown in Table 2. Note that the directory that sysfs is mounted on: /sys. That is the de facto standard location for the sysfs mount point. This was adopted without objection by every major distribution.
Navigating sysfs
Since sysfs is simply a collection of directories, files, and symbolic links, it can be navigated and manipulated using simple shell utilities. The author recommends the tree(1)utility. It was an invaluable aide during the development of the core kernel object infrastructure.
/sys/
-- block
-- bus
-- class
-- devices
-- firmware
-- module
‘-- power
Table 3: Top level sysfs directories
At the top level of the sysfs mount point are a number of directories. These directories represent the major subsystems that are registered with sysfs. At the time of publication, this consisted of the directories listed in Table 3. These directories are created at system startup when the subsystems register themselves with the kobject core. After they are initialized, they begin to discover objects, which are registered within their respective directories.The method by which objects register with sysfs and how directores are created is explained later in the paper. In the meantime, the curious are encouraged to meander on their own through the sysfs hierarchy, and the meaning of each subsystem and their contents follows now.
block
The block directory contains subdirectories for each block device that has been discovered in the system. In each block device’s directory are attributes that describe many things, including the size of the device and the dev_t number that it maps to. There is a symbolic link that points to the physical device that the block device maps to (in the physical device tree, which is explained later). And, there is a directory that exposes an interface to the I/O scheduler. This interface provides some statistics about about the device request queue and some tunable features that a user or administrator can use to

bus/
-- ide
-- pci
-- scsi
‘-- usb
Table 4: The bus directory
optimize performance, including the ability to dyanmically change the I/O scheduler to use.Each partition of each block device is represented as a subdirectory of the block device.Included in these directories are read-only attributes about the partitions.

bus
The bus directory contains subdirectories for each physical bus type that has support registered in the kernel (either statically compiled or loaded via a module). Partial output is listed in Table 4. Each bus type that is represented has two subdirectories: devices and drivers. The devices directory contains a flat listing of every device discovered on that type of bus in the entire system. The devices listed are actually symbolic links that point to the device’s direc-
tory in the global device tree. An example listing is shown in Table 5.
The drivers directory contains directories for each device driver that has been registered with the bus type. Within each of the drivers’ directories are attributes that allow viewing and manipulation of driver parameters, and symbolic links that point to the physical devices (in the global device tree) that the driver is bound to.
bus/pci/devices/
-- 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
-- 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0
-- 0000:01:00.0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0
-- 0000:02:00.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.0
-- 0000:02:00.1 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.1
-- 0000:02:01.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:01.0
‘-- 0000:02:02.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:02.0
Table 5: PCI devices represented in bus/pci/devices/

class/
-- graphics
-- input
-- net
-- printer
-- scsi_device
-- sound
‘-- tty
Table 6: The class directory
class
The class directory contains representations of every device class that is registered with the kernel. A device class describes a functional type of device. Examples of classes are shown in Table 6. Each device class contains subdirectories for each class object that has been allocated and registered with that device class. For most of class device objects, their directories contain
symbolic links to the device and driver directories (in the global device hierarchy and the bus hierarchy respectively) that are associated with that class object. Note that there is not necessarily a 1:1 mapping between class objects and physical devices; a physical device may contain multiple class objects that perform a different logical function. For example, a physical mouse device might map to a kernel mouse object, as well as a generic “input event” device and possibly a “input debug” device.
Each class and class object may contain attributes exposing parameters that describe or control the class object. The contents and format, though, are completely class dependent and depend on the support present in one’s kernel.
devices
The devices directory contains the global device hierarchy. This contains every physical device that has been discovered by the bus types registered with the kernel. It represents them in an ancestrally correct way—each device is shown as a subordinate device of the device that it is physically (electrically) subordinate to.
There are two types of devices that are exceptions to this representation: platform devices and system devices. Platform devices are peripheral devices that are inherent to a particular platform. They usually have some I/O ports, or MMIO, that exists at a known, fixed location. Examples of platform devices are legacy x86 devices like a serial controller or a floppy controller, or the embedded devices of a SoC solution. System devices are non-peripheral devices that are integral components of the system. In many ways, they are nothing like any other device. They may have some hardware register access for configuration, but do not have the capability to transfer data. They usually do not have drivers which can be bound to them. But, at least for those represented through sysfs, have some architecture-specific code that configures them and treats them enough as objects to export them. Examples of system devices are CPUs, APICs, and timers.

firmware
The firmware directory contains interfaces for viewing and manipulating firmware-
specific objects and attributes. In this case, ‘firmware’ refers to the platform-specific code that is executed on system power-on, like the x86 BIOS, OpenFirmware on PPC platforms,and EFI on ia64 platforms. Each directory contains a set of objects and attributes that is specific to the firmware “driver in the kernel.” For example, in the case of ACPI, every object found in the ACPI DSDT table is listed in firmware/acpi/ namespace/ directory.
module
The module directory contains subdirectories for each module that is loaded into the kernel.The name of each directory is the name of the module—both the name of the module object
file and the internal name of the module. Every module is represented here, regardless of
the subsystem it registers an object with. Note that the kernel has a single global namespace
for all modules. Within each module directory is a subdirectory called sections. This subdirectory contains attributes about the module sections. This information is used for debugging and generally not very interesting. Each module directory also contains at least one attribute: refcnt. This attributes displays the current reference count, or number of users, of the module. This is the same value in the fourth column of lsmod(8) output.
power
The power directory represents the underused power subsystem. It currently contains
only two attributes: disk which controls the method by which the system will suspend to disk; and state, which allows a process to enter a low power state. Reading this file displays which states the system supports.
General Kernel Information :
Code Organization :-
The code for sysfs resides in fs/sysfs/ and its shared function prototypes are in include/linux/sysfs.h. It is relatively small (~2000 lines), but it is divided up among 9 files, including the shared header file. The organization of these files is listed below. The contents of each of these files is described in the next section.
• include/linux/sysfs.h - Shared header file containing function prototypes and data structure definitions.
• fs/sysfs/sysfs.h - Internal header file for sysfs. Contains function definitions
shared locally among the sysfs source.
• fs/sysfs/mount.c - This contains the data structures, methods, and initialization functions necessary for interacting with the VFS layer.

Monday, November 1, 2010

Google Test Framework With Example in android

How to write a simple test for testing the opening of the framebuffer

1. Create a folder called mnuFBgtest in the vendor folder

2. In mnuFBgtest folder create two files called Android.mk and mnuFBgtest.cpp with the content stated below
mnuFBgtest.cpp:
#include // here gtest/gtest.h
#include // here iostream

#include // here fcntl.h
#include // here unistd.h
#include // here linux/fb.h

TEST(FBTest, OpenFrameBuffer) {
int fbfd;

// Open the file for reading and writing
fbfd = open("/dev/graphics/fb0", O_RDWR);
ASSERT_TRUE(fbfd) << "Cannot open framebuffer device \n";

close(fbfd);
}
int main(int argc, char **argv) {
std::cout << "Running main() from mnuFBgtest.cpp\n";
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := mnuFBgtest.cpp
LOCAL_MODULE := mnuFBgtest
LOCAL_MODULE_TAGS := tests
LOCAL_SHARED_LIBRARIES := libstlport libgtest
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_CFLAGS += -O0 -DANDROID
LOCAL_C_INCLUDES := \
$(TOPDIR)external/gtest/include \
$(TOPDIR)external/stlport/stlport \
$(LOCAL_PATH)

LOCAL_PRELINK_MODULE := false
include $(BUILD_EXECUTABLE)

3. Compile it with:

make mnuFBgtest

4. push the executable to target:

adb push out/target/product/productname/system/xbin/mnuFBgtest /data

5. start adb shell and type:

/data/mnuFBgtest

and you should get the following output:

Running main() from mnuFBgtest.cpp
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from FBTest
[ RUN ] FBTest.OpenFrameBuffer
[ OK ] FBTest.OpenFrameBuffer
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran.
[ PASSED ] 1 test.


And now you're done!

Google Test Framework With Example in android

How to build a shared lib and test it with gtest:

1. Get the latest kernel version or new software

mkdir mydroid
cd mydroid
repo init -u git://kernel.org (download the software from your own repository)
repo sync

2. Build the SW

source build/envsetup.sh
choosecombo 1 1 productname eng
make sin

3. Flash your phone with the newly built SW. (the sin files is located in out/target/product/productname).

4. Start the phone and connect it to you workstation

5. In the vendor folder create a new folder called mnuDummyLib

6. Now we create our "dummy lib" that we're going to test. In the mnuDummyLib folder create three files called Android.mk, mnu.c, and mnu.h with the content stated below

mnu.h:
#ifdef __cplusplus
extern "C" {
#endif
int add(int a, int b);
int multiply(int a, int b);

#ifdef __cplusplus
}
#endif
mnu.c:
#include
#include "mnu.h"
#include "utils/Log.h"

int add(int a, int b) {
LOGD("(mnuLib) calling add with %d and %d as inparams",a,b); /* logcat print*/
return a+b;
}

int multiply(int a, int b) {
LOGD("(mnuLib) calling multiply with %d and %d as inparams",a,b); /* logcat print*/
return a*b;
}
Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= mnu.c
LOCAL_C_INCLUDES +=$(LOCAL_PATH)
LOCAL_MODULE := libmnu
LOCAL_SHARED_LIBRARIES := libcutils libc
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)

7. to build our "dummy" shared lib navigate back to the "build root" and type:
make libmnu

8. ReMount the device and push the libmnu.so file to target

adb remount
adb push out/target/product/productname/system/lib/libmnu.so /system/lib

9. Now that we have our "dummy lib" in place we can start the development of your test suite. Navigate to vendor folder and create a folder called testLibMnu.

10. In the folder testLibMnu create two files called Android.mk and testLibMnu.cpp with the content stated below:

testLibMnu.cpp:
#include //here gtest
#include // here iostream

#include "mnu.h"

TEST(LibMnuTest, AddTestPass) {
EXPECT_EQ(10, add(5,5));
}

TEST(LibMnuTest, AddTestFail) {
// this test should fail
EXPECT_EQ(10, add(4,5));
}

TEST(LibMnuTest, MultiplyTestPass) {
EXPECT_EQ(25, multiply(5,5));
}

TEST(LibMnuTest, MultiplyTestFail) {
// this test should fail
EXPECT_EQ(10, multiply(5,5));
}

int main(int argc, char **argv) {
std::cout << "Running main() from testLibMnu.cpp\n";

testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := testLibMnu.cpp
LOCAL_MODULE := testLibMnu
LOCAL_MODULE_TAGS := tests
LOCAL_SHARED_LIBRARIES := libstlport libgtest libmnu
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_CFLAGS += -O0 -DANDROID
LOCAL_C_INCLUDES := \
$(TOPDIR)vendor/mnuDummyLib \
$(TOPDIR)external/gtest/include \
$(TOPDIR)external/stlport/stlport \
$(LOCAL_PATH)

LOCAL_PRELINK_MODULE := false
include $(BUILD_EXECUTABLE)

Make sure that you don't have any trailing whitespcaes in the make file because this will end up in strange compiler errors (I lerned it the hard way...)
11. Now we are ready to compile our test program and to do so navigate back to "build root" and type:
make testLibMnu
12. Now we need to push the executable file to the target:
adb push out/target/product/productname/system/xbin/testLibMnu /data
13. Now we are ready to run our test program, start adb shell and type:
adb shell /data/testLibMnu
you should get an output like this:
Running main() from testLibMnu.cpp
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from LibMnuTest
[ RUN ] LibMnuTest.AddTestPass
[ OK ] LibMnuTest.AddTestPass
[ RUN ] LibMnuTest.AddTestFail
vendor/testLibMnu/testLibMnu.cpp:11: Failure
Value of: add(4,5)
Actual: 9
Expected: 10
[ FAILED ] LibMnuTest.AddTestFail
[ RUN ] LibMnuTest.MultiplyTestPass
[ OK ] LibMnuTest.MultiplyTestPass
[ RUN ] LibMnuTest.MultiplyTestFail
vendor/testLibMnu/testLibMnu.cpp:20: Failure
Value of: multiply(5,5)
Actual: 25
Expected: 10
[ FAILED ] LibMnuTest.MultiplyTestFail
[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran.
[ PASSED ] 2 tests.
[ FAILED ] 2 tests, listed below:
[ FAILED ] LibMnuTest.AddTestFail
[ FAILED ] LibMnuTest.MultiplyTestFail

2 FAILED TESTS
And now you're done!!!

Google Test Framework Advanced Concepts

More Assertions
This section covers some less frequently used, but still significant, assertions.
Explicit Success and Failure
These three assertions do not actually test a value or expression. Instead, they generate a success or failure directly. Like the macros that actually perform a test, you may stream a custom failure message into the them.
SUCCEED();
Generates a success. This does NOT make the overall test succeed. A test is considered successful only if none of its assertions fail during its execution.
Note: SUCCEED() is purely documentary and currently doesn't generate any user-visible output. However, we may add SUCCEED() messages to Google Test's output in the future.
FAIL(); ADD_FAILURE(); ADD_FAILURE_AT("file_path", line_number);

FAIL() generates a fatal failure, while ADD_FAILURE() and ADD_FAILURE_AT() generate a nonfatal failure. These are useful when control flow, rather than a Boolean expression, deteremines the test's success or failure. For example, you might want to write something like:
switch(expression)
{
case 1: ... some checks ...
case 2: ... some other checks
...
default: FAIL() << "We shouldn't get here."; } Exception Assertions
These are for verifying that a piece of code throws (or does not throw) an exception of the given type:
Fatal assertion :
ASSERT_THROW(statement, exception_type);
ASSERT_ANY_THROW(statement);
ASSERT_NO_THROW(statement);
Nonfatal assertion :
EXPECT_THROW(statement, exception_type);
EXPECT_ANY_THROW(statement);
EXPECT_NO_THROW(statement);
Verifies :
statement throws an exception of the given type
statement throws an exception of any type
statement doesn't throw any exception
Examples:
ASSERT_THROW(Foo(5), bar_exception);
EXPECT_NO_THROW({
int n = 5;
Bar(&n);
});
Predicate Assertions for Better Error Messages
Even though Google Test has a rich set of assertions, they can never be complete, as it's impossible (nor a good idea) to anticipate all the scenarios a user might run into. Therefore, sometimes a user has to use EXPECT_TRUE() to check a complex expression, for lack of a better macro. This has the problem of not showing you the values of the parts of the expression, making it hard to understand what went wrong. As a workaround, some users choose to construct the failure message by themselves, streaming it into EXPECT_TRUE(). However, this is awkward especially when the expression has side-effects or is expensive to evaluate.
Google Test gives you three different options to solve this problem:

 
# #