21
#include "AsyncExecution.h"
22
#include "Command.h"
23
#include "RootCommand.h"
24
+#include "ArgumentValidation.h"
25
#include "ContainerCommand.h"
26
#include "ContainerTasks.h"
27
401
402
const auto& options = context.Data.Get<Data::ContainerOptions>();
403
VERIFY_ARE_EQUAL(1u, options.Networks.size());
403
- VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0]);
404
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
405
}
406
407
TEST_METHOD(RunCommand_ParseNetworkMultipleValues_PreservesOrder)
417
418
const auto& options = context.Data.Get<Data::ContainerOptions>();
419
VERIFY_ARE_EQUAL(2u, options.Networks.size());
419
- VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0]);
420
- VERIFY_ARE_EQUAL(std::string("net2"), options.Networks[1]);
420
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
421
+ VERIFY_ARE_EQUAL(std::string("net2"), options.Networks[1].Name);
422
+ }
423
+
424
+ TEST_METHOD(RunCommand_ParseDockerNetworkAliases_SetsPerNetworkAliases)
425
+ {
426
+ auto invocation =
427
+ CreateInvocationFromCommandLine(L"wslc --network name=net1,alias=a,alias=b --network name=net2,alias=c ubuntu sh");
428
+
429
+ ContainerRunCommand command{L""};
430
+ CLIExecutionContext context;
431
+ command.ParseArguments(invocation, context.Args);
432
+ command.ValidateArguments(context.Args);
433
+
434
+ wsl::windows::wslc::task::SetContainerOptionsFromArgs(context);
435
+
436
+ const auto& options = context.Data.Get<Data::ContainerOptions>();
437
+ VERIFY_ARE_EQUAL(2u, options.Networks.size());
438
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
439
+ VERIFY_ARE_EQUAL(2u, options.Networks[0].Aliases.size());
440
+ VERIFY_ARE_EQUAL(std::string("a"), options.Networks[0].Aliases[0]);
441
+ VERIFY_ARE_EQUAL(std::string("b"), options.Networks[0].Aliases[1]);
442
+ VERIFY_ARE_EQUAL(std::string("net2"), options.Networks[1].Name);
443
+ VERIFY_ARE_EQUAL(1u, options.Networks[1].Aliases.size());
444
+ VERIFY_ARE_EQUAL(std::string("c"), options.Networks[1].Aliases[0]);
445
+ }
446
+
447
+ TEST_METHOD(RunCommand_ParseDockerNetworkAliasesWithNameAfterAlias_SetsPerNetworkAliases)
448
+ {
449
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network alias=a,name=net1,alias=b ubuntu sh");
450
+
451
+ ContainerRunCommand command{L""};
452
+ CLIExecutionContext context;
453
+ command.ParseArguments(invocation, context.Args);
454
+ command.ValidateArguments(context.Args);
455
+
456
+ wsl::windows::wslc::task::SetContainerOptionsFromArgs(context);
457
+
458
+ const auto& options = context.Data.Get<Data::ContainerOptions>();
459
+ VERIFY_ARE_EQUAL(1u, options.Networks.size());
460
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
461
+ VERIFY_ARE_EQUAL(2u, options.Networks[0].Aliases.size());
462
+ VERIFY_ARE_EQUAL(std::string("a"), options.Networks[0].Aliases[0]);
463
+ VERIFY_ARE_EQUAL(std::string("b"), options.Networks[0].Aliases[1]);
464
}
465
466
TEST_METHOD(RunCommand_ParseNetworkEmptyValue_ThrowsArgumentException)
488
489
const auto& options = context.Data.Get<Data::ContainerOptions>();
490
VERIFY_ARE_EQUAL(1u, options.Networks.size());
448
- VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0]);
491
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
492
}
493
494
TEST_METHOD(CreateCommand_ParseNetworkMultipleValues_PreservesOrder)
504
505
const auto& options = context.Data.Get<Data::ContainerOptions>();
506
VERIFY_ARE_EQUAL(2u, options.Networks.size());
464
- VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0]);
465
- VERIFY_ARE_EQUAL(std::string("net2"), options.Networks[1]);
507
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
508
+ VERIFY_ARE_EQUAL(std::string("net2"), options.Networks[1].Name);
509
+ }
510
+
511
+ TEST_METHOD(CreateCommand_ParseDockerNetworkAliases_SetsPerNetworkAliases)
512
+ {
513
+ auto invocation =
514
+ CreateInvocationFromCommandLine(L"wslc --network name=net1,alias=a,alias=b --network name=net2,alias=c ubuntu sh");
515
+
516
+ ContainerCreateCommand command{L""};
517
+ CLIExecutionContext context;
518
+ command.ParseArguments(invocation, context.Args);
519
+ command.ValidateArguments(context.Args);
520
+
521
+ wsl::windows::wslc::task::SetContainerOptionsFromArgs(context);
522
+
523
+ const auto& options = context.Data.Get<Data::ContainerOptions>();
524
+ VERIFY_ARE_EQUAL(2u, options.Networks.size());
525
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
526
+ VERIFY_ARE_EQUAL(2u, options.Networks[0].Aliases.size());
527
+ VERIFY_ARE_EQUAL(std::string("a"), options.Networks[0].Aliases[0]);
528
+ VERIFY_ARE_EQUAL(std::string("b"), options.Networks[0].Aliases[1]);
529
+ VERIFY_ARE_EQUAL(std::string("net2"), options.Networks[1].Name);
530
+ VERIFY_ARE_EQUAL(1u, options.Networks[1].Aliases.size());
531
+ VERIFY_ARE_EQUAL(std::string("c"), options.Networks[1].Aliases[0]);
532
+ }
533
+
534
+ TEST_METHOD(CreateCommand_ParseDockerNetworkAliasesWithNameAfterAlias_SetsPerNetworkAliases)
535
+ {
536
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network alias=a,name=net1,alias=b ubuntu sh");
537
+
538
+ ContainerCreateCommand command{L""};
539
+ CLIExecutionContext context;
540
+ command.ParseArguments(invocation, context.Args);
541
+ command.ValidateArguments(context.Args);
542
+
543
+ wsl::windows::wslc::task::SetContainerOptionsFromArgs(context);
544
+
545
+ const auto& options = context.Data.Get<Data::ContainerOptions>();
546
+ VERIFY_ARE_EQUAL(1u, options.Networks.size());
547
+ VERIFY_ARE_EQUAL(std::string("net1"), options.Networks[0].Name);
548
+ VERIFY_ARE_EQUAL(2u, options.Networks[0].Aliases.size());
549
+ VERIFY_ARE_EQUAL(std::string("a"), options.Networks[0].Aliases[0]);
550
+ VERIFY_ARE_EQUAL(std::string("b"), options.Networks[0].Aliases[1]);
551
+ }
552
+
553
+ TEST_METHOD(CreateCommand_ParseNetworkDuplicateNameOption_ThrowsArgumentException)
554
+ {
555
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network name=net1,name=net2 ubuntu sh");
556
+
557
+ ContainerCreateCommand command{L""};
558
+ CLIExecutionContext context;
559
+ command.ParseArguments(invocation, context.Args);
560
+
561
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
562
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkDuplicateNameError(L"network");
563
+ return exception.Message() == expectedMessage;
564
+ });
565
+ }
566
+
567
+ TEST_METHOD(CreateCommand_ParseNetworkUnsupportedOption_ThrowsArgumentException)
568
+ {
569
+ auto invocation = CreateInvocationFromCommandLine(
570
+ L"wslc --network name=net1,driver-opt=com.docker.network.endpoint.sysctls="
571
+ L"net.ipv4.conf.IFNAME.log_martians=1 ubuntu sh");
572
+
573
+ ContainerCreateCommand command{L""};
574
+ CLIExecutionContext context;
575
+ command.ParseArguments(invocation, context.Args);
576
+
577
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
578
+ const auto expectedMessage =
579
+ wsl::shared::Localization::WSLCCLI_NetworkUnsupportedOptionError(L"network", L"driver-opt");
580
+ return exception.Message() == expectedMessage;
581
+ });
582
+ }
583
+
584
+ TEST_METHOD(CreateCommand_ParseNetworkUnknownOption_ThrowsArgumentException)
585
+ {
586
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network name=net1,aliases=a ubuntu sh");
587
+
588
+ ContainerCreateCommand command{L""};
589
+ CLIExecutionContext context;
590
+ command.ParseArguments(invocation, context.Args);
591
+
592
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
593
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkUnsupportedOptionError(L"network", L"aliases");
594
+ return exception.Message() == expectedMessage;
595
+ });
596
+ }
597
+
598
+ TEST_METHOD(CreateCommand_ParseNetworkBackendAliasesOption_ThrowsArgumentException)
599
+ {
600
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network name=net1,Aliases=a ubuntu sh");
601
+
602
+ ContainerCreateCommand command{L""};
603
+ CLIExecutionContext context;
604
+ command.ParseArguments(invocation, context.Args);
605
+
606
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
607
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkUnsupportedOptionError(L"network", L"Aliases");
608
+ return exception.Message() == expectedMessage;
609
+ });
610
+ }
611
+
612
+ TEST_METHOD(CreateCommand_ParseNetworkAliasWithoutName_ThrowsArgumentException)
613
+ {
614
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network alias=a ubuntu sh");
615
+
616
+ ContainerCreateCommand command{L""};
617
+ CLIExecutionContext context;
618
+ command.ParseArguments(invocation, context.Args);
619
+
620
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
621
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkEmptyError(L"network");
622
+ return exception.Message() == expectedMessage;
623
+ });
624
+ }
625
+
626
+ TEST_METHOD(CreateCommand_ParseNetworkNameWhitespaceValue_ThrowsArgumentException)
627
+ {
628
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network \"name= \" ubuntu sh");
629
+
630
+ ContainerCreateCommand command{L""};
631
+ CLIExecutionContext context;
632
+ command.ParseArguments(invocation, context.Args);
633
+
634
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
635
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkEmptyError(L"network");
636
+ return exception.Message() == expectedMessage;
637
+ });
638
+ }
639
+
640
+ TEST_METHOD(ParseNetworkArgument_NameUnicodeWhitespaceValue_ThrowsArgumentException)
641
+ {
642
+ VERIFY_THROWS_SPECIFIC(
643
+ validation::ParseNetworkArgument(L"name=\u3000", L"network"), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
644
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkEmptyError(L"network");
645
+ return exception.Message() == expectedMessage;
646
+ });
647
+ }
648
+
649
+ TEST_METHOD(CreateCommand_ParseNetworkAliasEmptyValue_ThrowsArgumentException)
650
+ {
651
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network name=net1,alias= ubuntu sh");
652
+
653
+ ContainerCreateCommand command{L""};
654
+ CLIExecutionContext context;
655
+ command.ParseArguments(invocation, context.Args);
656
+
657
+ VERIFY_THROWS_SPECIFIC(command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
658
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkAliasEmptyError(L"network");
659
+ return exception.Message() == expectedMessage;
660
+ });
661
}
662
663
TEST_METHOD(CreateCommand_ParseNetworkEmptyValue_ThrowsArgumentException)
672
command.ValidateArguments(context.Args), wsl::windows::wslc::ArgumentException, [](const auto&) { return true; });
673
}
674
675
+ TEST_METHOD(CreateCommand_SetContainerOptionsInvalidNetwork_ThrowsArgumentExceptionWithArgumentName)
676
+ {
677
+ auto invocation = CreateInvocationFromCommandLine(L"wslc --network name=net1,name=net2 ubuntu sh");
678
+
679
+ ContainerCreateCommand command{L""};
680
+ CLIExecutionContext context;
681
+ command.ParseArguments(invocation, context.Args);
682
+
683
+ VERIFY_THROWS_SPECIFIC(
684
+ wsl::windows::wslc::task::SetContainerOptionsFromArgs(context), wsl::windows::wslc::ArgumentException, [](const auto& exception) {
685
+ const auto expectedMessage = wsl::shared::Localization::WSLCCLI_NetworkDuplicateNameError(L"network");
686
+ return exception.Message() == expectedMessage;
687
+ });
688
+ }
689
+
690
// Test: Command Line test parsing all cases defined in CommandLineTestCases.h
691
// This test verifies the command line parsing logic used by the CLI and executes the same
692
// code as the CLI up to the point of command execution, including parsing and argument validtion.