Skip to content

Commit

Permalink
Merge pull request #2272 from brendandburns/coverage
Browse files Browse the repository at this point in the history
Improve coverage by adding unit tests for log.ts
  • Loading branch information
k8s-ci-robot authored Feb 26, 2025
2 parents 1d63ebf + 45bdb75 commit f1b77ac
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"src/**/*.ts"
],
"exclude": [
"src/gen/*/**.ts",
"src/gen/**/*.ts",
"src/index.ts",
"src/*_test.ts",
"src/test"
Expand Down
9 changes: 8 additions & 1 deletion src/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export class Log {
// TODO: the follow search param still has the stream close prematurely based on my testing
response.body!.pipe(stream);
} else if (status === 500) {
const v1status = response.body as V1Status;
const v1status = (await response.json()) as V1Status;
const v1code = v1status.code;
const v1message = v1status.message;
if (v1code !== undefined && v1message !== undefined) {
Expand All @@ -152,6 +152,13 @@ export class Log {
v1status,
normalizeResponseHeaders(response),
);
} else {
throw new ApiException<undefined>(
status,
'Error occurred in log request',
undefined,
normalizeResponseHeaders(response),
);
}
} else {
throw new ApiException<undefined>(
Expand Down
173 changes: 171 additions & 2 deletions src/log_test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,177 @@
import { strictEqual, throws } from 'node:assert';
import { AddOptionsToSearchParams, LogOptions } from './log.js';
import { strictEqual, rejects, throws } from 'node:assert';
import nock from 'nock';
import { AddOptionsToSearchParams, Log, LogOptions } from './log.js';
import { KubeConfig } from './config.js';
import { Writable } from 'node:stream';

describe('Log', () => {
describe('Constructor', () => {
it('should work', () => {
const config = new KubeConfig();
config.addCluster({
name: 'foo',
server: 'https://example.com',
caData: 'certificate-authority-data',
skipTLSVerify: false,
});
const log = new Log(config);
strictEqual(log.config, config);
});
});
describe('log', () => {
const config = new KubeConfig();
config.addCluster({
name: 'foo',
server: 'https://example.com',
caData: 'certificate-authority-data',
skipTLSVerify: false,
});
config.addContext({
name: 'foo',
cluster: 'foo',
user: 'foo',
});
config.setCurrentContext('foo');
const log = new Log(config);

afterEach(() => {
nock.cleanAll();
});

it('should make a request with correct parameters', async () => {
const namespace = 'default';
const podName = 'mypod';
const containerName = 'mycontainer';
const stream = new Writable({
write(chunk, encoding, callback) {
callback();
},
});
const options: LogOptions = {
follow: true,
limitBytes: 100,
pretty: true,
previous: true,
sinceSeconds: 1,
tailLines: 1,
timestamps: true,
};

nock('https://example.com')
.get('/api/v1/namespaces/default/pods/mypod/log')
.query({
container: 'mycontainer',
follow: 'true',
limitBytes: '100',
pretty: 'true',
previous: 'true',
sinceSeconds: '1',
tailLines: '1',
timestamps: 'true',
})
.reply(200, 'log data');

const controller = await log.log(namespace, podName, containerName, stream, options);
strictEqual(controller instanceof AbortController, true);
});

it('should throw an error if no active cluster', async () => {
const configWithoutCluster = new KubeConfig();
const logWithoutCluster = new Log(configWithoutCluster);
const namespace = 'default';
const podName = 'mypod';
const containerName = 'mycontainer';
const stream = new Writable({
write(chunk, encoding, callback) {
callback();
},
});

await rejects(async () => {
await logWithoutCluster.log(namespace, podName, containerName, stream);
}, /No currently active cluster/);
});

it('should handle API exceptions on non-500', async () => {
const namespace = 'default';
const podName = 'mypod';
const containerName = 'mycontainer';
const stream = new Writable({
write(chunk, encoding, callback) {
callback();
},
});

nock('https://example.com')
.get('/api/v1/namespaces/default/pods/mypod/log')
.query({ container: 'mycontainer' })
.reply(501, { message: 'Error occurred in log request' });

await rejects(async () => {
await log.log(namespace, podName, containerName, stream);
}, /Error occurred in log request/);
});

it('should handle API exceptions on 500', async () => {
const namespace = 'default';
const podName = 'mypod';
const containerName = 'mycontainer';
const stream = new Writable({
write(chunk, encoding, callback) {
callback();
},
});

nock('https://example.com')
.get('/api/v1/namespaces/default/pods/mypod/log')
.query({ container: 'mycontainer' })
.reply(500, { message: 'Error occurred in log request' });

await rejects(async () => {
await log.log(namespace, podName, containerName, stream);
}, /Error occurred in log request/);
});

it('should handle V1Status with code and message', async () => {
const namespace = 'default';
const podName = 'mypod';
const containerName = 'mycontainer';
const stream = new Writable({
write(chunk, encoding, callback) {
callback();
},
});

const v1Status = {
kind: 'Status',
apiVersion: 'v1',
metadata: {},
status: 'Failure',
message: 'Pod not found',
reason: 'NotFound',
details: {
name: podName,
kind: 'pods',
},
code: 404,
};

nock('https://example.com')
.get('/api/v1/namespaces/default/pods/mypod/log')
.query({ container: 'mycontainer' })
.reply(500, v1Status);

await rejects(async () => {
await log.log(namespace, podName, containerName, stream);
}, /Pod not found/);
});
});
describe('AddOptionsToSearchParams', () => {
it('should handle no log options', () => {
const searchParams = new URLSearchParams();
AddOptionsToSearchParams(undefined, searchParams);
// verify that it doesn't throw.
});
it('should add options to search params', () => {
let searchParams = new URLSearchParams();
let options: LogOptions = {
Expand Down

0 comments on commit f1b77ac

Please sign in to comment.