blob: e473070b97decb3ab1130403d720b41f14ed5400 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.openwhisk.core.entity.test
import org.junit.runner.RunWith
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalatest.junit.JUnitRunner
import org.apache.openwhisk.core.entity.EntityPath
import org.apache.openwhisk.core.entity.EntityName
import org.apache.openwhisk.core.entity.WhiskAction
import org.apache.openwhisk.core.entity.DocRevision
import org.apache.openwhisk.core.entity.Parameters
import org.apache.openwhisk.core.entity.FullyQualifiedEntityName
import org.apache.openwhisk.core.entity.SequenceExec
import org.apache.openwhisk.core.entity.WhiskPackage
import org.apache.openwhisk.core.entity.WhiskActivation
import org.apache.openwhisk.core.entity.Subject
import org.apache.openwhisk.core.entity.ActivationId
import org.apache.openwhisk.core.entity.WhiskDocumentReader
import java.time.Instant
import spray.json._
import org.apache.openwhisk.core.entity.ActivationLogs
import org.apache.openwhisk.core.entity.WhiskTrigger
import org.apache.openwhisk.core.entity.ReducedRule
import org.apache.openwhisk.core.entity.Status
import org.apache.openwhisk.core.entity.WhiskEntity
import org.apache.openwhisk.core.entity.WhiskRule
import org.apache.openwhisk.core.database.DocumentTypeMismatchException
@RunWith(classOf[JUnitRunner])
class WhiskEntityTests extends FlatSpec with ExecHelpers with Matchers {
val namespace = EntityPath("testspace")
val name = EntityName("testname")
val revision = DocRevision("test")
behavior of "WhiskAction"
it should "correctly inherit parameters and preserve revision through the process" in {
def withParameters(p: Parameters) =
WhiskAction(namespace, name, jsDefault("js1"), parameters = p).revision[WhiskAction](revision)
val toInherit = Parameters("testParam", "testValue")
Seq(Parameters(), Parameters("testParam2", "testValue"), Parameters("testParam", "testValue2")).foreach { params =>
val action = withParameters(params)
val inherited = action.inherit(toInherit)
inherited shouldBe action.copy(parameters = toInherit ++ action.parameters)
inherited.rev shouldBe action.rev
}
}
it should "correctly resolve default namespace and preserve its revision through the process" in {
val user = "testuser"
val sequenceAction = FullyQualifiedEntityName(EntityPath("_"), EntityName("testaction"))
val action = WhiskAction(namespace, name, sequence(Vector(sequenceAction))).revision[WhiskAction](revision)
val resolved = action.resolve(EntityName(user))
resolved.exec.asInstanceOf[SequenceExec].components.head shouldBe sequenceAction.copy(path = EntityPath(user))
action.rev shouldBe resolved.rev
}
behavior of "WhiskPackage"
it should "correctly inherit parameters and preserve revision through the process" in {
def withParameters(p: Parameters) = WhiskPackage(namespace, name, parameters = p).revision[WhiskPackage](revision)
val toInherit = Parameters("testParam", "testValue")
Seq(Parameters(), Parameters("testParam2", "testValue"), Parameters("testParam", "testValue2")).foreach { params =>
val pkg = withParameters(params)
val inherited = pkg.inherit(toInherit)
inherited shouldBe pkg.copy(parameters = toInherit ++ pkg.parameters)
inherited.rev shouldBe pkg.rev
}
}
it should "correctly merge parameters and preserve revision through the process" in {
def withParameters(p: Parameters) = WhiskPackage(namespace, name, parameters = p).revision[WhiskPackage](revision)
val toOverride = Parameters("testParam", "testValue")
Seq(Parameters(), Parameters("testParam2", "testValue"), Parameters("testParam", "testValue2")).foreach { params =>
val pkg = withParameters(params)
val inherited = pkg.mergeParameters(toOverride)
inherited shouldBe pkg.copy(parameters = pkg.parameters ++ toOverride)
inherited.rev shouldBe pkg.rev
}
}
behavior of "WhiskActivation"
it should "add and remove logs and preserve revision in the process" in {
val activation = WhiskActivation(namespace, name, Subject(), ActivationId.generate(), Instant.now(), Instant.now())
.revision[WhiskActivation](revision)
val logs = ActivationLogs(Vector("testlog"))
val withLogs = activation.withLogs(logs)
withLogs shouldBe activation.copy(logs = logs)
withLogs.rev shouldBe activation.rev
val withoutLogs = withLogs.withoutLogs
withoutLogs shouldBe activation
withoutLogs.rev shouldBe activation.rev
}
behavior of "WhiskTrigger"
it should "add and remove rules and preserve revision in the process" in {
val fqn = FullyQualifiedEntityName(namespace, name)
val trigger = WhiskTrigger(namespace, name).revision[WhiskTrigger](revision)
val rule = ReducedRule(fqn, Status.ACTIVE)
// Add a rule
val ruleAdded = trigger.addRule(fqn, rule)
ruleAdded.rules shouldBe Some(Map(fqn -> rule))
ruleAdded.rev shouldBe trigger.rev
// Remove the rule
val ruleRemoved = ruleAdded.removeRule(fqn)
ruleRemoved.rules shouldBe Some(Map.empty[FullyQualifiedEntityName, ReducedRule])
ruleRemoved.rev shouldBe trigger.rev
// Remove all rules
val rulesRemoved = ruleAdded.withoutRules
rulesRemoved.rules shouldBe None
rulesRemoved.rev shouldBe trigger.rev
}
behavior of "WhiskEntity"
it should "define the entityType property in its json representation" in {
val action = WhiskAction(namespace, name, jsDefault("code"), Parameters())
assertType(action, "action")
val activation = WhiskActivation(namespace, name, Subject(), ActivationId.generate(), Instant.now(), Instant.now())
assertType(activation, "activation")
val whiskPackage = WhiskPackage(namespace, name)
assertType(whiskPackage, "package")
val rule =
WhiskRule(namespace, name, FullyQualifiedEntityName(namespace, name), FullyQualifiedEntityName(namespace, name))
assertType(rule, "rule")
val trigger = WhiskTrigger(namespace, name)
assertType(trigger, "trigger")
}
behavior of "WhiskDocumentReader"
it should "check entityType when deserialize" in {
def assertType(d: WhiskEntity, entityType: String) = {
d.toDocumentRecord.fields("entityType") shouldBe JsString(entityType)
}
val json =
"""{
| "name": "action_test",
| "publish": false,
| "annotations": [],
| "version": "0.0.2",
| "entityType": "action",
| "exec": {
| "kind": "nodejs:10",
| "code": "foo",
| "binary": false
| },
| "parameters": [],
| "limits": {
| "timeout": 60000,
| "memory": 256
| },
| "namespace": "namespace"
|}""".stripMargin.parseJson
val action = WhiskDocumentReader.read(manifest[WhiskAction], json)
assertType(action.asInstanceOf[WhiskEntity], "action")
assertThrows[DocumentTypeMismatchException] {
WhiskDocumentReader.read(manifest[WhiskTrigger], json)
}
}
it should "deserialize without entityType" in {
val json =
"""{
| "name": "action_test",
| "publish": false,
| "annotations": [],
| "version": "0.0.1",
| "exec": {
| "kind": "nodejs:10",
| "code": "foo",
| "binary": false
| },
| "parameters": [],
| "limits": {
| "timeout": 60000,
| "memory": 256
| },
| "namespace": "namespace"
|}""".stripMargin.parseJson
val action = WhiskDocumentReader.read(manifest[WhiskAction], json)
assertType(action.asInstanceOf[WhiskEntity], "action")
}
protected def assertType(d: WhiskEntity, entityType: String) = {
d.toDocumentRecord.fields("entityType") shouldBe JsString(entityType)
}
}