Skip to content

Commit cd7a0fb

Browse files
committed
Improve test coverage and update doc
1 parent eda18b7 commit cd7a0fb

4 files changed

Lines changed: 94 additions & 2 deletions

File tree

docs/en/sql-reference/sql-statements/cluster-management/plugin/INSTALL_PLUGIN.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ This operation requires the SYSTEM-level PLUGIN privilege. You can follow the in
1616
## Syntax
1717

1818
```sql
19-
INSTALL PLUGIN FROM [source] [PROPERTIES ("key"="value", ...)]
19+
INSTALL PLUGIN [IF NOT EXISTS] FROM [source] [PROPERTIES ("key"="value", ...)]
2020
```
2121

22+
**IF NOT EXISTS**: If specified, the statement succeeds silently when the plugin is already installed instead of returning an error.
23+
2224
3 types of sources are supported:
2325

2426
```plain text
@@ -54,3 +56,9 @@ PROPERTIES supports setting some configurations of plugins, such as setting the
5456
```sql
5557
INSTALL PLUGIN FROM "http://mywebsite.com/plugin.zip" PROPERTIES("md5sum" = "73877f6029216f4314d712086a146570");
5658
```
59+
60+
5. Install a plugin if it is not already installed:
61+
62+
```sql
63+
INSTALL PLUGIN IF NOT EXISTS FROM "/home/users/starrocks/auditdemo.zip";
64+
```

docs/en/sql-reference/sql-statements/cluster-management/plugin/UNINSTALL_PLUGIN.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ This operation requires the SYSTEM-level PLUGIN privilege. You can follow the in
1616
## Syntax
1717

1818
```SQL
19-
UNINSTALL PLUGIN <plugin_name>
19+
UNINSTALL PLUGIN [IF EXISTS] <plugin_name>
2020
```
2121

22+
**IF EXISTS**: If specified, the statement succeeds silently when the plugin does not exist instead of returning an error.
23+
2224
plugin_name can be viewed through SHOW PLUGINS command
2325

2426
Only non-builtin plugins can be uninstalled.
@@ -30,3 +32,9 @@ Only non-builtin plugins can be uninstalled.
3032
```SQL
3133
UNINSTALL PLUGIN auditdemo;
3234
```
35+
36+
2. Uninstall a plugin if it exists:
37+
38+
```SQL
39+
UNINSTALL PLUGIN IF EXISTS auditdemo;
40+
```

fe/fe-core/src/test/java/com/starrocks/analysis/InstallPluginStmtTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,19 @@ public void testUninstallPluginWithoutIfExistsDefaultsFalse() {
7474
UninstallPluginStmt stmt = (UninstallPluginStmt) stmts.get(0);
7575
Assertions.assertFalse(stmt.isIfExists());
7676
}
77+
78+
@Test
79+
public void testInstallPluginConstructorDefaultsIfNotExistsFalse() {
80+
Map<String, String> props = Maps.newHashMap();
81+
InstallPluginStmt stmt = new InstallPluginStmt("http://test/plugin.zip", props);
82+
Assertions.assertFalse(stmt.isIfNotExists());
83+
Assertions.assertEquals("http://test/plugin.zip", stmt.getPluginPath());
84+
}
85+
86+
@Test
87+
public void testUninstallPluginConstructorDefaultsIfExistsFalse() {
88+
UninstallPluginStmt stmt = new UninstallPluginStmt("my_plugin");
89+
Assertions.assertFalse(stmt.isIfExists());
90+
Assertions.assertEquals("my_plugin", stmt.getPluginName());
91+
}
7792
}

fe/fe-core/src/test/java/com/starrocks/plugin/PluginMgrTest.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,32 @@
3434

3535
package com.starrocks.plugin;
3636

37+
import com.google.common.collect.Maps;
3738
import com.starrocks.common.Config;
3839
import com.starrocks.common.util.DigitalVersion;
40+
import com.starrocks.persist.EditLog;
41+
import com.starrocks.persist.UninstallPluginLog;
42+
import com.starrocks.persist.WALApplier;
3943
import com.starrocks.plugin.PluginInfo.PluginType;
4044
import com.starrocks.server.GlobalStateMgr;
45+
import com.starrocks.sql.ast.InstallPluginStmt;
46+
import com.starrocks.sql.ast.UninstallPluginStmt;
47+
import com.starrocks.sql.parser.NodePosition;
4148
import com.starrocks.utframe.UtFrameUtils;
49+
import mockit.Mock;
50+
import mockit.MockUp;
4251
import org.apache.commons.io.FileUtils;
4352
import org.junit.jupiter.api.BeforeAll;
4453
import org.junit.jupiter.api.BeforeEach;
4554
import org.junit.jupiter.api.Test;
4655

4756
import java.io.IOException;
4857
import java.nio.file.Files;
58+
import java.util.Map;
4959

60+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5061
import static org.junit.jupiter.api.Assertions.assertFalse;
62+
import static org.junit.jupiter.api.Assertions.assertNull;
5163
import static org.junit.jupiter.api.Assertions.assertTrue;
5264

5365
public class PluginMgrTest {
@@ -89,4 +101,53 @@ public void testLoadPluginFail() {
89101
assert false;
90102
}
91103
}
104+
105+
@Test
106+
public void testInstallPluginIfNotExistsIdempotent() throws Exception {
107+
String pluginName = "idempotent_install_plugin";
108+
PluginInfo pluginInfo = new PluginInfo(pluginName, PluginType.AUDIT, "test");
109+
110+
PluginMgr pluginMgr = new PluginMgr();
111+
pluginMgr.replayLoadDynamicPlugin(pluginInfo);
112+
113+
new MockUp<DynamicPluginLoader>() {
114+
@Mock
115+
public PluginInfo getPluginInfo() throws IOException {
116+
return pluginInfo;
117+
}
118+
};
119+
120+
Map<String, String> props = Maps.newHashMap();
121+
InstallPluginStmt stmt = new InstallPluginStmt("http://dummy/test.zip", props, true, NodePosition.ZERO);
122+
PluginInfo result = pluginMgr.installPlugin(stmt);
123+
assertNull(result);
124+
}
125+
126+
@Test
127+
public void testUninstallPluginIfExistsIdempotent() {
128+
PluginMgr pluginMgr = new PluginMgr();
129+
UninstallPluginStmt stmt = new UninstallPluginStmt("nonexistent_plugin", true, NodePosition.ZERO);
130+
assertDoesNotThrow(() -> pluginMgr.uninstallPluginFromStmt(stmt));
131+
}
132+
133+
@Test
134+
public void testUninstallPluginFromStmtNormal() throws Exception {
135+
String pluginName = "normal_uninstall_plugin";
136+
PluginInfo pluginInfo = new PluginInfo(pluginName, PluginType.AUDIT, "test");
137+
138+
PluginMgr pluginMgr = new PluginMgr();
139+
pluginMgr.replayLoadDynamicPlugin(pluginInfo);
140+
141+
new MockUp<EditLog>() {
142+
@Mock
143+
public void logUninstallPlugin(UninstallPluginLog log, WALApplier walApplier) {
144+
walApplier.apply(log);
145+
}
146+
};
147+
148+
UninstallPluginStmt stmt = new UninstallPluginStmt(pluginName);
149+
pluginMgr.uninstallPluginFromStmt(stmt);
150+
assertFalse(pluginMgr.getAllDynamicPluginInfo()
151+
.stream().anyMatch(p -> p.getName().equals(pluginName)));
152+
}
92153
}

0 commit comments

Comments
 (0)