OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // Test is intended to be executed on an Android device. The device should |
| 6 // have an sd card, and should have a /sdcard/profile directory already created |
| 7 // before running the test, because the test will dump the log file into that |
| 8 // directory. The test will enable order profiling, call some functions and |
| 9 // then disable profiling. The test will then check that the calls were |
| 10 // properly logged in the log file. Since the first entry of a function is |
| 11 // logged, the profiling should log the following: |
| 12 // 00008000-00023000 r-xp 00000000 b3:02 12322 /data/local/tmp/cygprofile_test |
| 13 // secs msecs pid:threadid func |
| 14 // START |
| 15 // 1315416566 712405 1818:1074467944 function2_addr |
| 16 // 1315416566 712457 1818:1074467944 function1_addr |
| 17 // 1315416566 712483 1818:1074467944 function3_addr |
| 18 // END |
| 19 // This is medium-sized unittest because it will first write the log file |
| 20 // during profiling and then reads the file to make sure it contains the correct |
| 21 // output. The test passes on normal exit (i.e. a 0 return value from main). |
| 22 |
| 23 #include <stdio.h> |
| 24 #include <stdint.h> |
| 25 #include <string.h> |
| 26 |
| 27 #include "./cygprofile_android.h" |
| 28 |
| 29 // Used to mod (i.e. %) seconds with to truncate the length. It seems |
| 30 // reasonable to expect logged calls to be at most 999 seconds apart. |
| 31 const int kTruncateSecs = 1000; |
| 32 |
| 33 int function1(void) { |
| 34 return 0; |
| 35 } |
| 36 |
| 37 int function2(void) { |
| 38 return function1 () + 1; |
| 39 } |
| 40 |
| 41 int function3(void) { |
| 42 return function2 () + 1; |
| 43 } |
| 44 |
| 45 int check_logfile(void) { |
| 46 // Check results to see if test passed. |
| 47 FILE* fp; |
| 48 char line[256]; |
| 49 int linenum = 0; |
| 50 char* str; |
| 51 char* res; |
| 52 unsigned long seconds, mtime, tid; |
| 53 unsigned long lastsecs, lastmtime, lasttid; |
| 54 int pid, addr, lastpid; |
| 55 |
| 56 // The test is to be run on an Android device with a sd card. Before running |
| 57 // the test there should be a /sdcard/profile directory created on the device. |
| 58 if ((fp=fopen("/sdcard/profile/logfile.out", "r")) == NULL) { |
| 59 printf("FAIL: could not open log file: Does directory /sdcard/profile exist?
\n"); |
| 60 return -1; |
| 61 } |
| 62 |
| 63 // Expect exactly 7 lines in log file |
| 64 for (linenum = 0; linenum < 7; linenum++) { |
| 65 if (fgets(line, sizeof(line), fp) == NULL) { |
| 66 printf("FAIL: log file does not contain correct number of lines\n"); |
| 67 return -1; |
| 68 } |
| 69 |
| 70 // Make sure line 2 is START, last line is END, and the correct calls |
| 71 // are profiled on lines 3, 4 and 5. |
| 72 switch (linenum) { |
| 73 case 2: |
| 74 str = strtok_r(line, " \n", &res); |
| 75 if (strcmp("START", str) != 0) { |
| 76 printf("FAIL: START not found where expected\n"); |
| 77 return -1; |
| 78 } |
| 79 break; |
| 80 case 3: |
| 81 sscanf(line, "%ld %ld\t%d:%ld\t%x\n", &lastsecs, &lastmtime, &lastpid, |
| 82 &lasttid, &addr); |
| 83 lastsecs = lastsecs % kTruncateSecs; |
| 84 if (reinterpret_cast<void*>(addr) != &function2) { |
| 85 // Test failed |
| 86 printf("FAIL: function2 call not found where expected\n"); |
| 87 printf(" line = %s, function2 = %p\n", line, &function2); |
| 88 return -1; |
| 89 } |
| 90 // fprintf (stdout, "addr: %x, %p equal=%d\n", addr, &function2, ; |
| 91 break; |
| 92 case 4: |
| 93 sscanf(line, "%ld %ld\t%d:%ld\t%x\n", &seconds, &mtime, &pid, &tid, |
| 94 &addr); |
| 95 seconds = seconds % kTruncateSecs; |
| 96 if (reinterpret_cast<void*>(addr) != &function1 || pid != lastpid || |
| 97 tid != lasttid || |
| 98 ((seconds * 1000000) + mtime) < ((lastsecs * 100000) + lastmtime)) { |
| 99 // Test failed |
| 100 // printf("addr = %p, function1 = %p, pid = %d, lastpid = %d\n", |
| 101 // reinterpret_cast<void*>(addr), &function1, pid, lastpid); |
| 102 // printf("seconds = %ld, mtime = %ld, lastsecs = %ld, lastmtime = %d\
n", |
| 103 // seconds, mtime, lastsecs, lastmtime); |
| 104 // printf("condition4: %ld < %ld\n", |
| 105 // ((seconds * 1000000) + mtime), ((lastsecs * 100000) + lastmt
ime)); |
| 106 printf("FAIL: function1 call not found where expected\n"); |
| 107 return -1; |
| 108 } |
| 109 lastsecs = seconds; |
| 110 lastmtime = mtime; |
| 111 lastpid = pid; |
| 112 lasttid = tid; |
| 113 break; |
| 114 case 5: |
| 115 sscanf(line, "%ld %ld\t%d:%ld\t%x\n", &seconds, &mtime, &pid, &tid, |
| 116 &addr); |
| 117 if (reinterpret_cast<void*>(addr) != &function3 || pid != lastpid || |
| 118 tid != lasttid || |
| 119 ((seconds * 1000000) + mtime) < ((lastsecs * 100000) + lastmtime)) { |
| 120 // Test failed |
| 121 printf("FAIL: function3 call not found where expected\n"); |
| 122 return -1; |
| 123 } |
| 124 break; |
| 125 case 6: |
| 126 str = strtok_r(line, " \n", &res); |
| 127 // sscanf(line, "%s%*s", str); |
| 128 if (strcmp("END", str) != 0) { |
| 129 printf("FAIL: END not found where expected\n"); |
| 130 return -1; |
| 131 } |
| 132 break; |
| 133 default: |
| 134 break; |
| 135 } |
| 136 } |
| 137 |
| 138 return 0; |
| 139 } |
| 140 |
| 141 int main(void) { |
| 142 int result, passed; |
| 143 cygprofile::cygprofile_start("/sdcard/profile/logfile.out"); |
| 144 function2(); |
| 145 result = function3(); |
| 146 cygprofile::cygprofile_end(); |
| 147 |
| 148 function2(); |
| 149 passed = check_logfile(); |
| 150 if (passed < 0) |
| 151 printf("test failed.\n"); |
| 152 else |
| 153 printf("test passed.\n"); |
| 154 return passed; |
| 155 } |
OLD | NEW |