blob: 55a2daeb581945300d2fa55f3d30d9fbcef56b0e [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <set>
#include <gmock/gmock.h>
#include <process/clock.hpp>
#include <process/gtest.hpp>
#include <stout/gtest.hpp>
#include <stout/stringify.hpp>
#include "linux/perf.hpp"
using std::set;
using std::string;
using namespace process;
class PerfTest : public ::testing::Test {};
TEST_F(PerfTest, ROOT_Events)
{
set<string> events;
// Valid events.
events.insert("cycles");
events.insert("task-clock");
EXPECT_TRUE(perf::valid(events));
// Add an invalid event.
events.insert("this-is-an-invalid-event");
EXPECT_FALSE(perf::valid(events));
}
TEST_F(PerfTest, Parse)
{
// uint64 and floats should be parsed.
Try<hashmap<string, mesos::PerfStatistics> > parse =
perf::parse("123,cycles\n0.123,task-clock");
CHECK_SOME(parse);
ASSERT_TRUE(parse.get().contains(""));
mesos::PerfStatistics statistics = parse.get().get("").get();
ASSERT_TRUE(statistics.has_cycles());
EXPECT_EQ(123u, statistics.cycles());
ASSERT_TRUE(statistics.has_task_clock());
EXPECT_EQ(0.123, statistics.task_clock());
// Parse multiple cgroups.
parse = perf::parse("123,cycles,cgroup1\n"
"456,cycles,cgroup2\n"
"0.456,task-clock,cgroup2\n"
"0.123,task-clock,cgroup1");
CHECK_SOME(parse);
EXPECT_FALSE(parse.get().contains(""));
ASSERT_TRUE(parse.get().contains("cgroup1"));
statistics = parse.get().get("cgroup1").get();
ASSERT_TRUE(statistics.has_cycles());
EXPECT_EQ(123u, statistics.cycles());
ASSERT_TRUE(statistics.has_task_clock());
EXPECT_EQ(0.123, statistics.task_clock());
ASSERT_TRUE(parse.get().contains("cgroup2"));
statistics = parse.get().get("cgroup2").get();
ASSERT_TRUE(statistics.has_cycles());
EXPECT_EQ(456u, statistics.cycles());
EXPECT_TRUE(statistics.has_task_clock());
EXPECT_EQ(0.456, statistics.task_clock());
// Statistics reporting <not supported> should not appear.
parse = perf::parse("<not supported>,cycles");
CHECK_SOME(parse);
ASSERT_TRUE(parse.get().contains(""));
statistics = parse.get().get("").get();
EXPECT_FALSE(statistics.has_cycles());
// Statistics reporting <not counted> should be zero.
parse = perf::parse("<not counted>,cycles\n<not counted>,task-clock");
CHECK_SOME(parse);
ASSERT_TRUE(parse.get().contains(""));
statistics = parse.get().get("").get();
EXPECT_TRUE(statistics.has_cycles());
EXPECT_EQ(0u, statistics.cycles());
EXPECT_TRUE(statistics.has_task_clock());
EXPECT_EQ(0.0, statistics.task_clock());
// Check parsing fails.
parse = perf::parse("1,cycles\ngarbage");
EXPECT_ERROR(parse);
parse = perf::parse("1,unknown-field");
EXPECT_ERROR(parse);
}
TEST_F(PerfTest, ROOT_SampleInit)
{
set<string> events;
// Hardware event.
events.insert("cycles");
// Software event.
events.insert("task-clock");
// Sample init/launchd/systemd (pid 1).
Future<mesos::PerfStatistics> statistics =
perf::sample(events, 1, Seconds(1));
AWAIT_READY(statistics);
// Check the sample timestamp is within the last 5 seconds. This is generous
// because there's the process reap delay in addition to the sampling
// duration.
ASSERT_TRUE(statistics.get().has_timestamp());
EXPECT_GT(
Seconds(5).secs(), Clock::now().secs() - statistics.get().timestamp());
EXPECT_EQ(Seconds(1).secs(), statistics.get().duration());
ASSERT_TRUE(statistics.get().has_cycles());
EXPECT_LT(0u, statistics.get().cycles());
ASSERT_TRUE(statistics.get().has_task_clock());
EXPECT_LT(0.0, statistics.get().task_clock());
}