{"action":"created","comment":{"url":"https://api.github.com/repos/DB1L/csc-bdse/pulls/comments/172028601","pull_request_review_id":100986728,"id":172028601,"diff_hunk":"@@ -16,53 +27,143 @@\n  *\n  * @author alesavin\n  */\n-public class KeyValueApiHttpClientTest2 {\n-\n-    @ClassRule\n-    public static final GenericContainer node = new GenericContainer(\n-            new ImageFromDockerfile()\n-                    .withFileFromFile(\"target/bdse-kvnode-0.0.1-SNAPSHOT.jar\", new File\n-                            (\"../bdse-kvnode/target/bdse-kvnode-0.0.1-SNAPSHOT.jar\"))\n-                    .withFileFromClasspath(\"Dockerfile\", \"kvnode/Dockerfile\"))\n-            .withEnv(Env.KVNODE_NAME, \"node-0\")\n-            .withExposedPorts(8080)\n-            .withStartupTimeout(Duration.of(30, SECONDS));\n+public class KeyValueApiHttpClientTest2 extends AbstractKeyValueApiTest {\n+    private static final int ATTEMPTS = 1000;\n+    private static final int THREADS = 20;\n+\n+    private static GenericContainer redis;\n+    private static GenericContainer node;\n+\n+    @BeforeClass\n+    public static void setUp() {\n+        final Network network = Network.newNetwork();\n+        redis = new GenericContainer(new RemoteDockerImage(\"redis\", \"latest\"))\n+                .withCommand(\"redis-server\", \"--appendonly\", \"yes\")\n+                .withExposedPorts(RedisKeyValueApiTest.REDIS_PORT)\n+                .withNetwork(network)\n+                .withNetworkAliases(\"redis\")\n+                .withStartupTimeout(Duration.of(30, SECONDS));\n+        redis.start();\n+        node = new GenericContainer(\n+                new ImageFromDockerfile()\n+                        .withFileFromFile(\"target/bdse-kvnode-0.0.1-SNAPSHOT.jar\", new File\n+                                (\"../bdse-kvnode/target/bdse-kvnode-0.0.1-SNAPSHOT.jar\"))\n+                        .withFileFromClasspath(\"Dockerfile\", \"kvnode/Dockerfile\"))\n+                .withEnv(Env.KVNODE_NAME, \"node-0\")\n+                .withEnv(Env.REDIS_HOSTNAME, \"redis\")\n+                .withEnv(Env.REDIS_PORT, String.valueOf(RedisKeyValueApiTest.REDIS_PORT))\n+                .withExposedPorts(8080)\n+                .withNetwork(network)\n+                .withLogConsumer(f -> System.out.print(((OutputFrame) f).getUtf8String()))\n+                .withStartupTimeout(Duration.of(30, SECONDS));\n+        node.start();\n+    }\n+\n+    @Before\n+    public void bringUp() {\n+        api.action(\"node-0\", NodeAction.UP);\n+    }\n+\n+    @AfterClass\n+    public static void tearDown() {\n+        node.stop();\n+        redis.stop();\n+    }\n \n     private KeyValueApi api = newKeyValueApi();\n \n-    private KeyValueApi newKeyValueApi() {\n+    protected KeyValueApi newKeyValueApi() {\n         final String baseUrl = \"http://localhost:\" + node.getMappedPort(8080);\n         return new KeyValueApiHttpClient(baseUrl);\n     }\n \n     @Test\n-    public void concurrentPuts() {\n-        // TODO simultanious puts for the same key value\n+    public void concurrentPuts() throws InterruptedException {\n+        final Thread[] threads = new Thread[THREADS];\n+        for (int i = 0; i < threads.length; ++i) {\n+            threads[i] = new Thread(() -> {\n+                for (int j = 0; j < ATTEMPTS; ++j) {\n+                    final byte[] value = String.valueOf(j).getBytes();\n+                    api.put(\"key\", value);\n+                }\n+            });\n+            threads[i].start();\n+        }\n+\n+        for (Thread thread : threads) {\n+            thread.join();\n+        }\n+\n+        final Optional<byte[]> finalResult = api.get(\"key\");\n+        Assert.assertTrue(finalResult.isPresent());\n+\n+        Assert.assertEquals(String.valueOf(ATTEMPTS - 1), finalResult.map(String::new).orElse(\"NAN\"));\n     }\n \n     @Test\n     public void concurrentDeleteAndKeys() {\n-        //TODO simultanious delete by key and keys listing\n+        final String prefix = \"prefix\";\n+        final List<String> keys = Stream.generate(UUID::randomUUID)\n+                .map(UUID::toString)\n+                .map(u -> prefix + u)\n+                .limit(ATTEMPTS)\n+                .collect(Collectors.toList());\n+\n+        for (String key : keys) {\n+            api.put(key, key.getBytes());\n+        }\n+\n+        final ExecutorService deleters = new ForkJoinPool(THREADS);\n+        for (String key : keys) {\n+            deleters.submit(() -> api.delete(key));\n+        }\n+\n+        deleters.shutdown();\n+\n+        while (!deleters.isTerminated()) {\n+            final Set<String> currentKeys = api.getKeys(prefix);\n+            Assert.assertTrue(keys.containsAll(currentKeys));\n+        }\n     }\n \n     @Test\n     public void actionUpDown() {","path":"bdse-integration-tests/src/test/java/ru/csc/bdse/kv/KeyValueApiHttpClientTest2.java","position":146,"original_position":146,"commit_id":"f43385685bb155bf624ad0f0979283f229401638","original_commit_id":"f43385685bb155bf624ad0f0979283f229401638","user":{"login":"alesavin","id":7188238,"avatar_url":"https://avatars1.githubusercontent.com/u/7188238?v=4","gravatar_id":"","url":"https://api.github.com/users/alesavin","html_url":"https://github.com/alesavin","followers_url":"https://api.github.com/users/alesavin/followers","following_url":"https://api.github.com/users/alesavin/following{/other_user}","gists_url":"https://api.github.com/users/alesavin/gists{/gist_id}","starred_url":"https://api.github.com/users/alesavin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alesavin/subscriptions","organizations_url":"https://api.github.com/users/alesavin/orgs","repos_url":"https://api.github.com/users/alesavin/repos","events_url":"https://api.github.com/users/alesavin/events{/privacy}","received_events_url":"https://api.github.com/users/alesavin/received_events","type":"User","site_admin":false},"body":"конечно хотелось бы посмотреть что будет если redis.stop() но нода работает и пытаемся записать (что не упали и есть ошибка), но это мелочи","created_at":"2018-03-03T21:02:03Z","updated_at":"2018-03-03T21:04:49Z","html_url":"https://github.com/DB1L/csc-bdse/pull/1#discussion_r172028601","pull_request_url":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/DB1L/csc-bdse/pulls/comments/172028601"},"html":{"href":"https://github.com/DB1L/csc-bdse/pull/1#discussion_r172028601"},"pull_request":{"href":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1","id":172016104,"html_url":"https://github.com/DB1L/csc-bdse/pull/1","diff_url":"https://github.com/DB1L/csc-bdse/pull/1.diff","patch_url":"https://github.com/DB1L/csc-bdse/pull/1.patch","issue_url":"https://api.github.com/repos/DB1L/csc-bdse/issues/1","number":1,"state":"open","locked":false,"title":"Csc bdse task1","user":{"login":"mrMakaronka","id":2129398,"avatar_url":"https://avatars1.githubusercontent.com/u/2129398?v=4","gravatar_id":"","url":"https://api.github.com/users/mrMakaronka","html_url":"https://github.com/mrMakaronka","followers_url":"https://api.github.com/users/mrMakaronka/followers","following_url":"https://api.github.com/users/mrMakaronka/following{/other_user}","gists_url":"https://api.github.com/users/mrMakaronka/gists{/gist_id}","starred_url":"https://api.github.com/users/mrMakaronka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrMakaronka/subscriptions","organizations_url":"https://api.github.com/users/mrMakaronka/orgs","repos_url":"https://api.github.com/users/mrMakaronka/repos","events_url":"https://api.github.com/users/mrMakaronka/events{/privacy}","received_events_url":"https://api.github.com/users/mrMakaronka/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-02-28T17:10:45Z","updated_at":"2018-03-03T21:04:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ccd4aa1635cebe40dbff05f54d9b3db81d078f2d","assignee":null,"assignees":[],"requested_reviewers":[{"login":"dormidon","id":727478,"avatar_url":"https://avatars3.githubusercontent.com/u/727478?v=4","gravatar_id":"","url":"https://api.github.com/users/dormidon","html_url":"https://github.com/dormidon","followers_url":"https://api.github.com/users/dormidon/followers","following_url":"https://api.github.com/users/dormidon/following{/other_user}","gists_url":"https://api.github.com/users/dormidon/gists{/gist_id}","starred_url":"https://api.github.com/users/dormidon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dormidon/subscriptions","organizations_url":"https://api.github.com/users/dormidon/orgs","repos_url":"https://api.github.com/users/dormidon/repos","events_url":"https://api.github.com/users/dormidon/events{/privacy}","received_events_url":"https://api.github.com/users/dormidon/received_events","type":"User","site_admin":false},{"login":"747mmHg","id":2040349,"avatar_url":"https://avatars0.githubusercontent.com/u/2040349?v=4","gravatar_id":"","url":"https://api.github.com/users/747mmHg","html_url":"https://github.com/747mmHg","followers_url":"https://api.github.com/users/747mmHg/followers","following_url":"https://api.github.com/users/747mmHg/following{/other_user}","gists_url":"https://api.github.com/users/747mmHg/gists{/gist_id}","starred_url":"https://api.github.com/users/747mmHg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/747mmHg/subscriptions","organizations_url":"https://api.github.com/users/747mmHg/orgs","repos_url":"https://api.github.com/users/747mmHg/repos","events_url":"https://api.github.com/users/747mmHg/events{/privacy}","received_events_url":"https://api.github.com/users/747mmHg/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1/commits","review_comments_url":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1/comments","review_comment_url":"https://api.github.com/repos/DB1L/csc-bdse/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DB1L/csc-bdse/issues/1/comments","statuses_url":"https://api.github.com/repos/DB1L/csc-bdse/statuses/f43385685bb155bf624ad0f0979283f229401638","head":{"label":"DB1L:csc-bdse-task1","ref":"csc-bdse-task1","sha":"f43385685bb155bf624ad0f0979283f229401638","user":{"login":"DB1L","id":36747808,"avatar_url":"https://avatars1.githubusercontent.com/u/36747808?v=4","gravatar_id":"","url":"https://api.github.com/users/DB1L","html_url":"https://github.com/DB1L","followers_url":"https://api.github.com/users/DB1L/followers","following_url":"https://api.github.com/users/DB1L/following{/other_user}","gists_url":"https://api.github.com/users/DB1L/gists{/gist_id}","starred_url":"https://api.github.com/users/DB1L/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DB1L/subscriptions","organizations_url":"https://api.github.com/users/DB1L/orgs","repos_url":"https://api.github.com/users/DB1L/repos","events_url":"https://api.github.com/users/DB1L/events{/privacy}","received_events_url":"https://api.github.com/users/DB1L/received_events","type":"Organization","site_admin":false},"repo":{"id":122543899,"name":"csc-bdse","full_name":"DB1L/csc-bdse","owner":{"login":"DB1L","id":36747808,"avatar_url":"https://avatars1.githubusercontent.com/u/36747808?v=4","gravatar_id":"","url":"https://api.github.com/users/DB1L","html_url":"https://github.com/DB1L","followers_url":"https://api.github.com/users/DB1L/followers","following_url":"https://api.github.com/users/DB1L/following{/other_user}","gists_url":"https://api.github.com/users/DB1L/gists{/gist_id}","starred_url":"https://api.github.com/users/DB1L/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DB1L/subscriptions","organizations_url":"https://api.github.com/users/DB1L/orgs","repos_url":"https://api.github.com/users/DB1L/repos","events_url":"https://api.github.com/users/DB1L/events{/privacy}","received_events_url":"https://api.github.com/users/DB1L/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DB1L/csc-bdse","description":"CSC Big Data Software Engineering labs template","fork":true,"url":"https://api.github.com/repos/DB1L/csc-bdse","forks_url":"https://api.github.com/repos/DB1L/csc-bdse/forks","keys_url":"https://api.github.com/repos/DB1L/csc-bdse/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DB1L/csc-bdse/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DB1L/csc-bdse/teams","hooks_url":"https://api.github.com/repos/DB1L/csc-bdse/hooks","issue_events_url":"https://api.github.com/repos/DB1L/csc-bdse/issues/events{/number}","events_url":"https://api.github.com/repos/DB1L/csc-bdse/events","assignees_url":"https://api.github.com/repos/DB1L/csc-bdse/assignees{/user}","branches_url":"https://api.github.com/repos/DB1L/csc-bdse/branches{/branch}","tags_url":"https://api.github.com/repos/DB1L/csc-bdse/tags","blobs_url":"https://api.github.com/repos/DB1L/csc-bdse/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DB1L/csc-bdse/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DB1L/csc-bdse/git/refs{/sha}","trees_url":"https://api.github.com/repos/DB1L/csc-bdse/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DB1L/csc-bdse/statuses/{sha}","languages_url":"https://api.github.com/repos/DB1L/csc-bdse/languages","stargazers_url":"https://api.github.com/repos/DB1L/csc-bdse/stargazers","contributors_url":"https://api.github.com/repos/DB1L/csc-bdse/contributors","subscribers_url":"https://api.github.com/repos/DB1L/csc-bdse/subscribers","subscription_url":"https://api.github.com/repos/DB1L/csc-bdse/subscription","commits_url":"https://api.github.com/repos/DB1L/csc-bdse/commits{/sha}","git_commits_url":"https://api.github.com/repos/DB1L/csc-bdse/git/commits{/sha}","comments_url":"https://api.github.com/repos/DB1L/csc-bdse/comments{/number}","issue_comment_url":"https://api.github.com/repos/DB1L/csc-bdse/issues/comments{/number}","contents_url":"https://api.github.com/repos/DB1L/csc-bdse/contents/{+path}","compare_url":"https://api.github.com/repos/DB1L/csc-bdse/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DB1L/csc-bdse/merges","archive_url":"https://api.github.com/repos/DB1L/csc-bdse/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DB1L/csc-bdse/downloads","issues_url":"https://api.github.com/repos/DB1L/csc-bdse/issues{/number}","pulls_url":"https://api.github.com/repos/DB1L/csc-bdse/pulls{/number}","milestones_url":"https://api.github.com/repos/DB1L/csc-bdse/milestones{/number}","notifications_url":"https://api.github.com/repos/DB1L/csc-bdse/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DB1L/csc-bdse/labels{/name}","releases_url":"https://api.github.com/repos/DB1L/csc-bdse/releases{/id}","deployments_url":"https://api.github.com/repos/DB1L/csc-bdse/deployments","created_at":"2018-02-22T22:39:34Z","updated_at":"2018-02-22T22:39:36Z","pushed_at":"2018-02-28T22:34:28Z","git_url":"git://github.com/DB1L/csc-bdse.git","ssh_url":"git@github.com:DB1L/csc-bdse.git","clone_url":"https://github.com/DB1L/csc-bdse.git","svn_url":"https://github.com/DB1L/csc-bdse","homepage":"","size":127,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"DB1L:master","ref":"master","sha":"b567e1ce49c051150d98bd372119ad19d6b34c65","user":{"login":"DB1L","id":36747808,"avatar_url":"https://avatars1.githubusercontent.com/u/36747808?v=4","gravatar_id":"","url":"https://api.github.com/users/DB1L","html_url":"https://github.com/DB1L","followers_url":"https://api.github.com/users/DB1L/followers","following_url":"https://api.github.com/users/DB1L/following{/other_user}","gists_url":"https://api.github.com/users/DB1L/gists{/gist_id}","starred_url":"https://api.github.com/users/DB1L/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DB1L/subscriptions","organizations_url":"https://api.github.com/users/DB1L/orgs","repos_url":"https://api.github.com/users/DB1L/repos","events_url":"https://api.github.com/users/DB1L/events{/privacy}","received_events_url":"https://api.github.com/users/DB1L/received_events","type":"Organization","site_admin":false},"repo":{"id":122543899,"name":"csc-bdse","full_name":"DB1L/csc-bdse","owner":{"login":"DB1L","id":36747808,"avatar_url":"https://avatars1.githubusercontent.com/u/36747808?v=4","gravatar_id":"","url":"https://api.github.com/users/DB1L","html_url":"https://github.com/DB1L","followers_url":"https://api.github.com/users/DB1L/followers","following_url":"https://api.github.com/users/DB1L/following{/other_user}","gists_url":"https://api.github.com/users/DB1L/gists{/gist_id}","starred_url":"https://api.github.com/users/DB1L/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DB1L/subscriptions","organizations_url":"https://api.github.com/users/DB1L/orgs","repos_url":"https://api.github.com/users/DB1L/repos","events_url":"https://api.github.com/users/DB1L/events{/privacy}","received_events_url":"https://api.github.com/users/DB1L/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DB1L/csc-bdse","description":"CSC Big Data Software Engineering labs template","fork":true,"url":"https://api.github.com/repos/DB1L/csc-bdse","forks_url":"https://api.github.com/repos/DB1L/csc-bdse/forks","keys_url":"https://api.github.com/repos/DB1L/csc-bdse/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DB1L/csc-bdse/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DB1L/csc-bdse/teams","hooks_url":"https://api.github.com/repos/DB1L/csc-bdse/hooks","issue_events_url":"https://api.github.com/repos/DB1L/csc-bdse/issues/events{/number}","events_url":"https://api.github.com/repos/DB1L/csc-bdse/events","assignees_url":"https://api.github.com/repos/DB1L/csc-bdse/assignees{/user}","branches_url":"https://api.github.com/repos/DB1L/csc-bdse/branches{/branch}","tags_url":"https://api.github.com/repos/DB1L/csc-bdse/tags","blobs_url":"https://api.github.com/repos/DB1L/csc-bdse/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DB1L/csc-bdse/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DB1L/csc-bdse/git/refs{/sha}","trees_url":"https://api.github.com/repos/DB1L/csc-bdse/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DB1L/csc-bdse/statuses/{sha}","languages_url":"https://api.github.com/repos/DB1L/csc-bdse/languages","stargazers_url":"https://api.github.com/repos/DB1L/csc-bdse/stargazers","contributors_url":"https://api.github.com/repos/DB1L/csc-bdse/contributors","subscribers_url":"https://api.github.com/repos/DB1L/csc-bdse/subscribers","subscription_url":"https://api.github.com/repos/DB1L/csc-bdse/subscription","commits_url":"https://api.github.com/repos/DB1L/csc-bdse/commits{/sha}","git_commits_url":"https://api.github.com/repos/DB1L/csc-bdse/git/commits{/sha}","comments_url":"https://api.github.com/repos/DB1L/csc-bdse/comments{/number}","issue_comment_url":"https://api.github.com/repos/DB1L/csc-bdse/issues/comments{/number}","contents_url":"https://api.github.com/repos/DB1L/csc-bdse/contents/{+path}","compare_url":"https://api.github.com/repos/DB1L/csc-bdse/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DB1L/csc-bdse/merges","archive_url":"https://api.github.com/repos/DB1L/csc-bdse/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DB1L/csc-bdse/downloads","issues_url":"https://api.github.com/repos/DB1L/csc-bdse/issues{/number}","pulls_url":"https://api.github.com/repos/DB1L/csc-bdse/pulls{/number}","milestones_url":"https://api.github.com/repos/DB1L/csc-bdse/milestones{/number}","notifications_url":"https://api.github.com/repos/DB1L/csc-bdse/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DB1L/csc-bdse/labels{/name}","releases_url":"https://api.github.com/repos/DB1L/csc-bdse/releases{/id}","deployments_url":"https://api.github.com/repos/DB1L/csc-bdse/deployments","created_at":"2018-02-22T22:39:34Z","updated_at":"2018-02-22T22:39:36Z","pushed_at":"2018-02-28T22:34:28Z","git_url":"git://github.com/DB1L/csc-bdse.git","ssh_url":"git@github.com:DB1L/csc-bdse.git","clone_url":"https://github.com/DB1L/csc-bdse.git","svn_url":"https://github.com/DB1L/csc-bdse","homepage":"","size":127,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1"},"html":{"href":"https://github.com/DB1L/csc-bdse/pull/1"},"issue":{"href":"https://api.github.com/repos/DB1L/csc-bdse/issues/1"},"comments":{"href":"https://api.github.com/repos/DB1L/csc-bdse/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/DB1L/csc-bdse/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DB1L/csc-bdse/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/DB1L/csc-bdse/statuses/f43385685bb155bf624ad0f0979283f229401638"}},"author_association":"NONE"}}
{"actor":{"display_login":"alesavin"}}