// 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 "common/atomic.h"
#include "testutil/gtest-util.h"
#include "util/disk-info.h"
#include "util/system-state-info.h"
#include "util/time.h"

#include <thread>

namespace impala {

class SystemStateInfoTest : public testing::Test {
 protected:
  SystemStateInfo info;
};

TEST_F(SystemStateInfoTest, FirstCallReturnsZero) {
  const SystemStateInfo::CpuUsageRatios& r = info.GetCpuUsageRatios();
  EXPECT_EQ(0, r.user + r.system + r.iowait);

  const SystemStateInfo::NetworkUsage& n = info.GetNetworkUsage();
  EXPECT_EQ(0, n.rx_rate + n.tx_rate);
}

// Smoke test to make sure that we read non-zero values from /proc/stat.
TEST_F(SystemStateInfoTest, ReadProcStat) {
  info.ReadCurrentProcStat();
  const SystemStateInfo::CpuValues& state = info.cpu_values_[info.cpu_val_idx_];
  EXPECT_GT(state[SystemStateInfo::CPU_USER], 0);
  EXPECT_GT(state[SystemStateInfo::CPU_SYSTEM], 0);
  EXPECT_GT(state[SystemStateInfo::CPU_IDLE], 0);
  EXPECT_GT(state[SystemStateInfo::CPU_IOWAIT], 0);
}

// Smoke test to make sure that we read non-zero values from /proc/net/dev.
TEST_F(SystemStateInfoTest, ReadProcNetDev) {
  info.ReadCurrentProcNetDev();
  const SystemStateInfo::NetworkValues& state = info.network_values_[info.net_val_idx_];
  // IMPALA-8413: Don't assume that counters are non-zero as that is sometimes not the
  // case, e.g. in virtualized environments.
  EXPECT_GE(state[SystemStateInfo::NET_RX_BYTES], 0);
  EXPECT_GE(state[SystemStateInfo::NET_RX_PACKETS], 0);
  EXPECT_GE(state[SystemStateInfo::NET_TX_BYTES], 0);
  EXPECT_GE(state[SystemStateInfo::NET_TX_PACKETS], 0);
}

// Smoke test to make sure that we read non-zero values from /proc/diskstats.
TEST_F(SystemStateInfoTest, ReadProcDiskStats) {
  info.ReadCurrentProcDiskStats();
  const SystemStateInfo::DiskValues& state = info.disk_values_[info.disk_val_idx_];
  EXPECT_GT(state[SystemStateInfo::DISK_READS_COMPLETED], 0);
  EXPECT_GT(state[SystemStateInfo::DISK_SECTORS_READ], 0);
  EXPECT_GT(state[SystemStateInfo::DISK_WRITES_COMPLETED], 0);
  EXPECT_GT(state[SystemStateInfo::DISK_SECTORS_WRITTEN], 0);
}

// Tests parsing a line similar to the first line of /proc/stat.
TEST_F(SystemStateInfoTest, ParseProcStat) {
  // Fields are: user nice system idle iowait irq softirq steal guest guest_nice
  info.ReadProcStatString("cpu  20 30 10 70 100 0 0 0 0 0");
  const SystemStateInfo::CpuValues& state = info.cpu_values_[info.cpu_val_idx_];
  EXPECT_EQ(state[SystemStateInfo::CPU_USER], 20);
  EXPECT_EQ(state[SystemStateInfo::CPU_SYSTEM], 10);
  EXPECT_EQ(state[SystemStateInfo::CPU_IDLE], 70);
  EXPECT_EQ(state[SystemStateInfo::CPU_IOWAIT], 100);

  // Test that values larger than INT_MAX parse without error.
  info.ReadProcStatString("cpu  3000000000 30 10 70 100 0 0 0 0 0");
  const SystemStateInfo::CpuValues& changed_state = info.cpu_values_[info.cpu_val_idx_];
  EXPECT_EQ(changed_state[SystemStateInfo::CPU_USER], 3000000000);
}

// Tests parsing a string similar to the contents of /proc/net/dev.
TEST_F(SystemStateInfoTest, ParseProcNetDevString) {
  // Fields are: user nice system idle iowait irq softirq steal guest guest_nice
  string dev_net = R"(Inter-|   Receive                                                |  Transmit
   face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
       lo: 12178099975318 24167151765    0    0    0     0          0         0 12178099975318 24167151765    0    0    0     0       0          0
       br-c4d9b4cafca2: 1025814     409    0    0    0     0          0         0 70616330 1638104    0    0    0     0       0          0
         eth0: 366039609986 388580561    0    2    0     0          0  62231368 95492744135 174535524    0    0    0     0       0          0)";
  info.ReadProcNetDevString(dev_net);
  const SystemStateInfo::NetworkValues& state = info.network_values_[info.net_val_idx_];
  EXPECT_EQ(state[SystemStateInfo::NET_RX_BYTES], 366040635800);
  EXPECT_EQ(state[SystemStateInfo::NET_RX_PACKETS], 388580970);
  EXPECT_EQ(state[SystemStateInfo::NET_TX_BYTES], 95563360465);
  EXPECT_EQ(state[SystemStateInfo::NET_TX_PACKETS], 176173628);
}

