Skip to content

Commit 661ec1b

Browse files
committed
Initial test for helm chart processing
1 parent 5de958d commit 661ec1b

File tree

6 files changed

+331
-0
lines changed

6 files changed

+331
-0
lines changed

kubernetes/charts/pom.xml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<!-- Copyright 2017, Oracle Corporation. All Rights Reserved. -->
2+
<!-- This is unreleased proprietary source code of Oracle Corporation -->
3+
<project xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<parent>
9+
<groupId>oracle.kubernetes</groupId>
10+
<artifactId>operator-parent</artifactId>
11+
<version>1.0</version>
12+
</parent>
13+
14+
<artifactId>helm-charts-test</artifactId>
15+
16+
<description>Oracle Weblogic Server Kubernetes Operator</description>
17+
<name>helm-chart-tests</name>
18+
19+
<url>https://oracle.github.io/weblogic-kubernetes-operator</url>
20+
<inceptionYear>2017</inceptionYear>
21+
<licenses>
22+
<license>
23+
<name>The Universal Permissive License (UPL), Version 1.0</name>
24+
<url>https://github.com/oracle/weblogic-kubernetes-operator/blob/master/LICENSE</url>
25+
</license>
26+
</licenses>
27+
28+
<build>
29+
<plugins>
30+
<plugin>
31+
<groupId>com.coveo</groupId>
32+
<artifactId>fmt-maven-plugin</artifactId>
33+
<version>2.4.0</version>
34+
<executions>
35+
<execution>
36+
<phase>test</phase>
37+
<goals>
38+
<goal>check</goal>
39+
</goals>
40+
</execution>
41+
</executions>
42+
</plugin>
43+
44+
</plugins>
45+
</build>
46+
47+
<dependencies>
48+
<dependency>
49+
<groupId>org.hamcrest</groupId>
50+
<artifactId>hamcrest-junit</artifactId>
51+
<version>2.0.0.0</version>
52+
<scope>test</scope>
53+
</dependency>
54+
<dependency>
55+
<groupId>junit</groupId>
56+
<artifactId>junit</artifactId>
57+
<version>${junit-version}</version>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.yaml</groupId>
62+
<artifactId>snakeyaml</artifactId>
63+
<version>1.19</version>
64+
<scope>test</scope>
65+
</dependency>
66+
</dependencies>
67+
68+
<profiles>
69+
<profile>
70+
<id>helm-integration-test</id>
71+
<build>
72+
<plugins>
73+
<plugin>
74+
<groupId>org.apache.maven.plugins</groupId>
75+
<artifactId>maven-failsafe-plugin</artifactId>
76+
<version>2.22.0</version>
77+
<executions>
78+
<execution>
79+
<goals>
80+
<goal>integration-test</goal>
81+
<goal>verify</goal>
82+
</goals>
83+
</execution>
84+
</executions>
85+
</plugin>
86+
</plugins>
87+
</build>
88+
</profile>
89+
</profiles>
90+
91+
</project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator.helm;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
@SuppressWarnings("SameParameterValue")
11+
class ChartITBase {
12+
private static List<ProcessedChart> charts = new ArrayList<>();
13+
14+
ProcessedChart getChart(String chartName, UpdateValues updater) {
15+
for (ProcessedChart chart : charts) {
16+
if (chart.matches(chartName, updater)) {
17+
return chart;
18+
}
19+
}
20+
21+
ProcessedChart chart = new ProcessedChart(chartName, updater);
22+
charts.add(chart);
23+
return chart;
24+
}
25+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator.helm;
6+
7+
import static org.hamcrest.MatcherAssert.assertThat;
8+
import static org.hamcrest.Matchers.containsString;
9+
import static org.hamcrest.Matchers.emptyOrNullString;
10+
import static org.hamcrest.Matchers.hasSize;
11+
12+
import java.util.Map;
13+
import org.junit.Test;
14+
15+
@SuppressWarnings("SameParameterValue")
16+
public class OperatorChartIT extends ChartITBase {
17+
18+
private static final NullUpdate NULL_UPDATE = new NullUpdate();
19+
private static final AddCertificates ADD_CERTIFICATES = new AddCertificates();
20+
private static final String OPERATOR_CHART = "weblogic-operator";
21+
22+
@Test
23+
public void whenNoCertificateSpecified_helmReportsFailure() throws Exception {
24+
ProcessedChart chart = getChart(OPERATOR_CHART, NULL_UPDATE);
25+
26+
assertThat(chart.getError(), containsString("property internalOperatorCert must be specified"));
27+
}
28+
29+
@Test
30+
public void whenCertificateSpecified_noErrorOccurs() throws Exception {
31+
ProcessedChart chart = getChart(OPERATOR_CHART, ADD_CERTIFICATES);
32+
33+
assertThat(chart.getError(), emptyOrNullString());
34+
}
35+
36+
@Test
37+
public void whenChartsGenerated_haveOneRoleBinding() throws Exception {
38+
ProcessedChart chart = getChart(OPERATOR_CHART, ADD_CERTIFICATES);
39+
40+
assertThat(chart.getDocuments("RoleBinding"), hasSize(1));
41+
}
42+
43+
private static class NullUpdate implements UpdateValues {
44+
@Override
45+
public void update(Map<String, String> values) {}
46+
}
47+
48+
private static class AddCertificates implements UpdateValues {
49+
@Override
50+
public void update(Map<String, String> values) {
51+
values.put("internalOperatorCert", "dummy.cert");
52+
values.put("internalOperatorKey", "dummy.key");
53+
}
54+
}
55+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator.helm;
6+
7+
import java.io.BufferedReader;
8+
import java.io.BufferedWriter;
9+
import java.io.File;
10+
import java.io.FileReader;
11+
import java.io.IOException;
12+
import java.io.InputStream;
13+
import java.io.InputStreamReader;
14+
import java.net.URISyntaxException;
15+
import java.net.URL;
16+
import java.nio.charset.Charset;
17+
import java.nio.file.Files;
18+
import java.nio.file.Path;
19+
import java.nio.file.Paths;
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import java.util.Map;
23+
import org.yaml.snakeyaml.Yaml;
24+
25+
/**
26+
* An encapsulation of a helm chart, along with the processing that must be done to make it usable.
27+
*/
28+
@SuppressWarnings({"unchecked", "SameParameterValue"})
29+
class ProcessedChart {
30+
private final String chartName;
31+
private final UpdateValues updateValues;
32+
private String error;
33+
private List<Map<String, String>> documents;
34+
private Process process;
35+
36+
ProcessedChart(String chartName, UpdateValues updateValues) {
37+
this.chartName = chartName;
38+
this.updateValues = updateValues;
39+
}
40+
41+
boolean matches(String chartName, UpdateValues updater) {
42+
return this.chartName.equals(chartName) && this.updateValues == updater;
43+
}
44+
45+
/**
46+
* Returns the contents of the error stream. May be empty if no error has occurred.
47+
*
48+
* @return an error string.
49+
* @throws Exception if an error occurs during processing.
50+
*/
51+
String getError() throws Exception {
52+
if (error == null) {
53+
error = dump(getProcess().getErrorStream());
54+
}
55+
56+
return error;
57+
}
58+
59+
private String dump(InputStream in) throws IOException {
60+
StringBuilder sb = new StringBuilder();
61+
62+
String line;
63+
BufferedReader br = new BufferedReader(new InputStreamReader(in));
64+
65+
while (((line = br.readLine()) != null)) sb.append(line).append(System.lineSeparator());
66+
67+
return sb.toString();
68+
}
69+
70+
/**
71+
* Returns a list containing a number of maps loaded from yaml documents whose Kind is as
72+
* specified.
73+
*
74+
* @param kind the specified kind of document to return
75+
* @return a list of yaml documents
76+
* @throws Exception if an error occurs
77+
*/
78+
List<Map<String, String>> getDocuments(String kind) throws Exception {
79+
if (documents == null) {
80+
documents = getDocuments();
81+
}
82+
83+
List<Map<String, String>> matches = new ArrayList<>();
84+
for (Map<String, String> document : documents) {
85+
if (document.get("kind").equals(kind)) {
86+
matches.add(document);
87+
}
88+
}
89+
90+
return matches;
91+
}
92+
93+
private List<Map<String, String>> getDocuments() throws Exception {
94+
List<Map<String, String>> charts = new ArrayList<>();
95+
new Yaml().loadAll(getProcess().getInputStream()).forEach(
96+
(document) -> {
97+
if (document != null) charts.add((Map<String, String>) document);
98+
});
99+
100+
return charts;
101+
}
102+
103+
private Process getProcess() throws Exception {
104+
if (process == null) {
105+
process = processChart(chartName, updateValues);
106+
}
107+
return process;
108+
}
109+
110+
private Process processChart(String chartName, UpdateValues updateValues) throws Exception {
111+
File chartsDir = getChartsDir(chartName);
112+
File baseValuesFile = new File(chartsDir, "values.yaml");
113+
Map<String, String> values = new Yaml().load(new FileReader(baseValuesFile));
114+
115+
Path valuesFile = createUpdatedValuesFile(updateValues, values);
116+
117+
ProcessBuilder pb = new ProcessBuilder(createCommandLine(chartsDir, valuesFile));
118+
return pb.start();
119+
}
120+
121+
private String[] createCommandLine(File chart, Path valuesPath) {
122+
return new String[] {"helm", "template", chart.getAbsolutePath(), "-f", valuesPath.toString()};
123+
}
124+
125+
private Path createUpdatedValuesFile(UpdateValues updateValues, Map<String, String> values)
126+
throws IOException {
127+
updateValues.update(values);
128+
Path valuesFile = Files.createTempFile("Value", ".yaml");
129+
try (BufferedWriter writer = Files.newBufferedWriter(valuesFile, Charset.forName("UTF-8"))) {
130+
new Yaml().dump(values, writer);
131+
}
132+
return valuesFile;
133+
}
134+
135+
private File getChartsDir(String chartName) throws URISyntaxException {
136+
return new File(getTargetDir(getClass()).getParentFile(), chartName);
137+
}
138+
139+
private File getTargetDir(Class<?> aClass) throws URISyntaxException {
140+
File dir = getPackageDir(aClass);
141+
while (dir.getParent() != null && !dir.getName().equals("target")) {
142+
dir = dir.getParentFile();
143+
}
144+
return dir;
145+
}
146+
147+
private File getPackageDir(Class<?> aClass) throws URISyntaxException {
148+
URL url = aClass.getResource(aClass.getSimpleName() + ".class");
149+
return Paths.get(url.toURI()).toFile().getParentFile();
150+
}
151+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package oracle.kubernetes.operator.helm;
2+
3+
import java.util.Map;
4+
5+
/** An interface which defines the changes to be made to a values file for testing. */
6+
interface UpdateValues {
7+
void update(Map<String, String> values);
8+
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<module>operator</module>
1414
<module>swagger</module>
1515
<module>integration-tests</module>
16+
<module>kubernetes/charts</module>
1617
</modules>
1718

1819
<scm>

0 commit comments

Comments
 (0)