159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme/* 259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * Copyright (C) 2016 The Android Open Source Project 359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * 459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License"); 559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * you may not use this file except in compliance with the License. 659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * You may obtain a copy of the License at 759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * 859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * http://www.apache.org/licenses/LICENSE-2.0 959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * 1059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * Unless required by applicable law or agreed to in writing, software 1159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS, 1259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * See the License for the specific language governing permissions and 1459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme * limitations under the License. 1559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme */ 1659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 1759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <gmock/gmock.h> 1859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <gtest/gtest.h> 1959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 2059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <stdio.h> 2159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <sys/types.h> 2259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <unistd.h> 2359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 2459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <string> 2559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 2659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include "bugreportz.h" 2759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 2859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Lemeusing ::testing::StrEq; 2959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Lemeusing ::testing::internal::CaptureStdout; 3059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Lemeusing ::testing::internal::GetCapturedStdout; 3159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 3259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Lemeclass BugreportzTest : public ::testing::Test { 3359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme public: 3459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // Creates the pipe used to communicate with bugreportz() 3559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme void SetUp() { 3659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme int fds[2]; 3759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme ASSERT_EQ(0, pipe(fds)); 3859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme read_fd_ = fds[0]; 3959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme write_fd_ = fds[1]; 4059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 4159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 4259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // Closes the pipe FDs. 4359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // If a FD is closed manually during a test, set it to -1 to prevent TearDown() trying to close 4459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // it again. 4559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme void TearDown() { 4659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme for (int fd : {read_fd_, write_fd_}) { 4759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme if (fd >= 0) { 4859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme close(fd); 4959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 5059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 5159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 5259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 5359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // Emulates dumpstate output by writing to the socket passed to bugreportz() 5459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme void WriteToSocket(const std::string& data) { 5559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme if (write_fd_ < 0) { 5659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme ADD_FAILURE() << "cannot write '" << data << "' because socket is already closed"; 5759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme return; 5859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 5959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme int expected = data.length(); 6059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme int actual = write(write_fd_, data.data(), data.length()); 6159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme ASSERT_EQ(expected, actual) << "wrong number of bytes written to socket"; 6259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 6359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 6459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme void AssertStdoutEquals(const std::string& expected) { 6559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme ASSERT_THAT(stdout_, StrEq(expected)) << "wrong stdout output"; 6659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 6759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 6859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // Calls bugreportz() using the internal pipe. 6959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // 7059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // Tests must call WriteToSocket() to set what's written prior to calling it, since the writing 7159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // end of the pipe will be closed before calling bugreportz() (otherwise that function would 7259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme // hang). 7302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme void Bugreportz(bool show_progress) { 7459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme close(write_fd_); 7559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme write_fd_ = -1; 7659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 7759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme CaptureStdout(); 7802b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme int status = bugreportz(read_fd_, show_progress); 7959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 8059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme close(read_fd_); 8159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme read_fd_ = -1; 8259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme stdout_ = GetCapturedStdout(); 8359f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 8459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme ASSERT_EQ(0, status) << "bugrepotz() call failed (stdout: " << stdout_ << ")"; 8559f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme } 8659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 8759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme private: 8859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme int read_fd_; 8959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme int write_fd_; 9059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme std::string stdout_; 9159f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme}; 9259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 9302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme// Tests 'bugreportz', without any argument - it will ignore progress lines. 9459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe LemeTEST_F(BugreportzTest, NoArgument) { 95aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme WriteToSocket("BEGIN:THE IGNORED PATH WARS HAS!\n"); // Should be ommited. 9659f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme WriteToSocket("What happens on 'dumpstate',"); 9759f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme WriteToSocket("stays on 'bugreportz'.\n"); 9802b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("PROGRESS:Y U NO OMITTED?\n"); // Should be ommited. 9902b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("But "); 10002b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("PROGRESS IN THE MIDDLE"); // Ok - not starting a line. 10102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket(" is accepted\n"); 10259f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 10302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme Bugreportz(false); 10459f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme 10502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme AssertStdoutEquals( 10602b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme "What happens on 'dumpstate',stays on 'bugreportz'.\n" 10702b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme "But PROGRESS IN THE MIDDLE is accepted\n"); 10802b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme} 10902b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 11002b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme// Tests 'bugreportz -p' - it will just echo dumpstate's output to stdout 11102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe LemeTEST_F(BugreportzTest, WithProgress) { 112aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme WriteToSocket("BEGIN:I AM YOUR PATH\n"); 11302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("What happens on 'dumpstate',"); 11402b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("stays on 'bugreportz'.\n"); 11502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("PROGRESS:IS INEVITABLE\n"); 11602b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("PROG"); 11702b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("RESS:IS NOT AUTOMATIC\n"); 11802b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme WriteToSocket("Newline is optional"); 11902b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 12002b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme Bugreportz(true); 12102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 12202b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme AssertStdoutEquals( 123aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme "BEGIN:I AM YOUR PATH\n" 12402b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme "What happens on 'dumpstate',stays on 'bugreportz'.\n" 12502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme "PROGRESS:IS INEVITABLE\n" 12602b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme "PROGRESS:IS NOT AUTOMATIC\n" 12702b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme "Newline is optional"); 12859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme} 129