// Tests parsing a string similar to the contents of /proc/net/dev on older kernels, such
// as the one on Centos6.
TEST_F(SystemStateInfoTest, ParseProcNetDevStringCentos6) {
  // Fields are: user nice system idle iowait irq softirq steal guest guest_nice
  string dev_net = R"(Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:    5829      53    0    0    0     0          0         0     5829      53    0    0    0     0       0          0
  eth0:285025090  212208    0    0    0     0          0         0  9137793   84770    0    0    0     0       0          0)";
  info.ReadProcNetDevString(dev_net);
  const SystemStateInfo::NetworkValues& state = info.network_values_[info.net_val_idx_];
  EXPECT_EQ(state[SystemStateInfo::NET_RX_BYTES], 285025090);
  EXPECT_EQ(state[SystemStateInfo::NET_RX_PACKETS], 212208);
  EXPECT_EQ(state[SystemStateInfo::NET_TX_BYTES], 9137793);
  EXPECT_EQ(state[SystemStateInfo::NET_TX_PACKETS], 84770);
}

// Tests parsing a string similar to the contents of /proc/diskstats. This test also makes
// sure that values of a partition are not accounted towards the disk it is on.
TEST_F(SystemStateInfoTest, ParseProcDiskStatsString) {
  // We cannot hard-code the device name since our Jenkins workers might see different
  // device names in their virtual environments.
  string disk_stats =
    R"(   8       0 $0 17124835 222797 716029974 8414920 43758807 38432095 7867287712 630179264 0 32547524 638999340
       8       1 $01 17124482 222797 716027002 8414892 43546943 38432095 7867287712 629089180 0 31590972 637917344)";
  string device = DiskInfo::device_name(0);
  cout << Substitute(disk_stats, device);
  info.ReadProcDiskStatsString(Substitute(disk_stats, device));
  const SystemStateInfo::DiskValues& state = info.disk_values_[info.disk_val_idx_];
  EXPECT_EQ(state[SystemStateInfo::DISK_SECTORS_READ], 716029974);
  EXPECT_EQ(state[SystemStateInfo::DISK_READS_COMPLETED], 17124835);
  EXPECT_EQ(state[SystemStateInfo::DISK_SECTORS_WRITTEN], 7867287712);
  EXPECT_EQ(state[SystemStateInfo::DISK_WRITES_COMPLETED], 43758807);
}

// Tests that computing CPU ratios doesn't overflow
TEST_F(SystemStateInfoTest, ComputeCpuRatiosIntOverflow) {
  // Load old and new values for CPU counters. These values are from a system where we
  // have seen this code overflow before.
  info.ReadProcStatString("cpu  100952877 534 18552749 6318822633 4119619 0 0 0 0 0");
  info.ReadProcStatString("cpu  100953598 534 18552882 6318826150 4119619 0 0 0 0 0");
  info.ComputeCpuRatios();
  const SystemStateInfo::CpuUsageRatios& r = info.GetCpuUsageRatios();
  EXPECT_EQ(r.user, 1649);
  EXPECT_EQ(r.system, 304);
  EXPECT_EQ(r.iowait, 0);
}

