blob: d759c902ea4e15650e442d53df39ffb244908364 [file] [log] [blame]
/**
*
* Copyright (c) 2020 Silicon Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* @jest-environment node
*/
// This file tests the spec check feature
const path = require('path')
const importJs = require('../src-electron/importexport/import')
const dbApi = require('../src-electron/db/db-api')
const env = require('../src-electron/util/env')
const zclLoader = require('../src-electron/zcl/zcl-loader')
const generationEngine = require('../src-electron/generator/generation-engine')
const queryEndpointType = require('../src-electron/db/query-endpoint-type')
const queryEndpoint = require('../src-electron/db/query-endpoint')
const testUtil = require('./test-util')
const testQuery = require('./test-query')
const util = require('../src-electron/util/util')
const queryConfig = require('../src-electron/db/query-config')
const queryZcl = require('../src-electron/db/query-zcl')
const queryPackage = require('../src-electron/db/query-package')
const restApi = require('../src-shared/rest-api.js')
let db
let specCheckAllClustersApp = path.join(
__dirname,
'resource/spec-check-all-clusters-app-matter.zap'
)
let templateContext
let templatePkgId
beforeAll(() => {
env.setDevelopmentEnv()
let file = env.sqliteTestFile('specCheck')
return dbApi
.initDatabaseAndLoadSchema(file, env.schemaFile(), env.zapVersion())
.then((d) => {
db = d
env.logInfo(`Test database initialized: ${file}.`)
})
.then(() => zclLoader.loadZcl(db, env.builtinMatterZclMetafile()))
.catch((err) => env.logError(`Error: ${err}`))
}, testUtil.timeout.medium())
afterAll(() => dbApi.closeDatabase(db), testUtil.timeout.short())
test(
'Basic gen template parsing and generation for matter templates',
async () => {
let context = await generationEngine.loadTemplates(
db,
testUtil.testTemplate.matter3
)
templatePkgId = context.packageId
expect(context.crc).not.toBeNull()
expect(context.templateData).not.toBeNull()
templateContext = context
},
testUtil.timeout.short()
)
test(
'Check for Device Type check failures in the zap file through the session notification table',
async () => {
await util.ensurePackagesAndPopulateSessionOptions(
templateContext.db,
templateContext.sessionId,
{
zcl: env.builtinMatterZclMetafile(),
template: env.builtinTemplateMetafile()
},
null,
[templatePkgId]
)
let importResult = await importJs.importDataFromFile(
db,
specCheckAllClustersApp
)
let sid = importResult.sessionId
let sessionNotifications = await testQuery.getAllSessionNotifications(
db,
sid
)
let sessionNotificationMessages = sessionNotifications.map(
(sn) => sn.message
)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor server needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor server needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: PartsList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
let endpointTypes = await queryEndpointType.selectAllEndpointTypes(db, sid)
let endpoint0 = endpointTypes.find(
(ep) => ep.name === 'MA-rootdevice' && ep.deviceIdentifier.length === 2
)
let endpoint1 = endpointTypes.find(
(ep) => ep.name === 'MA-onofflight' && ep.deviceIdentifier.length === 2
)
let allClusters = await testQuery.getAllSessionClusters(db, sid)
let descriptorCluster = allClusters.find((c) => c.code === 0x001d) // Finding the descriptor cluster by code
let identifyCluster = allClusters.find((c) => c.code === 0x0003) // Finding the identify cluster by code
let onOffCluster = allClusters.find((c) => c.code === 0x0006) // Find the on/off cluster by code
// Negative test: Adding on/off cluster to endpoint 0 and then disabling it.
// Note that on/off cluster is not a required cluster based on the device types
// enabled on endpoint 0 so there should be no additional session warnings when
// enabling or disabling the on/off cluster.
let sessionNotificationCountBeforeOnOffEnabled = sessionNotifications.length
// Enable on off server cluster
await queryConfig.insertOrReplaceClusterState(
db,
endpoint0.endpointTypeId,
onOffCluster.id,
'SERVER',
true
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
let sessionNotificationCountAfterOnOffEnabled = sessionNotifications.length
expect(sessionNotificationCountBeforeOnOffEnabled).toEqual(
sessionNotificationCountAfterOnOffEnabled
)
// Disable on off server cluster
await queryConfig.insertOrReplaceClusterState(
db,
endpoint0.endpointTypeId,
onOffCluster.id,
'SERVER',
false
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
let sessionNotificationCountAfterOnOffDisabled = sessionNotifications.length
expect(sessionNotificationCountBeforeOnOffEnabled).toEqual(
sessionNotificationCountAfterOnOffDisabled
)
// Insert the descriptor cluster and check for session notice warnings again
await queryConfig.insertOrReplaceClusterState(
db,
endpoint0.endpointTypeId,
descriptorCluster.id,
'SERVER',
true
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor server needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor server needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
// Get Descriptor cluster attributes and enable them. Check for warnings in the session notice table after
let sessionPackages = await queryPackage.getSessionPackages(db, sid)
let sessionPackageIds = sessionPackages.map((sp) => sp.packageRef)
let descriptorClusterAttributes =
await queryZcl.selectAttributesByClusterIdAndSideIncludingGlobal(
db,
descriptorCluster.id,
sessionPackageIds,
'server'
)
let serviceListAttribute = descriptorClusterAttributes.find(
(dca) => dca.name === 'ServerList'
)
let clientListAttribute = descriptorClusterAttributes.find(
(dca) => dca.name === 'ClientList'
)
let identifyClusterAttributes =
await queryZcl.selectAttributesByClusterIdAndSideIncludingGlobal(
db,
identifyCluster.id,
sessionPackageIds,
'server'
)
let identifyTimeAttribute = identifyClusterAttributes.find(
(ica) => ica.name === 'IdentifyTime'
)
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint0.endpointTypeId,
serviceListAttribute.clusterRef,
'server',
serviceListAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 1
}
],
null,
null,
null
)
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint0.endpointTypeId,
clientListAttribute.clusterRef,
'server',
clientListAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 1
}
],
null,
null,
null
)
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint1.endpointTypeId,
identifyTimeAttribute.clusterRef,
'server',
identifyTimeAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 1
}
],
null,
null,
null
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
)
).toBeFalsy()
// Disabling a cluster and attribute to check if the notification messages come back up
await queryConfig.insertOrReplaceClusterState(
db,
endpoint0.endpointTypeId,
descriptorCluster.id,
'server',
false
)
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint0.endpointTypeId,
clientListAttribute.clusterRef,
'server',
clientListAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 0
}
],
null,
null,
null
)
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint1.endpointTypeId,
identifyTimeAttribute.clusterRef,
'server',
identifyTimeAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 0
}
],
null,
null,
null
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Descriptor server needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 1, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
// Testing the compliance warnings for optional clusters of the device type.
// When attribute of an enabled optional cluster to a device type is disabled then throw a warning
let localConfigCluster = allClusters.find((c) => c.code === 0x002b) // Find the Localization Configuration cluster by code
let localConfigClusterAttributes =
await queryZcl.selectAttributesByClusterIdAndSideIncludingGlobal(
db,
localConfigCluster.id,
sessionPackageIds,
'server'
)
let activeLocaleAttribute = localConfigClusterAttributes.find(
(ica) => ica.name === 'ActiveLocale'
)
// Disable active Local attribute of an optional cluster to a device type
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint0.endpointTypeId,
activeLocaleAttribute.clusterRef,
'server',
activeLocaleAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 0
}
],
null,
null,
null
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
)
).toBeTruthy()
// Enable active Local attribute of an optional cluster to a device type
await queryConfig.insertOrUpdateAttributeState(
db,
endpoint0.endpointTypeId,
activeLocaleAttribute.clusterRef,
'server',
activeLocaleAttribute.id,
[
{
key: restApi.updateKey.attributeSelected,
value: 1
}
],
null,
null,
null
)
sessionNotifications = await testQuery.getAllSessionNotifications(db, sid)
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
)
).toBeFalsy()
// Disable the optional cluster to a device type and none of the optional cluster or its attribute warnings should show up.
await queryConfig.insertOrReplaceClusterState(
db,
endpoint0.endpointTypeId,
localConfigCluster.id,
'SERVER',
false
)
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration server needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
'⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
)
).toBeFalsy()
// Before deleting endpoints, notifications on endpoints should exist
expect(
sessionNotificationMessages.some((element) =>
element.includes('on endpoint: 0')
)
).toBeTruthy()
expect(
sessionNotificationMessages.some((element) =>
element.includes('on endpoint: 1')
)
).toBeTruthy()
// insert and then delete endpoints to test if DELETE trigger removes related notifications
endpoint0.eptId = await queryEndpoint.insertEndpoint(
db,
sid,
0,
endpoint0.endpointTypeId,
null,
null
)
endpoint1.eptId = await queryEndpoint.insertEndpoint(
db,
sid,
1,
endpoint1.endpointTypeId,
null,
null
)
await queryEndpoint.deleteEndpoint(db, endpoint0.eptId)
await queryEndpoint.deleteEndpoint(db, endpoint1.eptId)
sessionNotificationMessages = await testQuery.getAllNotificationMessages(
db,
sid
)
// after deleting endpoints, notifications on endpoints should be removed
expect(
sessionNotificationMessages.some((element) =>
element.includes('on endpoint: 0')
)
).toBeFalsy()
expect(
sessionNotificationMessages.some((element) =>
element.includes('on endpoint: 1')
)
).toBeFalsy()
},
testUtil.timeout.medium()
)