Merge remote-tracking branch 'origin/master' appcode/163.5074 clion/163.5075
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Fri, 23 Sep 2016 14:54:41 +0000 (17:54 +0300)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Fri, 23 Sep 2016 14:54:41 +0000 (17:54 +0300)
14 files changed:
.idea/modules.xml
update-server-mock/.editorconfig [new file with mode: 0644]
update-server-mock/.gitignore [new file with mode: 0644]
update-server-mock/build.gradle [new file with mode: 0644]
update-server-mock/lib/log4j-api-2.6.2.jar [new file with mode: 0644]
update-server-mock/lib/log4j-core-2.6.2.jar [new file with mode: 0644]
update-server-mock/log4j.xml [new file with mode: 0644]
update-server-mock/settings.gradle [new file with mode: 0644]
update-server-mock/src/main/java/com/intellij/updater/mock/Generator.kt [new file with mode: 0644]
update-server-mock/src/main/java/com/intellij/updater/mock/Server.kt [new file with mode: 0644]
update-server-mock/src/main/java/com/intellij/updater/mock/main.kt [new file with mode: 0644]
update-server-mock/src/main/resources/patch/patch.jar [new file with mode: 0644]
update-server-mock/src/test/java/com/intellij/updater/mock/GeneratorTest.kt [new file with mode: 0644]
update-server-mock/update-server-mock.iml [new file with mode: 0644]

index 5fbe4581a9198ddb871a08a140f22a02fb4a6c86..b724cbc1c2856d1dc7df395a2a91cb21bc466756 100644 (file)
       <module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" group="plugins" />
       <module fileurl="file://$PROJECT_DIR$/plugins/ui-designer-core/ui-designer-core.iml" filepath="$PROJECT_DIR$/plugins/ui-designer-core/ui-designer-core.iml" group="plugins" />
       <module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml" group="plugins" />
+      <module fileurl="file://$PROJECT_DIR$/update-server-mock/update-server-mock.iml" filepath="$PROJECT_DIR$/update-server-mock/update-server-mock.iml" group="platform" />
       <module fileurl="file://$PROJECT_DIR$/updater/updater.iml" filepath="$PROJECT_DIR$/updater/updater.iml" group="platform" />
       <module fileurl="file://$PROJECT_DIR$/platform/usageView/usageView.iml" filepath="$PROJECT_DIR$/platform/usageView/usageView.iml" group="platform" />
       <module fileurl="file://$PROJECT_DIR$/platform/util/util.iml" filepath="$PROJECT_DIR$/platform/util/util.iml" group="platform" />