// Smoke test for the public interface.
TEST_F(SystemStateInfoTest, GetCpuUsageRatios) {
  AtomicBool running(true);
  // Generate some load to observe counters > 0.
  std::thread t([&running]() { while (running.Load()); });
  for (int i = 0; i < 3; ++i) {
    SleepForMs(200);
    info.CaptureSystemStateSnapshot();
    const SystemStateInfo::CpuUsageRatios& r = info.GetCpuUsageRatios();
    EXPECT_GT(r.user + r.system + r.iowait, 0);
  }
  running.Store(false);
  t.join();
}

// Tests the computation logic for CPU ratios.
TEST_F(SystemStateInfoTest, ComputeCpuRatios) {
  info.ReadProcStatString("cpu  20 30 10 70 100 0 0 0 0 0");
  info.ReadProcStatString("cpu  30 30 20 70 100 0 0 0 0 0");
  info.ComputeCpuRatios();
  const SystemStateInfo::CpuUsageRatios& r = info.GetCpuUsageRatios();
  EXPECT_EQ(r.user, 5000);
  EXPECT_EQ(r.system, 5000);
  EXPECT_EQ(r.iowait, 0);
}

// Tests the computation logic for network usage.
TEST_F(SystemStateInfoTest, ComputeNetworkUsage) {
  // Two sets of values in the format of /proc/net/dev
  string dev_net_1 = R"(Inter-|   Receive                                                |  Transmit
   face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
       lo: 1000 2000    0    0    0     0          0         0 3000 4000    0    0    0     0       0          0
       br-c4d9b4cafca2: 5000     409    0    0    0     0          0         0 6000 7000    0    0    0     0       0          0
         eth0: 8000 9000    0    2    0     0          0  10000 11000 12000    0    0    0     0       0          0)";
  string dev_net_2 = R"(Inter-|   Receive                                                |  Transmit
   face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
       lo: 2000 4000    0    0    0     0          0         0 6000 8000    0    0    0     0       0          0
       br-c4d9b4cafca2: 7000     609    0    0    0     0          0         0 12000 14000    0    0    0     0       0          0
         eth0: 10000 11000    0    2    0     0          0  10000 11000 12000    0    0    0     0       0          0)";

  info.ReadProcNetDevString(dev_net_1);
  info.ReadProcNetDevString(dev_net_2);
  int period_ms = 500;
  info.ComputeNetworkUsage(period_ms);
  const SystemStateInfo::NetworkUsage& n = info.GetNetworkUsage();
  EXPECT_EQ(n.rx_rate, 8000);
  EXPECT_EQ(n.tx_rate, 12000);
}

// Tests the computation logic for disk statistics.
TEST_F(SystemStateInfoTest, ComputeDiskStats) {
  // Two sets of values in the format of /proc/diskstats. We cannot hard-code the device
  // name since our Jenkins workers might see different device names in their virtual
  // environments.
  string disk_stats_1 = R"(   1      15 ram15 0 0 0 0 0 0 0 0 0 0 0
     7       0 loop0 0 0 0 0 0 0 0 0 0 0 0
     8       0 $0 0 0 1000 0 0 0 2000 0 0 0 0
     8       1 $01 0 0 1000 0 0 0 2000 0 0 0 0)";
  string disk_stats_2 = R"(   8       0 $0 0 0 2000 0 0 0 4000 0 0 0 0
     8       1 $01 0 0 2000 0 0 0 4000 0 0 0 0)";

  string device = DiskInfo::device_name(0);
  info.ReadProcDiskStatsString(Substitute(disk_stats_1, device));
  info.ReadProcDiskStatsString(Substitute(disk_stats_2, device));
  int period_ms = 500;
  info.ComputeDiskStats(period_ms);
  const SystemStateInfo::DiskStats& ds = info.GetDiskStats();
  EXPECT_EQ(ds.read_rate, 2 * 1000 * SystemStateInfo::BYTES_PER_SECTOR);
  EXPECT_EQ(ds.write_rate, 2 * 2000 * SystemStateInfo::BYTES_PER_SECTOR);
}

} // namespace impala

