1 1.1 christos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 1.1 christos * 3 1.1 christos * Permission is hereby granted, free of charge, to any person obtaining a copy 4 1.1 christos * of this software and associated documentation files (the "Software"), to 5 1.1 christos * deal in the Software without restriction, including without limitation the 6 1.1 christos * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 1.1 christos * sell copies of the Software, and to permit persons to whom the Software is 8 1.1 christos * furnished to do so, subject to the following conditions: 9 1.1 christos * 10 1.1 christos * The above copyright notice and this permission notice shall be included in 11 1.1 christos * all copies or substantial portions of the Software. 12 1.1 christos * 13 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 1.1 christos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 1.1 christos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 1.1 christos * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 1.1 christos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 1.1 christos * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 1.1 christos * IN THE SOFTWARE. 20 1.1 christos */ 21 1.1 christos 22 1.1 christos #include "uv.h" 23 1.1 christos #include "task.h" 24 1.1 christos #include <string.h> 25 1.1 christos 26 1.1 christos 27 1.1 christos TEST_IMPL(platform_output) { 28 1.1 christos char buffer[512]; 29 1.1 christos size_t rss; 30 1.1 christos size_t size; 31 1.1 christos double uptime; 32 1.1 christos uv_pid_t pid; 33 1.1 christos uv_pid_t ppid; 34 1.1 christos uv_rusage_t rusage; 35 1.1 christos uv_cpu_info_t* cpus; 36 1.1 christos uv_interface_address_t* interfaces; 37 1.1 christos uv_passwd_t pwd; 38 1.1.1.3 christos uv_group_t grp; 39 1.1 christos uv_utsname_t uname; 40 1.1.1.2 christos unsigned par; 41 1.1.1.3 christos char* const* member; 42 1.1 christos int count; 43 1.1 christos int i; 44 1.1 christos int err; 45 1.1 christos 46 1.1 christos err = uv_get_process_title(buffer, sizeof(buffer)); 47 1.1.1.3 christos ASSERT_OK(err); 48 1.1 christos printf("uv_get_process_title: %s\n", buffer); 49 1.1 christos 50 1.1 christos size = sizeof(buffer); 51 1.1 christos err = uv_cwd(buffer, &size); 52 1.1.1.3 christos ASSERT_OK(err); 53 1.1 christos printf("uv_cwd: %s\n", buffer); 54 1.1 christos 55 1.1 christos err = uv_resident_set_memory(&rss); 56 1.1 christos #if defined(__MSYS__) 57 1.1.1.3 christos ASSERT_EQ(err, UV_ENOSYS); 58 1.1 christos #else 59 1.1.1.3 christos ASSERT_OK(err); 60 1.1 christos printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss); 61 1.1 christos #endif 62 1.1 christos 63 1.1 christos err = uv_uptime(&uptime); 64 1.1 christos #if defined(__PASE__) 65 1.1.1.3 christos ASSERT_EQ(err, UV_ENOSYS); 66 1.1 christos #else 67 1.1.1.3 christos ASSERT_OK(err); 68 1.1.1.3 christos ASSERT_GT(uptime, 0); 69 1.1 christos printf("uv_uptime: %f\n", uptime); 70 1.1 christos #endif 71 1.1 christos 72 1.1 christos err = uv_getrusage(&rusage); 73 1.1.1.3 christos ASSERT_OK(err); 74 1.1.1.3 christos ASSERT_GE(rusage.ru_utime.tv_sec, 0); 75 1.1.1.3 christos ASSERT_GE(rusage.ru_utime.tv_usec, 0); 76 1.1.1.3 christos ASSERT_GE(rusage.ru_stime.tv_sec, 0); 77 1.1.1.3 christos ASSERT_GE(rusage.ru_stime.tv_usec, 0); 78 1.1 christos printf("uv_getrusage:\n"); 79 1.1 christos printf(" user: %llu sec %llu microsec\n", 80 1.1 christos (unsigned long long) rusage.ru_utime.tv_sec, 81 1.1 christos (unsigned long long) rusage.ru_utime.tv_usec); 82 1.1 christos printf(" system: %llu sec %llu microsec\n", 83 1.1 christos (unsigned long long) rusage.ru_stime.tv_sec, 84 1.1 christos (unsigned long long) rusage.ru_stime.tv_usec); 85 1.1 christos printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt); 86 1.1 christos printf(" maximum resident set size: %llu\n", 87 1.1 christos (unsigned long long) rusage.ru_maxrss); 88 1.1 christos 89 1.1.1.2 christos par = uv_available_parallelism(); 90 1.1.1.2 christos ASSERT_GE(par, 1); 91 1.1.1.2 christos printf("uv_available_parallelism: %u\n", par); 92 1.1.1.2 christos 93 1.1.1.3 christos #ifdef __linux__ 94 1.1.1.3 christos FILE* file; 95 1.1.1.3 christos int cgroup_version = 0; 96 1.1.1.3 christos unsigned int cgroup_par = 0; 97 1.1.1.3 christos uint64_t quota, period; 98 1.1.1.3 christos 99 1.1.1.3 christos // Attempt to parse cgroup v2 to deduce parallelism constraints 100 1.1.1.3 christos file = fopen("/sys/fs/cgroup/cpu.max", "r"); 101 1.1.1.3 christos if (file) { 102 1.1.1.3 christos if (fscanf(file, "%lu %lu", "a, &period) == 2 && quota > 0) { 103 1.1.1.3 christos cgroup_version = 2; 104 1.1.1.3 christos cgroup_par = (unsigned int)(quota / period); 105 1.1.1.3 christos } 106 1.1.1.3 christos fclose(file); 107 1.1.1.3 christos } 108 1.1.1.3 christos 109 1.1.1.3 christos // If cgroup v2 wasn't present, try parsing cgroup v1 110 1.1.1.3 christos if (cgroup_version == 0) { 111 1.1.1.3 christos file = fopen("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us", "r"); 112 1.1.1.3 christos if (file) { 113 1.1.1.3 christos if (fscanf(file, "%lu", "a) == 1 && quota > 0 && quota < ~0ULL) { 114 1.1.1.3 christos fclose(file); 115 1.1.1.3 christos file = fopen("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us", "r"); 116 1.1.1.3 christos if (file && fscanf(file, "%lu", &period) == 1) { 117 1.1.1.3 christos cgroup_version = 1; 118 1.1.1.3 christos cgroup_par = (unsigned int)(quota / period); 119 1.1.1.3 christos } 120 1.1.1.3 christos } 121 1.1.1.3 christos if (file) fclose(file); 122 1.1.1.3 christos } 123 1.1.1.3 christos } 124 1.1.1.3 christos 125 1.1.1.3 christos // If we found cgroup parallelism constraints, assert and print them 126 1.1.1.3 christos if (cgroup_par > 0) { 127 1.1.1.3 christos ASSERT_GE(par, cgroup_par); 128 1.1.1.3 christos printf("cgroup v%d available parallelism: %u\n", cgroup_version, cgroup_par); 129 1.1.1.3 christos } 130 1.1.1.3 christos #endif 131 1.1.1.3 christos 132 1.1 christos err = uv_cpu_info(&cpus, &count); 133 1.1 christos #if defined(__CYGWIN__) || defined(__MSYS__) 134 1.1.1.3 christos ASSERT_EQ(err, UV_ENOSYS); 135 1.1 christos #else 136 1.1.1.3 christos ASSERT_OK(err); 137 1.1 christos 138 1.1 christos printf("uv_cpu_info:\n"); 139 1.1 christos for (i = 0; i < count; i++) { 140 1.1 christos printf(" model: %s\n", cpus[i].model); 141 1.1 christos printf(" speed: %d\n", cpus[i].speed); 142 1.1 christos printf(" times.sys: %llu\n", (unsigned long long) cpus[i].cpu_times.sys); 143 1.1 christos printf(" times.user: %llu\n", 144 1.1 christos (unsigned long long) cpus[i].cpu_times.user); 145 1.1 christos printf(" times.idle: %llu\n", 146 1.1 christos (unsigned long long) cpus[i].cpu_times.idle); 147 1.1 christos printf(" times.irq: %llu\n", (unsigned long long) cpus[i].cpu_times.irq); 148 1.1 christos printf(" times.nice: %llu\n", 149 1.1 christos (unsigned long long) cpus[i].cpu_times.nice); 150 1.1 christos } 151 1.1 christos #endif 152 1.1 christos uv_free_cpu_info(cpus, count); 153 1.1 christos 154 1.1 christos err = uv_interface_addresses(&interfaces, &count); 155 1.1.1.3 christos ASSERT_OK(err); 156 1.1 christos 157 1.1 christos printf("uv_interface_addresses:\n"); 158 1.1 christos for (i = 0; i < count; i++) { 159 1.1 christos printf(" name: %s\n", interfaces[i].name); 160 1.1 christos printf(" internal: %d\n", interfaces[i].is_internal); 161 1.1 christos printf(" physical address: "); 162 1.1 christos printf("%02x:%02x:%02x:%02x:%02x:%02x\n", 163 1.1 christos (unsigned char)interfaces[i].phys_addr[0], 164 1.1 christos (unsigned char)interfaces[i].phys_addr[1], 165 1.1 christos (unsigned char)interfaces[i].phys_addr[2], 166 1.1 christos (unsigned char)interfaces[i].phys_addr[3], 167 1.1 christos (unsigned char)interfaces[i].phys_addr[4], 168 1.1 christos (unsigned char)interfaces[i].phys_addr[5]); 169 1.1 christos 170 1.1 christos if (interfaces[i].address.address4.sin_family == AF_INET) { 171 1.1 christos uv_ip4_name(&interfaces[i].address.address4, buffer, sizeof(buffer)); 172 1.1 christos } else if (interfaces[i].address.address4.sin_family == AF_INET6) { 173 1.1 christos uv_ip6_name(&interfaces[i].address.address6, buffer, sizeof(buffer)); 174 1.1 christos } 175 1.1 christos 176 1.1 christos printf(" address: %s\n", buffer); 177 1.1 christos 178 1.1 christos if (interfaces[i].netmask.netmask4.sin_family == AF_INET) { 179 1.1 christos uv_ip4_name(&interfaces[i].netmask.netmask4, buffer, sizeof(buffer)); 180 1.1 christos printf(" netmask: %s\n", buffer); 181 1.1 christos } else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) { 182 1.1 christos uv_ip6_name(&interfaces[i].netmask.netmask6, buffer, sizeof(buffer)); 183 1.1 christos printf(" netmask: %s\n", buffer); 184 1.1 christos } else { 185 1.1 christos printf(" netmask: none\n"); 186 1.1 christos } 187 1.1 christos } 188 1.1 christos uv_free_interface_addresses(interfaces, count); 189 1.1 christos 190 1.1 christos err = uv_os_get_passwd(&pwd); 191 1.1.1.3 christos ASSERT_OK(err); 192 1.1.1.3 christos 193 1.1.1.3 christos err = uv_os_get_group(&grp, pwd.gid); 194 1.1.1.3 christos #if defined(_WIN32) 195 1.1.1.3 christos ASSERT_EQ(err, UV_ENOTSUP); 196 1.1.1.3 christos ASSERT_EQ(pwd.uid, (unsigned long) -1); 197 1.1.1.3 christos ASSERT_EQ(pwd.gid, (unsigned long) -1); 198 1.1.1.3 christos (void) member; 199 1.1.1.3 christos grp.groupname = "ENOTSUP"; 200 1.1.1.3 christos #else 201 1.1.1.3 christos ASSERT_OK(err); 202 1.1.1.3 christos ASSERT_EQ(pwd.gid, grp.gid); 203 1.1.1.3 christos #endif 204 1.1 christos 205 1.1 christos printf("uv_os_get_passwd:\n"); 206 1.1 christos printf(" euid: %ld\n", pwd.uid); 207 1.1.1.3 christos printf(" gid: %ld (%s)\n", pwd.gid, grp.groupname); 208 1.1.1.3 christos #if !defined(_WIN32) 209 1.1.1.3 christos printf(" members: ["); 210 1.1.1.3 christos for (member = grp.members; *member != NULL; member++) { 211 1.1.1.3 christos printf(" %s", *member); 212 1.1.1.3 christos } 213 1.1.1.3 christos printf(" ]\n"); 214 1.1.1.3 christos #endif 215 1.1 christos printf(" username: %s\n", pwd.username); 216 1.1.1.3 christos if (pwd.shell != NULL) /* Not set on Windows */ 217 1.1.1.3 christos printf(" shell: %s\n", pwd.shell); 218 1.1 christos printf(" home directory: %s\n", pwd.homedir); 219 1.1.1.2 christos uv_os_free_passwd(&pwd); 220 1.1.1.3 christos #if !defined(_WIN32) 221 1.1.1.3 christos uv_os_free_group(&grp); 222 1.1.1.3 christos #endif 223 1.1 christos 224 1.1 christos pid = uv_os_getpid(); 225 1.1.1.3 christos ASSERT_GT(pid, 0); 226 1.1 christos printf("uv_os_getpid: %d\n", (int) pid); 227 1.1 christos ppid = uv_os_getppid(); 228 1.1.1.3 christos ASSERT_GT(ppid, 0); 229 1.1 christos printf("uv_os_getppid: %d\n", (int) ppid); 230 1.1 christos 231 1.1 christos err = uv_os_uname(&uname); 232 1.1.1.3 christos ASSERT_OK(err); 233 1.1 christos printf("uv_os_uname:\n"); 234 1.1 christos printf(" sysname: %s\n", uname.sysname); 235 1.1 christos printf(" release: %s\n", uname.release); 236 1.1 christos printf(" version: %s\n", uname.version); 237 1.1 christos printf(" machine: %s\n", uname.machine); 238 1.1 christos 239 1.1.1.3 christos err = uv_getrusage_thread(&rusage); 240 1.1.1.3 christos if (err != UV_ENOTSUP) { 241 1.1.1.3 christos ASSERT_OK(err); 242 1.1.1.3 christos ASSERT_UINT64_GE(rusage.ru_utime.tv_sec, 0); 243 1.1.1.3 christos ASSERT_UINT64_GE(rusage.ru_utime.tv_usec, 0); 244 1.1.1.3 christos ASSERT_UINT64_GE(rusage.ru_stime.tv_sec, 0); 245 1.1.1.3 christos ASSERT_UINT64_GE(rusage.ru_stime.tv_usec, 0); 246 1.1.1.3 christos printf("uv_getrusage_thread:\n"); 247 1.1.1.3 christos printf(" user: %llu sec %llu microsec\n", 248 1.1.1.3 christos (unsigned long long) rusage.ru_utime.tv_sec, 249 1.1.1.3 christos (unsigned long long) rusage.ru_utime.tv_usec); 250 1.1.1.3 christos printf(" system: %llu sec %llu microsec\n", 251 1.1.1.3 christos (unsigned long long) rusage.ru_stime.tv_sec, 252 1.1.1.3 christos (unsigned long long) rusage.ru_stime.tv_usec); 253 1.1.1.3 christos printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt); 254 1.1.1.3 christos printf(" maximum resident set size: %llu\n", 255 1.1.1.3 christos (unsigned long long) rusage.ru_maxrss); 256 1.1.1.3 christos } 257 1.1.1.3 christos 258 1.1 christos return 0; 259 1.1 christos } 260