1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 07:44:48 -05:00
denoland-deno/cli/tests/unit/chown_test.ts
Nayeem Rahman 45c49034a7
BREAKING(unstable): Improve Deno.spawn() stdio API (#14919)
- "SpawnOutput" extends "ChildStatus" instead of composing it
- "SpawnOutput::stdout", "SpawnOutput::stderr", "Child::stdin", 
"Child::stdout" and "Child::stderr" are no longer optional, instead 
made them getters that throw at runtime if that stream wasn't set 
to "piped". 
- Remove the complicated "<T extends SpawnOptions = SpawnOptions>" 
which we currently need to give proper type hints for the availability of 
these fields. Their typings for these would get increasingly complex 
if it became dependent on more options (e.g. "SpawnOptions::pty" 
which if set should make the stdio streams unavailable)
2022-07-18 15:16:12 +02:00

190 lines
5.6 KiB
TypeScript

// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
import { assertEquals, assertRejects, assertThrows } from "./test_util.ts";
// chown on Windows is noop for now, so ignore its testing on Windows
async function getUidAndGid(): Promise<{ uid: number; gid: number }> {
// get the user ID and group ID of the current process
const uidProc = await Deno.spawn("id", {
args: ["-u"],
});
const gidProc = await Deno.spawn("id", {
args: ["-g"],
});
assertEquals(uidProc.code, 0);
assertEquals(gidProc.code, 0);
const uid = parseInt(new TextDecoder("utf-8").decode(uidProc.stdout));
const gid = parseInt(new TextDecoder("utf-8").decode(gidProc.stdout));
return { uid, gid };
}
Deno.test(
{ ignore: Deno.build.os == "windows", permissions: { write: false } },
async function chownNoWritePermission() {
const filePath = "chown_test_file.txt";
await assertRejects(async () => {
await Deno.chown(filePath, 1000, 1000);
}, Deno.errors.PermissionDenied);
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownSyncFileNotExist() {
const { uid, gid } = await getUidAndGid();
const filePath = Deno.makeTempDirSync() + "/chown_test_file.txt";
assertThrows(
() => {
Deno.chownSync(filePath, uid, gid);
},
Deno.errors.NotFound,
`chown '${filePath}'`,
);
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownFileNotExist() {
const { uid, gid } = await getUidAndGid();
const filePath = (await Deno.makeTempDir()) + "/chown_test_file.txt";
await assertRejects(
async () => {
await Deno.chown(filePath, uid, gid);
},
Deno.errors.NotFound,
`chown '${filePath}'`,
);
},
);
Deno.test(
{ permissions: { write: true }, ignore: Deno.build.os == "windows" },
function chownSyncPermissionDenied() {
const dirPath = Deno.makeTempDirSync();
const filePath = dirPath + "/chown_test_file.txt";
Deno.writeTextFileSync(filePath, "Hello");
assertThrows(() => {
// try changing the file's owner to root
Deno.chownSync(filePath, 0, 0);
}, Deno.errors.PermissionDenied);
Deno.removeSync(dirPath, { recursive: true });
},
);
Deno.test(
{ permissions: { write: true }, ignore: Deno.build.os == "windows" },
async function chownPermissionDenied() {
const dirPath = await Deno.makeTempDir();
const filePath = dirPath + "/chown_test_file.txt";
await Deno.writeTextFile(filePath, "Hello");
await assertRejects(async () => {
// try changing the file's owner to root
await Deno.chown(filePath, 0, 0);
}, Deno.errors.PermissionDenied);
await Deno.remove(dirPath, { recursive: true });
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownSyncSucceed() {
// TODO(bartlomieju): when a file's owner is actually being changed,
// chown only succeeds if run under priviledged user (root)
// The test script has no such privilege, so need to find a better way to test this case
const { uid, gid } = await getUidAndGid();
const dirPath = Deno.makeTempDirSync();
const filePath = dirPath + "/chown_test_file.txt";
Deno.writeTextFileSync(filePath, "Hello");
// the test script creates this file with the same uid and gid,
// here chown is a noop so it succeeds under non-priviledged user
Deno.chownSync(filePath, uid, gid);
Deno.removeSync(dirPath, { recursive: true });
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownSyncWithUrl() {
const { uid, gid } = await getUidAndGid();
const dirPath = Deno.makeTempDirSync();
const fileUrl = new URL(`file://${dirPath}/chown_test_file.txt`);
Deno.writeTextFileSync(fileUrl, "Hello");
Deno.chownSync(fileUrl, uid, gid);
Deno.removeSync(dirPath, { recursive: true });
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownSucceed() {
const { uid, gid } = await getUidAndGid();
const dirPath = await Deno.makeTempDir();
const filePath = dirPath + "/chown_test_file.txt";
await Deno.writeTextFile(filePath, "Hello");
await Deno.chown(filePath, uid, gid);
Deno.removeSync(dirPath, { recursive: true });
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownUidOnly() {
const { uid } = await getUidAndGid();
const dirPath = await Deno.makeTempDir();
const filePath = dirPath + "/chown_test_file.txt";
await Deno.writeTextFile(filePath, "Foo");
await Deno.chown(filePath, uid, null);
Deno.removeSync(dirPath, { recursive: true });
},
);
Deno.test(
{
permissions: { run: true, write: true },
ignore: Deno.build.os == "windows",
},
async function chownWithUrl() {
// TODO(bartlomieju): same as chownSyncSucceed
const { uid, gid } = await getUidAndGid();
const enc = new TextEncoder();
const dirPath = await Deno.makeTempDir();
const fileUrl = new URL(`file://${dirPath}/chown_test_file.txt`);
const fileData = enc.encode("Hello");
await Deno.writeFile(fileUrl, fileData);
// the test script creates this file with the same uid and gid,
// here chown is a noop so it succeeds under non-priviledged user
await Deno.chown(fileUrl, uid, gid);
Deno.removeSync(dirPath, { recursive: true });
},
);