Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add image util functions test #2821

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions react/src/hooks/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { imageParser } from '.';
import _ from 'lodash';

describe('Image util functions tests', () => {
// TODO: Use test hooks to test the functions

const { getBaseImage, getBaseVersion, getTags } = imageParser;

describe('Test with underbar image tag', () => {
const IMAGE_NAME = 'abc-def.ghi.systems/llm/jkl/mno_pqr:0.0.0_stu';
describe('getBaseVersion', () => {
it('should correctly parse the base version from an image name', () => {
const baseVersion = getBaseVersion(IMAGE_NAME);
expect(baseVersion).toBe('0.0.0');
});
});

describe('getBaseImage', () => {
it('should correctly parse the base image from an image name', () => {
const baseImage = getBaseImage(IMAGE_NAME);
expect(baseImage).toBe('mno_pqr');
});
});

describe('getTags', () => {
it('should correctly parse and process tags from a given tag string', () => {
const tag = '0.0.0_stu';
const labels = [{ key: 'abc', value: 'def' }];
const tags = getTags(tag, labels);
expect(tags).toEqual([{ key: 'stu', value: '' }]);
});
});
});
describe('Test with dash image tag', () => {
const IMAGE_NAME = 'abc-def.ghi.systems/llm/jkl/mno_pqr:0.0.0-stu';
describe('getBaseVersion', () => {
it('should correctly parse the base version from an image name', () => {
const baseVersion = getBaseVersion(IMAGE_NAME);
expect(baseVersion).toBe('0.0.0');
});
});

describe('getBaseImage', () => {
it('should correctly parse the base image from an image name', () => {
const baseImage = getBaseImage(IMAGE_NAME);
expect(baseImage).toBe('mno_pqr');
});
});

describe('getTags', () => {
it('should correctly parse and process tags from a given tag string', () => {
const tag = '0.0.0_stu';
const labels = [{ key: 'abc', value: 'def' }];
const tags = getTags(tag, labels);
expect(tags).toEqual([{ key: 'stu', value: '' }]);
});
});
});
describe('Test with customized image tag', () => {
const IMAGE_NAME =
'abc-def.ghi.systems/llm/jkl/mno_pqr:0.0.0-stu_customized_asdflkjnweri';
describe('getBaseVersion', () => {
it('should correctly parse the base version from an image name', () => {
const baseVersion = getBaseVersion(IMAGE_NAME);
expect(baseVersion).toBe('0.0.0');
});
});

describe('getBaseImage', () => {
it('should correctly parse the base image from an image name', () => {
const baseImage = getBaseImage(IMAGE_NAME);
expect(baseImage).toBe('mno_pqr');
});
});

describe('getTags', () => {
it('should handle customized_ tags correctly', () => {
const tag = '0.0.0-stu_customized_asdflkjnweri';
const labels = [
{ key: 'ai.backend.customized-image.name', value: 'CustomImage' },
];
const tags = getTags(tag, labels);
expect(tags).toEqual([
{ key: 'stu', value: '' },
{ key: 'Customized', value: 'CustomImage' },
]);
});
});
});
});
96 changes: 49 additions & 47 deletions react/src/hooks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,54 @@ interface ImageMetadata {
}[];
}

export const imageParser = {
getBaseVersion: (imageName: string) => {
return (
_.first(_.split(_.last(_.split(imageName, ':')), /[^a-zA-Z\d.]+/)) || ''
);
},
getBaseImage: (imageName: string) => {
const splitByColon = _.split(imageName, ':');
const beforeLastColon = _.join(_.initial(splitByColon), ':');
const lastItemAfterSplitBySlash = _.last(_.split(beforeLastColon, '/'));
return lastItemAfterSplitBySlash || '';
},
getTags: (tag: string, labels: Array<{ key: string; value: string }>) => {
// Remove the 'customized_' prefix and its following string from the tag
const cleanedTag = _.replace(tag, /customized_[a-zA-Z\d.]+/, '');
// Split the remaining tag into segments based on alphanumeric and '.' characters, ignoring the first segment
const tags = _.tail(_.split(cleanedTag, /[^a-zA-Z\d.]+/));
const result: Array<{ key: string; value: string }> = [];

// Process not 'customized_' tags
_.forEach(tags, (currentTag) => {
// Separate the alphabetic prefix from the numeric and '.' suffix for each tag
const match = /^([a-zA-Z]+)(.*)$/.exec(currentTag);
if (match) {
const [, key, value] = match;
// Ensure the value is an empty string if it's undefined
result.push({ key, value: value || '' });
}
});

// Handle the 'customized_' tag separately by finding the custom image name in labels
const customizedNameLabel = _.get(
_.find(labels, { key: 'ai.backend.customized-image.name' }),
'value',
'',
);
// If a custom image name exists, add it to the result with the key 'Customized'
if (customizedNameLabel) {
result.push({ key: 'Customized', value: customizedNameLabel });
}

// Remove duplicates and entries with an empty 'key'
return _.uniqWith(
_.filter(result, ({ key }) => !_.isEmpty(key)),
_.isEqual,
);
},
};
export const useBackendAIImageMetaData = () => {
const { data: metadata } = useSuspenseTanQuery<{
imageInfo: {
Expand Down Expand Up @@ -261,18 +309,6 @@ export const useBackendAIImageMetaData = () => {
})?.value;
return customizedNameLabel;
},
getBaseVersion: (imageName: string) => {
return (
_.first(_.split(_.last(_.split(imageName, ':')), /[^a-zA-Z\d.]+/)) ||
''
);
},
getBaseImage: (imageName: string) => {
const splitByColon = _.split(imageName, ':');
const beforeLastColon = _.join(_.initial(splitByColon), ':');
const lastItemAfterSplitBySlash = _.last(_.split(beforeLastColon, '/'));
return lastItemAfterSplitBySlash || '';
},
getBaseImages: (tag: string, name: string) => {
const tags = tag.split('-');
let baseImage;
Expand All @@ -297,41 +333,6 @@ export const useBackendAIImageMetaData = () => {
return baseImageArr;
},
getImageMeta,
getTags: (tag: string, labels: Array<{ key: string; value: string }>) => {
// Remove the 'customized_' prefix and its following string from the tag
const cleanedTag = _.replace(tag, /customized_[a-zA-Z\d.]+/, '');
// Split the remaining tag into segments based on alphanumeric and '.' characters, ignoring the first segment
const tags = _.tail(_.split(cleanedTag, /[^a-zA-Z\d.]+/));
const result: Array<{ key: string; value: string }> = [];

// Process not 'customized_' tags
_.forEach(tags, (currentTag) => {
// Separate the alphabetic prefix from the numeric and '.' suffix for each tag
const match = /^([a-zA-Z]+)(.*)$/.exec(currentTag);
if (match) {
const [, key, value] = match;
// Ensure the value is an empty string if it's undefined
result.push({ key, value: value || '' });
}
});

// Handle the 'customized_' tag separately by finding the custom image name in labels
const customizedNameLabel = _.get(
_.find(labels, { key: 'ai.backend.customized-image.name' }),
'value',
'',
);
// If a custom image name exists, add it to the result with the key 'Customized'
if (customizedNameLabel) {
result.push({ key: 'Customized', value: customizedNameLabel });
}

// Remove duplicates and entries with an empty 'key'
return _.uniqWith(
_.filter(result, ({ key }) => !_.isEmpty(key)),
_.isEqual,
);
},
getConstraints: (
tag: string,
labels: { key: string; value: string }[],
Expand Down Expand Up @@ -371,6 +372,7 @@ export const useBackendAIImageMetaData = () => {
preserveDotStartCase(tag)
);
},
...imageParser,
},
] as const;
};
Expand Down
Loading