summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2015-10-06 08:59:02 -0700
committerKevin Ma <kma@google.com>2015-11-12 11:51:41 -0800
commit5b0d59dde85162fa9ef3a32464c0f1b81d7e05cb (patch)
tree126d85c1aed8b2d0e33cfacc32cd84f8cb468efc
parent99cd21ef5c3548613d8a614551b858a5c47985fc (diff)
downloadsystem_core-5b0d59dde85162fa9ef3a32464c0f1b81d7e05cb.zip
system_core-5b0d59dde85162fa9ef3a32464c0f1b81d7e05cb.tar.gz
system_core-5b0d59dde85162fa9ef3a32464c0f1b81d7e05cb.tar.bz2
logcat: continue where we left off
Issue introduced as part of new logcatd functionality in commit f3555d9427425c2cba9600ceffb49305c440aa4a Faulty logic, add a gTest to confirm. Bug: 19608716 Change-Id: Ic1b97def25e03e69faae4398a3dff2ff0f88545e
-rw-r--r--logcat/logcat.cpp2
-rw-r--r--logcat/tests/logcat_test.cpp134
2 files changed, 120 insertions, 16 deletions
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index e598bb8..3d05d8f 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -649,7 +649,7 @@ int main(int argc, char **argv)
break;
case 'f':
- if ((tail_time == log_time::EPOCH) && (tail_lines != 0)) {
+ if ((tail_time == log_time::EPOCH) && (tail_lines == 0)) {
tail_time = lastLogTime(optarg);
}
// redirect output to a file
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index de2db67..9455d87 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -15,10 +15,12 @@
*/
#include <ctype.h>
+#include <dirent.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
#include <gtest/gtest.h>
#include <log/log.h>
@@ -284,7 +286,7 @@ TEST(logcat, get_size) {
while (fgets(buffer, sizeof(buffer), fp)) {
int size, consumed, max, payload;
- char size_mult[2], consumed_mult[2];
+ char size_mult[3], consumed_mult[3];
long full_size, full_consumed;
size = consumed = max = payload = 0;
@@ -489,12 +491,12 @@ TEST(logcat, logrotate) {
static const char comm[] = "logcat -b radio -b events -b system -b main"
" -d -f %s/log.txt -n 7 -r 1";
char command[sizeof(buf) + sizeof(comm)];
- sprintf(command, comm, buf);
+ snprintf(command, sizeof(command), comm, buf);
int ret;
EXPECT_FALSE((ret = system(command)));
if (!ret) {
- sprintf(command, "ls -s %s 2>/dev/null", buf);
+ snprintf(command, sizeof(command), "ls -s %s 2>/dev/null", buf);
FILE *fp;
EXPECT_TRUE(NULL != (fp = popen(command, "r")));
@@ -503,16 +505,12 @@ TEST(logcat, logrotate) {
int count = 0;
while (fgets(buffer, sizeof(buffer), fp)) {
- static const char match_1[] = "4 log.txt";
- static const char match_2[] = "8 log.txt";
- static const char match_3[] = "12 log.txt";
- static const char match_4[] = "16 log.txt";
static const char total[] = "total ";
+ int num;
+ char c;
- if (!strncmp(buffer, match_1, sizeof(match_1) - 1)
- || !strncmp(buffer, match_2, sizeof(match_2) - 1)
- || !strncmp(buffer, match_3, sizeof(match_3) - 1)
- || !strncmp(buffer, match_4, sizeof(match_4) - 1)) {
+ if ((2 == sscanf(buffer, "%d log.tx%c", &num, &c)) &&
+ (num <= 24)) {
++count;
} else if (strncmp(buffer, total, sizeof(total) - 1)) {
fprintf(stderr, "WARNING: Parse error: %s", buffer);
@@ -522,7 +520,7 @@ TEST(logcat, logrotate) {
EXPECT_TRUE(count == 7 || count == 8);
}
}
- sprintf(command, "rm -rf %s", buf);
+ snprintf(command, sizeof(command), "rm -rf %s", buf);
EXPECT_FALSE(system(command));
}
@@ -534,12 +532,12 @@ TEST(logcat, logrotate_suffix) {
static const char logcat_cmd[] = "logcat -b radio -b events -b system -b main"
" -d -f %s/log.txt -n 10 -r 1";
char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd)];
- sprintf(command, logcat_cmd, tmp_out_dir);
+ snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir);
int ret;
EXPECT_FALSE((ret = system(command)));
if (!ret) {
- sprintf(command, "ls %s 2>/dev/null", tmp_out_dir);
+ snprintf(command, sizeof(command), "ls %s 2>/dev/null", tmp_out_dir);
FILE *fp;
EXPECT_TRUE(NULL != (fp = popen(command, "r")));
@@ -575,7 +573,113 @@ TEST(logcat, logrotate_suffix) {
pclose(fp);
EXPECT_EQ(11, log_file_count);
}
- sprintf(command, "rm -rf %s", tmp_out_dir);
+ snprintf(command, sizeof(command), "rm -rf %s", tmp_out_dir);
+ EXPECT_FALSE(system(command));
+}
+
+TEST(logcat, logrotate_continue) {
+ static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
+ char tmp_out_dir[sizeof(tmp_out_dir_form)];
+ ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
+
+ static const char log_filename[] = "log.txt";
+ static const char logcat_cmd[] = "logcat -b all -d -f %s/%s -n 256 -r 1024";
+ static const char cleanup_cmd[] = "rm -rf %s";
+ char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename)];
+ snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
+
+ int ret;
+ EXPECT_FALSE((ret = system(command)));
+ if (ret) {
+ snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
+ EXPECT_FALSE(system(command));
+ return;
+ }
+ FILE *fp;
+ snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, log_filename);
+ EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
+ if (!fp) {
+ snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
+ EXPECT_FALSE(system(command));
+ return;
+ }
+ char *line = NULL;
+ char *last_line = NULL; // this line is allowed to stutter, one-line overlap
+ char *second_last_line = NULL;
+ size_t len = 0;
+ while (getline(&line, &len, fp) != -1) {
+ free(second_last_line);
+ second_last_line = last_line;
+ last_line = line;
+ line = NULL;
+ }
+ fclose(fp);
+ free(line);
+ if (second_last_line == NULL) {
+ fprintf(stderr, "No second to last line, using last, test may fail\n");
+ second_last_line = last_line;
+ last_line = NULL;
+ }
+ free(last_line);
+ EXPECT_TRUE(NULL != second_last_line);
+ if (!second_last_line) {
+ snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
+ EXPECT_FALSE(system(command));
+ return;
+ }
+ // re-run the command, it should only add a few lines more content if it
+ // continues where it left off.
+ snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
+ EXPECT_FALSE((ret = system(command)));
+ if (ret) {
+ snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
+ EXPECT_FALSE(system(command));
+ return;
+ }
+ DIR *dir;
+ EXPECT_TRUE(NULL != (dir = opendir(tmp_out_dir)));
+ if (!dir) {
+ snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
+ EXPECT_FALSE(system(command));
+ return;
+ }
+ struct dirent *entry;
+ unsigned count = 0;
+ while ((entry = readdir(dir))) {
+ if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
+ continue;
+ }
+ snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, entry->d_name);
+ EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
+ if (!fp) {
+ fprintf(stderr, "%s ?\n", command);
+ continue;
+ }
+ line = NULL;
+ size_t number = 0;
+ while (getline(&line, &len, fp) != -1) {
+ ++number;
+ if (!strcmp(line, second_last_line)) {
+ EXPECT_TRUE(++count <= 1);
+ fprintf(stderr, "%s(%zu):\n", entry->d_name, number);
+ }
+ }
+ fclose(fp);
+ free(line);
+ unlink(command);
+ }
+ closedir(dir);
+ if (count > 1) {
+ char *brk = strpbrk(second_last_line, "\r\n");
+ if (!brk) {
+ brk = second_last_line + strlen(second_last_line);
+ }
+ fprintf(stderr, "\"%.*s\" occured %u times\n",
+ (int)(brk - second_last_line), second_last_line, count);
+ }
+ free(second_last_line);
+
+ snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
EXPECT_FALSE(system(command));
}