summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/external_metrics_unittest.cc
blob: f32ed6bd83795909b4047e82dfbfdfa65296bef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <errno.h>
#include <sys/file.h>

#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/chromeos/external_metrics.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {  // Need this because of the FRIEND_TEST

class ExternalMetricsTest : public testing::Test {
};

// Because the metrics service is not essential, errors will not cause the
// program to terminate.  However, the errors produce logs.

#define MAXLENGTH ExternalMetrics::kMetricsMessageMaxLength

static void SendMessage(const char* path, const char* name, const char* value) {
  int fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0666);
  int32 l = strlen(name) + strlen(value) + 2 + sizeof(l);
  write(fd, &l, sizeof(l));
  write(fd, name, strlen(name) + 1);
  write(fd, value, strlen(value) + 1);
  close(fd);
}

static scoped_ptr<std::string> received_name;
static scoped_ptr<std::string> received_value;
int received_count = 0;

static void ReceiveMessage(const char* name, const char* value) {
  received_name.reset(new std::string(name));
  received_value.reset(new std::string(value));
  received_count++;
}

static void CheckMessage(const char* name, const char* value, int count) {
  EXPECT_EQ(*received_name.get(), name);
  EXPECT_EQ(*received_value.get(), value);
  EXPECT_EQ(received_count, count);
}

TEST(ExternalMetricsTest, ParseExternalMetricsFile) {
  struct {
    const char* name;
    const char* value;
  } pairs[] = {
    {"BootTime", "9500"},
    {"BootTime", "10000"},
    {"BootTime", "9200"},
    {"TabOverviewExitMouse", ""},
    {"ConnmanIdle", "1000"},
    {"ConnmanIdle", "1200"},
    {"TabOverviewKeystroke", ""},
    {"ConnmanDisconnect", "1000"},
    {"ConnmanFailure", "1000"},
    {"ConnmanFailure", "1300"},
    {"ConnmanAssociation", "1000"},
    {"ConnmanConfiguration", "1000"},
    {"ConnmanOffline", "1000"},
    {"ConnmanOnline", "1000"},
    {"ConnmanOffline", "2000"},
    {"ConnmanReady", "33000"},
    {"ConnmanReady", "44000"},
    {"ConnmanReady", "22000"},
  };
  int npairs = ARRAYSIZE_UNSAFE(pairs);
  int32 i;
  const char* path = "/tmp/.chromeos-metrics";
  scoped_refptr<chromeos::ExternalMetrics>
      external_metrics(new chromeos::ExternalMetrics());
  external_metrics->SetRecorder(&ReceiveMessage);

  EXPECT_TRUE(unlink(path) == 0 || errno == ENOENT);

  // Sends a few valid messages.  Once in a while, collect them and check the
  // last message.  We don't want to check every single message because we also
  // want to test the ability to deal with a file containing more than one
  // message.
  for (i = 0; i < npairs; i++) {
    SendMessage(path, pairs[i].name, pairs[i].value);
    if (i % 3 == 2) {
      external_metrics->CollectEvents();
      CheckMessage(pairs[i].name, pairs[i].value, i + 1);
    }
  }


  // Sends a message that's too large.
  char b[MAXLENGTH + 100];
  for (i = 0; i < MAXLENGTH + 99; i++) {
    b[i] = 'x';
  }
  b[i] = '\0';
  SendMessage(path, b, "yyy");
  external_metrics->CollectEvents();
  EXPECT_EQ(received_count, npairs);

  // Sends a malformed message (first string is not null-terminated).
  i = 100 + sizeof(i);
  int fd = open(path, O_CREAT | O_WRONLY, 0666);
  EXPECT_GT(fd, 0);
  EXPECT_EQ(write(fd, &i, sizeof(i)), static_cast<int>(sizeof(i)));
  EXPECT_EQ(write(fd, b, i), i);
  EXPECT_EQ(close(fd), 0);

  external_metrics->CollectEvents();
  EXPECT_EQ(received_count, npairs);

  // Sends a malformed message (second string is not null-terminated).
  b[50] = '\0';
  fd = open(path, O_CREAT | O_WRONLY, 0666);
  EXPECT_GT(fd, 0);
  EXPECT_EQ(write(fd, &i, sizeof(i)), static_cast<int>(sizeof(i)));
  EXPECT_EQ(write(fd, b, i), i);
  EXPECT_EQ(close(fd), 0);

  external_metrics->CollectEvents();
  EXPECT_EQ(received_count, npairs);

  // Checks that we survive when file doesn't exist.
  EXPECT_EQ(unlink(path), 0);
  external_metrics->CollectEvents();
  EXPECT_EQ(received_count, npairs);
}

}  // namespace chromeos