DefaultDockerImageMigrationHandler implements DockerImageMigrationHandler { @Nonnull @Override public Node performMigration(@Nonnull Node imageData) { DockerCloudUtils.requireNonNull(imageData, "Image data cannot be null."); try (Reader reader = new BufferedReader(new InputStreamReader(migrationScript.openStream(), StandardCharsets.UTF_8))) { ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName(JS_ENGINE); Invocable invocable = (Invocable) engine; Object modules = engine.eval("var module = {}; module;"); engine.eval(reader); Object json = engine.eval("JSON"); Object imagesData = invocable.invokeMethod(json, "parse", imageData.toString()); invocable.invokeMethod(modules, "exports", imagesData); Object result = invocable.invokeMethod(json, "stringify", imagesData); return Node.parse(result.toString()); } catch (IOException | ScriptException | NoSuchMethodException e) { throw new IllegalArgumentException("Failed to migrate image data.", e); } } DefaultDockerImageMigrationHandler(@Nonnull URL migrationScript); @Nonnull @Override Node performMigration(@Nonnull Node imageData);  }
@Test public void noopMigrationScript() { URL url = TestURLBuilder.forContent(noopScript()).build(); DefaultDockerImageMigrationHandler migrationHandler = new DefaultDockerImageMigrationHandler(url); Node result = migrationHandler.performMigration(TEST_NODE); assertThat(result).isEqualTo(TEST_NODE); }
@Test public void effectiveMigration() { URL url = TestURLBuilder.forContent(script("input.foo = 'baz';")).build(); DefaultDockerImageMigrationHandler migrationHandler = new DefaultDockerImageMigrationHandler(url); Node result = migrationHandler.performMigration(TEST_NODE); assertThat(result).isEqualTo(TEST_NODE.editNode().put("foo", "baz")); }
@Test public void globalStateMustBeCleared() { URL url = TestURLBuilder.forContent("var globalVar = 0;" + script("input.cpt = globalVar; globalVar++;")).build(); DefaultDockerImageMigrationHandler migrationHandler = new DefaultDockerImageMigrationHandler(url); Node result = migrationHandler.performMigration(TEST_NODE); assertThat(result).isEqualTo(TEST_NODE.editNode().put("cpt", 0)); result = migrationHandler.performMigration(TEST_NODE); assertThat(result).isEqualTo(TEST_NODE.editNode().put("cpt", 0)); }
@Test public void mustHandleJSONEscapeCharacters() { URL url = TestURLBuilder.forContent(noopScript()).build(); DefaultDockerImageMigrationHandler migrationHandler = new DefaultDockerImageMigrationHandler(url); Node testNode = Node.EMPTY_OBJECT.editNode().put("foo", "{\"\':").saveNode(); Node result = migrationHandler.performMigration(testNode); assertThat(result).isEqualTo(testNode); }
@Test public void mustHandleMultiByteCharSequences() { URL url = TestURLBuilder.forContent(noopScript()).build(); DefaultDockerImageMigrationHandler migrationHandler = new DefaultDockerImageMigrationHandler(url); Node testNode = Node.EMPTY_OBJECT.editNode().put("foo", "😀").saveNode(); Node result = migrationHandler.performMigration(testNode); assertThat(result).isEqualTo(testNode); }
@Test public void invalidScriptMustThrowException() { URL url = TestURLBuilder.forContent(script("throw 'invalid script';")).build(); DefaultDockerImageMigrationHandler migrationHandler = new DefaultDockerImageMigrationHandler(url); assertThatExceptionOfType(IllegalArgumentException.class). isThrownBy(() -> migrationHandler.performMigration(TEST_NODE)); }