Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include <errno.h>
     20 #include <signal.h>
     21 #include <stdlib.h>
     22 #include <sys/select.h>
     23 #include <sys/types.h>
     24 #include <sys/wait.h>
     25 
     26 #include "utils.h"
     27 
     28 TEST(sys_select, fd_set_smoke) {
     29   fd_set fds;
     30   FD_ZERO(&fds);
     31 
     32   for (size_t i = 0; i < 1024; ++i) {
     33     EXPECT_FALSE(FD_ISSET(i, &fds));
     34   }
     35 
     36   FD_SET(0, &fds);
     37   EXPECT_TRUE(FD_ISSET(0, &fds));
     38   EXPECT_FALSE(FD_ISSET(1, &fds));
     39   FD_SET(1, &fds);
     40   EXPECT_TRUE(FD_ISSET(0, &fds));
     41   EXPECT_TRUE(FD_ISSET(1, &fds));
     42   FD_CLR(0, &fds);
     43   EXPECT_FALSE(FD_ISSET(0, &fds));
     44   EXPECT_TRUE(FD_ISSET(1, &fds));
     45   FD_CLR(1, &fds);
     46   EXPECT_FALSE(FD_ISSET(0, &fds));
     47   EXPECT_FALSE(FD_ISSET(1, &fds));
     48 }
     49 
     50 #define DELAY_MSG "1234"
     51 
     52 static void DelayedWrite(int* pid, int* fd) {
     53   int fds[2];
     54   ASSERT_EQ(0, pipe(fds));
     55 
     56   if ((*pid = fork()) == 0) {
     57     close(fds[0]);
     58     usleep(5000);
     59     EXPECT_EQ(5, write(fds[1], DELAY_MSG, sizeof(DELAY_MSG)));
     60     close(fds[1]);
     61     exit(0);
     62   }
     63   ASSERT_LT(0, *pid);
     64   close(fds[1]);
     65 
     66   *fd = fds[0];
     67 }
     68 
     69 static void DelayedWriteCleanup(int pid, int fd) {
     70   char buf[sizeof(DELAY_MSG)];
     71   ASSERT_EQ(static_cast<ssize_t>(sizeof(DELAY_MSG)), read(fd, buf, sizeof(DELAY_MSG)));
     72   ASSERT_STREQ(DELAY_MSG, buf);
     73 
     74   AssertChildExited(pid, 0);
     75 }
     76 
     77 TEST(sys_select, select_smoke) {
     78   fd_set r;
     79   FD_ZERO(&r);
     80   fd_set w;
     81   FD_ZERO(&w);
     82   fd_set e;
     83   FD_ZERO(&e);
     84 
     85   FD_SET(STDIN_FILENO, &r);
     86   FD_SET(STDOUT_FILENO, &w);
     87   FD_SET(STDERR_FILENO, &w);
     88 
     89   int max = STDERR_FILENO + 1;
     90 
     91   // Invalid max fd.
     92   ASSERT_EQ(-1, select(-1, &r, &w, &e, NULL));
     93   ASSERT_EQ(EINVAL, errno);
     94 
     95   int num_fds = select(max, &r, &w, &e, NULL);
     96   // If there is data to be read on STDIN, then the number of
     97   // fds ready will be 3 instead of 2. Allow this case, but verify
     98   // every fd that is set.
     99   ASSERT_TRUE(num_fds == 2 || num_fds == 3) << "Num fds returned " << num_fds;
    100   ASSERT_TRUE(FD_ISSET(STDOUT_FILENO, &w));
    101   ASSERT_TRUE(FD_ISSET(STDERR_FILENO, &w));
    102   if (num_fds == 3) {
    103     ASSERT_TRUE(FD_ISSET(STDIN_FILENO, &r));
    104   }
    105 
    106   // Invalid timeout.
    107   timeval tv;
    108   tv.tv_sec = -1;
    109   tv.tv_usec = 0;
    110   ASSERT_EQ(-1, select(max, &r, &w, &e, &tv));
    111   ASSERT_EQ(EINVAL, errno);
    112 
    113   // Valid timeout...
    114   tv.tv_sec = 1;
    115   int pid, fd;
    116   DelayedWrite(&pid, &fd);
    117 
    118   FD_ZERO(&r);
    119   FD_SET(fd, &r);
    120   ASSERT_EQ(1, select(fd+1, &r, NULL, NULL, &tv));
    121   // Both tv_sec and tv_nsec should have been updated.
    122   ASSERT_EQ(0, tv.tv_sec);
    123   ASSERT_NE(0, tv.tv_usec);
    124 
    125   DelayedWriteCleanup(pid, fd);
    126 }
    127 
    128 TEST(sys_select, pselect_smoke) {
    129   sigset_t ss;
    130   sigemptyset(&ss);
    131   sigaddset(&ss, SIGPIPE);
    132 
    133   fd_set r;
    134   FD_ZERO(&r);
    135   fd_set w;
    136   FD_ZERO(&w);
    137   fd_set e;
    138   FD_ZERO(&e);
    139 
    140   FD_SET(STDIN_FILENO, &r);
    141   FD_SET(STDOUT_FILENO, &w);
    142   FD_SET(STDERR_FILENO, &w);
    143 
    144   int max = STDERR_FILENO + 1;
    145 
    146   // Invalid max fd.
    147   ASSERT_EQ(-1, pselect(-1, &r, &w, &e, NULL, &ss));
    148   ASSERT_EQ(EINVAL, errno);
    149 
    150   // If there is data to be read on STDIN, then the number of
    151   // fds ready will be 3 instead of 2. Allow this case, but verify
    152   // every fd that is set.
    153   int num_fds = pselect(max, &r, &w, &e, NULL, &ss);
    154   ASSERT_TRUE(num_fds == 2 || num_fds == 3) << "Num fds returned " << num_fds;
    155   ASSERT_TRUE(FD_ISSET(STDOUT_FILENO, &w));
    156   ASSERT_TRUE(FD_ISSET(STDERR_FILENO, &w));
    157   if (num_fds == 3) {
    158     ASSERT_TRUE(FD_ISSET(STDIN_FILENO, &r));
    159   }
    160 
    161   // Invalid timeout.
    162   timespec tv;
    163   tv.tv_sec = -1;
    164   tv.tv_nsec = 0;
    165   ASSERT_EQ(-1, pselect(max, &r, &w, &e, &tv, &ss));
    166   ASSERT_EQ(EINVAL, errno);
    167 
    168   // Valid timeout...
    169   tv.tv_sec = 1;
    170   int pid, fd;
    171   DelayedWrite(&pid, &fd);
    172 
    173   FD_ZERO(&r);
    174   FD_SET(fd, &r);
    175   ASSERT_EQ(1, pselect(fd+1, &r, NULL, NULL, &tv, NULL));
    176   // Neither tv_sec nor tv_nsec should have been updated.
    177   ASSERT_EQ(1, tv.tv_sec);
    178   ASSERT_EQ(0, tv.tv_nsec);
    179 
    180   DelayedWriteCleanup(pid, fd);
    181 }
    182 
    183 TEST(sys_select, FD_ISSET_const) {
    184   const fd_set none = {};
    185   ASSERT_FALSE(FD_ISSET(atoi("0"), &none));
    186 }
    187