Index: base/android/third_party/cygprofile_startup/cygprofile_startup_unittest.cc |
diff --git a/base/android/third_party/cygprofile_startup/cygprofile_startup_unittest.cc b/base/android/third_party/cygprofile_startup/cygprofile_startup_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..882a33c3ed4942a80e2ab62b0fd2b8f32af6d84a |
--- /dev/null |
+++ b/base/android/third_party/cygprofile_startup/cygprofile_startup_unittest.cc |
@@ -0,0 +1,155 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
Steve Block
2012/07/11 16:17:56
2012
felipeg
2012/07/11 17:10:25
Done.
|
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Test is intended to be executed on an Android device. The device should |
+// have an sd card, and should have a /sdcard/profile directory already created |
+// before running the test, because the test will dump the log file into that |
+// directory. The test will enable order profiling, call some functions and |
+// then disable profiling. The test will then check that the calls were |
+// properly logged in the log file. Since the first entry of a function is |
+// logged, the profiling should log the following: |
+// 00008000-00023000 r-xp 00000000 b3:02 12322 /data/local/tmp/cygprofile_test |
+// secs msecs pid:threadid func |
+// START |
+// 1315416566 712405 1818:1074467944 function2_addr |
+// 1315416566 712457 1818:1074467944 function1_addr |
+// 1315416566 712483 1818:1074467944 function3_addr |
+// END |
+// This is medium-sized unittest because it will first write the log file |
+// during profiling and then reads the file to make sure it contains the correct |
+// output. The test passes on normal exit (i.e. a 0 return value from main). |
+ |
+#include <stdio.h> |
+#include <stdint.h> |
+#include <string.h> |
+ |
+#include "./cygprofile_startup.h" |
+ |
+// Used to mod (i.e. %) seconds with to truncate the length. It seems |
+// reasonable to expect logged calls to be at most 999 seconds apart. |
+const int kTruncateSecs = 1000; |
+ |
+int function1(void) { |
+ return 0; |
+} |
+ |
+int function2(void) { |
+ return function1 () + 1; |
+} |
+ |
+int function3(void) { |
+ return function2 () + 1; |
+} |
+ |
+int check_logfile(void) { |
+ // Check results to see if test passed. |
+ FILE* fp; |
+ char line[256]; |
+ int linenum = 0; |
+ char* str; |
+ char* res; |
+ unsigned long seconds, mtime, tid; |
+ unsigned long lastsecs, lastmtime, lasttid; |
+ int pid, addr, lastpid; |
+ |
+ // The test is to be run on an Android device with a sd card. Before running |
+ // the test there should be a /sdcard/profile directory created on the device. |
+ if ((fp=fopen("/sdcard/profile/logfile.out", "r")) == NULL) { |
+ printf("FAIL: could not open log file: Does directory /sdcard/profile exist?\n"); |
+ return -1; |
+ } |
+ |
+ // Expect exactly 7 lines in log file |
+ for (linenum = 0; linenum < 7; linenum++) { |
+ if (fgets(line, sizeof(line), fp) == NULL) { |
+ printf("FAIL: log file does not contain correct number of lines\n"); |
+ return -1; |
+ } |
+ |
+ // Make sure line 2 is START, last line is END, and the correct calls |
+ // are profiled on lines 3, 4 and 5. |
+ switch (linenum) { |
+ case 2: |
+ str = strtok_r(line, " \n", &res); |
+ if (strcmp("START", str) != 0) { |
+ printf("FAIL: START not found where expected\n"); |
+ return -1; |
+ } |
+ break; |
+ case 3: |
+ sscanf(line, "%ld %ld\t%d:%ld\t%x\n", &lastsecs, &lastmtime, &lastpid, |
+ &lasttid, &addr); |
+ lastsecs = lastsecs % kTruncateSecs; |
+ if (reinterpret_cast<void*>(addr) != &function2) { |
+ // Test failed |
+ printf("FAIL: function2 call not found where expected\n"); |
+ printf(" line = %s, function2 = %p\n", line, &function2); |
+ return -1; |
+ } |
+ // fprintf (stdout, "addr: %x, %p equal=%d\n", addr, &function2, ; |
+ break; |
+ case 4: |
+ sscanf(line, "%ld %ld\t%d:%ld\t%x\n", &seconds, &mtime, &pid, &tid, |
+ &addr); |
+ seconds = seconds % kTruncateSecs; |
+ if (reinterpret_cast<void*>(addr) != &function1 || pid != lastpid || |
+ tid != lasttid || |
+ ((seconds * 1000000) + mtime) < ((lastsecs * 100000) + lastmtime)) { |
+ // Test failed |
+ // printf("addr = %p, function1 = %p, pid = %d, lastpid = %d\n", |
+ // reinterpret_cast<void*>(addr), &function1, pid, lastpid); |
+ // printf("seconds = %ld, mtime = %ld, lastsecs = %ld, lastmtime = %d\n", |
+ // seconds, mtime, lastsecs, lastmtime); |
+ // printf("condition4: %ld < %ld\n", |
+ // ((seconds * 1000000) + mtime), ((lastsecs * 100000) + lastmtime)); |
+ printf("FAIL: function1 call not found where expected\n"); |
+ return -1; |
+ } |
+ lastsecs = seconds; |
+ lastmtime = mtime; |
+ lastpid = pid; |
+ lasttid = tid; |
+ break; |
+ case 5: |
+ sscanf(line, "%ld %ld\t%d:%ld\t%x\n", &seconds, &mtime, &pid, &tid, |
+ &addr); |
+ if (reinterpret_cast<void*>(addr) != &function3 || pid != lastpid || |
+ tid != lasttid || |
+ ((seconds * 1000000) + mtime) < ((lastsecs * 100000) + lastmtime)) { |
+ // Test failed |
+ printf("FAIL: function3 call not found where expected\n"); |
+ return -1; |
+ } |
+ break; |
+ case 6: |
+ str = strtok_r(line, " \n", &res); |
+ // sscanf(line, "%s%*s", str); |
+ if (strcmp("END", str) != 0) { |
+ printf("FAIL: END not found where expected\n"); |
+ return -1; |
+ } |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ |
+ return 0; |
+} |
+ |
+int main(void) { |
+ int result, passed; |
+ cygprofile_startup::cygprofile_start("/sdcard/profile/logfile.out"); |
+ function2(); |
+ result = function3(); |
+ cygprofile_startup::cygprofile_end(); |
+ |
+ function2(); |
+ passed = check_logfile(); |
+ if (passed < 0) |
+ printf("test failed.\n"); |
+ else |
+ printf("test passed.\n"); |
+ return passed; |
+} |