diff --git a/update-server-mock/.editorconfig b/update-server-mock/.editorconfig
new file mode 100644 (file)
index 0000000..e3207ea
--- /dev/null
@@ -0,0 +1,5 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/update-server-mock/.gitignore b/update-server-mock/.gitignore
new file mode 100644 (file)
index 0000000..0c426e5
--- /dev/null
@@ -0,0 +1,3 @@
+/.gradle/
+/build/
+/.idea/
\ No newline at end of file
diff --git a/update-server-mock/build.gradle b/update-server-mock/build.gradle
new file mode 100644 (file)
index 0000000..692861f
--- /dev/null
@@ -0,0 +1,26 @@
+buildscript {
+  repositories { jcenter() }
+  dependencies {
+    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:+"
+  }
+}
+
+apply plugin: 'kotlin'
+
+repositories { jcenter() }
+dependencies {
+  compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.+"
+  compile "org.apache.logging.log4j:log4j-api:2.+"
+  runtime "org.apache.logging.log4j:log4j-core:2.+"
+  testCompile "junit:junit:4.+"
+  testCompile "org.assertj:assertj-core:3.+"
+}
+
+jar {
+  manifest {
+    attributes "Main-Class" : "com.intellij.updater.mock.MainKt"
+  }
+  from {
+    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
+  }
+}
\ No newline at end of file
diff --git a/update-server-mock/lib/log4j-api-2.6.2.jar b/update-server-mock/lib/log4j-api-2.6.2.jar
new file mode 100644 (file)
index 0000000..a40cc56
Binary files /dev/null and b/update-server-mock/lib/log4j-api-2.6.2.jar differ
diff --git a/update-server-mock/lib/log4j-core-2.6.2.jar b/update-server-mock/lib/log4j-core-2.6.2.jar
new file mode 100644 (file)
index 0000000..388918f
Binary files /dev/null and b/update-server-mock/lib/log4j-core-2.6.2.jar differ
diff --git a/update-server-mock/log4j.xml b/update-server-mock/log4j.xml
new file mode 100644 (file)
index 0000000..2e4483a
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/>
+    </Console>
+  </Appenders>
+
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
\ No newline at end of file
diff --git a/update-server-mock/settings.gradle b/update-server-mock/settings.gradle
new file mode 100644 (file)
index 0000000..2bb2145
--- /dev/null
@@ -0,0 +1 @@
+rootProject.name = 'update-server-mock'
\ No newline at end of file
diff --git a/update-server-mock/src/main/java/com/intellij/updater/mock/Generator.kt b/update-server-mock/src/main/java/com/intellij/updater/mock/Generator.kt
new file mode 100644 (file)
index 0000000..c019c18
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 JetBrains s.r.o.
+ *
+ * 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.
+ */
+package com.intellij.updater.mock
+
+class Generator {
+  private val patch = this.javaClass.classLoader.getResourceAsStream("patch/patch.jar").use { it.readBytes() }
+
+  fun generateXml(productCode: String, buildId: String, eap: Boolean): String {
+    val status = if (eap) "eap" else "release"
+    return """
+      <!DOCTYPE products SYSTEM "updates.dtd">
+      <products>
+        <product name="Mock Product">
+          <code>$productCode</code>
+          <channel id="MOCK" status="$status" licensing="$status">
+            <build number="9999.0.0" version="Mock">
+              <message><![CDATA[A mock update. For testing purposes only.]]></message>
+              <button name="Download" url="https://www.jetbrains.com/" download="true"/>
+              <patch from="$buildId" size="from 0 to ∞"/>
+            </build>
+          </channel>
+        </product>
+      </products>""".trimIndent()
+  }
+
+  fun generatePatch(): ByteArray = patch
+}
\ No newline at end of file
diff --git a/update-server-mock/src/main/java/com/intellij/updater/mock/Server.kt b/update-server-mock/src/main/java/com/intellij/updater/mock/Server.kt
new file mode 100644 (file)
index 0000000..d2b0c1c
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 JetBrains s.r.o.
+ *
+ * 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.
+ */
+package com.intellij.updater.mock
+
+import com.sun.net.httpserver.HttpServer
+import org.apache.logging.log4j.LogManager
+import java.net.HttpURLConnection.*
+import java.net.InetSocketAddress
+import java.net.URI
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+
+class Server(private val port: Int, private val generator: Generator) {
+  private val server = HttpServer.create()
+  private val log = LogManager.getLogger(Server::class.java)
+  private val buildFormat = "([A-Z]+)-([0-9.]+)".toRegex()
+  private val tsFormat = DateTimeFormatter.ofPattern("dd/MMM/yyyy:kk:mm:ss ZZ")
+
+  fun start() {
+    server.bind(InetSocketAddress("localhost", port), 0)
+
+    server.createContext("/") { ex ->
+      val response = try {
+        process(ex.requestMethod, ex.requestURI)
+      }
+      catch(e: Exception) {
+        log.error(e)
+        Response(HTTP_INTERNAL_ERROR, "Internal error")
+      }
+
+      try {
+        val contentType = if (response.type.startsWith("text/")) "${response.type}; charset=utf-8" else response.type
+        ex.responseHeaders.add("Content-Type", contentType)
+        ex.sendResponseHeaders(response.code, response.bytes.size.toLong())
+        ex.responseBody.write(response.bytes)
+        ex.close()
+
+        log.info("${ex.remoteAddress.address.hostAddress} - - [${tsFormat.format(ZonedDateTime.now())}]" +
+          " \"${ex.requestMethod} ${ex.requestURI}\" ${ex.responseCode} ${response.bytes.size}")
+      }
+      catch(e: Exception) {
+        log.error(e)
+      }
+    }
+
+    server.start()
+  }
+
+  private fun process(method: String, uri: URI): Response {
+    val path = uri.path
+    return when {
+      method != "GET" -> Response(HTTP_BAD_REQUEST, "Didn't get")
+      path == "/" -> Response(HTTP_OK, "Mock Update Server")
+      path == "/updates/updates.xml" -> xml(uri.query ?: "")
+      path.startsWith("/patches/") -> patch(path)
+      else -> Response(HTTP_NOT_FOUND, "Miss")
+    }
+  }
+
+  private fun xml(query: String): Response {
+    val parameters = query.splitToSequence('&')
+      .filter { it.startsWith("build") || it.startsWith("eap") }
+      .map { it.split('=', limit = 2) }
+      .map { it[0] to if (it.size > 1) it[1] else "" }
+      .toMap()
+
+    val build = parameters["build"]
+    if (build != null) {
+      val match = buildFormat.find(build)
+      val productCode = match?.groups?.get(1)?.value
+      val buildId = match?.groups?.get(2)?.value
+      if (productCode != null && buildId != null) {
+        val xml = generator.generateXml(productCode, buildId, "eap" in parameters)
+        return Response(HTTP_OK, "text/xml", xml.toByteArray())
+      }
+    }
+
+    return Response(HTTP_BAD_REQUEST, "Bad parameters")
+  }
+
+  private fun patch(path: String): Response = when {
+    path.endsWith(".jar") -> Response(HTTP_OK, "binary/octet-stream", generator.generatePatch())
+    else -> Response(HTTP_BAD_REQUEST, "Bad path")
+  }
+
+  private class Response(val code: Int, val type: String, val bytes: ByteArray) {
+    constructor(code: Int, text: String) : this(code, "text/plain", text.toByteArray())
+  }
+}
\ No newline at end of file
diff --git a/update-server-mock/src/main/java/com/intellij/updater/mock/main.kt b/update-server-mock/src/main/java/com/intellij/updater/mock/main.kt
new file mode 100644 (file)
index 0000000..a2cc499
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 JetBrains s.r.o.
+ *
+ * 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.
+ */
+package com.intellij.updater.mock
+
+import org.apache.logging.log4j.LogManager
+
+fun main(args: Array<String>) {
+  if (args.size != 1) {
+    println("usage: java -jar update-server-mock.jar <port>")
+    System.exit(1)
+  }
+
+  val log = LogManager.getLogger(Server::class.java)
+  val port = args[0]
+  try {
+    log.info("starting the server on port '$port' ...")
+    val generator = Generator()
+    Server(port.toInt(), generator).start()
+    log.info("ready")
+  }
+  catch(e: Exception) {
+    log.error("failed to start the server", e)
+    System.exit(2)
+  }
+}
\ No newline at end of file
diff --git a/update-server-mock/src/main/resources/patch/patch.jar b/update-server-mock/src/main/resources/patch/patch.jar
new file mode 100644 (file)
index 0000000..24f84df
Binary files /dev/null and b/update-server-mock/src/main/resources/patch/patch.jar differ
diff --git a/update-server-mock/src/test/java/com/intellij/updater/mock/GeneratorTest.kt b/update-server-mock/src/test/java/com/intellij/updater/mock/GeneratorTest.kt
new file mode 100644 (file)
index 0000000..9446d18
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 JetBrains s.r.o.
+ *
+ * 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.
+ */
+package com.intellij.updater.mock
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+
+class GeneratorTest {
+  @Test fun generateXml() {
+    val xml = Generator().generateXml("IC", "163.11.22", false)
+    assertThat(xml).contains("patch from=\"163.11.22\"").contains("status=\"release\"")
+  }
+
+  @Test fun generatePatch() {
+    val patch = Generator().generatePatch()
+    assertThat(patch).isNotEmpty()
+  }
+}
\ No newline at end of file
diff --git a/update-server-mock/update-server-mock.iml b/update-server-mock/update-server-mock.iml
new file mode 100644 (file)
index 0000000..2428286
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="KotlinJavaRuntime" level="project" />
+    <orderEntry type="module-library">
+      <library name="log4j-api">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/lib/log4j-api-2.6.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library" scope="RUNTIME">
+      <library name="log4j-core">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/lib/log4j-core-2.6.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
+    <orderEntry type="library" scope="TEST" name="assertJ" level="project" />
+  </component>
+</module>
\ No newline at end of file