summaryrefslogtreecommitdiffstats
path: root/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestRuntime.java
blob: c479bab6e136c4ae782a676febe625296f7cf6fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.hosted.cd;

import ai.vespa.hosted.api.ControllerHttpClient;
import ai.vespa.hosted.api.EndpointAuthenticator;
import ai.vespa.hosted.api.Properties;
import ai.vespa.hosted.api.TestConfig;
import ai.vespa.hosted.cd.http.HttpDeployment;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.zone.ZoneId;

import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * The place to obtain environment-dependent configuration for test of a Vespa deployment.
 *
 * @author jvenstad
 */
public class TestRuntime {

    private static TestRuntime theRuntime;

    private final TestConfig config;
    private final Deployment deploymentToTest;

    private TestRuntime(TestConfig config, EndpointAuthenticator authenticator) {
        this.config = config;
        this.deploymentToTest = new HttpDeployment(config.deployments().get(config.zone()), authenticator);
    }

    /**
     * Returns the config and authenticator to use when running integration tests.
     *
     * If the system property {@code "vespa.test.config"} is set (to a file path), a file at that location
     * is attempted read, and config parsed from it.
     * Otherwise, config is fetched over HTTP from the hosted Vespa API, assuming the deployment indicated
     * by the optional {@code "environment"} and {@code "region"} system properties exists.
     * When environment is not specified, it defaults to {@link Environment#dev},
     * while region must be set unless the environment is {@link Environment#dev} or {@link Environment#perf}.
     */
    public static synchronized TestRuntime get() {
        if (theRuntime == null) {
            String configPath = System.getProperty("vespa.test.config");
            TestConfig config = configPath != null ? fromFile(configPath) : fromController();
            theRuntime = new TestRuntime(config,
                                         new ai.vespa.hosted.auth.EndpointAuthenticator(config.system()));
        }
        return theRuntime;
    }

    /** Returns a copy of this runtime, with the given endpoint authenticator. */
    public TestRuntime with(EndpointAuthenticator authenticator) {
        return new TestRuntime(config, authenticator);
    }

    /** Returns the full id of the application this is testing. */
    public ApplicationId application() { return config.application(); }

    /** Returns the zone of the deployment this is testing. */
    public ZoneId zone() { return config.zone(); }

    /** Returns the deployment this is testing. */
    public Deployment deploymentToTest() { return deploymentToTest; }

    private static TestConfig fromFile(String path) {
        try {
            return TestConfig.fromJson(Files.readAllBytes(Paths.get(path)));
        }
        catch (Exception e) {
            throw new IllegalArgumentException("Failed reading config from '" + path + "'!", e);
        }
    }

    private static TestConfig fromController() {
        ControllerHttpClient controller = new ai.vespa.hosted.auth.ApiAuthenticator().controller();
        ApplicationId id = Properties.application();
        Environment environment = Properties.environment().orElse(Environment.dev);
        ZoneId zone = Properties.region().map(region -> ZoneId.from(environment, region))
                                .orElseGet(() -> controller.defaultZone(environment));
        return controller.testConfig(id, zone);
    }

}