summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fnet/src/tests/examples/examples_test.cpp91
-rwxr-xr-xfsa/src/alltest/alltest.sh1
-rw-r--r--lowercasing_test/CMakeLists.txt4
-rw-r--r--lowercasing_test/README4
-rw-r--r--lowercasing_test/src/.gitignore1
-rw-r--r--lowercasing_test/src/binref/env.sh.in2
l---------lowercasing_test/src/binref/progctl.sh1
-rw-r--r--lowercasing_test/src/grouping_test/hello-world-lib/.gitignore2
-rw-r--r--lowercasing_test/src/grouping_test/hello-world-lib/CMakeLists.txt6
-rw-r--r--lowercasing_test/src/grouping_test/hello-world-lib/hello-world.cpp9
-rw-r--r--lowercasing_test/src/grouping_test/hello-world-lib/hello-world.h9
-rw-r--r--lowercasing_test/src/grouping_test/hello-world/.gitignore4
-rw-r--r--lowercasing_test/src/grouping_test/hello-world/CMakeLists.txt8
-rw-r--r--lowercasing_test/src/grouping_test/hello-world/hello-world.cpp24
-rw-r--r--lowercasing_test/src/java/.gitignore4
-rw-r--r--lowercasing_test/src/java/CMakeLists.txt6
-rw-r--r--lowercasing_test/src/java/HelloWorld.java8
-rw-r--r--lowercasing_test/src/java/build.xml61
-rw-r--r--lowercasing_test/src/testlist.txt2
-rwxr-xr-xlowercasing_test/src/tests/create-test.sh73
-rw-r--r--lowercasing_test/src/tests/hello-world/.gitignore6
-rw-r--r--lowercasing_test/src/tests/hello-world/CMakeLists.txt8
-rw-r--r--lowercasing_test/src/tests/hello-world/DESC1
-rw-r--r--lowercasing_test/src/tests/hello-world/FILES5
-rw-r--r--lowercasing_test/src/tests/hello-world/HelloWorldLocal.java8
-rwxr-xr-xlowercasing_test/src/tests/hello-world/dotest.sh16
-rw-r--r--lowercasing_test/src/tests/hello-world/hello-world-local.cpp24
-rwxr-xr-xlowercasing_test/src/tests/hello-world/hello-world_test.sh5
-rw-r--r--lowercasing_test/src/tests/hello-world/ref.txt6
-rwxr-xr-xnode-admin/scripts/app.sh59
-rwxr-xr-xnode-admin/scripts/configure-container-networking.py337
-rwxr-xr-xnode-admin/scripts/node-admin.sh61
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java107
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java4
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java151
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java19
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java69
-rwxr-xr-xsearchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.sh2
-rw-r--r--searchcore/src/vespa/searchcore/fdispatch/program/fdispatch.cpp8
-rw-r--r--vespalib/src/tests/slaveproc/slaveproc_test.cpp2
40 files changed, 554 insertions, 664 deletions
diff --git a/fnet/src/tests/examples/examples_test.cpp b/fnet/src/tests/examples/examples_test.cpp
index 5debd969a60..b3a21a7bc42 100644
--- a/fnet/src/tests/examples/examples_test.cpp
+++ b/fnet/src/tests/examples/examples_test.cpp
@@ -3,6 +3,7 @@
#include <vespa/vespalib/util/slaveproc.h>
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/vespalib/util/thread.h>
+#include <atomic>
// reserved in vespa/factory/doc/port-ranges.txt
static const int PORT0 = 18570;
@@ -18,7 +19,7 @@ static const int PORT9 = 18579;
using vespalib::SlaveProc;
-bool runProc(SlaveProc &proc, bool &done) {
+bool runProc(SlaveProc &proc, std::atomic<bool> &done) {
char buf[4096];
proc.close(); // close stdin
while (proc.running() && !done) {
@@ -43,7 +44,7 @@ bool runProc(const std::string &cmd) {
fprintf(stderr, "retrying command in 500ms...\n");
vespalib::Thread::sleep(500);
}
- bool done = false;
+ std::atomic<bool> done(false);
SlaveProc proc(cmd.c_str());
ok = runProc(proc, done);
}
@@ -51,193 +52,193 @@ bool runProc(const std::string &cmd) {
}
TEST("usage") {
- bool done = false;
+ std::atomic<bool> done(false);
{
- SlaveProc proc("../../examples/proxy/fnet_proxy_app");
+ SlaveProc proc("exec ../../examples/proxy/fnet_proxy_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/ping/fnet_pingserver_app");
+ SlaveProc proc("exec ../../examples/ping/fnet_pingserver_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/ping/fnet_pingclient_app");
+ SlaveProc proc("exec ../../examples/ping/fnet_pingclient_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/fnet_rpc_client_app");
+ SlaveProc proc("exec ../../examples/frt/rpc/fnet_rpc_client_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/fnet_rpc_server_app");
+ SlaveProc proc("exec ../../examples/frt/rpc/fnet_rpc_server_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/fnet_echo_client_app");
+ SlaveProc proc("exec ../../examples/frt/rpc/fnet_echo_client_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/rpc_info");
+ SlaveProc proc("exec ../../examples/frt/rpc/rpc_info");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/rpc_invoke");
+ SlaveProc proc("exec ../../examples/frt/rpc/rpc_invoke");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/fnet_rpc_callback_server_app");
+ SlaveProc proc("exec ../../examples/frt/rpc/fnet_rpc_callback_server_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/fnet_rpc_callback_client_app");
+ SlaveProc proc("exec ../../examples/frt/rpc/fnet_rpc_callback_client_app");
EXPECT_FALSE(runProc(proc, done));
}
{
- SlaveProc proc("../../examples/frt/rpc/rpc_proxy");
+ SlaveProc proc("exec ../../examples/frt/rpc/rpc_proxy");
EXPECT_FALSE(runProc(proc, done));
}
}
TEST("timeout") {
std::string out;
- EXPECT_TRUE(SlaveProc::run("../../examples/timeout/fnet_timeout_app", out));
+ EXPECT_TRUE(SlaveProc::run("exec ../../examples/timeout/fnet_timeout_app", out));
fprintf(stderr, "%s\n", out.c_str());
}
-TEST_MT_F("ping", 2, bool()) {
+TEST_MT_F("ping", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/ping/fnet_pingserver_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/ping/fnet_pingserver_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/ping/fnet_pingclient_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/ping/fnet_pingclient_app tcp/localhost:%d",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("ping times out", 2, bool()) {
+TEST_MT_F("ping times out", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/ping/fnet_pingclient_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/ping/fnet_pingclient_app tcp/localhost:%d",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("ping with proxy", 3, bool()) {
+TEST_MT_F("ping with proxy", 3, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/ping/fnet_pingserver_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/ping/fnet_pingserver_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else if (thread_id == 1) {
- SlaveProc proc(vespalib::make_string("../../examples/proxy/fnet_proxy_app tcp/%d tcp/localhost:%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/proxy/fnet_proxy_app tcp/%d tcp/localhost:%d",
PORT1, PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/ping/fnet_pingclient_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/ping/fnet_pingclient_app tcp/localhost:%d",
PORT1).c_str()));
f1 = true;
}
}
-TEST_MT_F("rpc client server", 2, bool()) {
+TEST_MT_F("rpc client server", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_client_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_client_app tcp/localhost:%d",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("rpc echo client", 2, bool()) {
+TEST_MT_F("rpc echo client", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/fnet_echo_client_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_echo_client_app tcp/localhost:%d",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("rpc info", 2, bool()) {
+TEST_MT_F("rpc info", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/rpc_info tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/rpc_info tcp/localhost:%d",
PORT0).c_str()));
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/rpc_info tcp/localhost:%d verbose",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/rpc_info tcp/localhost:%d verbose",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("rpc invoke", 2, bool()) {
+TEST_MT_F("rpc invoke", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/rpc_invoke tcp/localhost:%d frt.rpc.echo "
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/rpc_invoke tcp/localhost:%d frt.rpc.echo "
"b:1 h:2 i:4 l:8 f:0.5 d:0.25 s:foo",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("rpc callback client server", 2, bool()) {
+TEST_MT_F("rpc callback client server", 2, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_callback_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_callback_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_callback_client_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_callback_client_app tcp/localhost:%d",
PORT0).c_str()));
f1 = true;
}
}
-TEST_MT_F("rpc callback client server with proxy", 3, bool()) {
+TEST_MT_F("rpc callback client server with proxy", 3, std::atomic<bool>()) {
if (thread_id == 0) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_callback_server_app tcp/%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_callback_server_app tcp/%d",
PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else if (thread_id == 1) {
- SlaveProc proc(vespalib::make_string("../../examples/frt/rpc/rpc_proxy tcp/%d tcp/localhost:%d",
+ SlaveProc proc(vespalib::make_string("exec ../../examples/frt/rpc/rpc_proxy tcp/%d tcp/localhost:%d",
PORT1, PORT0).c_str());
TEST_BARRIER();
EXPECT_TRUE(runProc(proc, f1));
} else {
TEST_BARRIER();
- EXPECT_TRUE(runProc(vespalib::make_string("../../examples/frt/rpc/fnet_rpc_callback_client_app tcp/localhost:%d",
+ EXPECT_TRUE(runProc(vespalib::make_string("exec ../../examples/frt/rpc/fnet_rpc_callback_client_app tcp/localhost:%d",
PORT1).c_str()));
f1 = true;
}
diff --git a/fsa/src/alltest/alltest.sh b/fsa/src/alltest/alltest.sh
index ad9994b7464..37274721e25 100755
--- a/fsa/src/alltest/alltest.sh
+++ b/fsa/src/alltest/alltest.sh
@@ -1,5 +1,4 @@
#!/bin/bash
-set -e
./detector_test.sh
./fsa_test.sh
./fsa_fsa_create_test_app
diff --git a/lowercasing_test/CMakeLists.txt b/lowercasing_test/CMakeLists.txt
index 159b6f6a4d4..79da02985b3 100644
--- a/lowercasing_test/CMakeLists.txt
+++ b/lowercasing_test/CMakeLists.txt
@@ -8,11 +8,7 @@ vespa_define_module(
APPS
src/binref
- src/java
TESTS
- src/grouping_test/hello-world
- src/grouping_test/hello-world-lib
- src/tests/hello-world
src/tests/lowercasing
)
diff --git a/lowercasing_test/README b/lowercasing_test/README
index 347914fce0c..883d38fffff 100644
--- a/lowercasing_test/README
+++ b/lowercasing_test/README
@@ -1,5 +1 @@
This module was created to test that lowercasing is consistent across Java and C++.
-
-If you want to copy the infrastructure from this module you should try
-to copy the hello-world test; it is designed to verify the integrity
-of the testing module itself.
diff --git a/lowercasing_test/src/.gitignore b/lowercasing_test/src/.gitignore
index a39df0815b3..d4590f3a58c 100644
--- a/lowercasing_test/src/.gitignore
+++ b/lowercasing_test/src/.gitignore
@@ -1,3 +1,2 @@
Makefile.ini
config_command.sh
-project.dsw
diff --git a/lowercasing_test/src/binref/env.sh.in b/lowercasing_test/src/binref/env.sh.in
index 6a0770c5f9b..dda4234226f 100644
--- a/lowercasing_test/src/binref/env.sh.in
+++ b/lowercasing_test/src/binref/env.sh.in
@@ -1,4 +1,2 @@
BINREF=@CMAKE_CURRENT_BINARY_DIR@
export BINREF
-HELLO_WORLD_APP=$BINREF/../grouping_test/hello-world/lowercasing_test_hello-world_app
-export HELLO_WORLD_APP
diff --git a/lowercasing_test/src/binref/progctl.sh b/lowercasing_test/src/binref/progctl.sh
deleted file mode 120000
index 2c1fb1d47ce..00000000000
--- a/lowercasing_test/src/binref/progctl.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../../vespalib/src/vespa/vespalib/testkit/progctl.sh \ No newline at end of file
diff --git a/lowercasing_test/src/grouping_test/hello-world-lib/.gitignore b/lowercasing_test/src/grouping_test/hello-world-lib/.gitignore
deleted file mode 100644
index 5dae353d999..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world-lib/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.depend
-Makefile
diff --git a/lowercasing_test/src/grouping_test/hello-world-lib/CMakeLists.txt b/lowercasing_test/src/grouping_test/hello-world-lib/CMakeLists.txt
deleted file mode 100644
index a6e6876f152..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world-lib/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_library(lowercasing_test_hello-world-lib STATIC
- SOURCES
- hello-world.cpp
- DEPENDS
-)
diff --git a/lowercasing_test/src/grouping_test/hello-world-lib/hello-world.cpp b/lowercasing_test/src/grouping_test/hello-world-lib/hello-world.cpp
deleted file mode 100644
index d280665ae7d..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world-lib/hello-world.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "hello-world.h"
-#include <stdio.h>
-
-void
-HelloWorld::print()
-{
- fprintf(stdout, "C++/lib/Hello World\n");
-}
diff --git a/lowercasing_test/src/grouping_test/hello-world-lib/hello-world.h b/lowercasing_test/src/grouping_test/hello-world-lib/hello-world.h
deleted file mode 100644
index 4bca4064da0..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world-lib/hello-world.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#pragma once
-
-class HelloWorld
-{
-public:
- static void print();
-};
-
diff --git a/lowercasing_test/src/grouping_test/hello-world/.gitignore b/lowercasing_test/src/grouping_test/hello-world/.gitignore
deleted file mode 100644
index 49082b83c4d..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.depend
-Makefile
-hello-world
-lowercasing_test_hello-world_app
diff --git a/lowercasing_test/src/grouping_test/hello-world/CMakeLists.txt b/lowercasing_test/src/grouping_test/hello-world/CMakeLists.txt
deleted file mode 100644
index 2d6940ef4d8..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(lowercasing_test_hello-world_app
- SOURCES
- hello-world.cpp
- INSTALL bin
- DEPENDS
- lowercasing_test_hello-world-lib
-)
diff --git a/lowercasing_test/src/grouping_test/hello-world/hello-world.cpp b/lowercasing_test/src/grouping_test/hello-world/hello-world.cpp
deleted file mode 100644
index 42504323bbe..00000000000
--- a/lowercasing_test/src/grouping_test/hello-world/hello-world.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
-#include <grouping_test/hello-world-lib/hello-world.h>
-
-class App : public FastOS_Application
-{
-public:
- int Main();
-};
-
-int
-App::Main()
-{
- HelloWorld::print();
- fprintf(stdout, "C++/app/Hello World\n");
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- App myapp;
- return myapp.Entry(argc, argv);
-}
diff --git a/lowercasing_test/src/java/.gitignore b/lowercasing_test/src/java/.gitignore
deleted file mode 100644
index b9e1611ac9e..00000000000
--- a/lowercasing_test/src/java/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-build.inc
-classes
-lowercasing_test.jar
-java_code_compiled
diff --git a/lowercasing_test/src/java/CMakeLists.txt b/lowercasing_test/src/java/CMakeLists.txt
deleted file mode 100644
index 34b531c2093..00000000000
--- a/lowercasing_test/src/java/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/java_code_compiled
- COMMAND ant -q -buildfile ${CMAKE_CURRENT_SOURCE_DIR}/build.xml >>/dev/null
- COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/java_code_compiled
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/build.xml ${CMAKE_CURRENT_SOURCE_DIR}/HelloWorld.java)
-add_custom_target(lowercasing_test_java ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/java_code_compiled)
diff --git a/lowercasing_test/src/java/HelloWorld.java b/lowercasing_test/src/java/HelloWorld.java
deleted file mode 100644
index 37d7bf11af7..00000000000
--- a/lowercasing_test/src/java/HelloWorld.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-public class HelloWorld
-{
- public static void main(String[] args)
- {
- System.out.println("Java/jar/HelloWorld");
- }
-}
diff --git a/lowercasing_test/src/java/build.xml b/lowercasing_test/src/java/build.xml
deleted file mode 100644
index 9e70af511f4..00000000000
--- a/lowercasing_test/src/java/build.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
-<project basedir="." default="all" name="lowercasing_test">
- <!-- Written to assume that classpath is rooted in the current directory. -->
- <!-- So this should be OK if you make this script in the root of a filesystem. -->
- <!-- If not, just change src.dir to be the root of your sources' package tree -->
- <!-- and use e.g. View over a Filesystem to mount that subdirectory with all capabilities. -->
- <!-- The idea is that both Ant and NetBeans have to know what the package root is -->
- <!-- for the classes in your application. -->
-
- <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! -->
- <!-- The standard Ant documentation can be downloaded from AutoUpdate and -->
- <!-- and then you can access the Ant manual in the online help. -->
-
- <property file="build.inc" />
-
- <target name="init">
- <property location="classes" name="classes.dir"/>
- <property location="." name="src.dir"/>
- <property location="doc/api" name="javadoc.dir"/>
- <property name="project.name" value="${ant.project.name}"/>
- <property location="${project.name}.jar" name="jar"/>
- </target>
-
- <target depends="init" name="compile">
- <!-- Both srcdir and destdir should be package roots. -->
- <mkdir dir="${classes.dir}"/>
- <javac debug="true" deprecation="true" destdir="${classes.dir}" srcdir="${src.dir}" includeantruntime="false">
- <classpath>
- </classpath>
- <!-- To add something to the classpath: -->
- <!-- <classpath><pathelement location="${mylib}"/></classpath> -->
- <!-- To exclude some files: -->
- <!-- <exclude name="com/foo/SomeFile.java"/><exclude name="com/foo/somepackage/"/> -->
- </javac>
- </target>
-
- <target depends="init,compile" name="jar">
- <!-- To make a standalone app, insert into <jar>: -->
- <!-- <manifest><attribute name="Main-Class" value="com.foo.Main"/></manifest> -->
- <jar basedir="${classes.dir}" compress="true" jarfile="${jar}"/>
- </target>
-
- <target depends="init,jar" description="Build everything." name="all"/>
-
- <target depends="init" description="Javadoc for my API." name="javadoc">
- <mkdir dir="${javadoc.dir}"/>
- <javadoc destdir="${javadoc.dir}" packagenames="*">
- <sourcepath>
- <pathelement location="${src.dir}"/>
- </sourcepath>
- </javadoc>
- </target>
-
- <target depends="init" description="Clean all build products." name="clean">
- <delete dir="${classes.dir}"/>
- <delete dir="${javadoc.dir}"/>
- <delete file="${jar}"/>
- </target>
-
-</project>
diff --git a/lowercasing_test/src/testlist.txt b/lowercasing_test/src/testlist.txt
deleted file mode 100644
index e5735a07456..00000000000
--- a/lowercasing_test/src/testlist.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/hello-world
-tests/lowercasing
diff --git a/lowercasing_test/src/tests/create-test.sh b/lowercasing_test/src/tests/create-test.sh
deleted file mode 100755
index feca94c7de2..00000000000
--- a/lowercasing_test/src/tests/create-test.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-gen_ignore_file() {
- echo "generating '$1' ..."
- echo ".depend" > $1
- echo "Makefile" >> $1
- echo "${test}_test" >> $1
-}
-
-gen_project_file() {
- echo "generating '$1' ..."
- echo "APPLICATION ${test}_test" > $1
- echo "OBJS $test" >> $1
- echo "EXTERNALLIBS searchlib" >> $1
- echo "EXTERNALLIBS vespalib" >> $1
- echo "EXTERNALLIBS vespalog" >> $1
- echo "" >> $1
- echo "CUSTOMMAKE" >> $1
- echo "test: depend ${test}_test" >> $1
- echo -e "\t@./${test}_test" >> $1
-}
-
-gen_source() {
- echo "generating '$1' ..."
- echo "#include <vespa/log/log.h>" > $1
- echo "LOG_SETUP(\"${test}_test\");" >> $1
- echo "#include <vespa/fastos/fastos.h>" >> $1
- echo "#include <vespa/vespalib/testkit/testapp.h>" >> $1
- echo "" >> $1
- echo "" >> $1
- echo "TEST_SETUP(Test);" >> $1
- echo "" >> $1
- echo "int" >> $1
- echo "Test::Main()" >> $1
- echo "{" >> $1
- echo " TEST_INIT(\"${test}_test\");" >> $1
- echo " TEST_DONE();" >> $1
- echo "}" >> $1
-}
-
-gen_desc() {
- echo "generating '$1' ..."
- echo "$test test. Take a look at $test.cpp for details." > $1
-}
-
-gen_file_list() {
- echo "generating '$1' ..."
- echo "$test.cpp" > $1
-}
-
-if [ $# -ne 1 ]; then
- echo "usage: $0 <name>"
- echo " name: name of the test to create"
- exit 1
-fi
-
-test=$1
-if [ -e $test ]; then
- echo "$test already present, don't want to mess it up..."
- exit 1
-fi
-
-echo "creating directory '$test' ..."
-mkdir -p $test || exit 1
-cd $test || exit 1
-test=`basename $test`
-
-gen_ignore_file .cvsignore
-gen_project_file fastos.project
-gen_source $test.cpp
-gen_desc DESC
-gen_file_list FILES
diff --git a/lowercasing_test/src/tests/hello-world/.gitignore b/lowercasing_test/src/tests/hello-world/.gitignore
deleted file mode 100644
index 40a57ff7d39..00000000000
--- a/lowercasing_test/src/tests/hello-world/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.depend
-HelloWorldLocal.class
-Makefile
-hello-world-local
-out.txt
-lowercasing_test_hello-world-local_app
diff --git a/lowercasing_test/src/tests/hello-world/CMakeLists.txt b/lowercasing_test/src/tests/hello-world/CMakeLists.txt
deleted file mode 100644
index 079fbe85d71..00000000000
--- a/lowercasing_test/src/tests/hello-world/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(lowercasing_test_hello-world-local_app TEST
- SOURCES
- hello-world-local.cpp
- DEPENDS
- lowercasing_test_hello-world-lib
-)
-vespa_add_test(NAME lowercasing_test_hello-world-local_app NO_VALGRIND COMMAND sh hello-world_test.sh)
diff --git a/lowercasing_test/src/tests/hello-world/DESC b/lowercasing_test/src/tests/hello-world/DESC
deleted file mode 100644
index 47ab72663ef..00000000000
--- a/lowercasing_test/src/tests/hello-world/DESC
+++ /dev/null
@@ -1 +0,0 @@
-Initial test to verify the integrity of this testing module.
diff --git a/lowercasing_test/src/tests/hello-world/FILES b/lowercasing_test/src/tests/hello-world/FILES
deleted file mode 100644
index beec05c0632..00000000000
--- a/lowercasing_test/src/tests/hello-world/FILES
+++ /dev/null
@@ -1,5 +0,0 @@
-hello-world-local.cpp
-HelloWorldLocal.java
-dotest.sh
-out.txt
-ref.txt
diff --git a/lowercasing_test/src/tests/hello-world/HelloWorldLocal.java b/lowercasing_test/src/tests/hello-world/HelloWorldLocal.java
deleted file mode 100644
index a0928a58c99..00000000000
--- a/lowercasing_test/src/tests/hello-world/HelloWorldLocal.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-public class HelloWorldLocal
-{
- public static void main(String[] args)
- {
- System.out.println("Java/local/Hello World");
- }
-}
diff --git a/lowercasing_test/src/tests/hello-world/dotest.sh b/lowercasing_test/src/tests/hello-world/dotest.sh
deleted file mode 100755
index 53f66a84ffe..00000000000
--- a/lowercasing_test/src/tests/hello-world/dotest.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-set -e
-
-. ../../binref/env.sh
-
-./lowercasing_test_hello-world-local_app > out.txt
-$HELLO_WORLD_APP >> out.txt
-$BINREF/runjava HelloWorldLocal >> out.txt
-$BINREF/runjava HelloWorld >> out.txt
-
-if diff -u out.txt ref.txt; then
- exit 0
-else
- exit 1
-fi
diff --git a/lowercasing_test/src/tests/hello-world/hello-world-local.cpp b/lowercasing_test/src/tests/hello-world/hello-world-local.cpp
deleted file mode 100644
index f9f42cf6b59..00000000000
--- a/lowercasing_test/src/tests/hello-world/hello-world-local.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
-#include <grouping_test/hello-world-lib/hello-world.h>
-
-class App : public FastOS_Application
-{
-public:
- int Main();
-};
-
-int
-App::Main()
-{
- HelloWorld::print();
- fprintf(stdout, "C++/local/Hello World\n");
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- App myapp;
- return myapp.Entry(argc, argv);
-}
diff --git a/lowercasing_test/src/tests/hello-world/hello-world_test.sh b/lowercasing_test/src/tests/hello-world/hello-world_test.sh
deleted file mode 100755
index f83dcbe2584..00000000000
--- a/lowercasing_test/src/tests/hello-world/hello-world_test.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-set -e
-. ../../binref/env.sh
-$BINREF/compilejava HelloWorldLocal.java
-sh dotest.sh
diff --git a/lowercasing_test/src/tests/hello-world/ref.txt b/lowercasing_test/src/tests/hello-world/ref.txt
deleted file mode 100644
index 5f2f17f3e52..00000000000
--- a/lowercasing_test/src/tests/hello-world/ref.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-C++/lib/Hello World
-C++/local/Hello World
-C++/lib/Hello World
-C++/app/Hello World
-Java/local/Hello World
-Java/jar/HelloWorld
diff --git a/node-admin/scripts/app.sh b/node-admin/scripts/app.sh
index 8f1787118ed..83754413508 100755
--- a/node-admin/scripts/app.sh
+++ b/node-admin/scripts/app.sh
@@ -1,65 +1,6 @@
#!/bin/bash
# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-# BEGIN environment bootstrap section
-# Do not edit between here and END as this section should stay identical in all scripts
-
-findpath () {
- myname=${0}
- mypath=${myname%/*}
- myname=${myname##*/}
- if [ "$mypath" ] && [ -d "$mypath" ]; then
- return
- fi
- mypath=$(pwd)
- if [ -f "${mypath}/${myname}" ]; then
- return
- fi
- echo "FATAL: Could not figure out the path where $myname lives from $0"
- exit 1
-}
-
-COMMON_ENV=libexec/vespa/common-env.sh
-
-source_common_env () {
- if [ "$VESPA_HOME" ] && [ -d "$VESPA_HOME" ]; then
- # ensure it ends with "/" :
- VESPA_HOME=${VESPA_HOME%/}/
- export VESPA_HOME
- common_env=$VESPA_HOME/$COMMON_ENV
- if [ -f "$common_env" ]; then
- . $common_env
- return
- fi
- fi
- return 1
-}
-
-findroot () {
- source_common_env && return
- if [ "$VESPA_HOME" ]; then
- echo "FATAL: bad VESPA_HOME value '$VESPA_HOME'"
- exit 1
- fi
- if [ "$ROOT" ] && [ -d "$ROOT" ]; then
- VESPA_HOME="$ROOT"
- source_common_env && return
- fi
- findpath
- while [ "$mypath" ]; do
- VESPA_HOME=${mypath}
- source_common_env && return
- mypath=${mypath%/*}
- done
- echo "FATAL: missing VESPA_HOME environment variable"
- echo "Could not locate $COMMON_ENV anywhere"
- exit 1
-}
-
-findroot
-
-# END environment bootstrap section
-
set -e
source "${0%/*}"/common.sh
diff --git a/node-admin/scripts/configure-container-networking.py b/node-admin/scripts/configure-container-networking.py
index 29ff6aa46ba..339621c13e1 100755
--- a/node-admin/scripts/configure-container-networking.py
+++ b/node-admin/scripts/configure-container-networking.py
@@ -70,44 +70,13 @@ def generate_mac_address(base_host_name, ip_address):
mac_address = ':'.join('%02x' % n for n in mac_address_bytes)
return mac_address
-
-flag_local_mode = "--local"
-local_mode = flag_local_mode in sys.argv
-if local_mode:
- sys.argv.remove(flag_local_mode)
-
-flag_vm_mode = "--vm"
-vm_mode = flag_vm_mode in sys.argv
-if vm_mode:
- sys.argv.remove(flag_vm_mode)
-
-if local_mode and vm_mode:
- raise RuntimeError("Cannot specify both --local and --vm")
-
-if len(sys.argv) != 3:
- raise RuntimeError("Usage: %s <container-pid> <ip>" % sys.argv[0])
-
-container_pid_arg = sys.argv[1]
-container_ip_arg = sys.argv[2]
-
-host_ns_name = "docker-host"
-try:
- container_pid = int(container_pid_arg)
-except ValueError:
- raise RuntimeError("Container pid must be an integer, got %s" % container_pid_arg)
-
-container_net_ns_path = net_namespace_path(container_pid)
-if not os.path.isfile(container_net_ns_path):
- raise RuntimeError("No such net namespace %s" % container_net_ns_path )
-
-container_ip = ipaddress.ip_address(unicode(container_ip_arg))
-
-create_directory_ignore_exists("/var/run/netns", 0766)
-create_symlink_ignore_exists(net_namespace_path(1), "/var/run/netns/%s" % host_ns_name)
-create_symlink_ignore_exists(container_net_ns_path, "/var/run/netns/%d" % container_pid)
-
-host_ns = NetNS(host_ns_name)
-container_ns = NetNS(str(container_pid))
+def get_net_namespace_for_pid(pid):
+ net_ns_path = net_namespace_path(pid)
+ if not os.path.isfile(net_ns_path):
+ raise RuntimeError("No such net namespace %s" % net_ns_path )
+ create_directory_ignore_exists("/var/run/netns", 0766)
+ create_symlink_ignore_exists(net_ns_path, "/var/run/netns/%d" % pid)
+ return NetNS(str(pid))
# ipv4 address format: {
# 'index': 3,
@@ -141,54 +110,35 @@ container_ns = NetNS(str(container_pid))
# 'scope': 0,
# 'event': 'RTM_NEWADDR'
# }
-# Note: This only fetches ipv4 addresses
-host_ips = host_ns.get_addr(family=AF_INET)
-
-host_ips_with_network_matching_container_ip = [host_ip for host_ip in host_ips if container_ip in network(host_ip)]
+def ip_with_most_specific_network_for_address(address, ipv4_ips):
+ host_ips_with_network_matching_address = [host_ip for host_ip in ipv4_ips if address in network(host_ip)]
-host_ip_best_match_for_container = None
-for host_ip in host_ips_with_network_matching_container_ip:
- if not host_ip_best_match_for_container:
- host_ip_best_match_for_container = host_ip
- elif host_ip['prefixlen'] < host_ip_best_match_for_container['prefixlen']:
- host_ip_best_match_for_container = host_ip
+ host_ip_best_match_for_address = None
+ for host_ip in host_ips_with_network_matching_address:
+ if not host_ip_best_match_for_address:
+ host_ip_best_match_for_address = host_ip
+ elif host_ip['prefixlen'] < host_ip_best_match_for_address['prefixlen']:
+ host_ip_best_match_for_address = host_ip
-if not host_ip_best_match_for_container:
- raise RuntimeError("No matching ip address for %s, candidates are on networks %s" % (container_ip, ', '.join([str(network(host_ip)) for host_ip in host_ips])))
-
-host_device_index_for_container = host_ip_best_match_for_container['index']
-container_network_prefix_length = host_ip_best_match_for_container['prefixlen']
+ if not host_ip_best_match_for_address:
+ raise RuntimeError("No matching ip address for %s, candidates are on networks %s" % (address, ', '.join([str(network(host_ip)) for host_ip in ipv4_ips])))
+ return host_ip_best_match_for_address
ipr = IPRoute()
+def delete_interface_by_name(interface_name):
+ for interface_index in ipr.link_lookup(ifname=interface_name):
+ ipr.link('delete', index=interface_index)
-# Create new interface for the container.
-
-# The interface to the vespa network are all named "vespa". However, the
-# container interfaces are prepared in the host network namespace, and so it
-# needs a temporary name to avoid name-clash.
-temporary_host_interface_name = "vespa-tmp-" + container_pid_arg
-assert len(temporary_host_interface_name) <= 15 # linux requirement
-
-container_interface_name = "vespa"
-assert len(container_interface_name) <= 15 # linux requirement
-
-for interface_index in ipr.link_lookup(ifname=temporary_host_interface_name):
- ipr.link('delete', index=interface_index)
-
-if not container_ns.link_lookup(ifname=container_interface_name):
-
+def create_interface_in_namespace(network_namespace, ip_address_textual, interface_name, link_device_index):
mac_address = generate_mac_address(
- gethostname(),
- container_ip_arg)
+ base_host_name=gethostname(),
+ ip_address=ip_address_textual)
# For traceability.
- with open('/tmp/container_mac_address_' + container_ip_arg, 'w') as f:
+ with open('/tmp/container_mac_address_' + ip_address_textual, 'w') as f:
f.write(mac_address)
- # Must be created in the host_ns to have the same lifetime as the host.
- # Otherwise, it will be deleted when the node-admin container stops.
- # (Only temporarily there, moved to the container namespace later.)
# result = [{
# 'header': {
# 'pid': 240,
@@ -200,78 +150,67 @@ if not container_ns.link_lookup(ifname=container_interface_name):
# },
# 'event': 'NLMSG_ERROR'
# }]
- #
- # TODO: Here we're linking against the most_specific_address device. For
- # the sake of argument, as of 2015-12-17, this device is always named
- # 'vespa'. 'vespa' is itself a macvlan bridge linked to the default route's
- # interface (typically eth0 or em1). So could we link against eth0 or em1
- # (or whatever) instead here? What's the difference?
- result = host_ns.link_create(
- ifname=temporary_host_interface_name,
+ result = network_namespace.link_create(
+ ifname=interface_name,
kind='macvlan',
- link=host_device_index_for_container,
+ link=link_device_index,
macvlan_mode='bridge',
address=mac_address)
if result[0]['header']['error']:
raise RuntimeError("Failed creating link, result = %s" % result )
- interface_index = host_ns.link_lookup(ifname=temporary_host_interface_name)[0]
-
- # Move interface from host namespace to container namespace, and change name from temporary name.
- # exploit that node_admin docker container shares net namespace with host:
- ipr.link('set', index=interface_index, net_ns_fd=str(container_pid),
- ifname=container_interface_name)
-
-
-# Find index of interface now in container namespace.
-
-container_interface_index_list = container_ns.link_lookup(ifname=container_interface_name)
-if not container_interface_index_list:
- raise RuntimeError("Concurrent modification to network interfaces in container")
-
-assert len(container_interface_index_list) == 1
-container_interface_index = container_interface_index_list[0]
-
-
-# Set ip address on interface in container namespace.
-
-ip_already_configured = False
-
-for host_ip in container_ns.get_addr(index=container_interface_index, family = AF_INET):
- if ipaddress.ip_address(unicode(get_attribute(host_ip, 'IFA_ADDRESS'))) == container_ip and host_ip['prefixlen'] == container_network_prefix_length:
+ index_of_created_interface = network_namespace.link_lookup(ifname=interface_name)[0]
+ return index_of_created_interface
+
+def index_of_interface_in_namespace(interface_name, namespace):
+ interface_index_list = namespace.link_lookup(ifname=interface_name)
+ if not interface_index_list:
+ return None
+ assert len(interface_index_list) == 1
+ return interface_index_list[0]
+
+def move_interface(src_interface_index, dest_namespace, dest_namespace_pid, dest_interface_name):
+ ipr.link('set',
+ index=src_interface_index,
+ net_ns_fd=str(dest_namespace_pid),
+ ifname=dest_interface_name)
+
+ new_interface_index = index_of_interface_in_namespace(interface_name=dest_interface_name,
+ namespace=dest_namespace)
+ if not new_interface_index:
+ raise RuntimeError("Concurrent modification to network interfaces")
+ return new_interface_index
+
+def set_ip_address(net_namespace, interface_index, ip_address, network_prefix_length):
+ ip_already_configured = False
+
+ for existing_ip in net_namespace.get_addr(index=interface_index, family = AF_INET):
+ existing_ip_address = get_attribute(existing_ip, 'IFA_ADDRESS')
+ existing_ip_prefixlen = existing_ip['prefixlen']
+ is_same_address = ipaddress.ip_address(unicode(existing_ip_address)) == ip_address
+ is_same_netmask = existing_ip_prefixlen == network_prefix_length
+ if is_same_address and is_same_netmask:
ip_already_configured = True
- else:
- print("Deleting old ip address. %s/%s" % (get_attribute(host_ip, 'IFA_ADDRESS'), host_ip['prefixlen']))
- print(container_ns.addr('remove',
- index=container_interface_index,
- address=get_attribute(host_ip, 'IFA_ADDRESS'),
- mask=host_ip['prefixlen']))
-
-if not ip_already_configured:
- try:
- container_ns.addr('add',
- index=container_interface_index,
- address=str(container_ip),
- #broadcast='192.168.59.255',
- mask=container_network_prefix_length)
- except NetlinkError as e:
- if e.code == 17: # File exists, i.e. address is already added
- pass
-
-
-# Activate container interface.
-
-container_ns.link('set', index=container_interface_index, state='up', name=container_interface_name)
-
-
-if local_mode:
- pass
-elif vm_mode:
- # Set the default route to the IP of the host vespa interface (e.g. osx)
- container_ns.route("add", gateway=get_attribute(host_ip_best_match_for_container, 'IFA_ADDRESS'))
-else:
- # Set up default route/gateway in container.
-
+ else:
+ print("Deleting old ip address. %s/%s" % (existing_ip_address, existing_ip_prefixlen))
+ result_of_remove = net_namespace.addr('remove',
+ index=interface_index,
+ address=existing_ip_address,
+ mask=existing_ip_prefixlen)
+ print(result_of_remove)
+
+ if not ip_already_configured:
+ try:
+ net_namespace.addr('add',
+ index=interface_index,
+ address=str(ip_address),
+ # broadcast='192.168.59.255',
+ mask=network_prefix_length)
+ except NetlinkError as e:
+ if e.code == 17: # File exists, i.e. address is already added
+ pass
+
+def get_default_route(net_namespace):
# route format: {
# 'family': 2,
# 'dst_len': 0,
@@ -297,15 +236,117 @@ else:
# 'type': 1,
# 'scope': 0
# }
- host_default_routes = host_ns.get_default_routes(family = AF_INET)
- if len(host_default_routes) != 1:
- raise RuntimeError("Couldn't find default route: " + str(host_default_routes))
- default_route = host_default_routes[0]
+ default_routes = net_namespace.get_default_routes(family = AF_INET)
+ if len(default_routes) != 1:
+ raise RuntimeError("Couldn't find single default route: " + str(default_routes))
+ return default_routes[0]
+
+
+# Parse arguments
+
+flag_local_mode = "--local"
+local_mode = flag_local_mode in sys.argv
+if local_mode:
+ sys.argv.remove(flag_local_mode)
+
+flag_vm_mode = "--vm"
+vm_mode = flag_vm_mode in sys.argv
+if vm_mode:
+ sys.argv.remove(flag_vm_mode)
+
+if local_mode and vm_mode:
+ raise RuntimeError("Cannot specify both --local and --vm")
+
+if len(sys.argv) != 3:
+ raise RuntimeError("Usage: %s <container-pid> <ip>" % sys.argv[0])
+
+container_pid_arg = sys.argv[1]
+container_ip_arg = sys.argv[2]
+
+try:
+ container_pid = int(container_pid_arg)
+except ValueError:
+ raise RuntimeError("Container pid must be an integer, got %s" % container_pid_arg)
+container_ip = ipaddress.ip_address(unicode(container_ip_arg))
+
+
+# Done parsing arguments, now let's get to work.
+
+host_ns = get_net_namespace_for_pid(1)
+container_ns = get_net_namespace_for_pid(container_pid)
+
+all_host_ipv4_ips = host_ns.get_addr(family=AF_INET)
+host_ip_best_match_for_container = ip_with_most_specific_network_for_address(address=container_ip,
+ ipv4_ips=all_host_ipv4_ips)
+host_device_index_for_container = host_ip_best_match_for_container['index']
+container_network_prefix_length = host_ip_best_match_for_container['prefixlen']
+
+
+# Create new interface for the container.
+
+# The interface to the vespa network are all (in the end) named "vespa". However,
+# the container interfaces are prepared in the host network namespace, and so they
+# need temporary names to avoid name-clash.
+temporary_interface_name_while_in_host_ns = "vespa-tmp-" + container_pid_arg
+assert len(temporary_interface_name_while_in_host_ns) <= 15 # linux requirement
+
+container_interface_name = "vespa"
+assert len(container_interface_name) <= 15 # linux requirement
+
+# Clean up any leftovers from the past.
+delete_interface_by_name(temporary_interface_name_while_in_host_ns)
+
+container_interface_index = index_of_interface_in_namespace(interface_name=container_interface_name,
+ namespace=container_ns)
+if not container_interface_index:
+ # Must be created in the host_ns to have the same lifetime as the host.
+ # Otherwise, it will be deleted when the node-admin container stops.
+ # (Only temporarily there, moved to the container namespace later.)
+ #
+ # TODO: Here we're linking against the device with the best matching network.
+ # For the sake of argument, as of 2015-12-17, this device is always named
+ # 'vespa'. 'vespa' is itself a macvlan bridge linked to the default route's
+ # interface (typically eth0 or em1). So could we link against eth0 or em1
+ # (or whatever) instead here? What's the difference?
+ temporary_interface_index = create_interface_in_namespace(network_namespace=host_ns,
+ ip_address_textual=container_ip_arg,
+ interface_name=temporary_interface_name_while_in_host_ns,
+ link_device_index=host_device_index_for_container)
+
+ # Move interface from host namespace to container namespace, and change name from temporary name.
+ # exploit that node_admin docker container shares net namespace with host:
+ container_interface_index = move_interface(src_interface_index=temporary_interface_index,
+ dest_namespace=container_ns,
+ dest_namespace_pid=container_pid,
+ dest_interface_name=container_interface_name)
+
+
+# Set ip address on interface in container namespace.
+set_ip_address(net_namespace=container_ns,
+ interface_index=container_interface_index,
+ ip_address=container_ip,
+ network_prefix_length=container_network_prefix_length)
+
+
+# Activate container interface.
+
+container_ns.link('set', index=container_interface_index, state='up', name=container_interface_name)
+
+
+if local_mode:
+ pass
+elif vm_mode:
+ # Set the default route to the IP of the host vespa interface (e.g. osx)
+ # TODO: What about idempotency? This does not check for existing. Re-does work every time.
+ container_ns.route("add", gateway=get_attribute(host_ip_best_match_for_container, 'IFA_ADDRESS'))
+else:
+ # Set up default route/gateway in container.
+
+ host_default_route = get_default_route(net_namespace=host_ns)
- host_default_route_device_index = get_attribute(default_route, 'RTA_OIF')
- host_default_gateway = get_attribute(default_route, 'RTA_GATEWAY')
+ host_default_route_device_index = get_attribute(host_default_route, 'RTA_OIF')
if host_device_index_for_container != host_default_route_device_index:
raise RuntimeError("Container's ip address is not on the same network as the host's default route."
" Could not set up default route for the container.")
- container_gateway = host_default_gateway
- container_ns.route("replace", gateway=container_gateway, index=container_interface_index)
+ host_default_route_gateway = get_attribute(host_default_route, 'RTA_GATEWAY')
+ container_ns.route("replace", gateway=host_default_route_gateway, index=container_interface_index)
diff --git a/node-admin/scripts/node-admin.sh b/node-admin/scripts/node-admin.sh
index cae3cf54d0d..405480e6d02 100755
--- a/node-admin/scripts/node-admin.sh
+++ b/node-admin/scripts/node-admin.sh
@@ -1,67 +1,6 @@
#!/bin/bash
# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-# BEGIN environment bootstrap section
-# Do not edit between here and END as this section should stay identical in all scripts
-
-findpath () {
- myname=${0}
- mypath=${myname%/*}
- myname=${myname##*/}
- if [ "$mypath" ] && [ -d "$mypath" ]; then
- return
- fi
- mypath=$(pwd)
- if [ -f "${mypath}/${myname}" ]; then
- return
- fi
- echo "FATAL: Could not figure out the path where $myname lives from $0"
- exit 1
-}
-
-COMMON_ENV=libexec/vespa/common-env.sh
-
-source_common_env () {
- if [ "$VESPA_HOME" ] && [ -d "$VESPA_HOME" ]; then
- # ensure it ends with "/" :
- VESPA_HOME=${VESPA_HOME%/}/
- export VESPA_HOME
- common_env=$VESPA_HOME/$COMMON_ENV
- if [ -f "$common_env" ]; then
- . $common_env
- return
- fi
- fi
- return 1
-}
-
-findroot () {
- source_common_env && return
- if [ "$VESPA_HOME" ]; then
- echo "FATAL: bad VESPA_HOME value '$VESPA_HOME'"
- exit 1
- fi
- if [ "$ROOT" ] && [ -d "$ROOT" ]; then
- VESPA_HOME="$ROOT"
- source_common_env && return
- fi
- findpath
- while [ "$mypath" ]; do
- VESPA_HOME=${mypath}
- source_common_env && return
- mypath=${mypath%/*}
- done
- echo "FATAL: missing VESPA_HOME environment variable"
- echo "Could not locate $COMMON_ENV anywhere"
- exit 1
-}
-
-findroot
-
-# END environment bootstrap section
-
-ROOT=$VESPA_HOME
-
set -e
source "${0%/*}/common.sh"
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java
new file mode 100644
index 00000000000..9f0227e7b38
--- /dev/null
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java
@@ -0,0 +1,107 @@
+package com.yahoo.vespa.hosted.node.admin.integrationTests;
+
+
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec;
+import com.yahoo.vespa.hosted.node.admin.NodeAdmin;
+import com.yahoo.vespa.hosted.node.admin.NodeAdminImpl;
+import com.yahoo.vespa.hosted.node.admin.NodeAdminStateUpdater;
+import com.yahoo.vespa.hosted.node.admin.NodeAgent;
+import com.yahoo.vespa.hosted.node.admin.NodeAgentImpl;
+import com.yahoo.vespa.hosted.node.admin.docker.ContainerName;
+import com.yahoo.vespa.hosted.node.admin.docker.DockerImage;
+import com.yahoo.vespa.hosted.node.admin.noderepository.NodeState;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author valerijf
+ */
+public class DockerFailTest {
+ private NodeRepoMock nodeRepositoryMock;
+ private DockerMock dockerMock;
+ private ContainerNodeSpec initialContainerNodeSpec;
+ private NodeAdminStateUpdater updater;
+
+ @Before
+ public void before() throws InterruptedException {
+ try {
+ OrchestratorMock.semaphore.acquire();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ OrchestratorMock.reset();
+ NodeRepoMock.reset();
+ DockerMock.reset();
+
+ OrchestratorMock orchestratorMock = new OrchestratorMock();
+ nodeRepositoryMock = new NodeRepoMock();
+ dockerMock = new DockerMock();
+
+ Function<HostName, NodeAgent> nodeAgentFactory = (hostName) ->
+ new NodeAgentImpl(hostName, dockerMock, nodeRepositoryMock, orchestratorMock);
+ NodeAdmin nodeAdmin = new NodeAdminImpl(dockerMock, nodeAgentFactory);
+
+ HostName hostName = new HostName("hostName");
+ initialContainerNodeSpec = new ContainerNodeSpec(
+ hostName,
+ Optional.of(new DockerImage("dockerImage")),
+ new ContainerName("container"),
+ NodeState.ACTIVE,
+ Optional.of(1L),
+ Optional.of(1L),
+ Optional.of(1d),
+ Optional.of(1d),
+ Optional.of(1d));
+ NodeRepoMock.addContainerNodeSpec(initialContainerNodeSpec);
+
+ updater = new NodeAdminStateUpdater(nodeRepositoryMock, nodeAdmin, 1, 1, orchestratorMock, "basehostname");
+
+ // Wait for node admin to be notified with node repo state and the docker container has been started
+ while (nodeAdmin.getListOfHosts().size() == 0) {
+ Thread.sleep(10);
+ }
+
+ while (!DockerMock.getRequests().startsWith("startContainer with DockerImage: DockerImage { imageId=dockerImage }, " +
+ "HostName: hostName, ContainerName: ContainerName { name=container }, minCpuCores: 1.0, minDiskAvailableGb: 1.0, " +
+ "minMainMemoryAvailableGb: 1.0\nexecuteInContainer with ContainerName: ContainerName { name=container }, " +
+ "args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\nexecuteInContainer with ContainerName: " +
+ "ContainerName { name=container }, args: [/opt/vespa/bin/vespa-nodectl, resume]\n")) {
+ Thread.sleep(10);
+ }
+ }
+
+ @After
+ public void after() {
+ updater.deconstruct();
+ OrchestratorMock.semaphore.release();
+ }
+
+ @Test
+ public void dockerFailTest() throws InterruptedException {
+ dockerMock.deleteContainer(initialContainerNodeSpec.containerName);
+
+ String goal = "startContainer with DockerImage: DockerImage { imageId=dockerImage }, HostName: hostName, " +
+ "ContainerName: ContainerName { name=container }, minCpuCores: 1.0, minDiskAvailableGb: 1.0, minMainMemoryAvailableGb: 1.0\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container }, args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container }, args: [/opt/vespa/bin/vespa-nodectl, resume]\n" +
+ "deleteContainer with ContainerName: ContainerName { name=container }\n" +
+ "startContainer with DockerImage: DockerImage { imageId=dockerImage }, HostName: hostName, ContainerName: " +
+ "ContainerName { name=container }, minCpuCores: 1.0, minDiskAvailableGb: 1.0, minMainMemoryAvailableGb: 1.0\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container }, args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container }, args: [/opt/vespa/bin/vespa-nodectl, resume]\n";
+ while (!DockerMock.getRequests().equals(goal)) {
+ Thread.sleep(10);
+ }
+
+ assertThat(DockerMock.getRequests(), is(goal));
+ }
+}
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java
index 81de3783bb2..b6165a8d545 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java
@@ -102,7 +102,9 @@ public class DockerMock implements Docker {
@Override
public void deleteApplicationStorage(ContainerName containerName) throws IOException {
-
+ synchronized (monitor) {
+ requests.append("deleteApplicationStorage with ContainerName: ").append(containerName).append("\n");
+ }
}
@Override
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java
new file mode 100644
index 00000000000..c61c690bb98
--- /dev/null
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java
@@ -0,0 +1,151 @@
+package com.yahoo.vespa.hosted.node.admin.integrationTests;
+
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec;
+import com.yahoo.vespa.hosted.node.admin.NodeAdmin;
+import com.yahoo.vespa.hosted.node.admin.NodeAdminImpl;
+import com.yahoo.vespa.hosted.node.admin.NodeAdminStateUpdater;
+import com.yahoo.vespa.hosted.node.admin.NodeAgent;
+import com.yahoo.vespa.hosted.node.admin.NodeAgentImpl;
+import com.yahoo.vespa.hosted.node.admin.docker.ContainerName;
+import com.yahoo.vespa.hosted.node.admin.docker.DockerImage;
+import com.yahoo.vespa.hosted.node.admin.noderepository.NodeState;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.function.Function;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author valerijf
+ */
+public class MultiDockerTest {
+ private NodeRepoMock nodeRepositoryMock;
+ private DockerMock dockerMock;
+ private NodeAdmin nodeAdmin;
+ private NodeAdminStateUpdater updater;
+
+ @Before
+ public void before() throws InterruptedException {
+ try {
+ OrchestratorMock.semaphore.acquire();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ OrchestratorMock.reset();
+ NodeRepoMock.reset();
+ DockerMock.reset();
+
+ OrchestratorMock orchestratorMock = new OrchestratorMock();
+ nodeRepositoryMock = new NodeRepoMock();
+ dockerMock = new DockerMock();
+
+ Function<HostName, NodeAgent> nodeAgentFactory = (hostName) ->
+ new NodeAgentImpl(hostName, dockerMock, nodeRepositoryMock, orchestratorMock);
+ nodeAdmin = new NodeAdminImpl(dockerMock, nodeAgentFactory);
+ updater = new NodeAdminStateUpdater(nodeRepositoryMock, nodeAdmin, 1, 1, orchestratorMock, "basehostname");
+ }
+
+ @After
+ public void after() {
+ updater.deconstruct();
+ OrchestratorMock.semaphore.release();
+ }
+
+ @Test
+ public void test() throws InterruptedException, IOException {
+ addAndWaitForNode(new HostName("host1"), new ContainerName("container1"), Optional.of(new DockerImage("image1")));
+ ContainerNodeSpec containerNodeSpec2 =
+ addAndWaitForNode(new HostName("host2"), new ContainerName("container2"), Optional.of(new DockerImage("image2")));
+
+
+ NodeRepoMock.updateContainerNodeSpec(
+ containerNodeSpec2.hostname,
+ containerNodeSpec2.wantedDockerImage,
+ containerNodeSpec2.containerName,
+ NodeState.DIRTY,
+ containerNodeSpec2.wantedRestartGeneration,
+ containerNodeSpec2.currentRestartGeneration,
+ containerNodeSpec2.minCpuCores,
+ containerNodeSpec2.minMainMemoryAvailableGb,
+ containerNodeSpec2.minDiskAvailableGb);
+
+ // Wait until it is marked ready
+ Optional<ContainerNodeSpec> tempContainerNodeSpec;
+ while ((tempContainerNodeSpec = nodeRepositoryMock.getContainerNodeSpec(containerNodeSpec2.hostname)).isPresent()
+ && tempContainerNodeSpec.get().nodeState != NodeState.READY) {
+ Thread.sleep(10);
+ }
+
+
+ addAndWaitForNode(new HostName("host3"), new ContainerName("container3"), Optional.of(new DockerImage("image1")));
+
+ assertThat(DockerMock.getRequests(), is(
+ "startContainer with DockerImage: DockerImage { imageId=image1 }, HostName: host1, ContainerName: ContainerName { name=container1 }, " +
+ "minCpuCores: 1.0, minDiskAvailableGb: 1.0, minMainMemoryAvailableGb: 1.0\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container1 }, args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container1 }, args: [/opt/vespa/bin/vespa-nodectl, resume]\n" +
+
+ "startContainer with DockerImage: DockerImage { imageId=image2 }, HostName: host2, ContainerName: ContainerName { name=container2 }, " +
+ "minCpuCores: 1.0, minDiskAvailableGb: 1.0, minMainMemoryAvailableGb: 1.0\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container2 }, args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container2 }, args: [/opt/vespa/bin/vespa-nodectl, resume]\n" +
+
+ "stopContainer with ContainerName: ContainerName { name=container2 }\n" +
+ "deleteContainer with ContainerName: ContainerName { name=container2 }\n" +
+ "deleteApplicationStorage with ContainerName: ContainerName { name=container2 }\n" +
+
+ "startContainer with DockerImage: DockerImage { imageId=image1 }, HostName: host3, ContainerName: ContainerName { name=container3 }, " +
+ "minCpuCores: 1.0, minDiskAvailableGb: 1.0, minMainMemoryAvailableGb: 1.0\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container3 }, args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\n" +
+ "executeInContainer with ContainerName: ContainerName { name=container3 }, args: [/opt/vespa/bin/vespa-nodectl, resume]\n"));
+
+
+ String nodeRepoExpectedRequests =
+ "updateNodeAttributes with HostName: host1, restartGeneration: 1, DockerImage: DockerImage { imageId=image1 }, containerVespaVersion: null\n" +
+ "updateNodeAttributes with HostName: host2, restartGeneration: 1, DockerImage: DockerImage { imageId=image2 }, containerVespaVersion: null\n" +
+ "markAsReady with HostName: host2\n" +
+ "updateNodeAttributes with HostName: host3, restartGeneration: 1, DockerImage: DockerImage { imageId=image1 }, containerVespaVersion: null\n";
+
+ while (!NodeRepoMock.getRequests().equals(nodeRepoExpectedRequests)) {
+ Thread.sleep(10);
+ }
+
+ assertThat(NodeRepoMock.getRequests(), is(nodeRepoExpectedRequests));
+ }
+
+ private ContainerNodeSpec addAndWaitForNode(HostName hostName, ContainerName containerName, Optional<DockerImage> dockerImage) throws InterruptedException {
+ ContainerNodeSpec containerNodeSpec = new ContainerNodeSpec(
+ hostName,
+ dockerImage,
+ containerName,
+ NodeState.ACTIVE,
+ Optional.of(1L),
+ Optional.of(1L),
+ Optional.of(1d),
+ Optional.of(1d),
+ Optional.of(1d));
+ NodeRepoMock.addContainerNodeSpec(containerNodeSpec);
+
+ // Wait for node admin to be notified with node repo state and the docker container has been started
+ while (nodeAdmin.getListOfHosts().size() != NodeRepoMock.getNumberOfContainerSpecs()) {
+ Thread.sleep(10);
+ }
+
+ while (!DockerMock.getRequests().endsWith("startContainer with DockerImage: " + dockerImage.get() + ", " +
+ "HostName: " + hostName + ", ContainerName: " + containerName + ", minCpuCores: 1.0, minDiskAvailableGb: 1.0, " +
+ "minMainMemoryAvailableGb: 1.0\nexecuteInContainer with ContainerName: " + containerName + ", " +
+ "args: [/usr/bin/env, test, -x, /opt/vespa/bin/vespa-nodectl]\nexecuteInContainer with ContainerName: " +
+ containerName + ", args: [/opt/vespa/bin/vespa-nodectl, resume]\n")) {
+ Thread.sleep(10);
+ }
+
+ return containerNodeSpec;
+ }
+}
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java
index d79079261cb..bffd6ddd22a 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java
@@ -92,11 +92,8 @@ public class NodeRepoMock implements NodeRepository {
}
public static void addContainerNodeSpec(ContainerNodeSpec containerNodeSpec) {
+ removeContainerNodeSpec(containerNodeSpec.hostname);
synchronized (monitor) {
- containerNodeSpecs = containerNodeSpecs.stream()
- .filter(c -> !c.hostname.equals(containerNodeSpec.hostname))
- .collect(Collectors.toList());
-
containerNodeSpecs.add(containerNodeSpec);
}
}
@@ -107,6 +104,20 @@ public class NodeRepoMock implements NodeRepository {
}
}
+ public static void removeContainerNodeSpec(HostName hostName) {
+ synchronized (monitor) {
+ containerNodeSpecs = containerNodeSpecs.stream()
+ .filter(c -> !c.hostname.equals(hostName))
+ .collect(Collectors.toList());
+ }
+ }
+
+ public static int getNumberOfContainerSpecs() {
+ synchronized (monitor) {
+ return containerNodeSpecs.size();
+ }
+ }
+
public static String getRequests() {
synchronized (monitor) {
return requests.toString();
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java
index dba84f81cd3..76b6ca4533d 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java
@@ -92,37 +92,40 @@ public class NodeStateTest {
}
- @Test
- public void activeToDirty() throws InterruptedException, IOException {
- // Change node state to dirty
- NodeRepoMock.updateContainerNodeSpec(
- initialContainerNodeSpec.hostname,
- initialContainerNodeSpec.wantedDockerImage,
- initialContainerNodeSpec.containerName,
- NodeState.DIRTY,
- initialContainerNodeSpec.wantedRestartGeneration,
- initialContainerNodeSpec.currentRestartGeneration,
- initialContainerNodeSpec.minCpuCores,
- initialContainerNodeSpec.minMainMemoryAvailableGb,
- initialContainerNodeSpec.minDiskAvailableGb);
-
- // Wait until it is marked ready
- Optional<ContainerNodeSpec> containerNodeSpec;
- while ((containerNodeSpec = nodeRepositoryMock.getContainerNodeSpec(hostName)).isPresent()
- && containerNodeSpec.get().nodeState != NodeState.READY) {
- Thread.sleep(10);
- }
-
- assertThat(nodeRepositoryMock.getContainerNodeSpec(hostName).get().nodeState, is(NodeState.READY));
-
-
- // Wait until docker receives deleteContainer request
- while (!DockerMock.getRequests().endsWith("deleteContainer with ContainerName: ContainerName { name=container }\n")) {
- Thread.sleep(10);
- }
-
- assertThat(DockerMock.getRequests(), endsWith("deleteContainer with ContainerName: ContainerName { name=container }\n"));
- }
+// @Test
+// public void activeToDirty() throws InterruptedException, IOException {
+// // Change node state to dirty
+// NodeRepoMock.updateContainerNodeSpec(
+// initialContainerNodeSpec.hostname,
+// initialContainerNodeSpec.wantedDockerImage,
+// initialContainerNodeSpec.containerName,
+// NodeState.DIRTY,
+// initialContainerNodeSpec.wantedRestartGeneration,
+// initialContainerNodeSpec.currentRestartGeneration,
+// initialContainerNodeSpec.minCpuCores,
+// initialContainerNodeSpec.minMainMemoryAvailableGb,
+// initialContainerNodeSpec.minDiskAvailableGb);
+//
+// // Wait until it is marked ready
+// Optional<ContainerNodeSpec> containerNodeSpec;
+// while ((containerNodeSpec = nodeRepositoryMock.getContainerNodeSpec(hostName)).isPresent()
+// && containerNodeSpec.get().nodeState != NodeState.READY) {
+// Thread.sleep(10);
+// }
+//
+// assertThat(nodeRepositoryMock.getContainerNodeSpec(hostName).get().nodeState, is(NodeState.READY));
+//
+//
+// // Wait until docker receives deleteContainer request
+// String expectedDockerRequests = "stopContainer with ContainerName: ContainerName { name=container }\n" +
+// "deleteContainer with ContainerName: ContainerName { name=container }\n" +
+// "deleteApplicationStorage with ContainerName: ContainerName { name=container }\n";
+// while (!DockerMock.getRequests().endsWith(expectedDockerRequests)) {
+// Thread.sleep(10);
+// }
+//
+// assertThat(DockerMock.getRequests(), endsWith(expectedDockerRequests));
+// }
@Test
@@ -144,7 +147,9 @@ public class NodeStateTest {
initialContainerNodeSpec.minMainMemoryAvailableGb,
initialContainerNodeSpec.minDiskAvailableGb);
- Thread.sleep(1000);
+ while (!initialDockerRequests.equals(DockerMock.getRequests())) {
+ Thread.sleep(10);
+ }
assertThat(initialDockerRequests, is(DockerMock.getRequests()));
diff --git a/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.sh b/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.sh
index cfa706ac013..810f29f6d4f 100755
--- a/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.sh
+++ b/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.sh
@@ -1,5 +1,5 @@
#!/bin/bash
set -e
-export PWD=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
+export PWD=$(pwd)
$VALGRIND ./searchcore_verify_ranksetup_test_app
diff --git a/searchcore/src/vespa/searchcore/fdispatch/program/fdispatch.cpp b/searchcore/src/vespa/searchcore/fdispatch/program/fdispatch.cpp
index 6e06c91a902..0af1a7e3e2b 100644
--- a/searchcore/src/vespa/searchcore/fdispatch/program/fdispatch.cpp
+++ b/searchcore/src/vespa/searchcore/fdispatch/program/fdispatch.cpp
@@ -259,15 +259,15 @@ namespace {
bool needRestart(const FdispatchrcConfig & curr, const FdispatchrcConfig & next)
{
if (curr.frtport != next.frtport) {
- LOG(error, "FRT port has changed from %d to %d.", curr.frtport, next.frtport);
+ LOG(warning, "FRT port has changed from %d to %d.", curr.frtport, next.frtport);
return true;
}
if (curr.ptport != next.ptport) {
- LOG(error, "PT port has changed from %d to %d.", curr.ptport, next.ptport);
+ LOG(warning, "PT port has changed from %d to %d.", curr.ptport, next.ptport);
return true;
}
if (curr.healthport != next.healthport) {
- LOG(error, "Health port has changed from %d to %d.", curr.healthport, next.healthport);
+ LOG(warning, "Health port has changed from %d to %d.", curr.healthport, next.healthport);
return true;
}
return false;
@@ -280,7 +280,7 @@ void Fdispatch::configure(std::unique_ptr<FdispatchrcConfig> cfg)
if (cfg && _config) {
if ( needRestart(*_config, *cfg) ) {
const int sleepMS = (1.0 + 30 * _rndGen.nextDouble()) * 1000;
- LOG(error, "Will restart by abort in %d ms.", sleepMS);
+ LOG(warning, "Will restart by abort in %d ms.", sleepMS);
std::this_thread::sleep_for(std::chrono::milliseconds(sleepMS));
_needRestart.store(true);
}
diff --git a/vespalib/src/tests/slaveproc/slaveproc_test.cpp b/vespalib/src/tests/slaveproc/slaveproc_test.cpp
index 71427be6709..481c9a1da01 100644
--- a/vespalib/src/tests/slaveproc/slaveproc_test.cpp
+++ b/vespalib/src/tests/slaveproc/slaveproc_test.cpp
@@ -30,7 +30,7 @@ TEST("simple run, strip single-line trailing newline") {
TEST("simple run, don't strip multi-line output") {
std::string out;
- EXPECT_TRUE(SlaveProc::run("echo -e \"foo\\n\"", out));
+ EXPECT_TRUE(SlaveProc::run("perl -e 'print \"foo\\n\\n\"'", out));
EXPECT_EQUAL(out, "foo\n\n");
}