[Closes #13] Adds a service life cycle state machine

This commit is contained in:
Chris Cheetham 2018-09-18 09:59:27 -04:00
Родитель 37a73a8dbc
Коммит 3203fdbc7f
135 изменённых файлов: 3585 добавлений и 1755 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -268,6 +268,8 @@ __pycache__/
# test files
\.steeltoe.tooling.yml
\.steeltoe.dummies
dummy-service-backend.db
# OS X Finder state
\.DS_Store

Просмотреть файл

@ -14,7 +14,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Tooling.Test", "te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Cli", "src\Steeltoe.Cli\Steeltoe.Cli.csproj", "{51D148CB-D7E1-453F-9EC7-2381294C29A2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Cli.Feature", "test\Steeltoe.Cli.Feature\Steeltoe.Cli.Feature.csproj", "{BD4A2CBD-33AF-48C3-914D-8A7F58A15348}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Cli.Test", "test\Steeltoe.Cli.Test\Steeltoe.Cli.Test.csproj", "{BD4A2CBD-33AF-48C3-914D-8A7F58A15348}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

Просмотреть файл

@ -1,12 +1,12 @@
<Project>
<PropertyGroup>
<LightBDDXUnit2Version>2.4.3</LightBDDXUnit2Version>
<McMasterExtensionsCommandLineUtilsVersion>2.2.5</McMasterExtensionsCommandLineUtilsVersion>
<MicrosoftExtensionsLoggingVersion>2.1.1</MicrosoftExtensionsLoggingVersion>
<ShouldlyVersion>3.0.0</ShouldlyVersion>
<TestSdkVersion>15.7.2</TestSdkVersion>
<XunitVersion>2.3.1</XunitVersion>
<XunitStudioVersion>2.3.1</XunitStudioVersion>
<XunitVersion>2.3.1</XunitVersion>
<YamlDotNetVersion>5.0.1</YamlDotNetVersion>
<LightBDDXUnit2Version>2.4.1</LightBDDXUnit2Version>
</PropertyGroup>
</Project>

5
scripts/cli-test Executable file
Просмотреть файл

@ -0,0 +1,5 @@
#!/usr/bin/env bash
basedir=$(dirname $0)/..
dotnet test $basedir/test/Steeltoe.Cli.Test

11
scripts/cli-test.ps1 Executable file
Просмотреть файл

@ -0,0 +1,11 @@
#!/usr/bin/env pwsh
$pwd = Get-Location
Set-Location $PSScriptRoot\..\test\Steeltoe.Cli.Test
dotnet test
$errors = $lastexitcode
Set-Location $pwd
if ($errors -gt 0)
{
Throw "$errors CLI test(s) failed"
}

Просмотреть файл

@ -1,17 +0,0 @@
#!/usr/bin/env bash
basedir=$(dirname $0)/..
featureTestDir=$basedir/test
errors=0
for project in $featureTestDir/*.Feature
do
dotnet test $project
errors=$(($errors + $?))
done
if [[ $errors > 0 ]]
then
echo "$errors unit test(s) failed" >&2
exit $errors
fi

Просмотреть файл

@ -1,18 +0,0 @@
$pwd = Get-Location
Set-Location $PSScriptRoot\..\test
[int]$errors = 0
Get-ChildItem -Directory -Filter "*.Feature" | ForEach-Object {
Set-Location $_.Name
dotnet test
$errors = $errors + $lastexitcode
Set-Location ..
}
Set-Location $pwd
if ($errors -gt 0)
{
Throw "$errors feature test(s) failed"
}

0
scripts/install.ps1 Normal file → Executable file
Просмотреть файл

Просмотреть файл

@ -1,18 +1,5 @@
#!/usr/bin/env bash
basedir=$(dirname $0)/..
unitTestDir=$basedir/test
dotnet test $basedir/test/Steeltoe.Tooling.Test
errors=0
for project in $unitTestDir/*.Test
do
dotnet test $project
errors=$(($errors + $?))
done
if [[ $errors > 0 ]]
then
echo "$errors unit test(s) failed" >&2
exit $errors
fi

17
scripts/unit-test.ps1 Normal file → Executable file
Просмотреть файл

@ -1,17 +1,10 @@
#!/usr/bin/env pwsh
$pwd = Get-Location
Set-Location $PSScriptRoot\..\test
[int]$errors = 0
Get-ChildItem -Directory -Filter "*.Test"| ForEach-Object {
Set-Location $_.Name
dotnet test
$errors = $errors + $lastexitcode
Set-Location ..
}
Set-Location $PSScriptRoot\..\test\Steeltoe.Tooling.Test
dotnet test
$errors = $lastexitcode
Set-Location $pwd
if ($errors -gt 0)
{
Throw "$errors unit test(s) failed"

Просмотреть файл

@ -16,9 +16,6 @@ using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
namespace Steeltoe.Cli
{
[Command(Description = "Add a service.")]
@ -26,16 +23,16 @@ namespace Steeltoe.Cli
{
[Required(ErrorMessage = "Service name not specified")]
[Argument(0, Name = "name", Description = "Service name")]
private string Name { get; }
private string Name { get; } = null;
[Required(ErrorMessage = "Service type not specified")]
[Argument(1, Name = "type",
Description = "Service type (run '" + CliName + " list types' for available service types)")]
private string Type { get; }
Description = "Service type (run '" + CliName + " list types' for available service types)")]
private string Type { get; } = null;
protected override IExecutor GetExecutor()
{
return null;
return new AddServiceExecutor(Name, Type);
}
}
}

Просмотреть файл

@ -14,38 +14,52 @@
using System;
using System.IO;
using System.Reflection;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling;
using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli
{
public abstract class Command
public abstract class Command : IConfigurationListener
{
public const string CliName = "steeltoe";
protected virtual int OnExecute(CommandLineApplication app)
private bool _configDirty;
protected int OnExecute(CommandLineApplication app)
{
var configFile = Path.Combine(Directory.GetCurrentDirectory(), Configuration.DefaultFileName);
var config = File.Exists(configFile) ? Configuration.Load(configFile) : new Configuration();
try
{
//
// TODO: Is there a better way to signal that config needs to be stores? Perhaps a dirty bit?
//
app.Out.WriteLine("!!! backend impl currently disconnected; commands are no-op'd for now !!!");
// if (GetExecutor().Execute(config, new CommandShell(), app.Out))
// {
// config.Store(configFile);
// }
var requiresInitializedProject = true;
{
var executor = GetExecutor();
MemberInfo minfo = executor.GetType();
foreach (var attr in minfo.GetCustomAttributes(true))
{
var initAttr = attr as RequiresInitializationAttribute;
if (initAttr != null)
{
requiresInitializedProject = initAttr.IsRequired;
}
}
}
var projectDirectory = Directory.GetCurrentDirectory();
var config = new ConfigurationFile(projectDirectory);
if (requiresInitializedProject && !config.Exists())
{
throw new ToolingException("Project has not been initialized for Steeltoe Developer Tools");
}
config.AddListener(this);
var context = new Context(projectDirectory, config, new CommandShell(app.Out));
GetExecutor().Execute(context);
if (_configDirty)
{
config.Store();
}
return 0;
}
catch (ArgumentException e)
{
app.Error.WriteLine(e.Message);
return 1;
}
catch (ToolingException e)
{
if (!string.IsNullOrEmpty(e.Message))
@ -63,5 +77,10 @@ namespace Steeltoe.Cli
}
protected abstract IExecutor GetExecutor();
public void ConfigurationChangeEvent()
{
_configDirty = true;
}
}
}

Просмотреть файл

@ -14,9 +14,9 @@
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using Microsoft.Extensions.Logging;
using Steeltoe.Tooling;
using Steeltoe.Tooling.System;
namespace Steeltoe.Cli
{
@ -26,6 +26,10 @@ namespace Steeltoe.Cli
private static int _count;
public CommandShell(TextWriter console = null) : base(console)
{
}
public override Result Run(string command, string arguments = null, string workingDirectory = null)
{
var result = new Result()

Просмотреть файл

@ -12,20 +12,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
using Steeltoe.Tooling.Executor.Service;
namespace Steeltoe.Cli
{
[Command(Description = "Start enabled services in the targeted deployment environment.")]
[Command(Description = "Start an enabled service in the targeted deployment environment.")]
public class DeployCommand : Command
{
protected override IExecutor GetExecutor()
[Required(ErrorMessage = "Service name not specified")]
[Argument(0, Name = "name", Description = "Service name")]
private string Name { get; } = null;
protected override IExecutor
GetExecutor()
{
return null;
return new DeployServiceExecutor(Name);
}
}
}

Просмотреть файл

@ -16,9 +16,6 @@ using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
namespace Steeltoe.Cli
{
[Command(Description = "Disable a service.")]
@ -30,7 +27,7 @@ namespace Steeltoe.Cli
protected override IExecutor GetExecutor()
{
return null;
return new DisableServiceExecutor(Name);
}
}
}

Просмотреть файл

@ -16,9 +16,6 @@ using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
namespace Steeltoe.Cli
{
[Command(Description = "Enable a service.")]
@ -30,7 +27,7 @@ namespace Steeltoe.Cli
protected override IExecutor GetExecutor()
{
return null;
return new EnableServiceExecutor(Name);
}
}
}

Просмотреть файл

@ -0,0 +1,56 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling;
using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli
{
[Command(Description = "Initialize a project for Steeltoe Developer Tools.")]
public class InitCommand : Command
{
[Option("-F|--force", Description = "Initialize the project even if already initialized")]
private bool Force { get; }
protected override IExecutor GetExecutor()
{
return new InitExecutor(Force);
}
}
[RequiresInitialization(false)]
internal class InitExecutor : IExecutor
{
private readonly bool _force;
internal InitExecutor(Boolean force = false)
{
_force = force;
}
public void Execute(Context context)
{
var cfgFile = context.Configuration as ConfigurationFile;
if (cfgFile.Exists() && !_force)
{
throw new ToolingException("Project already initialized");
}
cfgFile.Store();
context.Shell.Console.WriteLine("Project initialized for Steeltoe Developer Tools");
}
}
}

Просмотреть файл

@ -12,23 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
namespace Steeltoe.Cli
{
[Command(Description = "List services, service types, or deployment environments. If run with no args, list everything.")]
[Command(Description =
"List services, service types, or deployment environments. If run with no args, list everything.")]
public class ListCommand : Command
{
[Required(ErrorMessage = "List scope not specified")]
[Argument(0, Name = "scope", Description = "One of: services, types, environments")]
private string Scope { get; }
protected override IExecutor GetExecutor()
{
return null;
switch (Scope)
{
case "environments":
return new ListEnvironmentsExecutor();
case "types":
return new ListServiceTypesExecutor();
case "services":
return new ListServicesExecutor();
default:
throw new ToolingException($"Unknown list scope '{Scope}'");
}
}
}
}

Просмотреть файл

@ -14,11 +14,13 @@
using System.Reflection;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling;
namespace Steeltoe.Cli
{
[Command(Name = "steeltoe", Description = "Steeltoe Developer Tools")]
[VersionOptionFromMember("-V|--version", MemberName = nameof(GetVersion))]
[Subcommand("init", typeof(InitCommand))]
[Subcommand("target", typeof(TargetCommand))]
[Subcommand("add", typeof(AddCommand))]
[Subcommand("remove", typeof(RemoveCommand))]
@ -33,7 +35,15 @@ namespace Steeltoe.Cli
public static int Main(string[] args) => CommandLineApplication.Execute<Program>(args);
public static string GetVersion()
=> typeof(Program).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
=> typeof(Program).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
[Option("-D|--debug", Description = "Enable debug output")]
public static bool DebugEnabled
{
get => Settings.DebugEnabled;
set => Settings.DebugEnabled = value;
}
// ReSharper disable once UnusedMember.Local
private int OnExecute(CommandLineApplication app)

Просмотреть файл

@ -16,9 +16,6 @@ using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
namespace Steeltoe.Cli
{
[Command(Description = "Remove a service.")]
@ -30,7 +27,7 @@ namespace Steeltoe.Cli
protected override IExecutor GetExecutor()
{
return null;
return new RemoveServiceExecutor(Name);
}
}
}

Просмотреть файл

@ -14,13 +14,12 @@
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
using Steeltoe.Tooling.Executor.Service;
namespace Steeltoe.Cli
{
[Command(Description = "Show the status of a service in the targeted deployment environment. If run with no args, show the status of all services.")]
[Command(Description =
"Show the status of a service in the targeted deployment environment. If run with no args, show the status of all services.")]
public class StatusCommand : Command
{
[Argument(0, Name = "name", Description = "Service name")]
@ -28,7 +27,7 @@ namespace Steeltoe.Cli
protected override IExecutor GetExecutor()
{
return null;
return new StatusServiceExecutor(Name);
}
}
}

Просмотреть файл

@ -15,24 +15,28 @@
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
namespace Steeltoe.Cli
{
[Command(Description = "Target the deployment environment. If run with no args, show the targeted deployment environment.")]
[Command(Description =
"Target the deployment environment. If run with no args, show the targeted deployment environment.")]
public class TargetCommand : Command
{
[Argument(0, Name = "environment",
Description = "Deployment environment (run '" + CliName + " list targets' for available deployment environments)")]
Description = "Deployment environment (run '" + CliName +
" list targets' for available deployment environments)")]
private string Environment { get; }
[Option("-F|--force", Description = "Target the deployment environment even if checks fail")]
private string Force { get; }
private bool Force { get; }
protected override IExecutor GetExecutor()
{
return null;
if (Environment == null)
{
return new ShowTargetExecutor();
}
return new SetTargetExecutor(Environment, Force);
}
}
}

Просмотреть файл

@ -12,20 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
using Steeltoe.Tooling.Executor.Service;
namespace Steeltoe.Cli
{
[Command(Description = "Stop running services in the targeted deployment environment.")]
[Command(Description = "Stop an enabled service in the targeted deployment environment.")]
public class UndeployCommand : Command
{
[Required(ErrorMessage = "Service name not specified")]
[Argument(0, Name = "name", Description = "Service name")]
private string Name { get; } = null;
protected override IExecutor GetExecutor()
{
return null;
return new UndeployServiceExecutor(Name);
}
}
}

Просмотреть файл

@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment.CloudFoundry
namespace Steeltoe.Tooling.CloudFoundry
{
internal class CloudFoundryCli
{

Просмотреть файл

@ -12,47 +12,42 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment.CloudFoundry
namespace Steeltoe.Tooling.CloudFoundry
{
public class CloudFoundryEnvironment : IEnvironment
public class CloudFoundryEnvironment : Environment
{
public string GetName()
public CloudFoundryEnvironment() : base("cloud-foundry", "Cloud Foundry")
{
return "cloud-foundry";
}
public IServiceManager GetServiceManager()
public override IServiceBackend GetServiceBackend(Context context)
{
return new CloudFoundryServiceManager();
return new CloudFoundryServiceBackend(context.Shell);
}
public bool IsSane(Shell shell, TextWriter output)
public override bool IsSane(Shell shell)
{
var cli = new CloudFoundryCli(shell);
try
{
output.Write($"checking {cli.Command} ... ");
output.WriteLine(cli.GetVersion());
shell.Console.Write($"checking {cli.Command} ... ");
shell.Console.WriteLine(cli.GetVersion());
}
catch (ShellException e)
{
output.WriteLine($"ERROR: {e.Message.Trim()}");
shell.Console.WriteLine($"ERROR: {e.Message.Trim()}");
return false;
}
try
{
output.Write("checking if logged in ... ");
shell.Console.Write("checking if logged in ... ");
cli.GetTargetInfo();
output.WriteLine("yes");
shell.Console.WriteLine("yes");
}
catch (ToolingException e)
{
output.WriteLine($"WARNING: {e.Message.Trim()}");
shell.Console.WriteLine($"WARNING: {e.Message.Trim()}");
return false;
}

Просмотреть файл

@ -0,0 +1,60 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Steeltoe.Tooling.CloudFoundry
{
public class CloudFoundryServiceBackend : IServiceBackend
{
private static Dictionary<string, string> serviceMap = new Dictionary<string, string>
{
{"config-server", "p-config-server"},
{"registry", "p-service-registry"}
};
private readonly CloudFoundryCli _cli;
public CloudFoundryServiceBackend(Shell shell)
{
_cli = new CloudFoundryCli(shell);
}
public void DeployService(string name, string type)
{
_cli.CreateService(name, serviceMap[type]);
}
public void UndeployService(string name)
{
_cli.DeleteService(name);
}
public ServiceLifecycle.State GetServiceLifecleState(string name)
{
throw new NotImplementedException();
// var serviceInfo = new CloudFoundryCli(shell).GetServiceInfo(name);
// Regex exp = new Regex(@"^status:\s+(.*)$", RegexOptions.Multiline);
// Match match = exp.Match(serviceInfo);
// if (match.Groups[1].ToString().TrimEnd().Equals("create succeeded"))
// {
// return "online";
// }
// return "offline";
}
}
}

Просмотреть файл

@ -13,67 +13,37 @@
// limitations under the License.
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
// ReSharper disable InconsistentNaming
namespace Steeltoe.Tooling
{
public class Configuration
{
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<Configuration>();
[YamlMember(Alias = "environment")] public string EnvironmentName { get; set; }
public const string DefaultFileName = ".steeltoe.tooling.yml";
public string environment { get; set; }
public SortedDictionary<string, Service> services { get; set; } = new SortedDictionary<string, Service>();
public static Configuration Load(string path)
{
Logger.LogDebug($"loading tooling configuration from {path}");
using (var reader = new StreamReader(path))
{
return Load(reader);
}
}
public static Configuration Load(TextReader reader)
{
var deserializer = new DeserializerBuilder().Build();
return deserializer.Deserialize<Configuration>(reader);
}
public void Store(string path)
{
Logger.LogDebug($"storing tooling configuration to {path}");
using (var writer = new StreamWriter(path))
{
Store(writer);
}
}
public void Store(TextWriter writer)
{
var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(this);
writer.Write(yaml);
writer.Flush();
}
[YamlMember(Alias = "services")]
public SortedDictionary<string, Service> Services { get; protected set; } =
new SortedDictionary<string, Service>();
public class Service
{
public string type { get; set; }
[YamlMember(Alias = "type")] public string ServiceTypeName { get; set; }
public Service()
{
}
[YamlMember(Alias = "enabled")] public bool Enabled { get; set; }
}
public Service(string type)
private readonly List<IConfigurationListener> listeners = new List<IConfigurationListener>();
public void AddListener(IConfigurationListener listener)
{
listeners.Add(listener);
}
public void NotifyListeners()
{
foreach (var listener in listeners)
{
this.type = type;
listener.ConfigurationChangeEvent();
}
}
}

Просмотреть файл

@ -0,0 +1,72 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling
{
public class ConfigurationFile : Configuration
{
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<ConfigurationFile>();
public const string DefaultFileName = ".steeltoe.tooling.yml";
[YamlIgnore]
public string File { get; }
public ConfigurationFile(string path)
{
File = Directory.Exists(path) ? Path.Combine(path, DefaultFileName) : path;
if (Exists())
{
Load();
}
}
public void Load()
{
Logger.LogDebug($"loading tooling configuration from {File}");
var deserializer = new DeserializerBuilder().Build();
using (var reader = new StreamReader(File))
{
var cfg = deserializer.Deserialize<Configuration>(reader);
EnvironmentName = cfg.EnvironmentName;
Services = cfg.Services;
}
}
public void Store()
{
Logger.LogDebug($"storing tooling configuration to {File}");
var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(this);
using (var writer = new StreamWriter(File))
{
writer.Write(yaml);
}
}
public bool Exists()
{
return System.IO.File.Exists(File);
}
// private static string ToConfigurationPath(string path)
// {
// return Directory.Exists(path) ? Path.Combine(path, DefaultFileName) : path;
// }
}
}

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class Context
{
public string ProjectDirectory { get; }
public Configuration Configuration { get; }
public Shell Shell { get; }
public Environment Environment { get; }
public ServiceManager ServiceManager { get; }
public Context(string projectDirectory, Configuration config, Shell shell)
{
ProjectDirectory = projectDirectory;
Configuration = config;
Shell = shell;
ServiceManager = new ServiceManager(this);
if (Configuration.EnvironmentName != null)
{
Environment = EnvironmentRegistry.ForName(Configuration.EnvironmentName);
}
}
}
}

Просмотреть файл

@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment.Docker
namespace Steeltoe.Tooling.Docker
{
internal class DockerCli
{

Просмотреть файл

@ -12,35 +12,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment.Docker
namespace Steeltoe.Tooling.Docker
{
public class DockerEnvironment : IEnvironment
public class DockerEnvironment : Environment
{
public string GetName()
public DockerEnvironment() : base("docker", "Docker")
{
return "docker";
}
public IServiceManager GetServiceManager()
public override IServiceBackend GetServiceBackend(Context context)
{
return new DockerServiceManager();
return new DockerServiceBackend(context.Shell);
}
public bool IsSane(Shell shell, TextWriter output)
public override bool IsSane(Shell shell)
{
var cli = new DockerCli(shell);
try
{
output.Write($"checking {cli.Command} ... ");
output.WriteLine(cli.GetVersion());
shell.Console.Write($"checking {cli.Command} ... ");
shell.Console.WriteLine(cli.GetVersion());
}
catch (ShellException e)
{
output.WriteLine($"ERROR: {e.Message.Trim()}");
shell.Console.WriteLine($"ERROR: {e.Message.Trim()}");
return false;
}

Просмотреть файл

@ -14,12 +14,10 @@
using System;
using System.Collections.Generic;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment.Docker
namespace Steeltoe.Tooling.Docker
{
public class DockerServiceManager : IServiceManager
public class DockerServiceBackend : IServiceBackend
{
internal struct ImageSpec
{
@ -45,23 +43,31 @@ namespace Steeltoe.Tooling.Environment.Docker
}
};
public void StartService(Shell shell, string name, string type)
private readonly DockerCli _cli;
public DockerServiceBackend(Shell shell)
{
_cli = new DockerCli(shell);
}
public void DeployService(string name, string type)
{
var spec = imageSpecs[type];
new DockerCli(shell).StartContainer(name, spec.Name, spec.Port);
_cli.StartContainer(name, spec.Name, spec.Port);
}
public void StopService(Shell shell, string name)
public void UndeployService(string name)
{
new DockerCli(shell).StopContainer(name);
_cli.StopContainer(name);
}
public string CheckService(Shell shell, string name)
public ServiceLifecycle.State GetServiceLifecleState(string name)
{
var containerInfo = new DockerCli(shell).GetContainerInfo(name).Split('\n');
if (containerInfo.Length <= 2) return "offline";
var statusStart = containerInfo[0].IndexOf("STATUS", StringComparison.Ordinal);
return containerInfo[1].Substring(statusStart).StartsWith("Up ") ? "online" : "offline";
throw new NotImplementedException();
// var containerInfo = new DockerCli(shell).GetContainerInfo(name).Split('\n');
// if (containerInfo.Length <= 2) return "offline";
// var statusStart = containerInfo[0].IndexOf("STATUS", StringComparison.Ordinal);
// return containerInfo[1].Substring(statusStart).StartsWith("Up ") ? "online" : "offline";
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
namespace Steeltoe.Tooling.Dummy
{
public class DummyEnvironment : Environment
{
public DummyEnvironment() : base("dummy-env", "A dummy environment for testing Steeltoe Developer Tools")
{
}
public override IServiceBackend GetServiceBackend(Context context)
{
return new DummyServiceBackend(Path.Combine(context.ProjectDirectory, "dummy-service-backend.db"));
}
public override bool IsSane(Shell shell)
{
return true;
}
}
}

Просмотреть файл

@ -0,0 +1,94 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling.Dummy
{
public class DummyServiceBackend : IServiceBackend
{
public string Path { get; }
private DummyServiceDatabase _database;
public DummyServiceBackend(string path)
{
Path = path;
if (File.Exists(Path))
{
Load();
}
else
{
_database = new DummyServiceDatabase();
Store();
}
}
public void DeployService(string name, string type)
{
_database.Services[name] = ServiceLifecycle.State.Starting;
Store();
}
public void UndeployService(string name)
{
_database.Services[name] = ServiceLifecycle.State.Stopping;
Store();
}
public ServiceLifecycle.State GetServiceLifecleState(string name)
{
if (!_database.Services.ContainsKey(name))
{
return ServiceLifecycle.State.Offline;
}
var state = _database.Services[name];
switch (state)
{
case ServiceLifecycle.State.Starting:
_database.Services[name] = ServiceLifecycle.State.Online;
Store();
break;
case ServiceLifecycle.State.Stopping:
_database.Services.Remove(name);
Store();
break;
}
return state;
}
private void Store()
{
var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(_database);
using (var writer = new StreamWriter(Path))
{
writer.Write(yaml);
}
}
private void Load()
{
var deserializer = new DeserializerBuilder().Build();
using (var reader = new StreamReader(Path))
{
_database = deserializer.Deserialize<DummyServiceDatabase>(reader);
}
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
namespace Steeltoe.Tooling.Dummy
{
public class DummyServiceDatabase
{
public SortedDictionary<string, ServiceLifecycle.State> Services { get; set; } = new SortedDictionary<string, ServiceLifecycle.State>();
}
}

Просмотреть файл

@ -0,0 +1,38 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public abstract class Environment
{
public string Name { get; }
public string Description { get; }
protected Environment(string name, string description)
{
Name = name;
Description = description;
}
public abstract IServiceBackend GetServiceBackend(Context context);
public abstract bool IsSane(Shell shell);
public override string ToString()
{
return $"{Name} ({Description})";
}
}
}

Просмотреть файл

@ -1,53 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment.CloudFoundry
{
public class CloudFoundryServiceManager : IServiceManager
{
private static Dictionary<string, string> serviceMap = new Dictionary<string, string>
{
{"config-server", "p-config-server"},
{"registry", "p-service-registry"}
};
public void StartService(Shell shell, string name, string type)
{
new CloudFoundryCli(shell).CreateService(name, serviceMap[type]);
}
public void StopService(Shell shell, string name)
{
new CloudFoundryCli(shell).DeleteService(name);
}
public string CheckService(Shell shell, string name)
{
var serviceInfo = new CloudFoundryCli(shell).GetServiceInfo(name);
Regex exp = new Regex(@"^status:\s+(.*)$", RegexOptions.Multiline);
Match match = exp.Match(serviceInfo);
if (match.Groups[1].ToString().TrimEnd().Equals("create succeeded"))
{
return "online";
}
return "offline";
}
}
}

Просмотреть файл

@ -14,33 +14,30 @@
using System.Collections.Generic;
using System.Linq;
using Steeltoe.Tooling.Environment.CloudFoundry;
using Steeltoe.Tooling.Environment.Docker;
using Steeltoe.Tooling.CloudFoundry;
using Steeltoe.Tooling.Docker;
using Steeltoe.Tooling.Dummy;
namespace Steeltoe.Tooling.Environment
namespace Steeltoe.Tooling
{
public static class EnvironmentRegistry
{
private static SortedDictionary<string, IEnvironment> _environments =
new SortedDictionary<string, IEnvironment>();
private static SortedDictionary<string, Environment> _environments =
new SortedDictionary<string, Environment>();
static EnvironmentRegistry()
{
Register(new CloudFoundryEnvironment());
Register(new DockerEnvironment());
if (Settings.DummiesEnabled)
{
Register(new DummyEnvironment());
}
}
public static void Register(IEnvironment env)
{
_environments[env.GetName()] = env;
}
public static IEnumerable<string> Names => _environments.Keys.ToList();
public static IEnumerable<string> GetNames()
{
return _environments.Keys.ToList();
}
public static IEnvironment ForName(string name)
public static Environment ForName(string name)
{
try
{
@ -48,8 +45,13 @@ namespace Steeltoe.Tooling.Environment
}
catch (KeyNotFoundException)
{
return null;
throw new ToolingException($"Unknown deployment environment '{name}'");
}
}
private static void Register(Environment env)
{
_environments[env.Name] = env;
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class AddServiceExecutor : IExecutor
{
private string Name { get; }
private string Type { get; }
public AddServiceExecutor(string name, string type)
{
Name = name;
Type = type;
}
public void Execute(Context context)
{
context.ServiceManager.AddService(Name, Type);
context.ServiceManager.EnableService(Name);
context.Shell.Console.WriteLine($"Added {Type} service '{Name}'");
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor.Service
{
public class DeployServiceExecutor : ServiceExecutor
{
public DeployServiceExecutor(string name) : base(name)
{
}
public override void Execute(Context context)
{
base.Execute(context);
context.ServiceManager.DeployService(Name);
context.Shell.Console.WriteLine($"Deployed service '{Name}'");
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class DisableServiceExecutor : ServiceExecutor
{
public DisableServiceExecutor(string name) : base(name)
{
}
public override void Execute(Context context)
{
base.Execute(context);
context.ServiceManager.DisableService(Name);
context.Shell.Console.WriteLine($"Disabled service '{Name}'");
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class EnableServiceExecutor : ServiceExecutor
{
public EnableServiceExecutor(string name) : base(name)
{
}
public override void Execute(Context context)
{
base.Execute(context);
context.ServiceManager.EnableService(Name);
context.Shell.Console.WriteLine($"Enabled service '{Name}'");
}
}
}

Просмотреть файл

@ -12,13 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor
{
public interface IExecutor
{
bool Execute(Configuration config, Shell shell, TextWriter consoleOut);
void Execute(Context context);
}
}

Просмотреть файл

@ -12,21 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.Environment;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Target
namespace Steeltoe.Tooling.Executor
{
public class ListTargetsExecutor : IExecutor
[RequiresInitialization(false)]
public class ListEnvironmentsExecutor : IExecutor
{
public bool Execute(Configuration config, Shell shell, TextWriter output)
public void Execute(Context context)
{
foreach (var name in EnvironmentRegistry.GetNames())
foreach (var name in EnvironmentRegistry.Names)
{
output.WriteLine(name);
context.Shell.Console.WriteLine(EnvironmentRegistry.ForName(name));
}
return false;
}
}
}

Просмотреть файл

@ -12,22 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
namespace Steeltoe.Tooling.Executor
{
[RequiresInitialization(false)]
public class ListServiceTypesExecutor : IExecutor
{
public bool Execute(Configuration config, Shell shell, TextWriter output)
public void Execute(Context context)
{
foreach (var name in ServiceTypeRegistry.GetNames())
foreach (var name in ServiceTypeRegistry.Names)
{
output.WriteLine($"{name} ({ServiceTypeRegistry.GetDescription(name)})");
context.Shell.Console.WriteLine(ServiceTypeRegistry.ForName(name));
}
return false;
}
}
}

Просмотреть файл

@ -12,20 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
namespace Steeltoe.Tooling.Executor
{
public class ListServicesExecutor : IExecutor
{
public bool Execute(Configuration config, Shell shell, TextWriter console)
public void Execute(Context context)
{
foreach (var entry in config.services)
foreach (var entry in context.Configuration.Services)
{
console.WriteLine($"{entry.Key} ({entry.Value.type})");
context.Shell.Console.WriteLine($"{entry.Key} ({entry.Value.ServiceTypeName})");
}
return false;
}
}
}

Просмотреть файл

@ -12,11 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
namespace Steeltoe.Tooling.Executor
{
public class RemoveServiceExecutor : ServiceExecutor
{
@ -24,16 +20,11 @@ namespace Steeltoe.Tooling.Executor.Service
{
}
public override bool Execute(Configuration config, Shell shell, TextWriter output)
public override void Execute(Context context)
{
if (!config.services.ContainsKey(Name))
{
throw new ArgumentException($"Unknown service '{Name}'");
}
config.services.Remove(Name);
output.WriteLine($"Removed service '{Name}'");
return true;
base.Execute(context);
context.ServiceManager.RemoveService(Name);
context.Shell.Console.WriteLine($"Removed service '{Name}'");
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
namespace Steeltoe.Tooling.Executor
{
[AttributeUsage(AttributeTargets.Class)]
public class RequiresInitializationAttribute : Attribute
{
public bool IsRequired { get; private set; }
public RequiresInitializationAttribute(bool required = true)
{
IsRequired = required;
}
}
}

Просмотреть файл

@ -1,50 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using System.Linq;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
{
public class AddServiceExecutor : ServiceExecutor
{
private string Type { get; }
public AddServiceExecutor(string name, string type) : base(name)
{
Type = type;
}
public override bool Execute(Configuration config, Shell shell, TextWriter output)
{
if (config.services.ContainsKey(Name))
{
throw new ArgumentException($"Service '{Name}' already exists");
}
var type = Type.ToLower();
if (!ServiceTypeRegistry.GetNames().Contains(type))
{
throw new ArgumentException($"Unknown service type '{Type}'");
}
config.services.Add(Name, new Configuration.Service(type));
output.WriteLine($"Added {type} service '{Name}'");
return true;
}
}
}

Просмотреть файл

@ -1,41 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using Steeltoe.Tooling.Environment;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
{
public class CheckServiceExecutor : ServiceExecutor
{
public CheckServiceExecutor(string name) : base(name)
{
}
public override bool Execute(Configuration config, Shell shell, TextWriter output)
{
if (!config.services.ContainsKey(Name))
{
throw new ArgumentException($"Unknown service '{Name}'");
}
var env = EnvironmentRegistry.ForName(config.environment);
var status = env.GetServiceManager().CheckService(shell, Name);
output.WriteLine(status);
return false;
}
}
}

Просмотреть файл

@ -1,40 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using Steeltoe.Tooling.Environment;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
{
public class StartServiceExecutor : ServiceExecutor
{
public StartServiceExecutor(string name) : base(name)
{
}
public override bool Execute(Configuration config, Shell shell, TextWriter output)
{
if (!config.services.ContainsKey(Name))
{
throw new ArgumentException($"Unknown service '{Name}'");
}
var env = EnvironmentRegistry.ForName(config.environment);
env.GetServiceManager().StartService(shell, Name, config.services[Name].type);
return false;
}
}
}

Просмотреть файл

@ -1,40 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using Steeltoe.Tooling.Environment;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
{
public class StopServiceExecutor : ServiceExecutor
{
public StopServiceExecutor(string name) : base(name)
{
}
public override bool Execute(Configuration config, Shell shell, TextWriter output)
{
if (!config.services.ContainsKey(Name))
{
throw new ArgumentException($"Unknown service '{Name}'");
}
var env = EnvironmentRegistry.ForName(config.environment);
env.GetServiceManager().StopService(shell, Name);
return false;
}
}
}

Просмотреть файл

@ -12,10 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Service
namespace Steeltoe.Tooling.Executor
{
public abstract class ServiceExecutor : IExecutor
{
@ -26,6 +23,12 @@ namespace Steeltoe.Tooling.Executor.Service
Name = name;
}
public abstract bool Execute(Configuration config, Shell shell, TextWriter consoleOut);
public virtual void Execute(Context context)
{
if (!context.ServiceManager.HasService(Name))
{
throw new ServiceNotFoundException(Name);
}
}
}
}

Просмотреть файл

@ -12,12 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using Steeltoe.Tooling.Environment;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Executor.Target
namespace Steeltoe.Tooling.Executor
{
public class SetTargetExecutor : IExecutor
{
@ -31,27 +26,23 @@ namespace Steeltoe.Tooling.Executor.Target
_force = force;
}
public bool Execute(Configuration config, Shell shell, TextWriter output)
public void Execute(Context context)
{
var envName = _environment.ToLower();
IEnvironment env = EnvironmentRegistry.ForName(envName);
if (env == null)
{
throw new ArgumentException($"Unknown environment '{_environment}'");
}
Environment env = EnvironmentRegistry.ForName(envName);
if (!env.IsSane(shell, output))
if (!env.IsSane(context.Shell))
{
if (!_force)
{
output.WriteLine("Fix errors above or re-run with '-f|--force'");
throw new ToolingException();
context.Shell.Console.WriteLine("Fix errors above or re-run with '-f|--force'");
throw new ToolingException($"Environment '{envName}' not sane");
}
}
config.environment = envName;
output.WriteLine($"Target environment set to '{envName}'.");
return true;
context.Configuration.EnvironmentName = envName;
context.Configuration.NotifyListeners();
context.Shell.Console.WriteLine($"Target deployment environment set to '{envName}'.");
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class ShowTargetExecutor : IExecutor
{
public void Execute(Context context)
{
if (context.Configuration.EnvironmentName == null)
{
throw new ToolingException("Target deployment environment not set");
}
context.Shell.Console.WriteLine(
$"Target deployment environment set to '{context.Configuration.EnvironmentName}'.");
}
}
}

Просмотреть файл

@ -12,20 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using Shouldly;
using Steeltoe.Tooling.Executor.Target;
using Xunit;
namespace Steeltoe.Tooling.Test.Executor.Target
namespace Steeltoe.Tooling.Executor.Service
{
public class ListTargetsExecutorTest : ExecutorTest
public class StatusServiceExecutor : ServiceExecutor
{
[Fact]
public void TestList()
public StatusServiceExecutor(string name) : base(name)
{
var svc = new ListTargetsExecutor();
svc.Execute(Config, null, Output);
Output.ToString().ShouldContain("cloud-foundry");
}
public override void Execute(Context context)
{
base.Execute(context);
context.Shell.Console.WriteLine(context.ServiceManager.GetServiceStatus(Name));
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor.Service
{
public class UndeployServiceExecutor : ServiceExecutor
{
public UndeployServiceExecutor(string name) : base(name)
{
}
public override void Execute(Context context)
{
base.Execute(context);
context.ServiceManager.UndeployService(Name);
context.Shell.Console.WriteLine($"Undeployed service '{Name}'");
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
namespace Steeltoe.Tooling
{
public interface IConfigurationListener
{
void ConfigurationChangeEvent();
}
}

Просмотреть файл

@ -12,16 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Service
namespace Steeltoe.Tooling
{
public interface IServiceManager
public interface IServiceBackend
{
void StartService(Shell shell, string name, string type);
void DeployService(string name, string type);
void StopService(Shell shell, string name);
void UndeployService(string name);
string CheckService(Shell shell, string name);
ServiceLifecycle.State GetServiceLifecleState(string name);
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class Service
{
public string Name { get; }
public string Type { get; }
public Service(string name, string type)
{
Name = name;
Type = type;
}
}
}

Просмотреть файл

@ -0,0 +1,198 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class ServiceLifecycle
{
public enum State
{
Disabled,
Offline,
Starting,
Online,
Stopping
}
public Context Context { get; }
public string Name { get; }
public ServiceLifecycle(Context context, string name)
{
Context = context;
Name = name;
}
public State GetState()
{
if (!Context.Configuration.Services[Name].Enabled)
{
return State.Disabled;
}
return Context.ServiceManager.GetServiceBackend().GetServiceLifecleState(Name);
}
public void Enable()
{
GetStateManager().Enable();
}
public void Disable()
{
GetStateManager().Disable();
}
public void Deploy()
{
GetStateManager().Deploy();
}
public void Undeploy()
{
GetStateManager().Undeploy();
}
private StateManager GetStateManager()
{
var state = GetState();
switch (state)
{
case State.Disabled:
return new ServiceDisabled(Context, Name, state);
case State.Offline:
return new ServiceOffline(Context, Name, state);
case State.Starting:
return new ServiceStarting(Context, Name, state);
case State.Online:
return new ServiceOnline(Context, Name, state);
case State.Stopping:
return new ServiceStopping(Context, Name, state);
}
throw new ToolingException($"Unhandled service state '{state.ToString().ToLower()}'");
}
private class StateManager
{
internal Context Context { get; }
internal string Name { get; }
internal State State { get; }
internal StateManager(Context context, string name, State state)
{
Context = context;
Name = name;
State = state;
}
internal virtual void Enable()
{
throw new ServiceLifecycleException(State);
}
internal virtual void Disable()
{
throw new ServiceLifecycleException(State);
}
internal virtual void Deploy()
{
throw new ServiceLifecycleException(State);
}
internal virtual void Undeploy()
{
throw new ServiceLifecycleException(State);
}
}
private class ServiceDisabled : StateManager
{
internal ServiceDisabled(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Enable()
{
Context.Configuration.Services[Name].Enabled = true;
Context.Configuration.NotifyListeners();
}
internal override void Disable()
{
}
}
private class ServiceOffline : StateManager
{
internal ServiceOffline(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Enable()
{
}
internal override void Disable()
{
Context.Configuration.Services[Name].Enabled = false;
Context.Configuration.NotifyListeners();
}
internal override void Deploy()
{
Context.ServiceManager.GetServiceBackend()
.DeployService(Name, Context.Configuration.Services[Name].ServiceTypeName);
}
internal override void Undeploy()
{
}
}
private class ServiceOnline : StateManager
{
internal ServiceOnline(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Deploy()
{
}
internal override void Undeploy()
{
Context.ServiceManager.GetServiceBackend().UndeployService(Name);
}
}
private class ServiceStarting : StateManager
{
internal ServiceStarting(Context context, string name, State state) : base(context, name, state)
{
}
}
private class ServiceStopping : StateManager
{
internal ServiceStopping(Context context, string name, State state) : base(context, name, state)
{
}
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class ServiceLifecycleException : ToolingException
{
public ServiceLifecycle.State State { get; }
public ServiceLifecycleException(ServiceLifecycle.State state) : base(
$"Invalid service status '{state.ToString().ToLower()}'")
{
State = state;
}
}
}

Просмотреть файл

@ -0,0 +1,109 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.Linq;
namespace Steeltoe.Tooling
{
public class ServiceManager
{
protected internal readonly Context _context;
public ServiceManager(Context context)
{
_context = context;
}
public IServiceBackend GetServiceBackend()
{
return EnvironmentRegistry.ForName(_context.Configuration.EnvironmentName).GetServiceBackend(_context);
}
public Service AddService(string name, string type)
{
if (!ServiceTypeRegistry.Names.Contains(type))
{
throw new ToolingException($"Unknown service type '{type}'");
}
if (_context.Configuration.Services.ContainsKey(name))
{
throw new ToolingException($"Service '{name}' already exists");
}
_context.Configuration.Services[name] = new Configuration.Service {ServiceTypeName = type};
_context.Configuration.NotifyListeners();
return GetService(name);
}
public void RemoveService(string name)
{
if (!_context.Configuration.Services.Remove(name))
{
throw new ServiceNotFoundException(name);
}
_context.Configuration.NotifyListeners();
}
public Service GetService(string name)
{
try
{
var svccfg = _context.Configuration.Services[name];
return new Service(name, svccfg.ServiceTypeName);
}
catch (KeyNotFoundException)
{
throw new ServiceNotFoundException(name);
}
}
public List<string> GetServiceNames()
{
return _context.Configuration.Services.Keys.ToList();
}
public bool HasService(string name)
{
return _context.Configuration.Services.ContainsKey(name);
}
public string GetServiceStatus(string name)
{
return new ServiceLifecycle(_context, name).GetState().ToString().ToLower();
}
public void EnableService(string name)
{
new ServiceLifecycle(_context, name).Enable();
}
public void DisableService(string name)
{
new ServiceLifecycle(_context, name).Disable();
}
public void DeployService(string name)
{
new ServiceLifecycle(_context, name).Deploy();
}
public void UndeployService(string name)
{
new ServiceLifecycle(_context, name).Undeploy();
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class ServiceNotFoundException : ToolingException
{
public string Name { get; }
public ServiceNotFoundException(string name) : base($"Service '{name}' not found")
{
Name = name;
}
}
}

Просмотреть файл

@ -0,0 +1,34 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
internal class ServiceType
{
internal string Name { get; }
internal string Description { get; }
internal ServiceType(string name, string description)
{
Name = name;
Description = description;
}
public override string ToString()
{
return $"{Name} ({Description})";
}
}
}

Просмотреть файл

@ -15,22 +15,25 @@
using System.Collections.Generic;
using System.Linq;
namespace Steeltoe.Tooling.Service
namespace Steeltoe.Tooling
{
public static class ServiceTypeRegistry
{
private static SortedDictionary<string, string> _types = new SortedDictionary<string, string>
{
{"config-server", "Spring Cloud Config Server"},
{"registry", "Netflix Eureka Server"}
};
private static SortedDictionary<string, ServiceType> _types = new SortedDictionary<string, ServiceType>();
public static IEnumerable<string> GetNames()
static ServiceTypeRegistry()
{
return _types.Keys.ToList();
Register(new ServiceType("config-server", "Cloud Foundry Config Server"));
Register(new ServiceType("registry", "Netflix Eureka Server"));
if (Settings.DummiesEnabled)
{
Register(new ServiceType("dummy-svc", "A dummy service for testing Steeltoe Developer Tools"));
}
}
public static string GetDescription(string name)
public static IEnumerable<string> Names => _types.Keys.ToList();
internal static ServiceType ForName(string name)
{
try
{
@ -41,5 +44,10 @@ namespace Steeltoe.Tooling.Service
return null;
}
}
private static void Register(ServiceType type)
{
_types[type.Name] = type;
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright 2018 the original author or authors.
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -13,17 +13,18 @@
// limitations under the License.
using System.IO;
using Steeltoe.Tooling.Service;
using Steeltoe.Tooling.System;
namespace Steeltoe.Tooling.Environment
namespace Steeltoe.Tooling
{
public interface IEnvironment
public static class Settings
{
string GetName();
public static bool DebugEnabled { get; set; }
IServiceManager GetServiceManager();
public static bool DummiesEnabled { get; set; }
bool IsSane(Shell shell, TextWriter output);
static Settings()
{
DummiesEnabled = File.Exists(".steeltoe.dummies");
}
}
}

Просмотреть файл

@ -12,10 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.System
using System.IO;
namespace Steeltoe.Tooling
{
public abstract class Shell
{
public TextWriter Console { get; }
public Shell(TextWriter console)
{
Console = console;
}
public abstract Result Run(string command, string arguments = null, string workingDirectory = null);
public struct Result

Просмотреть файл

@ -14,7 +14,7 @@
using System;
namespace Steeltoe.Tooling.System
namespace Steeltoe.Tooling
{
public class ShellException : Exception
{

Просмотреть файл

@ -18,10 +18,6 @@ namespace Steeltoe.Tooling
{
public class ToolingException : Exception
{
public ToolingException()
{
}
public ToolingException(string message) : base(message)
{
}

Просмотреть файл

@ -1,113 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("add")]
public class AddFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void AddHelp()
{
Runner.RunScenario(
given => a_dotnet_project("add_help"),
when => the_developer_runs_steeltoe_command("add --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Add a service\."),
and => the_developer_should_see(@"\s+name\s+Service name"),
and => the_developer_should_see(@"\s+type\s+Service type\s+\(run 'steeltoe list types' for available service types\)")
);
}
[Scenario]
public void AddNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("add_not_enough_args0"),
when => the_developer_runs_steeltoe_command("add"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Service name not specified")
);
Runner.RunScenario(
given => a_dotnet_project("add_not_enough_args1"),
when => the_developer_runs_steeltoe_command("add myservice"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Service type not specified")
);
}
[Scenario]
public void AddTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("add_too_many_args"),
when => the_developer_runs_steeltoe_command("add arg1 arg2 arg3"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg3'")
);
}
// [Scenario]
// public void AddUnknownServiceType()
// {
// Runner.RunScenario(
// given => a_dotnet_project("add_unknown_service_type"),
// when => the_developer_runs_steeltoe_command("add-service foo --type no-such-type"),
// then => the_command_should_fail_with(1),
// and => the_developer_should_see_the_error("Unknown service type 'no-such-type'")
// );
// }
// [Scenario]
// public void AddAlreadyExistingService()
// {
// Runner.RunScenario(
// given => a_dotnet_project("add_already_existing_service"),
// and => a_service("existing-service", "existing-service-type"),
// when => the_developer_runs_steeltoe_command("add-service existing-service --type cloud-foundry-config-server"),
// then => the_command_should_fail_with(1),
// and => the_developer_should_see_the_error("Service 'existing-service' already exists")
// );
// }
// [Scenario]
// public void AddConfigServer()
// {
// Runner.RunScenario(
// given => a_dotnet_project("add_config_server"),
// when => the_developer_runs_steeltoe_command("add-service MyConfigServer --type config-server"),
// then => the_command_should_succeed(),
// and => the_developer_should_see("Added config-server service 'MyConfigServer'"),
// and => the_service_config_should_exist("MyConfigServer", "config-server")
// );
// }
// [Scenario]
// public void AddRegistry()
// {
// Runner.RunScenario(
// given => a_dotnet_project("add_registry"),
// when => the_developer_runs_steeltoe_command("add-service MyRegistryService --type registry"),
// then => the_command_should_succeed(),
// and => the_developer_should_see("Added registry service 'MyRegistryService'"),
// and => the_service_config_should_exist("MyRegistryService", "registry")
// );
// }
}
}

Просмотреть файл

@ -1,147 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using LightBDD.XUnit2;
using Microsoft.Extensions.Logging;
using Shouldly;
using Steeltoe.Tooling;
using Steeltoe.Tooling.System;
namespace Steeltoe.Cli.Feature
{
public class CliFeatureSpecs : FeatureFixture
{
private static ILogger Logger { get; } = Logging.LoggerFactory.CreateLogger<CliFeatureSpecs>();
private string CliProjectDirectory { get; } = Path.GetFullPath(Path.Combine(
Directory.GetCurrentDirectory(),
"../../../../../src/Steeltoe.Cli"));
private Shell _shell = new CommandShell();
private Shell.Result _shellResult;
private string _projectDirectory;
private string _configFile;
//
// Givens
//
protected void a_dotnet_project(string name)
{
Logger.LogInformation($"rigging a dotnet project '{name}'");
_projectDirectory = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), "sandboxes"), name);
if (Directory.Exists(_projectDirectory))
{
Directory.Delete(_projectDirectory, true);
}
Directory.CreateDirectory(_projectDirectory);
_shell.Run("dotnet", "new classlib", _projectDirectory).ExitCode.ShouldBe(0);
_configFile = Path.Combine(_projectDirectory, Configuration.DefaultFileName);
}
protected void a_target(string name)
{
Logger.LogInformation($"rigging a target '{name}'");
var cfg = LoadProjectConfiguration();
cfg.environment = name;
StoreProjectConfiguration(cfg);
}
protected void a_service(string name, string type)
{
Logger.LogInformation($"rigging a service '{name}'");
var cfg = LoadProjectConfiguration();
cfg.services.Add(name, new Configuration.Service(type));
StoreProjectConfiguration(cfg);
}
//
// Whens
//
protected void the_developer_runs_steeltoe_command(string command)
{
Logger.LogInformation($"running 'steeltoe {command}'");
_shellResult = _shell.Run("dotnet", $"run --project {CliProjectDirectory} -- {command}",
_projectDirectory);
}
//
// Thens
//
protected void the_command_should_succeed()
{
Logger.LogInformation($"checking the command succeeded");
_shellResult.ExitCode.ShouldBe(0);
}
protected void the_command_should_fail_with(int rc)
{
Logger.LogInformation($"checking the command failed");
_shellResult.ExitCode.ShouldBe(rc);
}
protected void the_developer_should_see(string message)
{
Logger.LogInformation($"checking the developer saw '{message}'");
_shellResult.Out.ShouldMatch(message);
}
protected void the_developer_should_see_the_error(string error)
{
Logger.LogInformation($"checking the developer saw the error '{error}'");
_shellResult.Error.ShouldMatch($".*{error}.*");
}
protected void the_target_config_should_exist(string name)
{
Logger.LogInformation($"checking the target config '{name}' exists");
var cfg = LoadProjectConfiguration();
cfg.environment.ShouldBe(name);
}
protected void the_service_config_should_exist(string name, string type)
{
Logger.LogInformation($"checking the service config '{name}' exists");
var cfg = LoadProjectConfiguration();
cfg.services.ShouldContainKey(name);
cfg.services[name].type.ShouldBe(type);
}
protected void the_service_config_should_not_exist(string name)
{
Logger.LogInformation($"checking the service config '{name}' does not exist");
var cfg = LoadProjectConfiguration();
cfg.services.ShouldNotContainKey(name);
}
// utilities
private void StoreProjectConfiguration(Configuration config)
{
config.Store(_configFile);
}
private Configuration LoadProjectConfiguration()
{
return File.Exists(_configFile) ? Configuration.Load(_configFile) : new Configuration();
}
}
}

Просмотреть файл

@ -1,47 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("deploy")]
public class DeployFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void DeployHelp()
{
Runner.RunScenario(
given => a_dotnet_project("deploy_help"),
when => the_developer_runs_steeltoe_command("deploy --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Start enabled services in the targeted deployment environment\.")
);
}
[Scenario]
public void DeployTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("deploy_too_many_args"),
when => the_developer_runs_steeltoe_command("deploy arg1"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg1'")
);
}
}
}

Просмотреть файл

@ -1,59 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("disable")]
public class DisableFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void DisableHelp()
{
Runner.RunScenario(
given => a_dotnet_project("disable_help"),
when => the_developer_runs_steeltoe_command("disable --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Disable a service\."),
and => the_developer_should_see(@"\s+name\s+Service name")
);
}
[Scenario]
public void DisableNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("disable_not_enough_args"),
when => the_developer_runs_steeltoe_command("disable"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Service name not specified")
);
}
[Scenario]
public void DisableTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("disable_too_many_args"),
when => the_developer_runs_steeltoe_command("disable arg1 arg2"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg2'")
);
}
}
}

Просмотреть файл

@ -1,59 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("enable")]
public class EnableFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void EnableHelp()
{
Runner.RunScenario(
given => a_dotnet_project("enable_help"),
when => the_developer_runs_steeltoe_command("enable --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Enable a service\."),
and => the_developer_should_see(@"\s+name\s+Service name")
);
}
[Scenario]
public void EnableNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("enable_not_enough_args"),
when => the_developer_runs_steeltoe_command("enable"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Service name not specified")
);
}
[Scenario]
public void EnableTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("enable_too_many_args"),
when => the_developer_runs_steeltoe_command("enable arg1 arg2"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg2'")
);
}
}
}

Просмотреть файл

@ -1,75 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("list")]
public class ListFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void ListHelp()
{
Runner.RunScenario(
given => a_dotnet_project("list_help"),
when => the_developer_runs_steeltoe_command("list --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"List services, service types, or deployment environments\. If run with no args, list everything\."),
and => the_developer_should_see(@"\s+scope\s+One of: services, types, environments")
);
}
[Scenario]
public void ListTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("list_too_many_args"),
when => the_developer_runs_steeltoe_command("list arg1 arg2"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg2'")
);
}
// [Scenario]
// public void ListServices()
// {
// Runner.RunScenario(
// given => a_dotnet_project("list_services"),
// when => the_developer_runs_steeltoe_command("list-services"),
// then => the_command_should_succeed(),
// and => the_developer_should_see(""),
// given => a_service("service-z", "service-type-Z"),
// and => a_service("service-a", "service-type-A"),
// when => the_developer_runs_steeltoe_command("list-services"),
// then => the_command_should_succeed(),
// and => the_developer_should_see(@"service-a\s+\(service-type-A\)\s+service-z\s\(service-type-Z\)")
// );
// }
// [Scenario]
// public void ListServicesTooManyArgs()
// {
// Runner.RunScenario(
// given => a_dotnet_project("list_services_too_many_args"),
// when => the_developer_runs_steeltoe_command("list-services arg1"),
// then => the_command_should_fail_with(1),
// and => the_developer_should_see_the_error("Unrecognized command or argument 'arg1'")
// );
// }
}
}

Просмотреть файл

@ -1,70 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("program")]
public class ProgramFeature : CliFeatureSpecs
{
[Scenario]
public void ProgramNoArgs()
{
Runner.RunScenario(
given => a_dotnet_project("main_no_args"),
when => the_developer_runs_steeltoe_command(""),
then => the_command_should_fail_with(1),
and => the_developer_should_see(@"Usage: steeltoe \[options\] \[command\]")
);
}
[Scenario]
[Label("help")]
public void ProgramHelp()
{
Runner.RunScenario(
given => a_dotnet_project("main_help"),
when => the_developer_runs_steeltoe_command("--help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Steeltoe Developer Tools"),
and => the_developer_should_see(@"-V\|--version\s+Show version information"),
and => the_developer_should_see(@"-\?\|-h\|--help\s+Show help information"),
and => the_developer_should_see(@"target\s+Target the deployment environment\."),
and => the_developer_should_see(@"add\s+Add a service\."),
and => the_developer_should_see(@"remove\s+Remove a service\."),
and => the_developer_should_see(@"enable\s+Enable a service\."),
and => the_developer_should_see(@"disable\s+Disable a service\."),
and => the_developer_should_see(@"deploy\s+Start enabled services in the targeted deployment environment\."),
and => the_developer_should_see(@"undeploy\s+Stop running services in the targeted deployment environment\."),
and => the_developer_should_see(@"status\s+Show the status of a service in the targeted deployment environment\. If run with no args, show the status of all services\."),
and => the_developer_should_see(@"list\s+List services, service types, or deployment environments\. If run with no args, list everything\.")
);
}
[Scenario]
[Label("version")]
public void ProgramVersion()
{
Runner.RunScenario(
given => a_dotnet_project("main_version"),
when => the_developer_runs_steeltoe_command("--version"),
then => the_command_should_succeed(),
and => the_developer_should_see("1.0.0")
);
}
}
}

Просмотреть файл

@ -1,97 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("remove")]
public class RemoveFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void RemoveHelp()
{
Runner.RunScenario(
given => a_dotnet_project("remove_help"),
when => the_developer_runs_steeltoe_command("remove --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Remove a service\."),
and => the_developer_should_see(@"\s+name\s+Service name")
);
}
[Scenario]
public void RemoveNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("remove_not_enough_args"),
when => the_developer_runs_steeltoe_command("remove"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Service name not specified")
);
}
[Scenario]
public void RemoveTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("remove_too_many_args"),
when => the_developer_runs_steeltoe_command("remove arg1 arg2"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg2'")
);
}
// [Scenario]
// public void RemoveServiceWithoutToolingConfiguration()
// {
// Runner.RunScenario(
// given => a_dotnet_project("remove_service_without_tooling_configuration"),
// when => the_developer_runs_steeltoe_command("remove-service unknown-service"),
// then => the_command_should_fail_with(1),
// and => the_developer_should_see_the_error("Unknown service 'unknown-service'")
// );
// }
// [Scenario]
// public void RemoveUnknownService()
// {
// Runner.RunScenario(
// given => a_dotnet_project("remove_unknown_service"),
// and => a_service("known-service", "known-service-type"),
// when => the_developer_runs_steeltoe_command("remove-service unknown-service"),
// then => the_command_should_fail_with(1),
// and => the_developer_should_see_the_error("Unknown service 'unknown-service'")
// );
// }
// [Scenario]
// public void RemoveKnownService()
// {
// Runner.RunScenario(
// given => a_dotnet_project("remove_known_service"),
// and => a_target("keep-this-target"),
// and => a_service("known-service", "known-service-type"),
// when => the_developer_runs_steeltoe_command("remove-service known-service"),
// then => the_command_should_succeed(),
// and => the_developer_should_see("Removed service 'known-service'"),
// and => the_service_config_should_not_exist("known-service"),
// and => the_target_config_should_exist("keep-this-target")
// );
// }
}
}

Просмотреть файл

@ -1,48 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("status")]
public class StatusFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void StatusHelp()
{
Runner.RunScenario(
given => a_dotnet_project("status_help"),
when => the_developer_runs_steeltoe_command("status --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Show the status of a service in the targeted deployment environment\. If run with no args, show the status of all services\."),
and => the_developer_should_see(@"\s+name\s+Service name")
);
}
[Scenario]
public void StatusTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("status_too_many_args"),
when => the_developer_runs_steeltoe_command("status arg1 arg2"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg2'")
);
}
}
}

Просмотреть файл

@ -1,84 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("target")]
public class TargetFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void TargetHelp()
{
Runner.RunScenario(
given => a_dotnet_project("target_help"),
when => the_developer_runs_steeltoe_command("target --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Target the deployment environment\. If run with no args, show the targeted deployment environment\."),
and => the_developer_should_see(@"\s+environment\s+Deployment environment\s+\(run 'steeltoe list targets' for available deployment environments\)"),
and => the_developer_should_see(@"\s+-F\|--force\s+Target the deployment environment even if checks fail")
);
}
[Scenario]
public void TargetTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("target_too_many_args"),
when => the_developer_runs_steeltoe_command("target arg1 arg2"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg2'")
);
}
// [Scenario]
// public void SetUnknownTargetType()
// {
// Runner.RunScenario(
// given => a_dotnet_project("set_unknown_environment"),
// when => the_developer_runs_steeltoe_command("set-target no-such-environment"),
// then => the_command_should_fail_with(1),
// and => the_developer_should_see_the_error("Unknown environment 'no-such-environment'")
// );
// }
// [Scenario]
// public void SetCloudFoundryTarget()
// {
// Runner.RunScenario(
// given => a_dotnet_project("set_cloud_foundry_target"),
// when => the_developer_runs_steeltoe_command("set-target cloud-foundry"),
// then => the_command_should_succeed(),
// and => the_developer_should_see("Target environment set to 'cloud-foundry'."),
// and => the_target_config_should_exist("cloud-foundry")
// );
// }
// [Scenario]
// public void SetDockerTarget()
// {
// Runner.RunScenario(
// given => a_dotnet_project("set_docker_target"),
// when => the_developer_runs_steeltoe_command("set-target docker"),
// then => the_command_should_succeed(),
// and => the_developer_should_see("Target environment set to 'docker'"),
// and => the_target_config_should_exist("docker")
// );
// }
}
}

Просмотреть файл

@ -1,47 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Feature
{
[Label("undeploy")]
public class UndeployFeature : CliFeatureSpecs
{
[Scenario]
[Label("help")]
public void UndeployHelp()
{
Runner.RunScenario(
given => a_dotnet_project("undeploy_help"),
when => the_developer_runs_steeltoe_command("undeploy --help"),
then => the_command_should_succeed(),
and => the_developer_should_see(@"Stop running services in the targeted deployment environment\.")
);
}
[Scenario]
public void UndeployTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("undeploy_too_many_args"),
when => the_developer_runs_steeltoe_command("undeploy arg1"),
then => the_command_should_fail_with(1),
and => the_developer_should_see_the_error("Unrecognized command or argument 'arg1'")
);
}
}
}

Просмотреть файл

@ -0,0 +1,96 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("add")]
public class AddFeature : ServiceFeatureSpecs
{
[Scenario]
[Label("help")]
public void AddHelp()
{
Runner.RunScenario(
given => a_dotnet_project("add_help"),
when => the_developer_runs_cli_command("add --help"),
and => the_cli_should_output("Add a service."),
and => the_cli_should_output("name Service name"),
and => the_cli_should_output(
"type Service type (run 'steeltoe list types' for available service types)")
);
}
[Scenario]
public void AddNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("add_not_enough_args0"),
when => the_developer_runs_cli_command("add"),
and => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
Runner.RunScenario(
given => a_dotnet_project("add_not_enough_args1"),
when => the_developer_runs_cli_command("add myservice"),
and => the_cli_should_error(ErrorCode.Argument, "Service type not specified")
);
}
[Scenario]
public void AddTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("add_too_many_args"),
when => the_developer_runs_cli_command("add arg1 arg2 arg3"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg3'")
);
}
[Scenario]
public void AddUnknownServiceType()
{
Runner.RunScenario(
given => a_steeltoe_project("add_unknown_service_type"),
when => the_developer_runs_cli_command("add foo no-such-type"),
and => the_cli_should_error(ErrorCode.Tooling, "Unknown service type 'no-such-type'")
);
}
[Scenario]
public void AddService()
{
Runner.RunScenario(
given => a_steeltoe_project("add_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_cli_should_output("Added dummy-svc service 'my-service'"),
and => the_configuration_should_contain_service("my-service"),
and => the_configuration_service_should_be_enabled("my-service")
);
}
[Scenario]
public void AddPreExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("add_pre_existing_service"),
when => the_developer_runs_cli_command("add existing-service dummy-svc"),
and => the_developer_runs_cli_command("add existing-service dummy-svc"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'existing-service' already exists")
);
}
}
}

Просмотреть файл

@ -0,0 +1,93 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("deploy")]
public class DeployFeature : FeatureSpecs
{
[Scenario]
[Label("help")]
public void DeployHelp()
{
Runner.RunScenario(
given => a_steeltoe_project("deploy_help"),
when => the_developer_runs_cli_command("deploy --help"),
and => the_cli_should_output("Start an enabled service in the targeted deployment environment."),
and => the_cli_should_output("name Service name")
);
}
[Scenario]
public void DeployNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("deploy_not_enough_args"),
when => the_developer_runs_cli_command("deploy"),
and => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void DeployTooManyArgs()
{
Runner.RunScenario(
given => a_steeltoe_project("deploy_too_many_args"),
when => the_developer_runs_cli_command("deploy arg1 arg2"),
then => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void DeployService()
{
Runner.RunScenario(
given => a_steeltoe_project("deploy_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_developer_runs_cli_command("deploy my-service"),
then => the_cli_should_output("Deployed service 'my-service'"),
when => the_developer_runs_cli_command("status my-service"),
then => the_cli_should_output("starting"),
when => the_developer_runs_cli_command("status my-service"),
then => the_cli_should_output("online")
);
}
[Scenario]
public void DeployNonExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("deploy_non_existing_service"),
when => the_developer_runs_cli_command("deploy unknown-service"),
and => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found")
);
}
[Scenario]
public void DeployDisabledService()
{
Runner.RunScenario(
given => a_steeltoe_project("deploy_disabled_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_developer_runs_cli_command("disable my-service"),
and => the_developer_runs_cli_command("deploy my-service"),
and => the_cli_should_error(ErrorCode.Tooling, "Invalid service status 'disabled'")
);
}
}
}

Просмотреть файл

@ -0,0 +1,78 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("disable")]
public class DisableFeature : ServiceFeatureSpecs
{
[Scenario]
[Label("help")]
public void DisableHelp()
{
Runner.RunScenario(
given => a_dotnet_project("disable_help"),
when => the_developer_runs_cli_command("disable --help"),
and => the_cli_should_output("Disable a service."),
and => the_cli_should_output("name Service name")
);
}
[Scenario]
public void DisableNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("disable_not_enough_args"),
when => the_developer_runs_cli_command("disable"),
and => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void DisableTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("disable_too_many_args"),
when => the_developer_runs_cli_command("disable arg1 arg2"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void DisableService()
{
Runner.RunScenario(
given => a_steeltoe_project("disable_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_developer_runs_cli_command("disable my-service"),
then => the_cli_should_output("disabled service 'my-service'"),
and => the_configuration_service_should_not_be_enabled("my-service")
);
}
[Scenario]
public void DisableNonExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("disable_non_existing_service"),
when => the_developer_runs_cli_command("disable unknown-service"),
and => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found")
);
}
}
}

Просмотреть файл

@ -0,0 +1,79 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("enable")]
public class EnableFeature : ServiceFeatureSpecs
{
[Scenario]
[Label("help")]
public void EnableHelp()
{
Runner.RunScenario(
given => a_dotnet_project("enable_help"),
when => the_developer_runs_cli_command("enable --help"),
and => the_cli_should_output("Enable a service."),
and => the_cli_should_output("name Service name")
);
}
[Scenario]
public void EnableNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("enable_not_enough_args"),
when => the_developer_runs_cli_command("enable"),
and => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void EnableTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("enable_too_many_args"),
when => the_developer_runs_cli_command("enable arg1 arg2"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void EnableService()
{
Runner.RunScenario(
given => a_steeltoe_project("enable_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_developer_runs_cli_command("disable my-service"),
and => the_developer_runs_cli_command("enable my-service"),
then => the_cli_should_output("Enabled service 'my-service'"),
and => the_configuration_service_should_be_enabled("my-service")
);
}
[Scenario]
public void EnableNonExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("enable_non_existing_service"),
when => the_developer_runs_cli_command("enable unknown-service"),
and => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found")
);
}
}
}

Просмотреть файл

@ -0,0 +1,114 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using LightBDD.XUnit2;
using Microsoft.Extensions.Logging;
using Shouldly;
using Steeltoe.Tooling;
namespace Steeltoe.Cli.Test
{
public class FeatureSpecs : FeatureFixture
{
private string CliProjectDirectory { get; } = Path.GetFullPath(Path.Combine(
Directory.GetCurrentDirectory(),
"../../../../../src/Steeltoe.Cli"));
protected enum ErrorCode
{
Argument = 1,
Tooling = 2
}
protected static ILogger Logger { get; } = Logging.LoggerFactory.CreateLogger<FeatureSpecs>();
protected Shell _shell = new CommandShell();
protected Shell.Result _shellResult;
protected string _shellOut;
protected string _shellError;
protected string _projectDirectory;
//
// Givens
//
protected void a_dotnet_project(string name)
{
Logger.LogInformation($"rigging a dotnet project '{name}'");
_projectDirectory = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), "sandboxes"), name);
if (Directory.Exists(_projectDirectory))
{
Directory.Delete(_projectDirectory, true);
}
Directory.CreateDirectory(_projectDirectory);
_shell.Run("dotnet", "new classlib", _projectDirectory).ExitCode.ShouldBe(0);
File.Create(Path.Combine(_projectDirectory, ".steeltoe.dummies")).Dispose();
}
protected void a_steeltoe_project(string name)
{
a_dotnet_project(name);
Logger.LogInformation($"enabling steeltoe developer tools");
var cfg = new ConfigurationFile(_projectDirectory);
cfg.EnvironmentName = "dummy-env";
cfg.Store();
}
//
// Whens
//
protected void the_developer_runs_cli_command(string command)
{
Logger.LogInformation($"checking the developer runs cli command '{command}'");
_shellResult = _shell.Run("dotnet", $"run --project {CliProjectDirectory} -- {command}",
_projectDirectory);
_shellOut = string.Join(" ", _shellResult.Out.Split(new char[0], StringSplitOptions.RemoveEmptyEntries));
_shellError = string.Join(" ",
_shellResult.Error.Split(new char[0], StringSplitOptions.RemoveEmptyEntries));
}
//
// Thens
//
protected void the_cli_command_should_succeed()
{
Logger.LogInformation($"checking the command succeeded");
_shellResult.ExitCode.ShouldBe(0);
}
protected void the_cli_should_output(string message)
{
the_cli_command_should_succeed();
Logger.LogInformation($"checking the cli output '{message}'");
_shellOut.ShouldContain(message);
}
protected void the_cli_should_error(ErrorCode code, string error)
{
Logger.LogInformation($"checking the command failed with {(int) code}");
_shellResult.ExitCode.ShouldBe((int) code);
Logger.LogInformation($"checking the cli errored '{error}'");
_shellError.ShouldContain(error);
}
}
}

Просмотреть файл

@ -0,0 +1,68 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("init")]
public class InitFeature : FeatureSpecs
{
[Scenario]
[Label("help")]
public void InitHelp()
{
Runner.RunScenario(
given => a_dotnet_project("init_help"),
when => the_developer_runs_cli_command("init --help"),
and => the_cli_should_output("Initialize a project for Steeltoe Developer Tools."),
and => the_cli_should_output("-F|--force Initialize the project even if already initialized")
);
}
[Scenario]
public void InitTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("init_too_many_args"),
when => the_developer_runs_cli_command("init arg1"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg1'")
);
}
[Scenario]
public void InitProject()
{
Runner.RunScenario(
given => a_dotnet_project("init_project"),
when => the_developer_runs_cli_command("init"),
and => the_cli_should_output("Project initialized for Steeltoe Developer Tools")
);
}
[Scenario]
public void InitProjectAlreadyInitialized()
{
Runner.RunScenario(
given => a_steeltoe_project("init_project_already_initialized"),
when => the_developer_runs_cli_command("init"),
and => the_cli_should_error(ErrorCode.Tooling, "Project already initialized"),
when => the_developer_runs_cli_command("init --force"),
and => the_cli_should_output("Project initialized for Steeltoe Developer Tools")
);
}
}
}

Просмотреть файл

@ -0,0 +1,100 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("list")]
public class ListFeature : ListFeatureSpecs
{
[Scenario]
[Label("help")]
public void ListHelp()
{
Runner.RunScenario(
given => a_dotnet_project("list_help"),
when => the_developer_runs_cli_command("list --help"),
and => the_cli_should_output(
"List services, service types, or deployment environments. If run with no args, list everything."),
and => the_cli_should_output("scope One of: services, types, environments")
);
}
[Scenario]
public void ListNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("list_not_enough_args"),
when => the_developer_runs_cli_command("list"),
and => the_cli_should_error(ErrorCode.Argument, "List scope not specified")
);
}
[Scenario]
public void ListTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("list_too_many_args"),
when => the_developer_runs_cli_command("list arg1 arg2"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void ListUnknownScope()
{
Runner.RunScenario(
given => a_dotnet_project("list_unknown_scope"),
when => the_developer_runs_cli_command("list unknown-scope"),
and => the_cli_should_error(ErrorCode.Tooling, "Unknown list scope 'unknown-scope")
);
}
[Scenario]
public void ListEnvironments()
{
Runner.RunScenario(
given => a_dotnet_project("list_environments"),
when => the_developer_runs_cli_command("list environments"),
and => the_cli_should_list_available_environments()
);
}
[Scenario]
public void ListTypes()
{
Runner.RunScenario(
given => a_dotnet_project("list_types"),
when => the_developer_runs_cli_command("list types"),
and => the_cli_should_list_available_service_types()
);
}
[Scenario]
public void ListServices()
{
Runner.RunScenario(
given => a_steeltoe_project("list_services"),
and => the_developer_runs_cli_command("add z-service dummy-svc"),
when => the_developer_runs_cli_command("add a-service dummy-svc"),
and => the_developer_runs_cli_command("add 9-service dummy-svc"),
and => the_developer_runs_cli_command("list services"),
then => the_cli_should_list_services(new[]{"a-service", "z-service", "9-service"})
);
}
}
}

Просмотреть файл

@ -0,0 +1,60 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Shouldly;
namespace Steeltoe.Cli.Test
{
public class ListFeatureSpecs : FeatureSpecs
{
protected void the_cli_should_list_available_environments()
{
the_cli_command_should_succeed();
string[] expected =
{
"dummy-env (A dummy environment for testing Steeltoe Developer Tools",
"cloud-foundry (Cloud Foundry)",
"docker (Docker)"
};
foreach (string env in expected)
{
_shellOut.ShouldContain(env);
}
}
protected void the_cli_should_list_available_service_types()
{
the_cli_command_should_succeed();
string[] expected =
{
"dummy-svc (A dummy service for testing Steeltoe Developer Tools)",
"config-server (Cloud Foundry Config Server)",
"registry (Netflix Eureka Server)"
};
foreach (string type in expected)
{
_shellOut.ShouldContain(type);
}
}
protected void the_cli_should_list_services(string[] expected)
{
the_cli_command_should_succeed();
foreach (string service in expected)
{
_shellOut.ShouldContain(service);
}
}
}
}

Просмотреть файл

@ -0,0 +1,71 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("program")]
public class ProgramFeature : FeatureSpecs
{
// [Scenario]
// public void ProgramNoArgs()
// {
// Runner.RunScenario(
// given => a_dotnet_project("program_no_args"),
// when => the_developer_runs_cli_command(""),
// and => the_cli_should_error(1, "Usage: steeltoe [options] [command]")
// );
// }
[Scenario]
[Label("help")]
public void ProgramHelp()
{
Runner.RunScenario(
given => a_dotnet_project("program_help"),
when => the_developer_runs_cli_command("--help"),
and => the_cli_should_output("Steeltoe Developer Tools"),
and => the_cli_should_output("-D|--debug Enable debug output"),
and => the_cli_should_output("-V|--version Show version information"),
and => the_cli_should_output("-?|-h|--help Show help information"),
and => the_cli_should_output("target Target the deployment environment."),
and => the_cli_should_output("add Add a service."),
and => the_cli_should_output("remove Remove a service."),
and => the_cli_should_output("enable Enable a service."),
and => the_cli_should_output("disable Disable a service."),
and => the_cli_should_output("deploy Start an enabled service in the targeted deployment environment."),
and => the_cli_should_output("init Initialize a project for Steeltoe Developer Tools."),
and => the_cli_should_output("undeploy Stop an enabled service in the targeted deployment environment."),
and => the_cli_should_output(
"status Show the status of a service in the targeted deployment environment. If run with no args, show the status of all services"),
and => the_cli_should_output(
"list List services, service types, or deployment environments. If run with no args, list everything.")
);
}
[Scenario]
[Label("version")]
public void ProgramVersion()
{
Runner.RunScenario(
given => a_dotnet_project("program_version"),
when => the_developer_runs_cli_command("--version"),
and => the_cli_should_output("1.0.0")
);
}
}
}

Просмотреть файл

@ -0,0 +1,78 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("remove")]
public class RemoveFeature : ServiceFeatureSpecs
{
[Scenario]
[Label("help")]
public void RemoveHelp()
{
Runner.RunScenario(
given => a_dotnet_project("remove_help"),
when => the_developer_runs_cli_command("remove --help"),
and => the_cli_should_output("Remove a service."),
and => the_cli_should_output("name Service name")
);
}
[Scenario]
public void RemoveNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("remove_not_enough_args"),
when => the_developer_runs_cli_command("remove"),
and => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void RemoveTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("remove_too_many_args"),
when => the_developer_runs_cli_command("remove arg1 arg2"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void RemoveService()
{
Runner.RunScenario(
given => a_steeltoe_project("remove_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_developer_runs_cli_command("remove my-service"),
then => the_cli_should_output("Removed service 'my-service'"),
and => the_configuration_should_not_contain_service("my-service")
);
}
[Scenario]
public void RemoveNonExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("remove_non_existing_service"),
when => the_developer_runs_cli_command("remove unknown-service"),
and => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found")
);
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Microsoft.Extensions.Logging;
using Shouldly;
using Steeltoe.Tooling;
namespace Steeltoe.Cli.Test
{
public class ServiceFeatureSpecs : FeatureSpecs
{
protected void the_configuration_should_contain_service(string service)
{
Logger.LogInformation($"checking the service '{service}' exists");
new ConfigurationFile(_projectDirectory).Services.Keys.ShouldContain(service);
}
protected void the_configuration_should_not_contain_service(string service)
{
Logger.LogInformation($"checking the service '{service}' does not exist");
new ConfigurationFile(_projectDirectory).Services.Keys.ShouldNotContain(service);
}
protected void the_configuration_service_should_be_enabled(string service)
{
Logger.LogInformation($"checking the service '{service}' is enabled");
new ConfigurationFile(_projectDirectory).Services[service].Enabled.ShouldBeTrue();
}
protected void the_configuration_service_should_not_be_enabled(string service)
{
Logger.LogInformation($"checking the service '{service}' is not enabled");
new ConfigurationFile(_projectDirectory).Services[service].Enabled.ShouldBeFalse();
}
}
}

Просмотреть файл

@ -0,0 +1,71 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("status")]
public class StatusFeature : FeatureSpecs
{
[Scenario]
[Label("help")]
public void StatusHelp()
{
Runner.RunScenario(
given => a_dotnet_project("status_help"),
when => the_developer_runs_cli_command("status --help"),
and => the_cli_should_output(
"Show the status of a service in the targeted deployment environment. If run with no args, show the status of all services."),
and => the_cli_should_output("name Service name")
);
}
[Scenario]
public void StatusTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("status_too_many_args"),
when => the_developer_runs_cli_command("status arg1 arg2"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void StatusDisabled()
{
Runner.RunScenario(
given => a_steeltoe_project("status_disabled"),
when => the_developer_runs_cli_command("add a-service dummy-svc"),
and => the_developer_runs_cli_command("disable a-service"),
and => the_developer_runs_cli_command("status a-service"),
and => the_cli_should_output("disabled")
);
}
[Scenario]
public void StatusOffline()
{
Runner.RunScenario(
given => a_steeltoe_project("status_offline"),
when => the_developer_runs_cli_command("add a-service dummy-svc"),
and => the_developer_runs_cli_command("enable a-service"),
and => the_developer_runs_cli_command("status a-service"),
and => the_cli_should_output("offline")
);
}
}
}

Просмотреть файл

@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\versions.props" />
<Import Project="..\..\config\versions.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>

Просмотреть файл

@ -17,9 +17,9 @@ using System.IO;
using System.Runtime.InteropServices;
using LightBDD.XUnit2;
using Shouldly;
using Steeltoe.Tooling.System;
using Steeltoe.Tooling;
namespace Steeltoe.Cli.Feature
namespace Steeltoe.Cli.Test
{
public partial class SystemShellFeature : FeatureFixture
{

Просмотреть файл

@ -13,19 +13,19 @@
// limitations under the License.
using System.IO;
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
using Steeltoe.Tooling.System;
using Steeltoe.Tooling;
namespace Steeltoe.Cli.Feature
namespace Steeltoe.Cli.Test
{
public partial class SystemShellFeature
{
[Scenario]
public void RunCommand()
{
Runner.RunScenario(
when => the_command_is_run(ListCommand),
ExtendedScenarioExtensions.RunScenario<NoContext>(Runner, when => the_command_is_run(SystemShellFeature.ListCommand),
then => the_command_should_succeed(),
and => the_command_output_should_not_be_empty()
);
@ -35,10 +35,9 @@ namespace Steeltoe.Cli.Feature
public void RunCommandWithArgs()
{
string sandbox = Path.Combine("sandboxes", "run_command_with_args");
Runner.RunScenario(
given => a_directory(sandbox),
ExtendedScenarioExtensions.RunScenario<NoContext>(Runner, given => a_directory(sandbox),
and => a_file(Path.Combine(sandbox, "aFile")),
when => the_command_is_run_with_args(ListCommand, sandbox),
when => the_command_is_run_with_args(SystemShellFeature.ListCommand, sandbox),
then => the_command_should_succeed(),
and => the_command_output_should_contain("aFile")
);
@ -48,10 +47,9 @@ namespace Steeltoe.Cli.Feature
public void RunCommandWithWorkingDirectory()
{
string sandbox = Path.Combine("sandboxes", "run_command_with_working_directory");
Runner.RunScenario(
given => a_directory(sandbox),
ExtendedScenarioExtensions.RunScenario<NoContext>(Runner, given => a_directory(sandbox),
and => a_file(Path.Combine(sandbox, "aFile")),
when => the_command_is_run_with_working_directory(ListCommand, sandbox),
when => the_command_is_run_with_working_directory(SystemShellFeature.ListCommand, sandbox),
then => the_command_should_succeed(),
and => the_command_output_should_contain("aFile")
);
@ -60,8 +58,7 @@ namespace Steeltoe.Cli.Feature
[Scenario]
public void RunCommandThatErrors()
{
Runner.RunScenario(
when => the_command_is_run(ErrorCommand),
ExtendedScenarioExtensions.RunScenario<NoContext>(Runner, when => the_command_is_run(SystemShellFeature.ErrorCommand),
then => the_command_should_fail()
);
}
@ -69,8 +66,7 @@ namespace Steeltoe.Cli.Feature
[Scenario]
public void RunNoSuchCommand()
{
Runner.RunScenario(
when => the_command_is_run("NoSuchCommand"),
ExtendedScenarioExtensions.RunScenario<NoContext>(Runner, when => the_command_is_run("NoSuchCommand"),
then => the_command_should_raise_exception<ShellException>()
);
}

Просмотреть файл

@ -0,0 +1,92 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("target")]
public class TargetFeature : TargetFeatureSpecs
{
[Scenario]
[Label("help")]
public void TargetHelp()
{
Runner.RunScenario(
given => a_dotnet_project("target_help"),
when => the_developer_runs_cli_command("target --help"),
and => the_cli_should_output(
"Target the deployment environment. If run with no args, show the targeted deployment environment."),
and => the_cli_should_output(
"environment Deployment environment (run 'steeltoe list targets' for available deployment environments)"),
and => the_cli_should_output("-F|--force Target the deployment environment even if checks fail")
);
}
[Scenario]
public void TargetTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("target_too_many_args"),
when => the_developer_runs_cli_command("target arg1 arg2"),
and => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void TargetEnvironment()
{
Runner.RunScenario(
given => a_dotnet_project("target_environment"),
when => the_developer_runs_cli_command("init"),
and => the_developer_runs_cli_command("target dummy-env"),
and => the_cli_should_output("Target deployment environment set to 'dummy-env'."),
and => the_configuration_should_target("dummy-env")
);
}
[Scenario]
public void TargetUnknownEnvironment()
{
Runner.RunScenario(
given => a_steeltoe_project("target_unknown_environment"),
when => the_developer_runs_cli_command("target no-such-environment"),
and => the_cli_should_error(ErrorCode.Tooling, "Unknown deployment environment 'no-such-environment'")
);
}
[Scenario]
public void TargetUninitializedProject()
{
Runner.RunScenario(
given => a_dotnet_project("target_uninitialized_project"),
when => the_developer_runs_cli_command("target"),
and => the_cli_should_error(ErrorCode.Tooling,
"Project has not been initialized for Steeltoe Developer Tools")
);
}
[Scenario]
public void ShowTargetEnvironment()
{
Runner.RunScenario(
given => a_steeltoe_project("show_target_environment"),
when => the_developer_runs_cli_command("target"),
and => the_cli_should_output("Target deployment environment set to 'dummy-env'.")
);
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Microsoft.Extensions.Logging;
using Shouldly;
using Steeltoe.Tooling;
namespace Steeltoe.Cli.Test
{
public class TargetFeatureSpecs : FeatureSpecs
{
protected void the_configuration_should_target(string env)
{
Logger.LogInformation($"checking the target config '{env}' exists");
new ConfigurationFile(_projectDirectory).EnvironmentName.ShouldBe(env);
}
}
}

Просмотреть файл

@ -0,0 +1,76 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("undeploy")]
public class UndeployFeature : FeatureSpecs
{
[Scenario]
[Label("help")]
public void UndeployHelp()
{
Runner.RunScenario(
given => a_steeltoe_project("undeploy_help"),
when => the_developer_runs_cli_command("undeploy --help"),
and => the_cli_should_output("Stop an enabled service in the targeted deployment environment."),
and => the_cli_should_output("name Service name")
);
}
[Scenario]
public void UndeployNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("undeploy_not_enough_args"),
when => the_developer_runs_cli_command("undeploy"),
and => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void UndeployTooManyArgs()
{
Runner.RunScenario(
given => a_steeltoe_project("undeploy_too_many_args"),
when => the_developer_runs_cli_command("undeploy arg1 arg2"),
then => the_cli_should_error(ErrorCode.Argument, "Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void UndeployService()
{
Runner.RunScenario(
given => a_steeltoe_project("undeploy_service"),
when => the_developer_runs_cli_command("add my-service dummy-svc"),
and => the_developer_runs_cli_command("deploy my-service"),
when => the_developer_runs_cli_command("status my-service"),
then => the_cli_should_output("starting"),
when => the_developer_runs_cli_command("status my-service"),
then => the_cli_should_output("online"),
when => the_developer_runs_cli_command("undeploy my-service"),
then => the_cli_should_output("Undeployed service 'my-service'"),
when => the_developer_runs_cli_command("status my-service"),
then => the_cli_should_output("stopping"),
when => the_developer_runs_cli_command("status my-service"),
then => the_cli_should_output("offline")
);
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше