Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
219 changes: 0 additions & 219 deletions x-pack/platform/test/fleet_api_integration/apis/epm/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import expect from '@kbn/expect';
import type { PackageInfo } from '@kbn/fleet-plugin/common/types/models/epm';
import fs from 'fs';
import path from 'path';
import pRetry from 'p-retry';
import type { FtrProviderContext } from '../../../api_integration/ftr_provider_context';
import { skipIfNoDockerRegistry } from '../../helpers';
import { testUsers } from '../test_users';
Expand Down Expand Up @@ -37,75 +36,6 @@ export default function (providerContext: FtrProviderContext) {
.send({ force: true });
};

// Helper function to clean up knowledge base content
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the knowledge base tests to their own file

const cleanupKnowledgeBase = async (name: string) => {
await es.deleteByQuery({
index: '.integration_knowledge',
query: {
term: { 'package_name.keyword': name },
},
refresh: true,
ignore_unavailable: true,
});
};

// Helper function to wait for knowledge base content to be available
const waitForKnowledgeBaseContent = async (packageName: string) => {
await pRetry(
async () => {
const res = await supertest
.get(`/internal/fleet/epm/packages/${packageName}/knowledge_base`)
.set('kbn-xsrf', 'xxxx')
.set('elastic-api-version', '1');

if (res.status !== 200) {
throw new Error(`Knowledge base not ready yet, status: ${res.status}`);
}

// Ensure we have the expected content structure
if (!res.body?.items || !Array.isArray(res.body.items) || res.body.items.length === 0) {
throw new Error('Knowledge base content not yet available');
}
},
{
retries: 12, // 12 retries * 5 seconds = 60 seconds max
minTimeout: 5000, // 5 seconds between retries
maxTimeout: 5000,
}
);
};

// Helper function to wait for knowledge base items to appear in package info
const waitForKnowledgeBaseInPackageInfo = async (packageName: string, packageVersion: string) => {
await pRetry(
async () => {
const res = await supertest.get(`/api/fleet/epm/packages/${packageName}/${packageVersion}`);

if (res.status !== 200) {
throw new Error(`Package info not ready yet, status: ${res.status}`);
}

const packageInfo = res.body.item;
if (!packageInfo?.installationInfo?.installed_es) {
throw new Error('Package installation info not yet available');
}

const knowledgeBaseItems = packageInfo.installationInfo.installed_es.filter(
(item: any) => item.type === 'knowledge_base'
);

if (knowledgeBaseItems.length === 0) {
throw new Error('Knowledge base items not yet available in package info');
}
},
{
retries: 12, // 12 retries * 5 seconds = 60 seconds max
minTimeout: 5000, // 5 seconds between retries
maxTimeout: 5000,
}
);
};

const testPkgArchiveZip = path.join(
path.dirname(__filename),
'../fixtures/direct_upload_packages/apache_0.1.4.zip'
Expand Down Expand Up @@ -373,154 +303,5 @@ export default function (providerContext: FtrProviderContext) {
);
expect(dataStream?.elasticsearch?.source_mode).equal(undefined);
});

// Re-enable when feature flag is on by default
// https://github.com/elastic/kibana/issues/239796
describe.skip('Knowledge Base', () => {
const knowledgeBasePkgName = 'knowledge_base_test';
const knowledgeBasePkgVersion = '1.0.0';

afterEach(async () => {
// Clean up knowledge base content after each test to avoid conflicts
await cleanupKnowledgeBase(knowledgeBasePkgName);
// Uninstall the knowledge base test package
try {
await uninstallPackage(knowledgeBasePkgName, knowledgeBasePkgVersion);
} catch (error) {
// Ignore errors if package is not installed
}
});

it('returns knowledge base content for an installed package', async function () {
await installPackage(knowledgeBasePkgName, knowledgeBasePkgVersion);
// Since KB indexing is async, wait for it to be ready before trying to fetch
// This is due to the ML model needing to get deployed first which can take a bit
await waitForKnowledgeBaseContent(knowledgeBasePkgName);

const res = await supertest
.get(`/internal/fleet/epm/packages/${knowledgeBasePkgName}/knowledge_base`)
.set('kbn-xsrf', 'xxxx')
.set('elastic-api-version', '1')
.expect(200);

expect(res.body).to.have.property('package');
expect(res.body.package).to.have.property('name');
expect(res.body).to.have.property('items');
expect(res.body.package.name).to.equal(knowledgeBasePkgName);
expect(res.body.items).to.be.an('array');
expect(res.body.items).to.have.length(3); // overview, troubleshooting, configuration

// Verify the content structure
const overviewDoc = res.body.items.find((item: any) => item.fileName === 'overview.md');
const troubleshootingDoc = res.body.items.find(
(item: any) => item.fileName === 'troubleshooting.md'
);
const configurationDoc = res.body.items.find(
(item: any) => item.fileName === 'configuration.md'
);

expect(overviewDoc).to.not.be(undefined);
expect(troubleshootingDoc).to.not.be(undefined);
expect(configurationDoc).to.not.be(undefined);
expect(overviewDoc.content).to.contain('Knowledge Base Test Integration Overview');
expect(troubleshootingDoc.content).to.contain('Troubleshooting Guide');
expect(configurationDoc.content).to.contain('Configuration Guide');
});

it('returns 404 for knowledge base of non-existent package', async function () {
await supertest
.get(`/internal/fleet/epm/packages/nonexistent/knowledge_base`)
.set('kbn-xsrf', 'xxxx')
.set('elastic-api-version', '1')
.expect(404);
});

it('validates knowledge base content structure', async function () {
await installPackage(knowledgeBasePkgName, knowledgeBasePkgVersion);
// Since KB indexing is async, wait for it to be ready before trying to fetch
// This is due to the ML model needing to get deployed first which can take a bit
await waitForKnowledgeBaseContent(knowledgeBasePkgName);
const res = await supertest
.get(`/internal/fleet/epm/packages/${knowledgeBasePkgName}/knowledge_base`)
.set('kbn-xsrf', 'xxxx')
.set('elastic-api-version', '1')
.expect(200);

// Validate response structure matches schema
expect(res.body.package.name).to.be.a('string');
expect(res.body.items).to.be.an('array');

// Validate knowledge base content items structure
res.body.items.forEach((item: any) => {
expect(item).to.have.property('fileName');
expect(item).to.have.property('content');
expect(item).to.have.property('path');
expect(item).to.have.property('installed_at');
expect(item).to.have.property('version');
expect(item.fileName).to.be.a('string');
expect(item.content).to.be.a('string');
expect(item.path).to.be.a('string');
expect(item.installed_at).to.be.a('string');
expect(item.version).to.be.a('string');
});
});

it('includes knowledge base information in package info assets when fetching from the info endpoint', async function () {
await installPackage(knowledgeBasePkgName, knowledgeBasePkgVersion);
// Since KB indexing is async, wait for knowledge base items to be ready in package info
// This is due to the ML model needing to get deployed first which can take a bit
await waitForKnowledgeBaseInPackageInfo(knowledgeBasePkgName, knowledgeBasePkgVersion);
const res = await supertest
.get(`/api/fleet/epm/packages/${knowledgeBasePkgName}/${knowledgeBasePkgVersion}`)
.expect(200);

const packageInfo = res.body.item;

// Check that the installed_es field contains knowledge_base items
expect(packageInfo.installationInfo).to.have.property('installed_es');
expect(packageInfo.installationInfo.installed_es).to.be.an('array');

const knowledgeBaseItems = packageInfo.installationInfo.installed_es.filter(
(item: any) => item.type === 'knowledge_base'
);

// Should have knowledge base items indexed
// Note: ALL .md files from docs/ folder are indexed (including CHANGELOG.md, INSTALL.md, etc.)
expect(knowledgeBaseItems.length).to.be.greaterThan(0);
// Expect: README, CHANGELOG, INSTALL, overview, troubleshooting, configuration
expect(knowledgeBaseItems.length).to.equal(6);

// Verify knowledge base items have correct structure with packageName-fileName format
// IDs follow the format: packageName-fileName (e.g., "knowledge_base_test-overview.md")

// Verify all items have the correct type and structure
knowledgeBaseItems.forEach((item: any) => {
expect(item).to.have.property('id');
expect(item).to.have.property('type');
expect(item.type).to.equal('knowledge_base');
expect(item.id).to.be.a('string');
expect(item.id).to.not.be.empty(); // ID should be a non-empty string
// Verify ID follows packageName-fileName format
expect(item.id).to.match(/^knowledge_base_test-.+\.md$/);
});

// Verify that expected core documentation files are present
const expectedCoreDocumentIds = [
'knowledge_base_test-README.md',
'knowledge_base_test-CHANGELOG.md',
'knowledge_base_test-INSTALL.md',
'knowledge_base_test-overview.md',
'knowledge_base_test-troubleshooting.md',
'knowledge_base_test-configuration.md',
];

const actualDocumentIds = knowledgeBaseItems.map((item: any) => item.id);

// Check that all expected core docs are present
expectedCoreDocumentIds.forEach((expectedId: string) => {
expect(actualDocumentIds.includes(expectedId)).to.equal(true);
});
});
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) {
loadTestFile(require.resolve('./data_views'));
loadTestFile(require.resolve('./custom_integrations'));
loadTestFile(require.resolve('./rollback'));
loadTestFile(require.resolve('./knowledge_base'));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default function (providerContext: FtrProviderContext) {
.type('application/zip')
.send(buf)
.expect(200);
expect(res.body.items.length).to.be(33);
expect(res.body.items.length).to.be.greaterThan(32);
expect(res.body.items.some((item: any) => item.id.includes(testPkgNewVersion)));

await deletePackage(testPkgName, testPkgNewVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export default function (providerContext: FtrProviderContext) {
const supertest = getService('supertest');
const es: Client = getService('es');
const fleetAndAgents = getService('fleetAndAgents');
const retry = getService('retry');
const pkgName = 'all_assets';
const pkgVersion = '0.1.0';
const logsTemplateName = `logs-${pkgName}.test_logs`;
Expand All @@ -48,8 +47,7 @@ export default function (providerContext: FtrProviderContext) {
describe('installs and uninstalls all assets', () => {
skipIfNoDockerRegistry(providerContext);

// FLAKY: https://github.com/elastic/kibana/issues/246272
describe.skip('installs all assets when installing a package for the first time', () => {
describe('installs all assets when installing a package for the first time', () => {
before(async () => {
await fleetAndAgents.setup();
if (!isDockerRegistryEnabledOrSkipped(providerContext)) return;
Expand All @@ -66,7 +64,6 @@ export default function (providerContext: FtrProviderContext) {
pkgName,
es,
kibanaServer,
retry,
});
});

Expand Down Expand Up @@ -381,7 +378,6 @@ export default function (providerContext: FtrProviderContext) {
pkgName,
es,
kibanaServer,
retry,
});
});
});
Expand All @@ -394,15 +390,13 @@ const expectAssetsInstalled = ({
pkgName,
es,
kibanaServer,
retry,
}: {
logsTemplateName: string;
metricsTemplateName: string;
pkgVersion: string;
pkgName: string;
es: Client;
kibanaServer: any;
retry: any;
}) => {
it('should have installed the ILM policy', async function () {
const resPolicy = await es.transport.request(
Expand Down Expand Up @@ -746,10 +740,6 @@ const expectAssetsInstalled = ({
id: 'metrics-all_assets.test_metrics-0.1.0',
type: 'ingest_pipeline',
},
{
id: 'all_assets-README.md',
type: 'knowledge_base',
},
{
id: 'default',
type: 'ml_model',
Expand Down Expand Up @@ -929,12 +919,17 @@ const expectAssetsInstalled = ({
verification_key_id: null,
};

expect(sortedRes).eql(expectedSavedObject);
expectedSavedObject.installed_es.forEach((item) => {
expect(
sortedRes.installed_es.find(
(asset: any) => asset.type === item.type && asset.id === item.id
)
).to.not.be(undefined);
});
expect({ ...sortedRes, installed_es: [] }).eql({ ...expectedSavedObject, installed_es: [] });
}

await retry.tryForTime(10000, async () => {
await verifySO();
});
await verifySO();
});

// TODO enable when feature flag is turned on https://github.com/elastic/kibana/issues/244655
Expand Down
Loading
Loading