This is an automated email from the ASF dual-hosted git repository. csantanapr pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git
commit 5397c81c13b47736ddaf88c955006e142c5523be Author: Rodric Rabbah <rab...@us.ibm.com> AuthorDate: Mon Mar 20 11:16:07 2017 -0400 Stricter namespace extraction for vanity web action url. Separate whisk api host into 3 parts: protocol, hostname, scheme. Use hostname for nginx server_name configuration. Use hostname for SSL certificate generation. Add test for vanity URL. Remove unnecessary nginx rules. --- .../whisk/core/cli/test/WskBasicUsageTests.scala | 2 +- .../whisk/core/cli/test/WskEntitlementTests.scala | 18 +---- .../whisk/core/cli/test/WskWebActionsTests.scala | 92 ++++++++++++++++++++-- 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala index 5fe9dbe..7ee62ff 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala @@ -510,7 +510,7 @@ class WskBasicUsageTests activation => activation.response.status shouldBe "success" val fields = activation.response.result.get.convertTo[Map[String, String]] - fields("api_host") shouldBe WhiskProperties.getApiHost + fields("api_host") shouldBe WhiskProperties.getApiHostForAction fields("api_key") shouldBe wskprops.authKey fields("namespace") shouldBe namespace fields("action_name") shouldBe s"/$namespace/$name" diff --git a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala index c7627bd..b0b1078 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala @@ -20,7 +20,6 @@ import org.junit.runner.RunWith import org.scalatest.BeforeAndAfterAll import org.scalatest.junit.JUnitRunner -import common.RunWskAdminCmd import common.TestHelpers import common.TestUtils import common.TestUtils.FORBIDDEN @@ -43,27 +42,12 @@ class WskEntitlementTests val wsk = new Wsk lazy val defaultWskProps = WskProps() - lazy val guestWskProps = getAdditionalTestSubject() + lazy val guestWskProps = getAdditionalTestSubject(Subject().asString) override def afterAll() = { disposeAdditionalTestSubject(guestWskProps.namespace) } - def getAdditionalTestSubject() = { - val wskadmin = new RunWskAdminCmd {} - val newSubject = Subject().toString - WskProps( - namespace = newSubject, - authKey = wskadmin.cli(Seq("user", "create", newSubject)).stdout.trim) - } - - def disposeAdditionalTestSubject(subject: String) = { - val wskadmin = new RunWskAdminCmd {} - withClue(s"failed to delete temporary subject $subject") { - wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted") - } - } - val samplePackage = "samplePackage" val sampleAction = "sampleAction" val fullSampleActionName = s"$samplePackage/$sampleAction" diff --git a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala index 9d12be8..547d8eb 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala @@ -18,13 +18,18 @@ package whisk.core.cli.test import java.nio.charset.StandardCharsets +import scala.util.Failure +import scala.util.Try + import org.junit.runner.RunWith +import org.scalatest.BeforeAndAfterAll import org.scalatest.junit.JUnitRunner import com.jayway.restassured.RestAssured import common.TestHelpers import common.TestUtils +import common.WhiskProperties import common.Wsk import common.WskAdmin import common.WskProps @@ -32,6 +37,10 @@ import common.WskTestHelpers import spray.json._ import spray.json.DefaultJsonProtocol._ import system.rest.RestUtil +import whisk.common.PrintStreamLogging +import whisk.common.SimpleExec +import whisk.common.TransactionId +import whisk.core.entity.Subject /** * Tests web actions. @@ -42,20 +51,89 @@ class WskWebActionsTestsV1 extends WskWebActionsTests { } @RunWith(classOf[JUnitRunner]) -class WskWebActionsTestsV2 extends WskWebActionsTests { +class WskWebActionsTestsV2 extends WskWebActionsTests with BeforeAndAfterAll { override val testRoutePath = "/api/v1/web" + + private val subdomainRegex = Seq.fill(WhiskProperties.getPartsInVanitySubdomain)("[a-zA-Z0-9]+").mkString("-") + + private val (vanitySubdomain, vanityNamespace, makeTestSubject) = { + if (namespace.matches(subdomainRegex)) { + (namespace, namespace, false) + } else { + val s = Subject().asString.toLowerCase // this will generate two confirming parts + (s, s.replace("-", "_"), true) + } + } + + private val wskPropsForSubdomainTest = if (makeTestSubject) { + getAdditionalTestSubject(vanityNamespace) // create new subject for the test + } else { + WskProps() + } + + override def afterAll() = { + if (makeTestSubject) { + disposeAdditionalTestSubject(vanityNamespace) + } + } + + "test subdomain" should "have conforming parts" in { + vanitySubdomain should fullyMatch regex subdomainRegex.r + vanitySubdomain.length should be <= 63 + } + + "vanity subdomain" should "access a web action via namespace subdomain" in withAssetCleaner(wskPropsForSubdomainTest) { + (wp, assetHelper) => + val actionName = "webaction" + + val file = Some(TestUtils.getTestActionFilename("echo.js")) + assetHelper.withCleaner(wsk.action, actionName) { + (action, _) => + action.create(actionName, file, web = Some(true.toString))(wp) + } + + val url = getServiceApiHost(vanitySubdomain, true) + s"/default/$actionName.text/a?a=A" + println(s"url: $url") + + // try the rest assured path first, failing that, try curl with explicit resolve + Try { + val response = RestAssured.given().config(sslconfig).get(url) + val responseCode = response.statusCode + responseCode shouldBe 200 + response.body.asString shouldBe "A" + } match { + case Failure(t) => + println(s"RestAssured path failed, trying curl: $t") + implicit val tid = TransactionId.testing + implicit val logger = new PrintStreamLogging(Console.out) + val host = getServiceApiHost(vanitySubdomain, false) + // if the edge host is a name, try to resolve it, otherwise, it should be an ip address already + val edgehost = WhiskProperties.getEdgeHost + val ip = Try(java.net.InetAddress.getByName(edgehost).getHostAddress) getOrElse "???" + println(s"edge: $edgehost, ip: $ip") + val cmd = Seq("curl", "-k", url, "--resolve", s"$host:$ip") + val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(cmd) + withClue(s"\n$stderr\n") { + stdout shouldBe "A" + exitCode shouldBe 0 + } + + case _ => + } + } } -abstract class WskWebActionsTests +trait WskWebActionsTests extends TestHelpers with WskTestHelpers with RestUtil { val MAX_URL_LENGTH = 8192 // 8K matching nginx default - implicit val wskprops = WskProps() val wsk = new Wsk + private implicit val wskprops = WskProps() val namespace = WskAdmin.getUser(wskprops.authKey)._2 + protected val testRoutePath: String behavior of "Wsk Web Actions" @@ -91,9 +169,9 @@ abstract class WskWebActionsTests withClue(s"response code: $responseCode, url length: ${url.length}, pad amount: ${pad.length}, url: $url") { responseCode shouldBe code if (code == 200) { - response.body().asString() shouldBe pad + response.body.asString shouldBe pad } else { - response.body().asString() should include("414 Request-URI Too Large") // from nginx + response.body.asString should include("414 Request-URI Too Large") // from nginx } } } @@ -129,7 +207,7 @@ abstract class WskWebActionsTests .get(url) authorizedResponse.statusCode shouldBe 200 - authorizedResponse.body().asString() shouldBe namespace + authorizedResponse.body.asString shouldBe namespace } if (testRoutePath == "/api/v1/web") { @@ -194,6 +272,6 @@ abstract class WskWebActionsTests val url = host + s"$testRoutePath/$namespace/default/webaction.http" val response = RestAssured.given().header("accept", "application/json").config(sslconfig).get(url) response.statusCode shouldBe 406 - response.body().asString() should include("Resource representation is only available with these Content-Types:\\ntext/html") + response.body.asString should include("Resource representation is only available with these Content-Types:\\ntext/html") } } -- To stop receiving notification emails like this one, please contact "commits@openwhisk.apache.org" <commits@openwhisk.apache.org>.